if (
(NULL == CU_add_test(pSuite, "test_signum()", test_signum)) ||
(NULL == CU_add_test(pSuite, "test_gbox_from_spherical_coordinates()", test_gbox_from_spherical_coordinates)) ||
-/* (NULL == CU_add_test(pSuite, "test_gserialized_get_gbox_geocentric()", test_gserialized_get_gbox_geocentric)) || */
+ (NULL == CU_add_test(pSuite, "test_gserialized_get_gbox_geocentric()", test_gserialized_get_gbox_geocentric)) ||
(NULL == CU_add_test(pSuite, "test_clairaut()", test_clairaut)) ||
(NULL == CU_add_test(pSuite, "test_edge_intersection()", test_edge_intersection)) ||
(NULL == CU_add_test(pSuite, "test_edge_distance_to_point()", test_edge_distance_to_point)) ||
extern double ptarray_locate_point(POINTARRAY *, POINT2D *);
extern void closest_point_on_segment(POINT2D *p, POINT2D *A, POINT2D *B, POINT2D *ret);
extern LWLINE *lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end);
+extern LWMLINE* lwmline_measured_from_lwmline(const LWMLINE *lwmline, double m_start, double m_end);
/*
* Ensure every segment is at most 'dist' long.
if( TYPE_GETTYPE(lwline->type) != LINETYPE )
{
- lwerror("lwmline_construct_from_lwline: only line types supported");
+ lwerror("lwline_construct_from_lwline: only line types supported");
return NULL;
}
}
+/**
+* Re-write the measure ordinate (or add one, if it isn't already there) interpolating
+* the measure between the supplied start and end values.
+*/
+LWMLINE*
+lwmline_measured_from_lwmline(const LWMLINE *lwmline, double m_start, double m_end)
+{
+ int i = 0;
+ int hasm = 0, hasz = 0;
+ double length = 0.0, length_so_far = 0.0;
+ double m_range = m_end - m_start;
+ LWGEOM **geoms = NULL;
+
+ if( TYPE_GETTYPE(lwmline->type) != MULTILINETYPE )
+ {
+ lwerror("lwmline_measured_from_lmwline: only multiline types supported");
+ return NULL;
+ }
+
+ hasz = TYPE_HASZ(lwmline->type);
+ hasm = 1;
+
+ /* Calculate the total length of the mline */
+ for( i = 0; i < lwmline->ngeoms; i++ )
+ {
+ LWLINE *lwline = (LWLINE*)lwmline->geoms[i];
+ if( lwline->points && lwline->points->npoints > 1 )
+ {
+ length += lwgeom_pointarray_length2d(lwline->points);
+ }
+ }
+
+ if( lwgeom_is_empty((LWGEOM*)lwmline) )
+ {
+ return (LWMLINE*)lwcollection_construct_empty(lwmline->SRID, hasz, hasm);
+ }
+
+ geoms = lwalloc(sizeof(LWGEOM*) * lwmline->ngeoms);
+
+ for( i = 0; i < lwmline->ngeoms; i++ )
+ {
+ double sub_m_start, sub_m_end;
+ double sub_length = 0.0;
+ LWLINE *lwline = (LWLINE*)lwmline->geoms[i];
+
+ if( lwline->points && lwline->points->npoints > 1 )
+ {
+ sub_length = lwgeom_pointarray_length2d(lwline->points);
+ }
+
+ sub_m_start = (m_start + m_range * length_so_far / length);
+ sub_m_end = (m_start + m_range * (length_so_far + sub_length) / length);
+
+ geoms[i] = (LWGEOM*)lwline_measured_from_lwline(lwline, sub_m_start, sub_m_end);
+
+ length_so_far += sub_length;
+ }
+
+ return (LWMLINE*)lwcollection_construct(lwmline->type, lwmline->SRID, NULL, lwmline->ngeoms, geoms);
+}
+
void lwmline_free(LWMLINE *mline)
{
int i;
double start_measure = PG_GETARG_FLOAT8(1);
double end_measure = PG_GETARG_FLOAT8(2);
LWGEOM *lwin, *lwout;
+ int type = TYPE_GETTYPE(gin->type);
- /* Raise an error if input is not a linestring */
- if ( TYPE_GETTYPE(gin->type) != LINETYPE )
+ /* Raise an error if input is not a linestring or multilinestring */
+ if ( type != LINETYPE && type != MULTILINETYPE )
{
- lwerror("Only LINESTRING is supported");
+ lwerror("Only LINESTRING and MULTILINESTRING are supported");
PG_RETURN_NULL();
}
lwin = pglwgeom_deserialize(gin);
- lwout = (LWGEOM*)lwline_measured_from_lwline((LWLINE*)lwin, start_measure, end_measure);
+ if( type == LINETYPE )
+ lwout = (LWGEOM*)lwline_measured_from_lwline((LWLINE*)lwin, start_measure, end_measure);
+ else
+ lwout = (LWGEOM*)lwmline_measured_from_lwmline((LWMLINE*)lwin, start_measure, end_measure);
+
lwgeom_release(lwin);
if ( lwout == NULL )