int lwgeom_is_closed(const LWGEOM *geom) { int type = geom->type; if( lwgeom_is_empty(geom) ) return LW_FALSE; /* Test linear types for closure */ switch (type) { case LINETYPE: return lwline_is_closed((LWLINE*)geom); case POLYGONTYPE: return lwpoly_is_closed((LWPOLY*)geom); case CIRCSTRINGTYPE: return lwcircstring_is_closed((LWCIRCSTRING*)geom); case COMPOUNDTYPE: return lwcompound_is_closed((LWCOMPOUND*)geom); case TINTYPE: return lwtin_is_closed((LWTIN*)geom); case POLYHEDRALSURFACETYPE: return lwpsurface_is_closed((LWPSURFACE*)geom); } /* Recurse into collections and see if anything is not closed */ if ( lwgeom_is_collection(geom) ) { LWCOLLECTION *col = lwgeom_as_lwcollection(geom); int i; int closed; for ( i = 0; i < col->ngeoms; i++ ) { closed = lwgeom_is_closed(col->geoms[i]); if ( ! closed ) return LW_FALSE; } return LW_TRUE; } /* All non-linear non-collection types we will call closed */ return LW_TRUE; }
LWGEOM* wkt_parser_curvepolygon_add_ring(LWGEOM *poly, LWGEOM *ring) { LWDEBUG(4,"entered"); /* Toss error on null input */ if( ! (ring && poly) ) { SET_PARSER_ERROR(PARSER_ERROR_OTHER); LWDEBUG(4,"inputs are null"); return NULL; } /* All the elements must agree on dimensionality */ if( FLAGS_NDIMS(poly->flags) != FLAGS_NDIMS(ring->flags) ) { LWDEBUG(4,"dimensionality does not match"); lwgeom_free(ring); lwgeom_free(poly); SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS); return NULL; } /* Apply check for minimum number of points, if requested. */ if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_MINPOINTS) && (lwgeom_count_vertices(ring) < 4) ) { LWDEBUG(4,"number of points is incorrect"); lwgeom_free(ring); lwgeom_free(poly); SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS); return NULL; } /* Apply check for not closed rings, if requested. */ if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_CLOSURE) ) { int is_closed = 1; LWDEBUG(4,"checking ring closure"); switch ( ring->type ) { case LINETYPE: is_closed = lwline_is_closed(lwgeom_as_lwline(ring)); break; case CIRCSTRINGTYPE: is_closed = lwcircstring_is_closed(lwgeom_as_lwcircstring(ring)); break; case COMPOUNDTYPE: is_closed = lwcompound_is_closed(lwgeom_as_lwcompound(ring)); break; } if ( ! is_closed ) { LWDEBUG(4,"ring is not closed"); lwgeom_free(ring); lwgeom_free(poly); SET_PARSER_ERROR(PARSER_ERROR_UNCLOSED); return NULL; } } if( LW_FAILURE == lwcurvepoly_add_ring(lwgeom_as_lwcurvepoly(poly), ring) ) { LWDEBUG(4,"failed to add ring"); lwgeom_free(ring); lwgeom_free(poly); SET_PARSER_ERROR(PARSER_ERROR_OTHER); return NULL; } return poly; }
static void test_isclosed(void) { LWGEOM *geom; /* LINESTRING */ /* Not Closed on 2D */ geom = lwgeom_from_wkt("LINESTRING(1 2,3 4)", LW_PARSER_CHECK_NONE); CU_ASSERT(!lwline_is_closed((LWLINE *) geom)); lwgeom_free(geom); /* Closed on 2D */ geom = lwgeom_from_wkt("LINESTRING(1 2,3 4,1 2)", LW_PARSER_CHECK_NONE); CU_ASSERT(lwline_is_closed((LWLINE *) geom)); lwgeom_free(geom); /* Not closed on 3D */ geom = lwgeom_from_wkt("LINESTRING(1 2 3,4 5 6)", LW_PARSER_CHECK_NONE); CU_ASSERT(!lwline_is_closed((LWLINE *) geom)); lwgeom_free(geom); /* Closed on 3D */ geom = lwgeom_from_wkt("LINESTRING(1 2 3,4 5 6,1 2 3)", LW_PARSER_CHECK_NONE); CU_ASSERT(lwline_is_closed((LWLINE *) geom)); lwgeom_free(geom); /* Closed on 4D, even if M is not the same */ geom = lwgeom_from_wkt("LINESTRING(1 2 3 4,5 6 7 8,1 2 3 0)", LW_PARSER_CHECK_NONE); CU_ASSERT(lwline_is_closed((LWLINE *) geom)); lwgeom_free(geom); /* CIRCULARSTRING */ /* Not Closed on 2D */ geom = lwgeom_from_wkt("CIRCULARSTRING(1 2,3 4,5 6)", LW_PARSER_CHECK_NONE); CU_ASSERT(!lwcircstring_is_closed((LWCIRCSTRING *) geom)); lwgeom_free(geom); /* Closed on 2D */ geom = lwgeom_from_wkt("CIRCULARSTRING(1 2,3 4,1 2)", LW_PARSER_CHECK_NONE); CU_ASSERT(lwcircstring_is_closed((LWCIRCSTRING *) geom)); lwgeom_free(geom); /* Not closed on 3D */ geom = lwgeom_from_wkt("CIRCULARSTRING(1 2 3,4 5 6,7 8 9)", LW_PARSER_CHECK_NONE); CU_ASSERT(!lwcircstring_is_closed((LWCIRCSTRING *) geom)); lwgeom_free(geom); /* Closed on 3D */ geom = lwgeom_from_wkt("CIRCULARSTRING(1 2 3,4 5 6,1 2 3)", LW_PARSER_CHECK_NONE); CU_ASSERT(lwcircstring_is_closed((LWCIRCSTRING *) geom)); lwgeom_free(geom); /* Closed on 4D, even if M is not the same */ geom = lwgeom_from_wkt("CIRCULARSTRING(1 2 3 4,5 6 7 8,1 2 3 0)", LW_PARSER_CHECK_NONE); CU_ASSERT(lwcircstring_is_closed((LWCIRCSTRING *) geom)); lwgeom_free(geom); /* COMPOUNDCURVE */ /* Not Closed on 2D */ geom = lwgeom_from_wkt("COMPOUNDCURVE(CIRCULARSTRING(1 2,3 4,1 2),(1 2,7 8,5 6))", LW_PARSER_CHECK_NONE); CU_ASSERT(!lwcompound_is_closed((LWCOMPOUND *) geom)); lwgeom_free(geom); geom = lwgeom_from_wkt("COMPOUNDCURVE((1 2,3 4,1 2),CIRCULARSTRING(1 2,7 8,5 6))", LW_PARSER_CHECK_NONE); CU_ASSERT(!lwcompound_is_closed((LWCOMPOUND *) geom)); lwgeom_free(geom); /* Closed on 2D */ geom = lwgeom_from_wkt("COMPOUNDCURVE(CIRCULARSTRING(1 2,3 4,5 6), (5 6,7 8,1 2))", LW_PARSER_CHECK_NONE); CU_ASSERT(lwcompound_is_closed((LWCOMPOUND *) geom)); lwgeom_free(geom); geom = lwgeom_from_wkt("COMPOUNDCURVE((1 2,3 4,5 6),CIRCULARSTRING(5 6,7 8,1 2))", LW_PARSER_CHECK_NONE); CU_ASSERT(lwcompound_is_closed((LWCOMPOUND *) geom)); lwgeom_free(geom); /* Not Closed on 3D */ geom = lwgeom_from_wkt("COMPOUNDCURVE(CIRCULARSTRING(1 2 3,4 5 6,1 2 3),(1 2 3,7 8 9,10 11 12))", LW_PARSER_CHECK_NONE); CU_ASSERT(!lwcompound_is_closed((LWCOMPOUND *) geom)); lwgeom_free(geom); geom = lwgeom_from_wkt("COMPOUNDCURVE((1 2 3,4 5 6,1 2 3),CIRCULARSTRING(1 2 3,7 8 9,10 11 12))", LW_PARSER_CHECK_NONE); CU_ASSERT(!lwcompound_is_closed((LWCOMPOUND *) geom)); lwgeom_free(geom); /* Closed on 3D */ geom = lwgeom_from_wkt("COMPOUNDCURVE(CIRCULARSTRING(1 2 3,4 5 6,7 8 9),(7 8 9,10 11 12,1 2 3))", LW_PARSER_CHECK_NONE); CU_ASSERT(lwcompound_is_closed((LWCOMPOUND *) geom)); lwgeom_free(geom); geom = lwgeom_from_wkt("COMPOUNDCURVE((1 2 3,4 5 6,7 8 9),CIRCULARSTRING(7 8 9,10 11 12,1 2 3))", LW_PARSER_CHECK_NONE); CU_ASSERT(lwcompound_is_closed((LWCOMPOUND *) geom)); lwgeom_free(geom); /* Closed on 4D, even if M is not the same */ geom = lwgeom_from_wkt("COMPOUNDCURVE((1 2 3 4,5 6 7 8,9 10 11 12),CIRCULARSTRING(9 10 11 12,13 14 15 16,1 2 3 0))", LW_PARSER_CHECK_NONE); CU_ASSERT(lwcompound_is_closed((LWCOMPOUND *) geom)); lwgeom_free(geom); }