/* * Construct a polygon from a LWLINE being * the shell and an array of LWLINE (possibly NULL) being holes. * Pointarrays from intput geoms are cloned. * SRID must be the same for each input line. * Input lines must have at least 4 points, and be closed. */ LWPOLY * lwpoly_from_lwlines(const LWLINE *shell, uint32_t nholes, const LWLINE **holes) { uint32_t nrings; POINTARRAY **rings = lwalloc((nholes+1)*sizeof(POINTARRAY *)); int srid = shell->srid; LWPOLY *ret; if ( shell->points->npoints < 4 ) lwerror("lwpoly_from_lwlines: shell must have at least 4 points"); if ( ! ptarray_is_closed_2d(shell->points) ) lwerror("lwpoly_from_lwlines: shell must be closed"); rings[0] = ptarray_clone_deep(shell->points); for (nrings=1; nrings<=nholes; nrings++) { const LWLINE *hole = holes[nrings-1]; if ( hole->srid != srid ) lwerror("lwpoly_from_lwlines: mixed SRIDs in input lines"); if ( hole->points->npoints < 4 ) lwerror("lwpoly_from_lwlines: holes must have at least 4 points"); if ( ! ptarray_is_closed_2d(hole->points) ) lwerror("lwpoly_from_lwlines: holes must be closed"); rings[nrings] = ptarray_clone_deep(hole->points); } ret = lwpoly_construct(srid, NULL, nrings, rings); return ret; }
/** * POLYGON */ static LWPOLY* lwpoly_from_twkb_state(twkb_parse_state *s) { uint32_t nrings; int i; LWPOLY *poly; LWDEBUG(2,"Entering lwpoly_from_twkb_state"); if ( s->is_empty ) return lwpoly_construct_empty(SRID_UNKNOWN, s->has_z, s->has_m); /* Read number of rings */ nrings = twkb_parse_state_uvarint(s); /* Start w/ empty polygon */ poly = lwpoly_construct_empty(SRID_UNKNOWN, s->has_z, s->has_m); LWDEBUGF(4,"Polygon has %d rings", nrings); /* Empty polygon? */ if( nrings == 0 ) return poly; for( i = 0; i < nrings; i++ ) { /* Ret number of points */ uint32_t npoints = twkb_parse_state_uvarint(s); POINTARRAY *pa = ptarray_from_twkb_state(s, npoints); /* Skip empty rings */ if( pa == NULL ) continue; /* Force first and last points to be the same. */ if( ! ptarray_is_closed_2d(pa) ) { POINT4D pt; getPoint4d_p(pa, 0, &pt); ptarray_append_point(pa, &pt, LW_FALSE); } /* Check for at least four points. */ if( s->check & LW_PARSER_CHECK_MINPOINTS && pa->npoints < 4 ) { LWDEBUGF(2, "%s must have at least four points in each ring", lwtype_name(s->lwtype)); lwerror("%s must have at least four points in each ring", lwtype_name(s->lwtype)); return NULL; } /* Add ring to polygon */ if ( lwpoly_add_ring(poly, pa) == LW_FAILURE ) { LWDEBUG(2, "Unable to add ring to polygon"); lwerror("Unable to add ring to polygon"); } } return poly; }
int ptarray_is_closed_z(const POINTARRAY *in) { if ( FLAGS_GET_Z(in->flags) ) return ptarray_is_closed_3d(in); else return ptarray_is_closed_2d(in); }
/** * POLYGON * Read a WKB polygon, starting just after the endian byte, * type number and optional srid number. Advance the parse state * forward appropriately. * First read the number of rings, then read each ring * (which are structured as point arrays) */ static LWPOLY* lwpoly_from_wkb_state(wkb_parse_state *s) { uint32_t nrings = integer_from_wkb_state(s); int i = 0; LWPOLY *poly = lwpoly_construct_empty(s->srid, s->has_z, s->has_m); LWDEBUGF(4,"Polygon has %d rings", nrings); /* Empty polygon? */ if( nrings == 0 ) return poly; for( i = 0; i < nrings; i++ ) { POINTARRAY *pa = ptarray_from_wkb_state(s); if( pa == NULL ) continue; /* Check for at least four points. */ if( s->check & LW_PARSER_CHECK_MINPOINTS && pa->npoints < 4 ) { LWDEBUGF(2, "%s must have at least four points in each ring", lwtype_name(s->lwtype)); lwerror("%s must have at least four points in each ring", lwtype_name(s->lwtype)); return NULL; } /* Check that first and last points are the same. */ if( s->check & LW_PARSER_CHECK_CLOSURE && ! ptarray_is_closed_2d(pa) ) { LWDEBUGF(2, "%s must have closed rings", lwtype_name(s->lwtype)); lwerror("%s must have closed rings", lwtype_name(s->lwtype)); return NULL; } /* Add ring to polygon */ if ( lwpoly_add_ring(poly, pa) == LW_FAILURE ) { LWDEBUG(2, "Unable to add ring to polygon"); lwerror("Unable to add ring to polygon"); } } return poly; }
/* * Construct a triangle from a LWLINE being * the shell * Pointarray from intput geom are cloned. * Input line must have 4 points, and be closed. */ LWTRIANGLE * lwtriangle_from_lwline(const LWLINE *shell) { LWTRIANGLE *ret; POINTARRAY *pa; if ( shell->points->npoints != 4 ) lwerror("lwtriangle_from_lwline: shell must have exactly 4 points"); if ( (!FLAGS_GET_Z(shell->flags) && !ptarray_is_closed_2d(shell->points)) || (FLAGS_GET_Z(shell->flags) && !ptarray_is_closed_3d(shell->points)) ) lwerror("lwtriangle_from_lwline: shell must be closed"); pa = ptarray_clone_deep(shell->points); ret = lwtriangle_construct(shell->srid, NULL, pa); if (lwtriangle_is_repeated_points(ret)) lwerror("lwtriangle_from_lwline: some points are repeated in triangle"); return ret; }
int lwpoly_is_closed(const LWPOLY *poly) { int i = 0; if ( poly->nrings == 0 ) return LW_TRUE; for ( i = 0; i < poly->nrings; i++ ) { if (FLAGS_GET_Z(poly->flags)) { if ( ! ptarray_is_closed_3d(poly->rings[i]) ) return LW_FALSE; } else { if ( ! ptarray_is_closed_2d(poly->rings[i]) ) return LW_FALSE; } } return LW_TRUE; }