static void test_geos_linemerge(void) { char *ewkt; char *out_ewkt; LWGEOM *geom1; LWGEOM *geom2; ewkt = "MULTILINESTRING((0 0, 0 100),(0 -5, 0 0))"; geom1 = lwgeom_from_wkt(ewkt, LW_PARSER_CHECK_NONE); geom2 = lwgeom_linemerge(geom1); out_ewkt = lwgeom_to_ewkt((LWGEOM*)geom2); ASSERT_STRING_EQUAL(out_ewkt, "LINESTRING(0 -5,0 0,0 100)"); lwfree(out_ewkt); lwgeom_free(geom1); lwgeom_free(geom2); ewkt = "MULTILINESTRING EMPTY"; geom1 = lwgeom_from_wkt(ewkt, LW_PARSER_CHECK_NONE); geom2 = lwgeom_linemerge(geom1); out_ewkt = lwgeom_to_ewkt((LWGEOM*)geom2); ASSERT_STRING_EQUAL(out_ewkt, "GEOMETRYCOLLECTION EMPTY"); lwfree(out_ewkt); lwgeom_free(geom1); lwgeom_free(geom2); }
static void test_geos_subdivide(void) { #if POSTGIS_GEOS_VERSION < 35 // printf("%d\n", POSTGIS_GEOS_VERSION); return; #else char *ewkt = "MULTILINESTRING((0 0, 0 100))"; char *out_ewkt; LWGEOM *geom1 = lwgeom_from_wkt(ewkt, LW_PARSER_CHECK_NONE); LWGEOM *geom2 = lwgeom_segmentize2d(geom1, 1.0); LWCOLLECTION *geom3 = lwgeom_subdivide(geom2, 80); out_ewkt = lwgeom_to_ewkt((LWGEOM*)geom3); // printf("\n--------\n%s\n--------\n", out_ewkt); CU_ASSERT_EQUAL(2, geom3->ngeoms); lwfree(out_ewkt); lwcollection_free(geom3); geom3 = lwgeom_subdivide(geom2, 20); out_ewkt = lwgeom_to_ewkt((LWGEOM*)geom3); // printf("\n--------\n%s\n--------\n", out_ewkt); CU_ASSERT_EQUAL(8, geom3->ngeoms); lwfree(out_ewkt); lwcollection_free(geom3); lwgeom_free(geom2); lwgeom_free(geom1); #endif }
static void test_lwgeom_simplify(void) { LWGEOM *l; LWGEOM *g; char *ewkt; /* Simplify but only so far... */ g = lwgeom_from_wkt("LINESTRING(0 0, 1 0, 1 1, 0 1, 0 0)", LW_PARSER_CHECK_NONE); l = lwgeom_simplify(g, 10, LW_TRUE); ewkt = lwgeom_to_ewkt(l); CU_ASSERT_STRING_EQUAL(ewkt, "LINESTRING(0 0,0 0)"); lwgeom_free(g); lwgeom_free(l); lwfree(ewkt); /* Simplify but only so far... */ g = lwgeom_from_wkt("POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))", LW_PARSER_CHECK_NONE); l = lwgeom_simplify(g, 10, LW_TRUE); ewkt = lwgeom_to_ewkt(l); CU_ASSERT_STRING_EQUAL(ewkt, "POLYGON((0 0,1 0,1 1,0 0))"); lwgeom_free(g); lwgeom_free(l); lwfree(ewkt); /* Simplify and collapse */ g = lwgeom_from_wkt("LINESTRING(0 0, 1 0, 1 1, 0 1, 0 0)", LW_PARSER_CHECK_NONE); l = lwgeom_simplify(g, 10, LW_FALSE); CU_ASSERT_EQUAL(l, NULL); lwgeom_free(g); lwgeom_free(l); /* Simplify and collapse */ g = lwgeom_from_wkt("POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))", LW_PARSER_CHECK_NONE); l = lwgeom_simplify(g, 10, LW_FALSE); CU_ASSERT_EQUAL(l, NULL); lwgeom_free(g); lwgeom_free(l); /* Not simplifiable */ g = lwgeom_from_wkt("LINESTRING(0 0, 50 1.00001, 100 0)", LW_PARSER_CHECK_NONE); l = lwgeom_simplify(g, 1.0, LW_FALSE); ewkt = lwgeom_to_ewkt(l); CU_ASSERT_STRING_EQUAL(ewkt, "LINESTRING(0 0,50 1.00001,100 0)"); lwgeom_free(g); lwgeom_free(l); lwfree(ewkt); /* Simplifiable */ g = lwgeom_from_wkt("LINESTRING(0 0,50 0.99999,100 0)", LW_PARSER_CHECK_NONE); l = lwgeom_simplify(g, 1.0, LW_FALSE); ewkt = lwgeom_to_ewkt(l); CU_ASSERT_STRING_EQUAL(ewkt, "LINESTRING(0 0,100 0)"); lwgeom_free(g); lwgeom_free(l); lwfree(ewkt); }
static void test_lwgeom_delaunay_triangulation(void) { #if POSTGIS_GEOS_VERSION >= 34 LWGEOM *in, *tmp, *out; char *wkt, *exp_wkt; /* Because i don't trust that much prior tests... ;) */ cu_error_msg_reset(); in = lwgeom_from_wkt("MULTIPOINT(10 0, 20 0, 5 5)", LW_PARSER_CHECK_NONE); tmp = lwgeom_delaunay_triangulation(in, 0, 0); lwgeom_free(in); out = lwgeom_normalize(tmp); lwgeom_free(tmp); wkt = lwgeom_to_ewkt(out); lwgeom_free(out); exp_wkt = "GEOMETRYCOLLECTION(POLYGON((5 5,20 0,10 0,5 5)))"; if ( strcmp(wkt, exp_wkt) ) { fprintf(stderr, "\nExp: %s\nObt: %s\n", exp_wkt, wkt); } CU_ASSERT_STRING_EQUAL(wkt, exp_wkt); lwfree(wkt); #endif /* POSTGIS_GEOS_VERSION >= 33 */ }
/** * Serializes a LWPOINT to a char*. This is a helper function that partially * writes the appropriate draw and fill commands used to generate an SVG image * using ImageMagick's "convert" command. * @param output a char reference to write the LWPOINT to * @param lwp a reference to a LWPOINT * @return the numbers of character written to *output */ static size_t drawPoint(char *output, LWPOINT *lwp, LAYERSTYLE *styles) { char x[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1]; char y1[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1]; char y2[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1]; char *ptr = output; POINTARRAY *pa = lwp->point; POINT2D p; getPoint2d_p(pa, 0, &p); LWDEBUGF(4, "%s", "drawPoint called"); LWDEBUGF( 4, "point = %s", lwgeom_to_ewkt((LWGEOM*)lwp,0) ); sprintf(x, "%f", p.x); trim_trailing_zeros(x); sprintf(y1, "%f", p.y); trim_trailing_zeros(y1); sprintf(y2, "%f", p.y + styles->pointSize); trim_trailing_zeros(y2); ptr += sprintf(ptr, "-fill %s -strokewidth 0 ", styles->pointColor); ptr += sprintf(ptr, "-draw \"circle %s,%s %s,%s", x, y1, x, y2); ptr += sprintf(ptr, "'\" "); return (ptr - output); }
static void test_lwline_clip_big(void) { POINTARRAY *pa = ptarray_construct(1, 0, 3); LWLINE *line = lwline_construct(SRID_UNKNOWN, NULL, pa); LWCOLLECTION *c; char *ewkt; POINT4D p; p.x = 0.0; p.y = 0.0; p.z = 0.0; ptarray_set_point4d(pa, 0, &p); p.x = 1.0; p.y = 1.0; p.z = 1.0; ptarray_set_point4d(pa, 1, &p); p.x = 2.0; p.y = 2.0; p.z = 2.0; ptarray_set_point4d(pa, 2, &p); c = lwline_clip_to_ordinate_range(line, 'Z', 0.5, 1.5); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0.5 0.5 0.5,1 1 1,1.5 1.5 1.5))" ); lwfree(ewkt); lwcollection_free(c); lwline_free(line); }
static void test_lwgeom_node(void) { #if POSTGIS_GEOS_VERSION >= 33 LWGEOM *in, *out; const char *wkt; char *tmp; /* Because i don't trust that much prior tests... ;) */ cu_error_msg_reset(); wkt = "LINESTRING(0 0,5 5, 10 0)"; in = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE); out = lwgeom_node(in); /* printf("%s\n", lwgeom_to_ewkt(out)); */ CU_ASSERT(lwgeom_same(in, out)); lwgeom_free(out); lwgeom_free(in); wkt = "MULTILINESTRING((0 0,0 5),(10 0, -10 5))"; in = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE); out = lwgeom_node(in); tmp = lwgeom_to_ewkt(out); CU_ASSERT_STRING_EQUAL("MULTILINESTRING((0 2.5,-10 5),(0 0,0 2.5),(0 2.5,0 5),(10 0,0 2.5))", tmp) lwfree(tmp); lwgeom_free(out); lwgeom_free(in); wkt = "MULTILINESTRING((0 0,5 5,10 0, 11 0, 20 0),(10 0, 12 0, 22 0))"; in = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE); out = lwgeom_node(in); tmp = lwgeom_to_ewkt(out); printf("%s\n", tmp); CU_ASSERT_STRING_EQUAL("MULTILINESTRING((0 0,5 5,10 0),(10 0,11 0,12 0,20 0),(20 0,22 0))", tmp); lwfree(tmp); lwgeom_free(out); lwgeom_free(in); wkt = "MULTILINESTRING((0 0,5 5,10 0, 11 0, 20 0),(22 0, 12 0, 10 0),(0 5, 5 0))"; in = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE); out = lwgeom_node(in); tmp = lwgeom_to_ewkt(out); printf("%s\n", tmp); CU_ASSERT_STRING_EQUAL( "MULTILINESTRING((0 0,2.5 2.5),(0 5,2.5 2.5),(22 0,20 0),(20 0,12 0,11 0,10 0),(10 0,5 5,2.5 2.5),(2.5 2.5,5 0))", tmp); lwfree(tmp); lwgeom_free(out); lwgeom_free(in); #endif /* POSTGIS_GEOS_VERSION >= 33 */ }
static void test_lwgeom_segmentize2d(void) { LWGEOM *linein = lwgeom_from_wkt("LINESTRING(0 0,10 0)", LW_PARSER_CHECK_NONE); LWGEOM *lineout = lwgeom_segmentize2d(linein, 5); char *strout = lwgeom_to_ewkt(lineout); CU_ASSERT_STRING_EQUAL(strout, "LINESTRING(0 0,5 0,10 0)"); lwfree(strout); lwgeom_free(linein); lwgeom_free(lineout); }
static void test_misc_force_2d(void) { LWGEOM *geom; LWGEOM *geom2d; char *wkt_out; geom = lwgeom_from_wkt("CIRCULARSTRINGM(-5 0 4,0 5 3,5 0 2,10 -5 1,15 0 0)", LW_PARSER_CHECK_NONE); geom2d = lwgeom_force_2d(geom); wkt_out = lwgeom_to_ewkt(geom2d); CU_ASSERT_STRING_EQUAL("CIRCULARSTRING(-5 0,0 5,5 0,10 -5,15 0)",wkt_out); lwgeom_free(geom); lwgeom_free(geom2d); lwfree(wkt_out); geom = lwgeom_from_wkt("GEOMETRYCOLLECTION(POINT(0 0 0),LINESTRING(1 1 1,2 2 2),POLYGON((0 0 1,0 1 1,1 1 1,1 0 1,0 0 1)),CURVEPOLYGON(CIRCULARSTRING(0 0 0,1 1 1,2 2 2,1 1 1,0 0 0)))", LW_PARSER_CHECK_NONE); geom2d = lwgeom_force_2d(geom); wkt_out = lwgeom_to_ewkt(geom2d); CU_ASSERT_STRING_EQUAL("GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(1 1,2 2),POLYGON((0 0,0 1,1 1,1 0,0 0)),CURVEPOLYGON(CIRCULARSTRING(0 0,1 1,2 2,1 1,0 0)))",wkt_out); lwgeom_free(geom); lwgeom_free(geom2d); lwfree(wkt_out); }
static void test_misc_simplify(void) { LWGEOM *geom; LWGEOM *geom2d; char *wkt_out; geom = lwgeom_from_wkt("LINESTRING(0 0,0 10,0 51,50 20,30 20,7 32)", LW_PARSER_CHECK_NONE); geom2d = lwgeom_simplify(geom, 2, LW_FALSE); wkt_out = lwgeom_to_ewkt(geom2d); CU_ASSERT_STRING_EQUAL("LINESTRING(0 0,0 51,50 20,30 20,7 32)",wkt_out); lwgeom_free(geom); lwgeom_free(geom2d); lwfree(wkt_out); geom = lwgeom_from_wkt("MULTILINESTRING((0 0,0 10,0 51,50 20,30 20,7 32))", LW_PARSER_CHECK_NONE); geom2d = lwgeom_simplify(geom, 2, LW_FALSE); wkt_out = lwgeom_to_ewkt(geom2d); CU_ASSERT_STRING_EQUAL("MULTILINESTRING((0 0,0 51,50 20,30 20,7 32))",wkt_out); lwgeom_free(geom); lwgeom_free(geom2d); lwfree(wkt_out); }
/** * Serializes a LWLINE to a char*. This is a helper function that partially * writes the appropriate draw and stroke commands used to generate an SVG image * using ImageMagick's "convert" command. * @param output a char reference to write the LWLINE to * @param lwl a reference to a LWLINE * @return the numbers of character written to *output */ static size_t drawLineString(char *output, LWLINE *lwl, LAYERSTYLE *style) { char *ptr = output; LWDEBUGF(4, "%s", "drawLineString called"); LWDEBUGF( 4, "line = %s", lwgeom_to_ewkt((LWGEOM*)lwl,0) ); ptr += sprintf(ptr, "-fill none -stroke %s -strokewidth %d ", style->lineColor, style->lineWidth); ptr += sprintf(ptr, "-draw \"stroke-linecap round stroke-linejoin round path 'M "); ptr += pointarrayToString(ptr, lwl->points ); ptr += sprintf(ptr, "'\" "); return (ptr - output); }
static void do_geom_test(char * in, char * out) { LWGEOM *g, *h; char *tmp; g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); h = lwgeom_homogenize(g); tmp = lwgeom_to_ewkt(h); if (strcmp(tmp, out)) fprintf(stderr, "\nIn: %s\nOut: %s\nExp: %s\n", in, tmp, out); CU_ASSERT_STRING_EQUAL(tmp, out); lwfree(tmp); lwgeom_free(g); /* See http://trac.osgeo.org/postgis/ticket/1104 */ lwgeom_free(h); }
static void test_geos_noop(void) { int i; char *ewkt[] = { "POINT(0 0.2)", "LINESTRING(-1 -1,-1 2.5,2 2,2 -1)", "MULTIPOINT(0.9 0.9,0.9 0.9,0.9 0.9,0.9 0.9,0.9 0.9,0.9 0.9)", "SRID=1;MULTILINESTRING((-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1))", "SRID=1;MULTILINESTRING((-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1))", "POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0))", "SRID=4326;POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0))", "SRID=4326;POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5))", "SRID=100000;POLYGON((-1 -1 3,-1 2.5 3,2 2 3,2 -1 3,-1 -1 3),(0 0 3,0 1 3,1 1 3,1 0 3,0 0 3),(-0.5 -0.5 3,-0.5 -0.4 3,-0.4 -0.4 3,-0.4 -0.5 3,-0.5 -0.5 3))", "SRID=4326;MULTIPOLYGON(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)),((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)))", "SRID=4326;GEOMETRYCOLLECTION(POINT(0 1),POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0)),MULTIPOLYGON(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5))))", }; for ( i = 0; i < (sizeof ewkt/sizeof(char *)); i++ ) { LWGEOM *geom_in, *geom_out; char *in_ewkt; char *out_ewkt; in_ewkt = ewkt[i]; geom_in = lwgeom_from_wkt(in_ewkt, LW_PARSER_CHECK_NONE); geom_out = lwgeom_geos_noop(geom_in); if ( ! geom_out ) { fprintf(stderr, "\nNull return from lwgeom_geos_noop with wkt: %s\n", in_ewkt); lwgeom_free(geom_in); continue; } out_ewkt = lwgeom_to_ewkt(geom_out); if (strcmp(in_ewkt, out_ewkt)) fprintf(stderr, "\nExp: %s\nObt: %s\n", in_ewkt, out_ewkt); CU_ASSERT_STRING_EQUAL(in_ewkt, out_ewkt); lwfree(out_ewkt); lwgeom_free(geom_out); lwgeom_free(geom_in); } }
static void test_grid(void) { gridspec grid; static char *wkt = "MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)))"; LWGEOM *geom = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_ALL); LWGEOM *geomgrid; char *str; grid.ipx = grid.ipy = 0; grid.xsize = grid.ysize = 20; geomgrid = lwgeom_grid(geom, &grid); str = lwgeom_to_ewkt(geomgrid); CU_ASSERT_STRING_EQUAL(str, "MULTIPOLYGON EMPTY"); lwfree(str); lwgeom_free(geom); lwgeom_free(geomgrid); }
/** * Serializes a LWPOLY to a char*. This is a helper function that partially * writes the appropriate draw and fill commands used to generate an SVG image * using ImageMagick's "convert" command. * @param output a char reference to write the LWPOLY to * @param lwp a reference to a LWPOLY * @return the numbers of character written to *output */ static size_t drawPolygon(char *output, LWPOLY *lwp, LAYERSTYLE *style) { char *ptr = output; int i; LWDEBUGF(4, "%s", "drawPolygon called"); LWDEBUGF( 4, "poly = %s", lwgeom_to_ewkt((LWGEOM*)lwp,0) ); ptr += sprintf(ptr, "-fill %s -stroke %s -strokewidth %d ", style->polygonFillColor, style->polygonStrokeColor, style->polygonStrokeWidth ); ptr += sprintf(ptr, "-draw \"path '"); for (i=0; i<lwp->nrings; i++) { ptr += sprintf(ptr, "M "); ptr += pointarrayToString(ptr, lwp->rings[i] ); ptr += sprintf(ptr, " "); } ptr += sprintf(ptr, "'\" "); return (ptr - output); }
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); }
void tin_parse(void) { LWGEOM *geom; GSERIALIZED *g; char *tmp; cu_error_msg_reset(); /* Because i don't trust that much prior tests... ;) */ /* empty */ geom = lwgeom_from_wkt("TIN EMPTY", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TINTYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("TIN EMPTY", tmp); lwfree(tmp); lwgeom_free(geom); /* 2 dims */ geom = lwgeom_from_wkt("TIN(((0 1,2 3,4 5,0 1)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TINTYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("TIN(((0 1,2 3,4 5,0 1)))", tmp); lwfree(tmp); lwgeom_free(geom); /* 3DM */ geom = lwgeom_from_wkt("TINM(((0 1 2,3 4 5,6 7 8,0 1 2)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TINTYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("TINM(((0 1 2,3 4 5,6 7 8,0 1 2)))", tmp); lwfree(tmp); lwgeom_free(geom); /* ERROR: a missing Z values */ geom = lwgeom_from_wkt("TIN(((0 1 2,3 4 5,6 7,0 1 2)))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("can not mix dimensionality in a geometry", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: non closed rings */ geom = lwgeom_from_wkt("TIN(((0 1 2,3 4 5,6 7 8,0 0 2)))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: non closed face in Z dim */ geom = lwgeom_from_wkt("TIN(((0 1 2,3 4 5,6 7 8,0 1 3)))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: non closed face in Z dim, with a 4D geom */ geom = lwgeom_from_wkt("TIN(((0 1 2 3,4 5 6 7,8 9 10 11,0 1 3 3)))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: only 3 points in a face */ geom = lwgeom_from_wkt("TIN(((0 1 2,3 4 5,0 1 2)))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("triangle must have exactly 4 points", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: more than 3 points in a face */ geom = lwgeom_from_wkt("TIN(((0 1 2,3 4 5,6 7 8,9 10 11,0 1 2)))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("triangle must have exactly 4 points", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: use ring for triangle */ geom = lwgeom_from_wkt("TIN(((0 1 2,3 4 5,6 7 8,0 1 2),(9 10 11,12 13 14,15 16 17,9 10 11)))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("parse error - invalid geometry", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* EMPTY face */ geom = lwgeom_from_wkt("TIN EMPTY", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TINTYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("TIN EMPTY", tmp); lwfree(tmp); lwgeom_free(geom); /* A simple tetrahedron */ geom = lwgeom_from_wkt("TIN(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TINTYPE); CU_ASSERT_EQUAL(geom->srid, SRID_UNKNOWN); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("TIN(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", tmp); lwfree(tmp); lwgeom_free(geom); /* A 4D tetrahedron */ geom = lwgeom_from_wkt("TIN(((0 0 0 0,0 0 1 0,0 1 0 2,0 0 0 0)),((0 0 0 0,0 1 0 0,1 0 0 4,0 0 0 0)),((0 0 0 0,1 0 0 0,0 0 1 6,0 0 0 0)),((1 0 0 0,0 1 0 0,0 0 1 0,1 0 0 0)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TINTYPE); CU_ASSERT_EQUAL(FLAGS_GET_M(geom->flags), 1); CU_ASSERT_EQUAL(geom->srid, SRID_UNKNOWN); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("TIN(((0 0 0 0,0 0 1 0,0 1 0 2,0 0 0 0)),((0 0 0 0,0 1 0 0,1 0 0 4,0 0 0 0)),((0 0 0 0,1 0 0 0,0 0 1 6,0 0 0 0)),((1 0 0 0,0 1 0 0,0 0 1 0,1 0 0 0)))", tmp); lwfree(tmp); lwgeom_free(geom); /* explicit SRID */ geom = lwgeom_from_wkt("SRID=4326;TIN(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TINTYPE); CU_ASSERT_EQUAL(geom->srid, 4326); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("SRID=4326;TIN(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", tmp); lwfree(tmp); lwgeom_free(geom); /* geography support */ geom = lwgeom_from_wkt("TIN(((0 1 2,3 4 5,6 7 8,0 1 2)))", LW_PARSER_CHECK_NONE); g = gserialized_from_lwgeom(geom, 1, 0); CU_ASSERT_EQUAL(gserialized_get_type(g), TINTYPE); lwgeom_free(geom); lwfree(g); }
GEOSGeometry* LWGEOM_GEOS_buildArea(const GEOSGeometry* geom_in) { GEOSGeometry *tmp; GEOSGeometry *geos_result, *shp; GEOSGeometry const *vgeoms[1]; uint32_t i, ngeoms; int srid = GEOSGetSRID(geom_in); Face ** geoms; vgeoms[0] = geom_in; #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Polygonizing"); #endif geos_result = GEOSPolygonize(vgeoms, 1); LWDEBUGF(3, "GEOSpolygonize returned @ %p", geos_result); /* Null return from GEOSpolygonize (an exception) */ if ( ! geos_result ) return 0; /* * We should now have a collection */ #if PARANOIA_LEVEL > 0 if ( GEOSGeometryTypeId(geos_result) != COLLECTIONTYPE ) { GEOSGeom_destroy(geos_result); lwerror("Unexpected return from GEOSpolygonize"); return 0; } #endif ngeoms = GEOSGetNumGeometries(geos_result); #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Num geometries from polygonizer: %d", ngeoms); #endif LWDEBUGF(3, "GEOSpolygonize: ngeoms in polygonize output: %d", ngeoms); LWDEBUGF(3, "GEOSpolygonize: polygonized:%s", lwgeom_to_ewkt(GEOS2LWGEOM(geos_result, 0))); /* * No geometries in collection, early out */ if ( ngeoms == 0 ) { GEOSSetSRID(geos_result, srid); return geos_result; } /* * Return first geometry if we only have one in collection, * to avoid the unnecessary Geometry clone below. */ if ( ngeoms == 1 ) { tmp = (GEOSGeometry *)GEOSGetGeometryN(geos_result, 0); if ( ! tmp ) { GEOSGeom_destroy(geos_result); return 0; /* exception */ } shp = GEOSGeom_clone(tmp); GEOSGeom_destroy(geos_result); /* only safe after the clone above */ GEOSSetSRID(shp, srid); return shp; } LWDEBUGF(2, "Polygonize returned %d geoms", ngeoms); /* * Polygonizer returns a polygon for each face in the built topology. * * This means that for any face with holes we'll have other faces * representing each hole. We can imagine a parent-child relationship * between these faces. * * In order to maximize the number of visible rings in output we * only use those faces which have an even number of parents. * * Example: * * +---------------+ * | L0 | L0 has no parents * | +---------+ | * | | L1 | | L1 is an hole of L0 * | | +---+ | | * | | |L2 | | | L2 is an hole of L1 (which is an hole of L0) * | | | | | | * | | +---+ | | * | +---------+ | * | | * +---------------+ * * See http://trac.osgeo.org/postgis/ticket/1806 * */ #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Preparing face structures"); #endif /* Prepare face structures for later analysis */ geoms = lwalloc(sizeof(Face**)*ngeoms); for (i=0; i<ngeoms; ++i) geoms[i] = newFace(GEOSGetGeometryN(geos_result, i)); #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Finding face holes"); #endif /* Find faces representing other faces holes */ findFaceHoles(geoms, ngeoms); #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Colletting even ancestor faces"); #endif /* Build a MultiPolygon composed only by faces with an * even number of ancestors */ tmp = collectFacesWithEvenAncestors(geoms, ngeoms); #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Cleaning up"); #endif /* Cleanup face structures */ for (i=0; i<ngeoms; ++i) delFace(geoms[i]); lwfree(geoms); /* Faces referenced memory owned by geos_result. * It is safe to destroy geos_result after deleting them. */ GEOSGeom_destroy(geos_result); #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Self-unioning"); #endif /* Run a single overlay operation to dissolve shared edges */ shp = GEOSUnionCascaded(tmp); if ( ! shp ) { GEOSGeom_destroy(tmp); return 0; /* exception */ } #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Final cleanup"); #endif GEOSGeom_destroy(tmp); GEOSSetSRID(shp, srid); return shp; }
/** * Main Application. Currently, drawing styles are hardcoded in this method. * Future work may entail reading the styles from a .properties file. */ int main( int argc, const char* argv[] ) { FILE *pfile; LWGEOM *lwgeom; char line [2048]; char *filename; int layerCount; int styleNumber; LAYERSTYLE *styles; getStyles(&styles); if ( argc != 2 ) { lwerror("You must specifiy a wkt filename to convert.\n"); return -1; } if ( (pfile = fopen(argv[1], "r")) == NULL) { perror ( argv[1] ); return -1; } filename = malloc( strlen(argv[1])+11 ); strncpy( filename, "../images/", 10 ); strncat( filename, argv[1], strlen(argv[1])-3 ); strncat( filename, "png", 3 ); printf( "generating %s\n", filename ); layerCount = 0; while ( fgets ( line, sizeof line, pfile ) != NULL && !isspace(*line) ) { char output[2048]; char *ptr = output; char *styleName; int useDefaultStyle; ptr += sprintf( ptr, "convert -size %s xc:none ", imageSize ); useDefaultStyle = getStyleName(&styleName, line); LWDEBUGF( 4, "%s", styleName ); if (useDefaultStyle) { printf(" Warning: using Default style for layer %d\n", layerCount); lwgeom = lwgeom_from_ewkt( line, PARSER_CHECK_NONE ); } else lwgeom = lwgeom_from_ewkt( line+strlen(styleName)+1, PARSER_CHECK_NONE ); LWDEBUGF( 4, "geom = %s", lwgeom_to_ewkt((LWGEOM*)lwgeom,0) ); styleNumber = layerCount % length(styles); ptr += drawGeometry( ptr, lwgeom, getStyle(styles, styleName) ); ptr += sprintf( ptr, "-flip tmp%d.png", layerCount ); lwfree( lwgeom ); LWDEBUGF( 4, "%s", output ); system(output); addHighlight( layerCount ); addDropShadow( layerCount ); layerCount++; free(styleName); } flattenLayers(filename); optimizeImage(filename); fclose(pfile); free(filename); freeStyles(&styles); return 0; }
GEOSGeometry* LWGEOM_GEOS_buildArea(const GEOSGeometry* geom_in) { GEOSGeometry *tmp; GEOSGeometry *geos_result, *shp; GEOSGeometry const *vgeoms[1]; uint32_t i, ngeoms; int srid = GEOSGetSRID(geom_in); vgeoms[0] = geom_in; geos_result = GEOSPolygonize(vgeoms, 1); LWDEBUGF(3, "GEOSpolygonize returned @ %p", geos_result); /* Null return from GEOSpolygonize (an exception) */ if ( ! geos_result ) return 0; /* * We should now have a collection */ #if PARANOIA_LEVEL > 0 if ( GEOSGeometryTypeId(geos_result) != COLLECTIONTYPE ) { GEOSGeom_destroy(geos_result); lwerror("Unexpected return from GEOSpolygonize"); return 0; } #endif ngeoms = GEOSGetNumGeometries(geos_result); LWDEBUGF(3, "GEOSpolygonize: ngeoms in polygonize output: %d", ngeoms); LWDEBUGF(3, "GEOSpolygonize: polygonized:%s", lwgeom_to_ewkt(GEOS2LWGEOM(geos_result, 0))); /* * No geometries in collection, early out */ if ( ngeoms == 0 ) { GEOSSetSRID(geos_result, srid); return geos_result; } /* * Return first geometry if we only have one in collection, * to avoid the unnecessary Geometry clone below. */ if ( ngeoms == 1 ) { tmp = (GEOSGeometry *)GEOSGetGeometryN(geos_result, 0); if ( ! tmp ) { GEOSGeom_destroy(geos_result); return 0; /* exception */ } shp = GEOSGeom_clone(tmp); GEOSGeom_destroy(geos_result); /* only safe after the clone above */ GEOSSetSRID(shp, srid); return shp; } /* * Iteratively invoke symdifference on outer rings * as suggested by Carl Anderson: * postgis-devel/2005-December/001805.html */ shp = NULL; for (i=0; i<ngeoms; ++i) { GEOSGeom extring; GEOSCoordSeq sq; /* * Construct a Polygon from geometry i exterior ring * We don't use GEOSGeom_clone on the ExteriorRing * due to a bug in CAPI contained in GEOS 2.2 branch * failing to properly return a LinearRing from * a LinearRing clone. */ sq=GEOSCoordSeq_clone(GEOSGeom_getCoordSeq( GEOSGetExteriorRing(GEOSGetGeometryN( geos_result, i)) )); extring = GEOSGeom_createPolygon( GEOSGeom_createLinearRing(sq), NULL, 0 ); if ( extring == NULL ) /* exception */ { lwerror("GEOSCreatePolygon threw an exception"); return 0; } if ( shp == NULL ) { shp = extring; LWDEBUGF(3, "GEOSpolygonize: shp:%s", lwgeom_to_ewkt(GEOS2LWGEOM(shp, 0))); } else { tmp = GEOSSymDifference(shp, extring); LWDEBUGF(3, "GEOSpolygonize: SymDifference(%s, %s):%s", lwgeom_to_ewkt(GEOS2LWGEOM(shp, 0)), lwgeom_to_ewkt(GEOS2LWGEOM(extring, 0)), lwgeom_to_ewkt(GEOS2LWGEOM(tmp, 0)) ); GEOSGeom_destroy(shp); GEOSGeom_destroy(extring); shp = tmp; } } GEOSGeom_destroy(geos_result); GEOSSetSRID(shp, srid); return shp; }
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_lwmline_clip(void) { LWCOLLECTION *c; char *ewkt; LWMLINE *mline = NULL; LWLINE *line = NULL; /* ** Set up the input line. Trivial one-member case. */ mline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((0 0,0 1,0 2,0 3,0 4))", LW_PARSER_CHECK_NONE); /* Clip in the middle, mid-range. */ c = lwmline_clip_to_ordinate_range(mline, 'Y', 1.5, 2.5); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1.5,0 2,0 2.5))"); lwfree(ewkt); lwcollection_free(c); lwmline_free(mline); /* ** Set up the input line. Two-member case. */ mline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((1 0,1 1,1 2,1 3,1 4), (0 0,0 1,0 2,0 3,0 4))", LW_PARSER_CHECK_NONE); /* Clip off the top. */ c = lwmline_clip_to_ordinate_range(mline, 'Y', 3.5, 5.5); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((1 3.5,1 4),(0 3.5,0 4))"); lwfree(ewkt); lwcollection_free(c); lwmline_free(mline); /* ** Set up staggered input line to create multi-type output. */ mline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((1 0,1 -1,1 -2,1 -3,1 -4), (0 0,0 1,0 2,0 3,0 4))", LW_PARSER_CHECK_NONE); /* Clip from 0 upwards.. */ c = lwmline_clip_to_ordinate_range(mline, 'Y', 0.0, 2.5); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 0),LINESTRING(0 0,0 1,0 2,0 2.5))"); lwfree(ewkt); lwcollection_free(c); lwmline_free(mline); /* ** Set up input line from MAC */ line = (LWLINE*)lwgeom_from_wkt("LINESTRING(0 0 0 0,1 1 1 1,2 2 2 2,3 3 3 3,4 4 4 4,3 3 3 5,2 2 2 6,1 1 1 7,0 0 0 8)", LW_PARSER_CHECK_NONE); /* Clip from 3 to 3.5 */ c = lwline_clip_to_ordinate_range(line, 'Z', 3.0, 3.5); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((3 3 3 3,3.5 3.5 3.5 3.5),(3.5 3.5 3.5 4.5,3 3 3 5))"); lwfree(ewkt); lwcollection_free(c); /* Clip from 2 to 3.5 */ c = lwline_clip_to_ordinate_range(line, 'Z', 2.0, 3.5); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2 2,3 3 3 3,3.5 3.5 3.5 3.5),(3.5 3.5 3.5 4.5,3 3 3 5,2 2 2 6))"); lwfree(ewkt); lwcollection_free(c); /* Clip from 3 to 4 */ c = lwline_clip_to_ordinate_range(line, 'Z', 3.0, 4.0); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((3 3 3 3,4 4 4 4,3 3 3 5))"); lwfree(ewkt); lwcollection_free(c); /* Clip from 2 to 3 */ c = lwline_clip_to_ordinate_range(line, 'Z', 2.0, 3.0); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2 2,3 3 3 3),(3 3 3 5,2 2 2 6))"); lwfree(ewkt); lwcollection_free(c); lwline_free(line); }
/** * Take in a LINESTRING and return a MULTILINESTRING of those portions of the * LINESTRING between the from/to range for the specified ordinate (XYZM) */ LWCOLLECTION* lwline_clip_to_ordinate_range(const LWLINE *line, char ordinate, double from, double to) { POINTARRAY *pa_in = NULL; LWCOLLECTION *lwgeom_out = NULL; POINTARRAY *dp = NULL; int i, rv; int added_last_point = 0; POINT4D *p = NULL, *q = NULL, *r = NULL; double ordinate_value_p = 0.0, ordinate_value_q = 0.0; char hasz = lwgeom_has_z(lwline_as_lwgeom(line)); char hasm = lwgeom_has_m(lwline_as_lwgeom(line)); char dims = FLAGS_NDIMS(line->flags); /* Null input, nothing we can do. */ if ( ! line ) { lwerror("Null input geometry."); return NULL; } /* Ensure 'from' is less than 'to'. */ if ( to < from ) { double t = from; from = to; to = t; } LWDEBUGF(4, "from = %g, to = %g, ordinate = %c", from, to, ordinate); LWDEBUGF(4, "%s", lwgeom_to_ewkt((LWGEOM*)line)); /* Asking for an ordinate we don't have. Error. */ if ( (ordinate == 'Z' && ! hasz) || (ordinate == 'M' && ! hasm) ) { lwerror("Cannot clip on ordinate %d in a %d-d geometry.", ordinate, dims); return NULL; } /* Prepare our working point objects. */ p = lwalloc(sizeof(POINT4D)); q = lwalloc(sizeof(POINT4D)); r = lwalloc(sizeof(POINT4D)); /* Construct a collection to hold our outputs. */ lwgeom_out = lwcollection_construct_empty(MULTILINETYPE, line->srid, hasz, hasm); /* Get our input point array */ pa_in = line->points; for ( i = 0; i < pa_in->npoints; i++ ) { LWDEBUGF(4, "Point #%d", i); LWDEBUGF(4, "added_last_point %d", added_last_point); if ( i > 0 ) { *q = *p; ordinate_value_q = ordinate_value_p; } rv = getPoint4d_p(pa_in, i, p); ordinate_value_p = lwpoint_get_ordinate(p, ordinate); LWDEBUGF(4, " ordinate_value_p %g (current)", ordinate_value_p); LWDEBUGF(4, " ordinate_value_q %g (previous)", ordinate_value_q); /* Is this point inside the ordinate range? Yes. */ if ( ordinate_value_p >= from && ordinate_value_p <= to ) { LWDEBUGF(4, " inside ordinate range (%g, %g)", from, to); if ( ! added_last_point ) { LWDEBUG(4," new ptarray required"); /* We didn't add the previous point, so this is a new segment. * Make a new point array. */ dp = ptarray_construct_empty(hasz, hasm, 32); /* We're transiting into the range so add an interpolated * point at the range boundary. * If we're on a boundary and crossing from the far side, * we also need an interpolated point. */ if ( i > 0 && ( /* Don't try to interpolate if this is the first point */ ( ordinate_value_p > from && ordinate_value_p < to ) || /* Inside */ ( ordinate_value_p == from && ordinate_value_q > to ) || /* Hopping from above */ ( ordinate_value_p == to && ordinate_value_q < from ) ) ) /* Hopping from below */ { double interpolation_value; (ordinate_value_q > to) ? (interpolation_value = to) : (interpolation_value = from); rv = point_interpolate(q, p, r, hasz, hasm, ordinate, interpolation_value); rv = ptarray_append_point(dp, r, LW_FALSE); LWDEBUGF(4, "[0] interpolating between (%g, %g) with interpolation point (%g)", ordinate_value_q, ordinate_value_p, interpolation_value); } } /* Add the current vertex to the point array. */ rv = ptarray_append_point(dp, p, LW_FALSE); if ( ordinate_value_p == from || ordinate_value_p == to ) { added_last_point = 2; /* Added on boundary. */ } else { added_last_point = 1; /* Added inside range. */ } } /* Is this point inside the ordinate range? No. */ else { LWDEBUGF(4, " added_last_point (%d)", added_last_point); if ( added_last_point == 1 ) { /* We're transiting out of the range, so add an interpolated point * to the point array at the range boundary. */ double interpolation_value; (ordinate_value_p > to) ? (interpolation_value = to) : (interpolation_value = from); rv = point_interpolate(q, p, r, hasz, hasm, ordinate, interpolation_value); rv = ptarray_append_point(dp, r, LW_FALSE); LWDEBUGF(4, " [1] interpolating between (%g, %g) with interpolation point (%g)", ordinate_value_q, ordinate_value_p, interpolation_value); } else if ( added_last_point == 2 ) { /* We're out and the last point was on the boundary. * If the last point was the near boundary, nothing to do. * If it was the far boundary, we need an interpolated point. */ if ( from != to && ( (ordinate_value_q == from && ordinate_value_p > from) || (ordinate_value_q == to && ordinate_value_p < to) ) ) { double interpolation_value; (ordinate_value_p > to) ? (interpolation_value = to) : (interpolation_value = from); rv = point_interpolate(q, p, r, hasz, hasm, ordinate, interpolation_value); rv = ptarray_append_point(dp, r, LW_FALSE); LWDEBUGF(4, " [2] interpolating between (%g, %g) with interpolation point (%g)", ordinate_value_q, ordinate_value_p, interpolation_value); } } else if ( i && ordinate_value_q < from && ordinate_value_p > to ) { /* We just hopped over the whole range, from bottom to top, * so we need to add *two* interpolated points! */ dp = ptarray_construct(hasz, hasm, 2); /* Interpolate lower point. */ rv = point_interpolate(p, q, r, hasz, hasm, ordinate, from); ptarray_set_point4d(dp, 0, r); /* Interpolate upper point. */ rv = point_interpolate(p, q, r, hasz, hasm, ordinate, to); ptarray_set_point4d(dp, 1, r); } else if ( i && ordinate_value_q > to && ordinate_value_p < from ) { /* We just hopped over the whole range, from top to bottom, * so we need to add *two* interpolated points! */ dp = ptarray_construct(hasz, hasm, 2); /* Interpolate upper point. */ rv = point_interpolate(p, q, r, hasz, hasm, ordinate, to); ptarray_set_point4d(dp, 0, r); /* Interpolate lower point. */ rv = point_interpolate(p, q, r, hasz, hasm, ordinate, from); ptarray_set_point4d(dp, 1, r); } /* We have an extant point-array, save it out to a multi-line. */ if ( dp ) { LWDEBUG(4, "saving pointarray to multi-line (1)"); /* Only one point, so we have to make an lwpoint to hold this * and set the overall output type to a generic collection. */ if ( dp->npoints == 1 ) { LWPOINT *opoint = lwpoint_construct(line->srid, NULL, dp); lwgeom_out->type = COLLECTIONTYPE; lwgeom_out = lwcollection_add_lwgeom(lwgeom_out, lwpoint_as_lwgeom(opoint)); } else { LWLINE *oline = lwline_construct(line->srid, NULL, dp); lwgeom_out = lwcollection_add_lwgeom(lwgeom_out, lwline_as_lwgeom(oline)); } /* Pointarray is now owned by lwgeom_out, so drop reference to it */ dp = NULL; } added_last_point = 0; } } /* Still some points left to be saved out. */ if ( dp && dp->npoints > 0 ) { LWDEBUG(4, "saving pointarray to multi-line (2)"); LWDEBUGF(4, "dp->npoints == %d", dp->npoints); LWDEBUGF(4, "lwgeom_out->ngeoms == %d", lwgeom_out->ngeoms); if ( dp->npoints == 1 ) { LWPOINT *opoint = lwpoint_construct(line->srid, NULL, dp); lwgeom_out->type = COLLECTIONTYPE; lwgeom_out = lwcollection_add_lwgeom(lwgeom_out, lwpoint_as_lwgeom(opoint)); } else { LWLINE *oline = lwline_construct(line->srid, NULL, dp); lwgeom_out = lwcollection_add_lwgeom(lwgeom_out, lwline_as_lwgeom(oline)); } /* Pointarray is now owned by lwgeom_out, so drop reference to it */ dp = NULL; } lwfree(p); lwfree(q); lwfree(r); if ( lwgeom_out->ngeoms > 0 ) { lwgeom_drop_bbox((LWGEOM*)lwgeom_out); lwgeom_add_bbox((LWGEOM*)lwgeom_out); } return lwgeom_out; }
void triangle_parse(void) { LWGEOM *geom; GSERIALIZED *g; char *tmp; cu_error_msg_reset(); /* Because i don't trust that much prior tests... ;) */ /* 2 dims */ geom = lwgeom_from_wkt("TRIANGLE((0 1,2 3,4 5,0 1))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TRIANGLETYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("TRIANGLE((0 1,2 3,4 5,0 1))", tmp); lwfree(tmp); lwgeom_free(geom); /* 3DM */ geom = lwgeom_from_wkt("TRIANGLEM((0 1 2,3 4 5,6 7 8,0 1 2))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TRIANGLETYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("TRIANGLEM((0 1 2,3 4 5,6 7 8,0 1 2))", tmp); lwfree(tmp); lwgeom_free(geom); /* ERROR: a missing Z values */ geom = lwgeom_from_wkt("TRIANGLE((0 1 2,3 4 5,6 7,0 1 2))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("can not mix dimensionality in a geometry", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: non closed rings */ geom = lwgeom_from_wkt("TRIANGLE((0 1 2,3 4 5,6 7 8,0 0 2))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: non closed face in Z dim */ geom = lwgeom_from_wkt("TRIANGLE((0 1 2,3 4 5,6 7 8,0 1 3))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: non closed face in Z dim, with a 4D geom */ geom = lwgeom_from_wkt("TRIANGLE((0 1 2 3,4 5 6 7,8 9 10 11,0 1 3 3))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: only 3 points in a face */ geom = lwgeom_from_wkt("TRIANGLE((0 1 2,3 4 5,0 1 2))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("triangle must have exactly 4 points", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: more than 4 points in a face */ geom = lwgeom_from_wkt("TRIANGLE((0 1 2,3 4 5,6 7 8,9 10 11,0 1 2))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("triangle must have exactly 4 points", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: no interior rings allowed */ geom = lwgeom_from_wkt("TRIANGLE((0 1 2,3 4 5,6 7 8,0 1 2),(9 10 11,12 13 14,15 16 17,9 10 11)", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("parse error - invalid geometry", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* EMPTY face */ geom = lwgeom_from_wkt("TRIANGLE EMPTY", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TRIANGLETYPE); tmp = lwgeom_to_wkt(geom, LW_PARSER_CHECK_NONE, 0, 0); CU_ASSERT_STRING_EQUAL("TRIANGLE EMPTY", tmp); lwfree(tmp); lwgeom_free(geom); /* explicit SRID */ geom = lwgeom_from_wkt("SRID=4326;TRIANGLE((0 1 2,3 4 5,6 7 8,0 1 2))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TRIANGLETYPE); CU_ASSERT_EQUAL(geom->srid, 4326); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("SRID=4326;TRIANGLE((0 1 2,3 4 5,6 7 8,0 1 2))", tmp); lwfree(tmp); lwgeom_free(geom); /* geography support */ geom = lwgeom_from_wkt("TRIANGLE((0 1 2,3 4 5,6 7 8,0 1 2))", LW_PARSER_CHECK_NONE); g = gserialized_from_lwgeom(geom, 1, 0); CU_ASSERT_EQUAL(gserialized_get_type(g), TRIANGLETYPE); lwgeom_free(geom); lwfree(g); }
void polyhedralsurface_parse(void) { LWGEOM *geom; GSERIALIZED *g; char *tmp; cu_error_msg_reset(); /* Because i don't trust that much prior tests... ;) */ /* 2 dims */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1,2 3,4 5,0 1)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F00000001000000010300000001000000040000000000000000000000000000000000F03F00000000000000400000000000000840000000000000104000000000000014400000000000000000000000000000F03F", tmp); lwfree(tmp); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 1,2 3,4 5,0 1)))", tmp); lwfree(tmp); lwgeom_free(geom); /* 3DM */ geom = lwgeom_from_wkt("POLYHEDRALSURFACEM(((0 1 2,3 4 5,6 7 8,0 1 2)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACEM(((0 1 2,3 4 5,6 7 8,0 1 2)))", tmp); lwfree(tmp); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F00004001000000010300004001000000040000000000000000000000000000000000F03F000000000000004000000000000008400000000000001040000000000000144000000000000018400000000000001C4000000000000020400000000000000000000000000000F03F0000000000000040", tmp); lwfree(tmp); lwgeom_free(geom); /* ERROR: a missing Z values */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7,0 1 2)))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("can not mix dimensionality in a geometry", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* 1 face with 1 interior ring */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 1 2),(9 10 11,12 13 14,15 16 17,9 10 11)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 1 2),(9 10 11,12 13 14,15 16 17,9 10 11)))", tmp); lwfree(tmp); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F00008001000000010300008002000000040000000000000000000000000000000000F03F000000000000004000000000000008400000000000001040000000000000144000000000000018400000000000001C4000000000000020400000000000000000000000000000F03F00000000000000400400000000000000000022400000000000002440000000000000264000000000000028400000000000002A400000000000002C400000000000002E4000000000000030400000000000003140000000000000224000000000000024400000000000002640", tmp); lwfree(tmp); lwgeom_free(geom); /* ERROR: non closed rings */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 0 2)))", LW_PARSER_CHECK_ALL); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: non closed face in Z dim */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 1 3)))", LW_PARSER_CHECK_ALL); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: non closed face in Z dim, with a 4D geom */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2 3,4 5 6 7,8 9 10 11,0 1 3 3)))", LW_PARSER_CHECK_ALL); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: only 3 points in a face */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,0 1 2)))", LW_PARSER_CHECK_ALL); CU_ASSERT_STRING_EQUAL("geometry requires more points", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* EMPTY face */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE EMPTY", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); tmp = (char *)lwgeom_to_wkb(geom, WKB_HEX | WKB_ISO | WKB_NDR, 0); CU_ASSERT_STRING_EQUAL("010F00000000000000", tmp); lwfree(tmp); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE EMPTY", tmp); lwfree(tmp); lwgeom_free(geom); /* A simple tetrahedron */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); CU_ASSERT_EQUAL(geom->srid, SRID_UNKNOWN); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", tmp); lwfree(tmp); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F000080040000000103000080010000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000010300008001000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000000001030000800100000004000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000000001030000800100000004000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F00000000000000000000000000000000", tmp); lwfree(tmp); lwgeom_free(geom); /* A 4D tetrahedron */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 0 0 0,0 0 1 0,0 1 0 2,0 0 0 0)),((0 0 0 0,0 1 0 0,1 0 0 4,0 0 0 0)),((0 0 0 0,1 0 0 0,0 0 1 6,0 0 0 0)),((1 0 0 0,0 1 0 0,0 0 1 0,1 0 0 0)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); CU_ASSERT_EQUAL(FLAGS_GET_M(geom->flags), 1); CU_ASSERT_EQUAL(geom->srid, SRID_UNKNOWN); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 0 0 0,0 0 1 0,0 1 0 2,0 0 0 0)),((0 0 0 0,0 1 0 0,1 0 0 4,0 0 0 0)),((0 0 0 0,1 0 0 0,0 0 1 6,0 0 0 0)),((1 0 0 0,0 1 0 0,0 0 1 0,1 0 0 0)))", tmp); lwfree(tmp); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F0000C00400000001030000C00100000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000F03F00000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000001030000C0010000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000F03F000000000000000000000000000000000000000000001040000000000000000000000000000000000000000000000000000000000000000001030000C001000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000001840000000000000000000000000000000000000000000000000000000000000000001030000C00100000004000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000000000000000000000000000000000000000", tmp); lwfree(tmp); lwgeom_free(geom); /* explicit SRID */ geom = lwgeom_from_wkt("SRID=4326;POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); CU_ASSERT_EQUAL(geom->srid, 4326); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("SRID=4326;POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", tmp); lwfree(tmp); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F0000A0E6100000040000000103000080010000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000010300008001000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000000001030000800100000004000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000000001030000800100000004000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F00000000000000000000000000000000", tmp); lwfree(tmp); lwgeom_free(geom); /* geography support */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 1 2)))", LW_PARSER_CHECK_NONE); g = gserialized_from_lwgeom(geom, 1, 0); CU_ASSERT_EQUAL(gserialized_get_type(g), POLYHEDRALSURFACETYPE); lwgeom_free(geom); lwfree(g); }
/** ** @brief lwline_crossing_direction: returns the kind of #CG_LINE_CROSS_TYPE behavior of 2 linestrings ** @param l1 first line string ** @param l2 second line string ** @return a #CG_LINE_CROSS_TYPE ** LINE_NO_CROSS = 0 ** LINE_CROSS_LEFT = -1 ** LINE_CROSS_RIGHT = 1 ** LINE_MULTICROSS_END_LEFT = -2 ** LINE_MULTICROSS_END_RIGHT = 2 ** LINE_MULTICROSS_END_SAME_FIRST_LEFT = -3 ** LINE_MULTICROSS_END_SAME_FIRST_RIGHT = 3 ** */ int lwline_crossing_direction(const LWLINE *l1, const LWLINE *l2) { int i = 0, j = 0, rv = 0; POINT2D p1, p2, q1, q2; POINTARRAY *pa1 = NULL, *pa2 = NULL; int cross_left = 0; int cross_right = 0; int first_cross = 0; int this_cross = 0; pa1 = (POINTARRAY*)l1->points; pa2 = (POINTARRAY*)l2->points; /* One-point lines can't intersect (and shouldn't exist). */ if ( pa1->npoints < 2 || pa2->npoints < 2 ) return LINE_NO_CROSS; LWDEBUGF(4, "l1 = %s", lwgeom_to_ewkt((LWGEOM*)l1)); LWDEBUGF(4, "l2 = %s", lwgeom_to_ewkt((LWGEOM*)l2)); /* Initialize first point of q */ rv = getPoint2d_p(pa2, 0, &q1); for ( i = 1; i < pa2->npoints; i++ ) { /* Update second point of q to next value */ rv = getPoint2d_p(pa2, i, &q2); /* Initialize first point of p */ rv = getPoint2d_p(pa1, 0, &p1); for ( j = 1; j < pa1->npoints; j++ ) { /* Update second point of p to next value */ rv = getPoint2d_p(pa1, j, &p2); this_cross = lw_segment_intersects(&p1, &p2, &q1, &q2); LWDEBUGF(4, "i=%d, j=%d (%.8g %.8g, %.8g %.8g)", this_cross, i, j, p1.x, p1.y, p2.x, p2.y); if ( this_cross == SEG_CROSS_LEFT ) { LWDEBUG(4,"this_cross == SEG_CROSS_LEFT"); cross_left++; if ( ! first_cross ) first_cross = SEG_CROSS_LEFT; } if ( this_cross == SEG_CROSS_RIGHT ) { LWDEBUG(4,"this_cross == SEG_CROSS_RIGHT"); cross_right++; if ( ! first_cross ) first_cross = SEG_CROSS_LEFT; } /* ** Crossing at a co-linearity can be turned handled by extending ** segment to next vertext and seeing if the end points straddle ** the co-linear segment. */ if ( this_cross == SEG_COLINEAR ) { LWDEBUG(4,"this_cross == SEG_COLINEAR"); /* TODO: Add logic here and in segment_intersects() continue; */ } LWDEBUG(4,"this_cross == SEG_NO_INTERSECTION"); /* Turn second point of p into first point */ p1 = p2; } /* Turn second point of q into first point */ q1 = q2; } LWDEBUGF(4, "first_cross=%d, cross_left=%d, cross_right=%d", first_cross, cross_left, cross_right); if ( !cross_left && !cross_right ) return LINE_NO_CROSS; if ( !cross_left && cross_right == 1 ) return LINE_CROSS_RIGHT; if ( !cross_right && cross_left == 1 ) return LINE_CROSS_LEFT; if ( cross_left - cross_right == 1 ) return LINE_MULTICROSS_END_LEFT; if ( cross_left - cross_right == -1 ) return LINE_MULTICROSS_END_RIGHT; if ( cross_left - cross_right == 0 && first_cross == SEG_CROSS_LEFT ) return LINE_MULTICROSS_END_SAME_FIRST_LEFT; if ( cross_left - cross_right == 0 && first_cross == SEG_CROSS_RIGHT ) return LINE_MULTICROSS_END_SAME_FIRST_RIGHT; return LINE_NO_CROSS; }
static void test_lwgeom_make_valid(void) { #if POSTGIS_GEOS_VERSION >= 33 LWGEOM *gin, *gout, *gexp; char *ewkt; /* Because i don't trust that much prior tests... ;) */ cu_error_msg_reset(); gin = lwgeom_from_wkt( "MULTIPOLYGON(((1725063 4819121, 1725104 4819067, 1725060 4819087, 1725064.14183882 4819094.70208557,1725064.13656044 4819094.70235069,1725064.14210359 4819094.70227252,1725064.14210362 4819094.70227252,1725064.13656043 4819094.70235069,1725055. 4819094, 1725055 4819094, 1725055 4819094, 1725063 4819121)))", LW_PARSER_CHECK_NONE); CU_ASSERT(gin != NULL); gout = lwgeom_make_valid(gin); /* We're really only interested in avoiding a crash in here. * See http://trac.osgeo.org/postgis/ticket/1738 * TODO: enhance the test if we find a workaround * to the excepion: * See http://trac.osgeo.org/postgis/ticket/1735 */ lwgeom_free(gout); lwgeom_free(gin); /* Test for http://trac.osgeo.org/postgis/ticket/2307 */ gin = lwgeom_from_hexwkb("0106000020E6100000010000000103000000010000000A0000004B7DA956B99844C0DB0790FE8B4D1DC010BA74A9AF9444C049AFFC5B8C4D1DC03FC6CC690D9844C0DD67E5628C4D1DC07117B56B0D9844C0C80ABA67C45E1DC0839166ABAF9444C0387D4568C45E1DC010BA74A9AF9444C049AFFC5B8C4D1DC040C3CD74169444C0362EC0608C4D1DC07C1A3B77169444C0DC3ADB40B2641DC03AAE5F68B99844C0242948DEB1641DC04B7DA956B99844C0DB0790FE8B4D1DC0", LW_PARSER_CHECK_NONE); CU_ASSERT(gin != NULL); gout = lwgeom_make_valid(gin); CU_ASSERT(gout != NULL); lwgeom_free(gin); /* We're really only interested in avoiding memory problems. * Convertion to ewkt ensures full scan of coordinates thus * triggering the error, if any */ ewkt = lwgeom_to_ewkt(gout); lwgeom_free(gout); lwfree(ewkt); /* Test collection */ gin = lwgeom_from_wkt( "GEOMETRYCOLLECTION(LINESTRING(0 0, 0 0), POLYGON((0 0, 10 10, 10 0, 0 10, 0 0)), LINESTRING(10 0, 10 10))", LW_PARSER_CHECK_NONE); CU_ASSERT(gin != NULL); gout = lwgeom_make_valid(gin); CU_ASSERT(gout != NULL); ewkt = lwgeom_to_ewkt(gout); /* printf("c = %s\n", ewkt); */ /* TODO: This doesn't work on windows returns in different order. strk figure out why. For now will replace with normalized version */ /* CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(0 0),MULTIPOLYGON(((5 5,0 0,0 10,5 5)),((5 5,10 10,10 0,5 5))),LINESTRING(10 0,10 10))");*/ gexp = lwgeom_from_wkt( "GEOMETRYCOLLECTION(POINT(0 0),MULTIPOLYGON(((5 5,0 0,0 10,5 5)),((5 5,10 10,10 0,5 5))),LINESTRING(10 0,10 10))", LW_PARSER_CHECK_NONE); check_geom_equal(gout, gexp); lwfree(ewkt); lwgeom_free(gout); lwgeom_free(gin); lwgeom_free(gexp); /* Test multipoint */ gin = lwgeom_from_wkt( "MULTIPOINT(0 0,1 1,2 2)", LW_PARSER_CHECK_NONE); CU_ASSERT(gin != NULL); gout = lwgeom_make_valid(gin); CU_ASSERT(gout != NULL); ewkt = lwgeom_to_ewkt(gout); /* printf("c = %s\n", ewkt); */ CU_ASSERT_STRING_EQUAL(ewkt, "MULTIPOINT(0 0,1 1,2 2)"); lwfree(ewkt); lwgeom_free(gout); lwgeom_free(gin); #endif /* POSTGIS_GEOS_VERSION >= 33 */ }
static void test_lwline_clip(void) { LWCOLLECTION *c; LWLINE *line = NULL; LWLINE *l51 = NULL; char *ewkt; /* Vertical line with vertices at y integers */ l51 = (LWLINE*)lwgeom_from_wkt("LINESTRING(0 0, 0 1, 0 2, 0 3, 0 4)", LW_PARSER_CHECK_NONE); /* Clip in the middle, mid-range. */ c = lwline_clip_to_ordinate_range(l51, 'Y', 1.5, 2.5); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1.5,0 2,0 2.5))"); lwfree(ewkt); lwcollection_free(c); /* Clip off the top. */ c = lwline_clip_to_ordinate_range(l51, 'Y', 3.5, 5.5); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 3.5,0 4))"); lwfree(ewkt); lwcollection_free(c); /* Clip off the bottom. */ c = lwline_clip_to_ordinate_range(l51, 'Y', -1.5, 2.5); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2,0 2.5))" ); lwfree(ewkt); lwcollection_free(c); /* Range holds entire object. */ c = lwline_clip_to_ordinate_range(l51, 'Y', -1.5, 5.5); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2,0 3,0 4))" ); lwfree(ewkt); lwcollection_free(c); /* Clip on vertices. */ c = lwline_clip_to_ordinate_range(l51, 'Y', 1.0, 2.0); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1,0 2))" ); lwfree(ewkt); lwcollection_free(c); /* Clip on vertices off the bottom. */ c = lwline_clip_to_ordinate_range(l51, 'Y', -1.0, 2.0); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2))" ); lwfree(ewkt); lwcollection_free(c); /* Clip on top. */ c = lwline_clip_to_ordinate_range(l51, 'Y', -1.0, 0.0); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(0 0))" ); lwfree(ewkt); lwcollection_free(c); /* ST_LocateBetweenElevations(ST_GeomFromEWKT('LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)'), 1, 2)) */ line = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)", LW_PARSER_CHECK_NONE); c = lwline_clip_to_ordinate_range(line, 'Z', 1.0, 2.0); ewkt = lwgeom_to_ewkt((LWGEOM*)c); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2,1 1 1))" ); lwfree(ewkt); lwcollection_free(c); lwline_free(line); /* ST_LocateBetweenElevations('LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)', 1, 2)) */ line = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)", LW_PARSER_CHECK_NONE); c = lwline_clip_to_ordinate_range(line, 'Z', 1.0, 2.0); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("a = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2,1 1 1))" ); lwfree(ewkt); lwcollection_free(c); lwline_free(line); /* ST_LocateBetweenElevations('LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)', 1, 1)) */ line = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)", LW_PARSER_CHECK_NONE); c = lwline_clip_to_ordinate_range(line, 'Z', 1.0, 1.0); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("b = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 1 1))" ); lwfree(ewkt); lwcollection_free(c); lwline_free(line); /* ST_LocateBetweenElevations('LINESTRING(1 1 1, 1 2 2)', 1,1) */ line = (LWLINE*)lwgeom_from_wkt("LINESTRING(1 1 1, 1 2 2)", LW_PARSER_CHECK_NONE); c = lwline_clip_to_ordinate_range(line, 'Z', 1.0, 1.0); ewkt = lwgeom_to_ewkt((LWGEOM*)c); //printf("c = %s\n", ewkt); CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 1 1))" ); lwfree(ewkt); lwcollection_free(c); lwline_free(line); lwline_free(l51); }