LWGEOM* lwmpoint_remove_repeated_points(LWMPOINT *mpoint) { uint32_t nnewgeoms; uint32_t i, j; LWGEOM **newgeoms; newgeoms = lwalloc(sizeof(LWGEOM *)*mpoint->ngeoms); nnewgeoms = 0; for (i=0; i<mpoint->ngeoms; ++i) { /* Brute force, may be optimized by building an index */ int seen=0; for (j=0; j<nnewgeoms; ++j) { if ( lwpoint_same((LWPOINT*)newgeoms[j], (LWPOINT*)mpoint->geoms[i]) ) { seen=1; break; } } if ( seen ) continue; newgeoms[nnewgeoms++] = (LWGEOM*)lwpoint_clone(mpoint->geoms[i]); } return (LWGEOM*)lwcollection_construct(mpoint->type, mpoint->srid, mpoint->bbox ? gbox_copy(mpoint->bbox) : NULL, nnewgeoms, newgeoms); }
/* @brief Clone LWGEOM object. Serialized point lists are not copied. * * @see ptarray_clone */ LWGEOM * lwgeom_clone(const LWGEOM *lwgeom) { LWDEBUGF(2, "lwgeom_clone called with %p, %s", lwgeom, lwtype_name(lwgeom->type)); switch (lwgeom->type) { case POINTTYPE: return (LWGEOM *)lwpoint_clone((LWPOINT *)lwgeom); case LINETYPE: return (LWGEOM *)lwline_clone((LWLINE *)lwgeom); case CIRCSTRINGTYPE: return (LWGEOM *)lwcircstring_clone((LWCIRCSTRING *)lwgeom); case POLYGONTYPE: return (LWGEOM *)lwpoly_clone((LWPOLY *)lwgeom); case TRIANGLETYPE: return (LWGEOM *)lwtriangle_clone((LWTRIANGLE *)lwgeom); case COMPOUNDTYPE: case CURVEPOLYTYPE: case MULTICURVETYPE: case MULTISURFACETYPE: case MULTIPOINTTYPE: case MULTILINETYPE: case MULTIPOLYGONTYPE: case POLYHEDRALSURFACETYPE: case TINTYPE: case COLLECTIONTYPE: return (LWGEOM *)lwcollection_clone((LWCOLLECTION *)lwgeom); default: lwerror("lwgeom_clone: Unknown geometry type: %s", lwtype_name(lwgeom->type)); return NULL; } }
static LWMPOINT* lwpoint_locate_along(const LWPOINT *lwpoint, double m, double offset) { double point_m = lwpoint_get_m(lwpoint); LWGEOM *lwg = lwpoint_as_lwgeom(lwpoint); LWMPOINT *r = lwmpoint_construct_empty(lwgeom_get_srid(lwg), lwgeom_has_z(lwg), lwgeom_has_m(lwg)); if ( FP_EQUALS(m, point_m) ) { lwmpoint_add_lwpoint(r, lwpoint_clone(lwpoint)); } return r; }
/** * Clip an input MULTIPOINT between two values, on any ordinate input. */ LWCOLLECTION* lwmpoint_clip_to_ordinate_range(const LWMPOINT *mpoint, char ordinate, double from, double to) { LWCOLLECTION *lwgeom_out = NULL; char hasz, hasm; int i; /* Nothing to do with NULL */ if ( ! mpoint ) lwerror("Null input geometry."); /* Ensure 'from' is less than 'to'. */ if ( to < from ) { double t = from; from = to; to = t; } /* Read Z/M info */ hasz = lwgeom_has_z(lwmpoint_as_lwgeom(mpoint)); hasm = lwgeom_has_m(lwmpoint_as_lwgeom(mpoint)); /* Prepare return object */ lwgeom_out = lwcollection_construct_empty(MULTIPOINTTYPE, mpoint->srid, hasz, hasm); /* For each point, is its ordinate value between from and to? */ for ( i = 0; i < mpoint->ngeoms; i ++ ) { POINT4D p4d; double ordinate_value; lwpoint_getPoint4d_p(mpoint->geoms[i], &p4d); ordinate_value = lwpoint_get_ordinate(&p4d, ordinate); if ( from <= ordinate_value && to >= ordinate_value ) { LWPOINT *lwp = lwpoint_clone(mpoint->geoms[i]); lwcollection_add_lwgeom(lwgeom_out, lwpoint_as_lwgeom(lwp)); } } /* Set the bbox */ lwgeom_drop_bbox((LWGEOM*)lwgeom_out); lwgeom_add_bbox((LWGEOM*)lwgeom_out); return lwgeom_out; }
/** * Clip an input POINT between two values, on any ordinate input. */ LWCOLLECTION* lwpoint_clip_to_ordinate_range(const LWPOINT *point, char ordinate, double from, double to) { LWCOLLECTION *lwgeom_out = NULL; char hasz, hasm; POINT4D p4d; double ordinate_value; /* Nothing to do with NULL */ if ( ! point ) lwerror("Null input geometry."); /* Ensure 'from' is less than 'to'. */ if ( to < from ) { double t = from; from = to; to = t; } /* Read Z/M info */ hasz = lwgeom_has_z(lwpoint_as_lwgeom(point)); hasm = lwgeom_has_m(lwpoint_as_lwgeom(point)); /* Prepare return object */ lwgeom_out = lwcollection_construct_empty(MULTIPOINTTYPE, point->srid, hasz, hasm); /* Test if ordinate is in range */ lwpoint_getPoint4d_p(point, &p4d); ordinate_value = lwpoint_get_ordinate(&p4d, ordinate); if ( from <= ordinate_value && to >= ordinate_value ) { LWPOINT *lwp = lwpoint_clone(point); lwcollection_add_lwgeom(lwgeom_out, lwpoint_as_lwgeom(lwp)); } /* Set the bbox */ lwgeom_drop_bbox((LWGEOM*)lwgeom_out); lwgeom_add_bbox((LWGEOM*)lwgeom_out); return lwgeom_out; }
/* * Point is assumed to have an M value. * Return NULL if point is not in the given range (inclusive) * Return an LWPOINT *copy* otherwise. */ static LWGEOM * lwpoint_locate_between_m(LWPOINT *lwpoint, double m0, double m1) { POINT3DM p3dm; POSTGIS_DEBUGF(2, "lwpoint_locate_between called for lwpoint %p", lwpoint); lwpoint_getPoint3dm_p(lwpoint, &p3dm); if ( p3dm.m >= m0 && p3dm.m <= m1) { POSTGIS_DEBUG(3, " lwpoint... returning a clone of input"); return (LWGEOM *)lwpoint_clone(lwpoint); } else { POSTGIS_DEBUG(3, " lwpoint... returning a clone of input"); return NULL; } }
static LWMPOINT* lwmpoint_locate_along(const LWMPOINT *lwin, double m, double offset) { LWGEOM *lwg = lwmpoint_as_lwgeom(lwin); LWMPOINT *lwout = NULL; int i; /* Construct return */ lwout = lwmpoint_construct_empty(lwgeom_get_srid(lwg), lwgeom_has_z(lwg), lwgeom_has_m(lwg)); for ( i = 0; i < lwin->ngeoms; i++ ) { double point_m = lwpoint_get_m(lwin->geoms[i]); if ( FP_EQUALS(m, point_m) ) { lwmpoint_add_lwpoint(lwout, lwpoint_clone(lwin->geoms[i])); } } return lwout; }