LWPOLY* lwpoly_simplify(const LWPOLY *ipoly, double dist, int preserve_collapsed) { int i; LWPOLY *opoly = lwpoly_construct_empty(ipoly->srid, FLAGS_GET_Z(ipoly->flags), FLAGS_GET_M(ipoly->flags)); LWDEBUGF(2, "%s: simplifying polygon with %d rings", __func__, ipoly->nrings); if ( lwpoly_is_empty(ipoly) ) { lwpoly_free(opoly); return NULL; } for ( i = 0; i < ipoly->nrings; i++ ) { POINTARRAY *opts; int minvertices = 0; /* We'll still let holes collapse, but if we're preserving */ /* and this is a shell, we ensure it is kept */ if ( preserve_collapsed && i == 0 ) minvertices = 4; opts = ptarray_simplify(ipoly->rings[i], dist, minvertices); LWDEBUGF(3, "ring%d simplified from %d to %d points", i, ipoly->rings[i]->npoints, opts->npoints); /* Less points than are needed to form a closed ring, we can't use this */ if ( opts->npoints < 4 ) { LWDEBUGF(3, "ring%d skipped (% pts)", i, opts->npoints); ptarray_free(opts); if ( i ) continue; else break; /* Don't scan holes if shell is collapsed */ } /* Add ring to simplified polygon */ if( lwpoly_add_ring(opoly, opts) == LW_FAILURE ) { lwpoly_free(opoly); return NULL; } } LWDEBUGF(3, "simplified polygon with %d rings", ipoly->nrings); opoly->type = ipoly->type; if( lwpoly_is_empty(opoly) ) { lwpoly_free(opoly); return NULL; } return opoly; }
void lwpoly_reverse(LWPOLY *poly) { int i; if ( lwpoly_is_empty(poly) ) return; for (i=0; i<poly->nrings; i++) ptarray_reverse(poly->rings[i]); }
LWPOLY* lwpoly_simplify(const LWPOLY *ipoly, double dist) { int i; LWPOLY *opoly = lwpoly_construct_empty(ipoly->srid, FLAGS_GET_Z(ipoly->flags), FLAGS_GET_M(ipoly->flags)); LWDEBUGF(2, "simplify_polygon3d: simplifying polygon with %d rings", ipoly->nrings); if( lwpoly_is_empty(ipoly) ) return opoly; /* should we return NULL instead ? */ for (i = 0; i < ipoly->nrings; i++) { static const int minvertices = 0; /* TODO: allow setting this */ POINTARRAY *opts = ptarray_simplify(ipoly->rings[i], dist, minvertices); LWDEBUGF(3, "ring%d simplified from %d to %d points", i, ipoly->rings[i]->npoints, opts->npoints); /* Less points than are needed to form a closed ring, we can't use this */ if ( opts->npoints < 4 ) { LWDEBUGF(3, "ring%d skipped (% pts)", i, opts->npoints); ptarray_free(opts); if ( i ) continue; else break; /* Don't scan holes if shell is collapsed */ } /* Add ring to simplified polygon */ if( lwpoly_add_ring(opoly, opts) == LW_FAILURE ) return NULL; } LWDEBUGF(3, "simplified polygon with %d rings", ipoly->nrings); opoly->type = ipoly->type; if( lwpoly_is_empty(opoly) ) return NULL; return opoly; }
static LWPOLY* lwpoly_set_effective_area(const LWPOLY *ipoly,int set_area, double trshld) { LWDEBUG(2, "Entered lwpoly_set_effective_area"); int i; int set_m; int avoid_collapse=4; if(set_area) set_m=1; else set_m=FLAGS_GET_M(ipoly->flags); LWPOLY *opoly = lwpoly_construct_empty(ipoly->srid, FLAGS_GET_Z(ipoly->flags), set_m); if( lwpoly_is_empty(ipoly) ) return opoly; /* should we return NULL instead ? */ for (i = 0; i < ipoly->nrings; i++) { POINTARRAY *pa = ptarray_set_effective_area(ipoly->rings[i],avoid_collapse,set_area,trshld); /* Add ring to simplified polygon */ if(pa->npoints>=4) { if( lwpoly_add_ring(opoly,pa ) == LW_FAILURE ) return NULL; } /*Inner rings we allow to ocollapse and then we remove them*/ avoid_collapse=0; } opoly->type = ipoly->type; if( lwpoly_is_empty(opoly) ) return NULL; return opoly; }
int lwpoly_is_clockwise(LWPOLY *poly) { int i; if ( lwpoly_is_empty(poly) ) return LW_TRUE; if ( ptarray_isccw(poly->rings[0]) ) return LW_FALSE; for ( i = 1; i < poly->nrings; i++) if ( !ptarray_isccw(poly->rings[i]) ) return LW_FALSE; return LW_TRUE; }
int lwpoly_contains_point(const LWPOLY *poly, const POINT2D *pt) { int i; if ( lwpoly_is_empty(poly) ) return LW_FALSE; if ( ptarray_contains_point(poly->rings[0], pt) == LW_OUTSIDE ) return LW_FALSE; for ( i = 1; i < poly->nrings; i++ ) { if ( ptarray_contains_point(poly->rings[i], pt) == LW_INSIDE ) return LW_FALSE; } return LW_TRUE; }
void lwpoly_force_clockwise(LWPOLY *poly) { int i; /* No-op empties */ if ( lwpoly_is_empty(poly) ) return; /* External ring */ if ( ptarray_isccw(poly->rings[0]) ) ptarray_reverse(poly->rings[0]); /* Internal rings */ for (i=1; i<poly->nrings; i++) if ( ! ptarray_isccw(poly->rings[i]) ) ptarray_reverse(poly->rings[i]); }
int lwgeom_is_empty(const LWGEOM *geom) { int result = LW_FALSE; LWDEBUGF(4, "lwgeom_is_empty: got type %s", lwtype_name(geom->type)); switch (geom->type) { case POINTTYPE: return lwpoint_is_empty((LWPOINT*)geom); break; case LINETYPE: return lwline_is_empty((LWLINE*)geom); break; case CIRCSTRINGTYPE: return lwcircstring_is_empty((LWCIRCSTRING*)geom); break; case POLYGONTYPE: return lwpoly_is_empty((LWPOLY*)geom); break; case TRIANGLETYPE: return lwtriangle_is_empty((LWTRIANGLE*)geom); break; case MULTIPOINTTYPE: case MULTILINETYPE: case MULTIPOLYGONTYPE: case COMPOUNDTYPE: case CURVEPOLYTYPE: case MULTICURVETYPE: case MULTISURFACETYPE: case POLYHEDRALSURFACETYPE: case TINTYPE: case COLLECTIONTYPE: return lwcollection_is_empty((LWCOLLECTION *)geom); break; default: lwerror("lwgeom_is_empty: unsupported input geometry type: %s", lwtype_name(geom->type)); break; } return result; }
LWPOLY* lwpoly_force_dims(const LWPOLY *poly, int hasz, int hasm) { LWPOLY *polyout; /* Return 2D empty */ if( lwpoly_is_empty(poly) ) { polyout = lwpoly_construct_empty(poly->srid, hasz, hasm); } else { POINTARRAY **rings = NULL; int i; rings = lwalloc(sizeof(POINTARRAY*) * poly->nrings); for( i = 0; i < poly->nrings; i++ ) { rings[i] = ptarray_force_dims(poly->rings[i], hasz, hasm); } polyout = lwpoly_construct(poly->srid, NULL, poly->nrings, rings); } polyout->type = poly->type; return polyout; }