/** * LINESTRING * Read a WKB linestring, starting just after the endian byte, * type number and optional srid number. Advance the parse state * forward appropriately. * There is only one pointarray in a linestring. Optionally * check for minimal following of rules (two point minimum). */ static LWLINE* lwline_from_wkb_state(wkb_parse_state *s) { POINTARRAY *pa = ptarray_from_wkb_state(s); if( pa == NULL || pa->npoints == 0 ) return lwline_construct_empty(s->srid, s->has_z, s->has_m); if( s->check & LW_PARSER_CHECK_MINPOINTS && pa->npoints < 2 ) { lwerror("%s must have at least two points", lwtype_name(s->lwtype)); return NULL; } return lwline_construct(s->srid, NULL, pa); }
/** * TRIANGLE * Read a WKB triangle, starting just after the endian byte, * type number and optional srid number. Advance the parse state * forward appropriately. * Triangles are encoded like polygons in WKB, but more like linestrings * as lwgeometries. */ static LWTRIANGLE* lwtriangle_from_wkb_state(wkb_parse_state *s) { uint32_t nrings = integer_from_wkb_state(s); LWTRIANGLE *tri = lwtriangle_construct_empty(s->srid, s->has_z, s->has_m); POINTARRAY *pa = NULL; /* Empty triangle? */ if( nrings == 0 ) return tri; /* Should be only one ring. */ if ( nrings != 1 ) lwerror("Triangle has wrong number of rings: %d", nrings); /* There's only one ring, we hope? */ pa = ptarray_from_wkb_state(s); /* If there's no points, return an empty triangle. */ if( pa == NULL ) return tri; /* 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", lwtype_name(s->lwtype)); lwerror("%s must have at least four points", lwtype_name(s->lwtype)); return NULL; } if( s->check & LW_PARSER_CHECK_CLOSURE && ! ptarray_is_closed(pa) ) { lwerror("%s must have closed rings", lwtype_name(s->lwtype)); return NULL; } if( s->check & LW_PARSER_CHECK_ZCLOSURE && ! ptarray_is_closed_z(pa) ) { lwerror("%s must have closed rings", lwtype_name(s->lwtype)); return NULL; } /* Empty TRIANGLE starts w/ empty POINTARRAY, free it first */ if (tri->points) ptarray_free(tri->points); tri->points = pa; return tri; }
/** * 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; }
/** * CIRCULARSTRING * Read a WKB circularstring, starting just after the endian byte, * type number and optional srid number. Advance the parse state * forward appropriately. * There is only one pointarray in a linestring. Optionally * check for minimal following of rules (three point minimum, * odd number of points). */ static LWCIRCSTRING* lwcircstring_from_wkb_state(wkb_parse_state *s) { POINTARRAY *pa = ptarray_from_wkb_state(s); if( pa == NULL || pa->npoints == 0 ) return lwcircstring_construct_empty(s->srid, s->has_z, s->has_m); if( s->check & LW_PARSER_CHECK_MINPOINTS && pa->npoints < 3 ) { lwerror("%s must have at least three points", lwtype_name(s->lwtype)); return NULL; } if( s->check & LW_PARSER_CHECK_ODD && ! (pa->npoints % 2) ) { lwerror("%s must have an odd number of points", lwtype_name(s->lwtype)); return NULL; } return lwcircstring_construct(s->srid, NULL, pa); }