static LWMPOINT* lwmline_locate_along(const LWMLINE *lwmline, double m, double offset) { LWMPOINT *lwmpoint = NULL; LWGEOM *lwg = lwmline_as_lwgeom(lwmline); int i, j; /* Return degenerates upwards */ if ( (!lwmline) || (lwmline->ngeoms < 1) ) return NULL; /* Construct return */ lwmpoint = lwmpoint_construct_empty(lwgeom_get_srid(lwg), lwgeom_has_z(lwg), lwgeom_has_m(lwg)); /* Locate along each sub-line */ for ( i = 0; i < lwmline->ngeoms; i++ ) { LWMPOINT *along = lwline_locate_along(lwmline->geoms[i], m, offset); if ( along != NULL ) { for ( j = 0; j < along->ngeoms; j++ ) { lwmpoint_add_lwpoint(lwmpoint, along->geoms[i]); } /* Free the containing geometry, but leave the sub-geometries around */ if ( along->bbox ) lwfree(along->bbox); lwfree(along); } } return lwmpoint; }
void lwmline_release(LWMLINE *lwmline) { lwgeom_release(lwmline_as_lwgeom(lwmline)); }
/** * Clip an input MULTILINESTRING between two values, on any ordinate input. */ LWCOLLECTION* lwmline_clip_to_ordinate_range(const LWMLINE *mline, char ordinate, double from, double to) { LWCOLLECTION *lwgeom_out = NULL; if ( ! mline ) { lwerror("Null input geometry."); return NULL; } if ( mline->ngeoms == 1) { lwgeom_out = lwline_clip_to_ordinate_range(mline->geoms[0], ordinate, from, to); } else { LWCOLLECTION *col; char hasz = lwgeom_has_z(lwmline_as_lwgeom(mline)); char hasm = lwgeom_has_m(lwmline_as_lwgeom(mline)); int i, j; char homogeneous = 1; size_t geoms_size = 0; lwgeom_out = lwcollection_construct_empty(MULTILINETYPE, mline->srid, hasz, hasm); FLAGS_SET_Z(lwgeom_out->flags, hasz); FLAGS_SET_M(lwgeom_out->flags, hasm); for ( i = 0; i < mline->ngeoms; i ++ ) { col = lwline_clip_to_ordinate_range(mline->geoms[i], ordinate, from, to); if ( col ) { /* Something was left after the clip. */ if ( lwgeom_out->ngeoms + col->ngeoms > geoms_size ) { geoms_size += 16; if ( lwgeom_out->geoms ) { lwgeom_out->geoms = lwrealloc(lwgeom_out->geoms, geoms_size * sizeof(LWGEOM*)); } else { lwgeom_out->geoms = lwalloc(geoms_size * sizeof(LWGEOM*)); } } for ( j = 0; j < col->ngeoms; j++ ) { lwgeom_out->geoms[lwgeom_out->ngeoms] = col->geoms[j]; lwgeom_out->ngeoms++; } if ( col->type != mline->type ) { homogeneous = 0; } /* Shallow free the struct, leaving the geoms behind. */ if ( col->bbox ) lwfree(col->bbox); lwfree(col->geoms); lwfree(col); } } lwgeom_drop_bbox((LWGEOM*)lwgeom_out); lwgeom_add_bbox((LWGEOM*)lwgeom_out); if ( ! homogeneous ) { lwgeom_out->type = COLLECTIONTYPE; } } if ( ! lwgeom_out || lwgeom_out->ngeoms == 0 ) /* Nothing left after clip. */ { return NULL; } return lwgeom_out; }