static LWGEOM* lwcollection_split(const LWCOLLECTION* lwcoll_in, const LWGEOM* blade_in) { LWGEOM** split_vector=NULL; LWCOLLECTION* out; size_t split_vector_capacity; size_t split_vector_size=0; size_t i,j; split_vector_capacity=8; split_vector = lwalloc(split_vector_capacity * sizeof(LWGEOM*)); if ( ! split_vector ) { lwerror("Out of virtual memory"); return NULL; } for (i=0; i<lwcoll_in->ngeoms; ++i) { LWCOLLECTION* col; LWGEOM* split = lwgeom_split(lwcoll_in->geoms[i], blade_in); /* an exception should prevent this from ever returning NULL */ if ( ! split ) return NULL; col = lwgeom_as_lwcollection(split); /* Output, if any, will always be a collection */ assert(col); /* Reallocate split_vector if needed */ if ( split_vector_size + col->ngeoms > split_vector_capacity ) { /* NOTE: we could be smarter on reallocations here */ split_vector_capacity += col->ngeoms; split_vector = lwrealloc(split_vector, split_vector_capacity * sizeof(LWGEOM*)); if ( ! split_vector ) { lwerror("Out of virtual memory"); return NULL; } } for (j=0; j<col->ngeoms; ++j) { col->geoms[j]->srid = SRID_UNKNOWN; /* strip srid */ split_vector[split_vector_size++] = col->geoms[j]; } lwfree(col->geoms); lwfree(col); } /* Now split_vector has split_vector_size geometries */ out = lwcollection_construct(COLLECTIONTYPE, lwcoll_in->srid, NULL, split_vector_size, split_vector); return (LWGEOM*)out; }
static void test_lwgeom_split(void) { LWGEOM *geom, *blade, *ret; char *wkt, *in_wkt; geom = lwgeom_from_wkt( "MULTILINESTRING((-5 -2,0 0),(0 0,10 10))", LW_PARSER_CHECK_NONE); CU_ASSERT(geom != NULL); blade = lwgeom_from_wkt( "POINT(0 0)", LW_PARSER_CHECK_NONE); CU_ASSERT(blade != NULL); ret = lwgeom_split(geom, blade); CU_ASSERT(ret != NULL); wkt = lwgeom_to_ewkt(ret); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(-5 -2,0 0),LINESTRING(0 0,10 10))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* See #1311 */ geom = lwgeom_from_wkt( "LINESTRING(0 0,10 0,20 4,0 3)", LW_PARSER_CHECK_NONE); CU_ASSERT(geom != NULL); blade = lwgeom_from_wkt("POINT(10 0)", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); CU_ASSERT(ret != NULL); wkt = lwgeom_to_ewkt(ret); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,10 0),LINESTRING(10 0,20 4,0 3))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* See #2528 (1) -- memory leak test, needs valgrind to check */ geom = lwgeom_from_wkt("SRID=1;LINESTRING(0 1,10 1)", LW_PARSER_CHECK_NONE); CU_ASSERT(geom != NULL); blade = lwgeom_from_wkt("LINESTRING(7 0,7 3)", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); CU_ASSERT(ret != NULL); wkt = lwgeom_to_ewkt(ret); in_wkt = "SRID=1;GEOMETRYCOLLECTION(LINESTRING(0 1,7 1),LINESTRING(7 1,10 1))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* See #2528 (2) -- memory leak test, needs valgrind to check */ geom = lwgeom_from_wkt("SRID=1;POLYGON((0 1, 10 1, 10 10, 0 10, 0 1))", LW_PARSER_CHECK_NONE); CU_ASSERT(geom != NULL); blade = lwgeom_from_wkt("LINESTRING(7 0,7 20)", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); CU_ASSERT(ret != NULL); wkt = lwgeom_to_ewkt(ret); in_wkt = "SRID=1;GEOMETRYCOLLECTION(POLYGON((7 1,0 1,0 10,7 10,7 1)),POLYGON((7 10,10 10,10 1,7 1,7 10)))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* Split line by multiline */ geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE); CU_ASSERT_FATAL(geom != NULL); blade = lwgeom_from_wkt("MULTILINESTRING((1 1,1 -1),(2 1,2 -1,3 -1,3 1))", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); if ( ! ret ) printf("%s", cu_error_msg); CU_ASSERT_FATAL(ret != NULL); wkt = lwgeom_to_ewkt(ret); CU_ASSERT_FATAL(wkt != NULL); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,1 0),LINESTRING(1 0,2 0),LINESTRING(2 0,3 0),LINESTRING(3 0,10 0))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* Split line by polygon (boundary) */ geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE); CU_ASSERT_FATAL(geom != NULL); blade = lwgeom_from_wkt( "POLYGON((1 -2,1 1,2 1,2 -1,3 -1,3 1,11 1,11 -2,1 -2))", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); if ( ! ret ) printf("%s", cu_error_msg); CU_ASSERT_FATAL(ret != NULL); wkt = lwgeom_to_ewkt(ret); CU_ASSERT_FATAL(wkt != NULL); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,1 0),LINESTRING(1 0,2 0),LINESTRING(2 0,3 0),LINESTRING(3 0,10 0))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* Split line by EMPTY polygon (boundary) */ geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE); CU_ASSERT_FATAL(geom != NULL); blade = lwgeom_from_wkt("POLYGON EMPTY", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); if ( ! ret ) printf("%s", cu_error_msg); CU_ASSERT_FATAL(ret != NULL); wkt = lwgeom_to_ewkt(ret); CU_ASSERT_FATAL(wkt != NULL); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,10 0))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* Split line by multipolygon (boundary) */ geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE); CU_ASSERT_FATAL(geom != NULL); blade = lwgeom_from_wkt( "MULTIPOLYGON(((1 -1,1 1,2 1,2 -1,1 -1)),((3 -1,3 1,11 1,11 -1,3 -1)))", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); if ( ! ret ) printf("%s", cu_error_msg); CU_ASSERT_FATAL(ret != NULL); wkt = lwgeom_to_ewkt(ret); CU_ASSERT_FATAL(wkt != NULL); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,1 0),LINESTRING(1 0,2 0),LINESTRING(2 0,3 0),LINESTRING(3 0,10 0))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* Split line by multipoint */ geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE); CU_ASSERT_FATAL(geom != NULL); blade = lwgeom_from_wkt("MULTIPOINT(2 0,8 0,4 0)", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); if ( ! ret ) printf("%s", cu_error_msg); CU_ASSERT_FATAL(ret != NULL); wkt = lwgeom_to_ewkt(ret); CU_ASSERT_FATAL(wkt != NULL); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(8 0,10 0),LINESTRING(0 0,2 0),LINESTRING(4 0,8 0),LINESTRING(2 0,4 0))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); }
static void test_lwgeom_split(void) { LWGEOM *geom, *blade, *ret; char *wkt, *in_wkt; geom = lwgeom_from_wkt( "MULTILINESTRING((-5 -2,0 0),(0 0,10 10))", LW_PARSER_CHECK_NONE); CU_ASSERT(geom != NULL); blade = lwgeom_from_wkt( "POINT(0 0)", LW_PARSER_CHECK_NONE); CU_ASSERT(blade != NULL); ret = lwgeom_split(geom, blade); CU_ASSERT(ret != NULL); wkt = lwgeom_to_ewkt(ret); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(-5 -2,0 0),LINESTRING(0 0,10 10))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* See #1311 */ geom = lwgeom_from_wkt( "LINESTRING(0 0,10 0,20 4,0 3)", LW_PARSER_CHECK_NONE); CU_ASSERT(geom != NULL); blade = lwgeom_from_wkt("POINT(10 0)", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); CU_ASSERT(ret != NULL); wkt = lwgeom_to_ewkt(ret); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,10 0),LINESTRING(10 0,20 4,0 3))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* See #2528 (1) -- memory leak test, needs valgrind to check */ geom = lwgeom_from_wkt("SRID=1;LINESTRING(0 1,10 1)", LW_PARSER_CHECK_NONE); CU_ASSERT(geom != NULL); blade = lwgeom_from_wkt("LINESTRING(7 0,7 3)", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); CU_ASSERT(ret != NULL); wkt = lwgeom_to_ewkt(ret); in_wkt = "SRID=1;GEOMETRYCOLLECTION(LINESTRING(0 1,7 1),LINESTRING(7 1,10 1))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* See #2528 (2) -- memory leak test, needs valgrind to check */ geom = lwgeom_from_wkt("SRID=1;POLYGON((0 1, 10 1, 10 10, 0 10, 0 1))", LW_PARSER_CHECK_NONE); CU_ASSERT(geom != NULL); blade = lwgeom_from_wkt("LINESTRING(7 0,7 20)", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); CU_ASSERT(ret != NULL); wkt = lwgeom_to_ewkt(ret); in_wkt = "SRID=1;GEOMETRYCOLLECTION(POLYGON((7 1,0 1,0 10,7 10,7 1)),POLYGON((7 10,10 10,10 1,7 1,7 10)))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* Split line by multiline */ geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE); CU_ASSERT_FATAL(geom != NULL); blade = lwgeom_from_wkt("MULTILINESTRING((1 1,1 -1),(2 1,2 -1,3 -1,3 1))", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); if ( ! ret ) printf("%s", cu_error_msg); CU_ASSERT_FATAL(ret != NULL); wkt = lwgeom_to_ewkt(ret); CU_ASSERT_FATAL(wkt != NULL); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,1 0),LINESTRING(1 0,2 0),LINESTRING(2 0,3 0),LINESTRING(3 0,10 0))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* Split line by polygon (boundary) */ geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE); CU_ASSERT_FATAL(geom != NULL); blade = lwgeom_from_wkt( "POLYGON((1 -2,1 1,2 1,2 -1,3 -1,3 1,11 1,11 -2,1 -2))", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); if ( ! ret ) printf("%s", cu_error_msg); CU_ASSERT_FATAL(ret != NULL); wkt = lwgeom_to_ewkt(ret); CU_ASSERT_FATAL(wkt != NULL); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,1 0),LINESTRING(1 0,2 0),LINESTRING(2 0,3 0),LINESTRING(3 0,10 0))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* Split line by EMPTY polygon (boundary) */ geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE); CU_ASSERT_FATAL(geom != NULL); blade = lwgeom_from_wkt("POLYGON EMPTY", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); if ( ! ret ) printf("%s", cu_error_msg); CU_ASSERT_FATAL(ret != NULL); wkt = lwgeom_to_ewkt(ret); CU_ASSERT_FATAL(wkt != NULL); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,10 0))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* Split line by multipolygon (boundary) */ geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE); CU_ASSERT_FATAL(geom != NULL); blade = lwgeom_from_wkt( "MULTIPOLYGON(((1 -1,1 1,2 1,2 -1,1 -1)),((3 -1,3 1,11 1,11 -1,3 -1)))", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); if ( ! ret ) printf("%s", cu_error_msg); CU_ASSERT_FATAL(ret != NULL); wkt = lwgeom_to_ewkt(ret); CU_ASSERT_FATAL(wkt != NULL); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,1 0),LINESTRING(1 0,2 0),LINESTRING(2 0,3 0),LINESTRING(3 0,10 0))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* Split line by multipoint */ geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE); CU_ASSERT_FATAL(geom != NULL); blade = lwgeom_from_wkt("MULTIPOINT(2 0,8 0,4 0)", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); if ( ! ret ) printf("%s", cu_error_msg); CU_ASSERT_FATAL(ret != NULL); wkt = lwgeom_to_ewkt(ret); CU_ASSERT_FATAL(wkt != NULL); in_wkt = "GEOMETRYCOLLECTION(LINESTRING(8 0,10 0),LINESTRING(0 0,2 0),LINESTRING(4 0,8 0),LINESTRING(2 0,4 0))"; if (strcmp(in_wkt, wkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt); CU_ASSERT_STRING_EQUAL(wkt, in_wkt); lwfree(wkt); lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); /* See #3401 -- robustness issue */ geom = lwgeom_from_wkt("LINESTRING(-180 0,0 0)", LW_PARSER_CHECK_NONE); CU_ASSERT(geom != NULL); blade = lwgeom_from_wkt("POINT(-20 0)", LW_PARSER_CHECK_NONE); ret = lwgeom_split(geom, blade); CU_ASSERT(ret != NULL); { LWCOLLECTION *split = lwgeom_as_lwcollection(ret); LWLINE *l1, *l2; POINT2D pt; CU_ASSERT(split != NULL); l1 = lwgeom_as_lwline(split->geoms[0]); CU_ASSERT(l1 != NULL); getPoint2d_p(l1->points, 1, &pt); ASSERT_DOUBLE_EQUAL(pt.x, -20); ASSERT_DOUBLE_EQUAL(pt.y, 0); l2 = lwgeom_as_lwline(split->geoms[1]); CU_ASSERT(l2 != NULL); getPoint2d_p(l2->points, 0, &pt); ASSERT_DOUBLE_EQUAL(pt.x, -20); ASSERT_DOUBLE_EQUAL(pt.y, 0); } lwgeom_free(ret); lwgeom_free(geom); lwgeom_free(blade); }