lwgeom_free(g);
}
+static void do_gml2_extent_test(char * in, char * out, char * srs,
+ double precision, char * prefix)
+{
+ LWGEOM *g;
+ char *h;
+
+ g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE);
+ h = lwgeom_extent_to_gml2(g, srs, precision, prefix);
+ if ( ! h ) h = cu_error_msg;
+
+ if (strcmp(h, out))
+ fprintf(stderr, "\nEXT GML 2 - In: %s\nObt: %s\nExp: %s\n",
+ in, h, out);
+ CU_ASSERT_STRING_EQUAL(out, h);
+ cu_error_msg_reset();
+
+ lwfree(h);
+ lwgeom_free(g);
+}
+
+static void do_gml3_extent_test(char * in, char * out, char * srs,
+ double precision, int opts, char* prefix)
+{
+ LWGEOM *g;
+ char *h;
+
+ g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE);
+ h = lwgeom_extent_to_gml3(g, srs, precision, opts, prefix);
+ if ( ! h ) h = cu_error_msg;
+
+ if (strcmp(h, out))
+ fprintf(stderr, "\nEXT GML 3 - In: %s\nObt: %s\nExp: %s\n",
+ in, h, out);
+ CU_ASSERT_STRING_EQUAL(out, h);
+ cu_error_msg_reset();
+
+ lwfree(h);
+ lwgeom_free(g);
+}
+
static void out_gml_test_precision(void)
{
NULL, 0, 0, 0, "");
}
+static void out_gml2_extent(void)
+{
+ /* GML2: Point */
+ do_gml2_extent_test(
+ "POINT(-15 60)",
+ "<Box><coordinates>-15,60 -15,60</coordinates></Box>",
+ NULL, 15, "");
+ do_gml2_extent_test(
+ "POINT(-15 60)",
+ "<gml:Box><gml:coordinates>-15,60 -15,60</gml:coordinates></gml:Box>",
+ NULL, 15, "gml:");
+ do_gml2_extent_test(
+ "POINT(-15 60)",
+ "<Box srsName=\"urn:ogc:def:crs:EPSG::4326\"><coordinates>-15,60 -15,60</coordinates></Box>",
+ "urn:ogc:def:crs:EPSG::4326", 15, "");
+
+ /* GML2: Multipoint */
+ do_gml2_extent_test(
+ "MULTIPOINT(2 3, -5 -6)",
+ "<Box><coordinates>-5,-6 2,3</coordinates></Box>",
+ NULL, 15, "");
+
+ /* GML2: Linestring */
+ do_gml2_extent_test(
+ "LINESTRING(0 1,2 3,4 5)",
+ "<Box><coordinates>0,1 4,5</coordinates></Box>",
+ NULL, 15, "");
+
+ /* GML2: MultiLinestring */
+ do_gml2_extent_test(
+ "MULTILINESTRING((0 1,2 3),(4 5, 10 6))",
+ "<Box><coordinates>0,1 10,6</coordinates></Box>",
+ NULL, 15, "");
+
+ /* GML2: Polygon */
+ do_gml2_extent_test(
+ "POLYGON((1 7,7 14, 14 7, 1 7))",
+ "<Box><coordinates>1,7 14,14</coordinates></Box>",
+ NULL, 15, "");
+
+ /* GML2: MultiPolygon */
+ do_gml2_extent_test(
+ "MULTIPOLYGON(((1 7,7 14, 14 7, 1 7)),((-4 -6, -15 3, 0 0, -4 -6))))",
+ "<Box><coordinates>-15,-6 14,14</coordinates></Box>",
+ NULL, 15, "");
+
+ /* GML2: MultiSurface */
+ do_gml2_extent_test(
+ "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))",
+ "<Box><coordinates>-2,-1 10,14</coordinates></Box>",
+ NULL, 15, "");
+
+ /* GML2: empty (FIXME) */
+ do_gml2_extent_test(
+ "GEOMETRYCOLLECTION EMPTY",
+ "<Box><coordinates>0,0 0,0</coordinates></Box>",
+ NULL, 15, "");
+
+}
+
+static void out_gml3_extent(void)
+{
+ /* GML3: Point */
+ do_gml3_extent_test(
+ "POINT(-15 60)",
+ "<Envelope><lowerCorner>-15 60</lowerCorner><upperCorner>-15 60</upperCorner></Envelope>",
+ NULL, 15, 0, "");
+ do_gml3_extent_test(
+ "POINT(-15 60)",
+ "<gml:Envelope><gml:lowerCorner>-15 60</gml:lowerCorner><gml:upperCorner>-15 60</gml:upperCorner></gml:Envelope>",
+ NULL, 15, 0, "gml:");
+ do_gml3_extent_test(
+ "POINT(-15 60)",
+ "<Envelope srsName=\"urn:ogc:def:crs:EPSG::4326\"><lowerCorner>-15 60</lowerCorner><upperCorner>-15 60</upperCorner></Envelope>",
+ "urn:ogc:def:crs:EPSG::4326", 15, 0, "");
+
+ /* GML3: Multipoint */
+ do_gml3_extent_test(
+ "MULTIPOINT(2 3, -5 -6)",
+ "<Envelope><lowerCorner>-5 -6</lowerCorner><upperCorner>2 3</upperCorner></Envelope>",
+ NULL, 15, 0, "");
+
+ /* GML3: Linestring */
+ do_gml3_extent_test(
+ "LINESTRING(0 1,2 3,4 5)",
+ "<Envelope><lowerCorner>0 1</lowerCorner><upperCorner>4 5</upperCorner></Envelope>",
+ NULL, 15, 0, "");
+
+ /* GML3: MultiLinestring */
+ do_gml3_extent_test(
+ "MULTILINESTRING((0 1,2 3),(4 5, 10 6))",
+ "<Envelope><lowerCorner>0 1</lowerCorner><upperCorner>10 6</upperCorner></Envelope>",
+ NULL, 15, 0, "");
+ do_gml3_extent_test(
+ "MULTILINESTRING((0 1,2 3),(4 5, 10 6))",
+ "<Envelope><lowerCorner>1 0</lowerCorner><upperCorner>6 10</upperCorner></Envelope>",
+ NULL, 15, LW_GML_IS_DEGREE, "");
+ do_gml3_extent_test(
+ "MULTILINESTRING((0 1,2 3),(4 5, 10 6))",
+ "<Envelope srsDimension=\"2\"><lowerCorner>1 0</lowerCorner><upperCorner>6 10</upperCorner></Envelope>",
+ NULL, 15, LW_GML_IS_DEGREE|LW_GML_IS_DIMS, "");
+ do_gml3_extent_test(
+ "MULTILINESTRING((0 1 10,2 3 30),(4 5 50, 10 6 -70))",
+ "<Envelope srsDimension=\"3\"><lowerCorner>1 0 -70</lowerCorner><upperCorner>6 10 50</upperCorner></Envelope>",
+ NULL, 15, LW_GML_IS_DEGREE|LW_GML_IS_DIMS, "");
+
+ /* GML3: Polygon */
+ do_gml3_extent_test(
+ "POLYGON((1 7,7 14, 14 7, 1 7))",
+ "<Envelope><lowerCorner>1 7</lowerCorner><upperCorner>14 14</upperCorner></Envelope>",
+ NULL, 15, 0, "");
+
+ /* GML3: MultiPolygon */
+ do_gml3_extent_test(
+ "MULTIPOLYGON(((1 7,7 14, 14 7, 1 7)),((-4 -6, -15 3, 0 0, -4 -6))))",
+ "<Envelope><lowerCorner>-15 -6</lowerCorner><upperCorner>14 14</upperCorner></Envelope>",
+ NULL, 15, 0, "");
+
+ /* GML3: MultiSurface */
+ do_gml3_extent_test(
+ "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))",
+ "<Envelope><lowerCorner>-2 -1</lowerCorner><upperCorner>10 14</upperCorner></Envelope>",
+ NULL, 15, 0, "");
+
+ /* GML3: empty (FIXME) */
+ do_gml3_extent_test(
+ "GEOMETRYCOLLECTION EMPTY",
+ "<Envelope><lowerCorner>0 0</lowerCorner><upperCorner>0 0</upperCorner></Envelope>",
+ NULL, 15, 0, "");
+
+}
+
+
/*
PG_TEST(out_gml_test_geoms),
PG_TEST(out_gml_test_geoms_prefix),
PG_TEST(out_gml_test_geoms_nodims),
+ PG_TEST(out_gml2_extent),
+ PG_TEST(out_gml3_extent),
CU_TEST_INFO_NULL
};
CU_SuiteInfo out_gml_suite = {"GML Out Suite", NULL, NULL, out_gml_tests};
static size_t pointArray_GMLsize(POINTARRAY *pa, int precision);
+static const GBOX *
+lwgeom_get_bbox(const LWGEOM *lwg)
+{
+ /* if ( ! lwg->bbox ) lwnotice("Adding a bbox"); */
+ lwgeom_add_bbox((LWGEOM *)lwg); /* adds one if not already there */
+ return lwg->bbox;
+}
-
-extern char *
-lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
+static char *
+gbox_to_gml2(const GBOX *bbox, const char *srs, int precision, const char *prefix)
{
int size;
POINT4D pt;
char *ptr, *output;
size_t prefixlen = strlen(prefix);
- switch (geom->type)
- {
- case POINTTYPE:
- case LINETYPE:
- case POLYGONTYPE:
- case MULTIPOINTTYPE:
- case MULTILINETYPE:
- case MULTIPOLYGONTYPE:
- case COLLECTIONTYPE:
- break;
-
- default:
- lwerror("lwgeom_extent_to_gml2: '%s' geometry type not supported", lwtype_name(geom->type));
- return NULL;
- }
-
- pa = ptarray_construct_empty(FLAGS_GET_Z(geom->flags), 0, 2);
+ pa = ptarray_construct_empty(FLAGS_GET_Z(bbox->flags), 0, 2);
- pt.x = geom->bbox->xmin;
- pt.y = geom->bbox->ymin;
- if (FLAGS_GET_Z(geom->flags)) pt.z = geom->bbox->zmin;
+ pt.x = bbox->xmin;
+ pt.y = bbox->ymin;
+ if (FLAGS_GET_Z(bbox->flags)) pt.z = bbox->zmin;
ptarray_append_point(pa, &pt, LW_TRUE);
- pt.x = geom->bbox->xmax;
- pt.y = geom->bbox->ymax;
- if (FLAGS_GET_Z(geom->flags)) pt.z = geom->bbox->zmax;
+ pt.x = bbox->xmax;
+ pt.y = bbox->ymax;
+ if (FLAGS_GET_Z(bbox->flags)) pt.z = bbox->zmax;
ptarray_append_point(pa, &pt, LW_TRUE);
size = pointArray_GMLsize(pa, precision);
return output;
}
-
-extern char *
-lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
+static char *
+gbox_to_gml3(const GBOX *bbox, const char *srs, int precision, int opts, const char *prefix)
{
int size;
POINT4D pt;
POINTARRAY *pa;
char *ptr, *output;
size_t prefixlen = strlen(prefix);
+ int dimension = 2;
- switch (geom->type)
- {
- case POINTTYPE:
- case LINETYPE:
- case POLYGONTYPE:
- case MULTIPOINTTYPE:
- case MULTILINETYPE:
- case MULTIPOLYGONTYPE:
- case COLLECTIONTYPE:
- break;
-
- default:
- lwerror("lwgeom_extent_to_gml3: '%s' geometry type not supported", lwtype_name(geom->type));
- return NULL;
- }
+ if (FLAGS_GET_Z(bbox->flags)) dimension = 3;
- pa = ptarray_construct_empty(FLAGS_GET_Z(geom->flags), 0, 1);
+ pa = ptarray_construct_empty(FLAGS_GET_Z(bbox->flags), 0, 1);
- pt.x = geom->bbox->xmin;
- pt.y = geom->bbox->ymin;
- if (FLAGS_GET_Z(geom->flags)) pt.z = geom->bbox->zmin;
+ pt.x = bbox->xmin;
+ pt.y = bbox->ymin;
+ if (FLAGS_GET_Z(bbox->flags)) pt.z = bbox->zmin;
ptarray_append_point(pa, &pt, LW_TRUE);
size = pointArray_GMLsize(pa, precision) * 2;
size += ( sizeof("<Envelope><lowerCorner><upperCorner>//") + (prefixlen*3) ) * 2;
if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+ if ( IS_DIMS(opts) ) size += sizeof(" srsDimension=. .");
ptr = output = lwalloc(size);
- if ( srs ) ptr += sprintf(ptr, "<%sEnvelope srsName=\"%s\">", prefix, srs);
- else ptr += sprintf(ptr, "<%sEnvelope>", prefix);
+ ptr += sprintf(ptr, "<%sEnvelope", prefix);
+ if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+ if ( IS_DIMS(opts) ) ptr += sprintf(ptr, " srsDimension=\"%d\"", dimension);
+ ptr += sprintf(ptr, ">");
ptr += sprintf(ptr, "<%slowerCorner>", prefix);
ptr += pointArray_toGML3(pa, ptr, precision, opts);
ptr += sprintf(ptr, "</%slowerCorner>", prefix);
ptarray_remove_point(pa, 0);
- pt.x = geom->bbox->xmax;
- pt.y = geom->bbox->ymax;
- if (FLAGS_GET_Z(geom->flags)) pt.z = geom->bbox->zmax;
+ pt.x = bbox->xmax;
+ pt.y = bbox->ymax;
+ if (FLAGS_GET_Z(bbox->flags)) pt.z = bbox->zmax;
ptarray_append_point(pa, &pt, LW_TRUE);
ptr += sprintf(ptr, "<%supperCorner>", prefix);
return output;
}
+
+
+extern char *
+lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
+{
+ const GBOX* bbox = lwgeom_get_bbox(geom);
+ if ( ! bbox ) {
+ lwerror("lwgeom_extent_to_gml2: empty geometry doesn't have a bounding box");
+ return NULL;
+ }
+ char *ret = gbox_to_gml2(bbox, srs, precision, prefix);
+ return ret;
+}
+
+
+extern char *
+lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
+{
+ const GBOX* bbox = lwgeom_get_bbox(geom);
+ if ( ! bbox ) {
+ lwerror("lwgeom_extent_to_gml3: empty geometry doesn't have a bounding box");
+ return NULL;
+ }
+ return gbox_to_gml3(bbox, srs, precision, opts, prefix);
+}
/**