Permalink
Browse files

GML output: export XYZ when USE_POINT_Z_M is defined and gml_geomtype…

… is set to Point25D/LineString25D/etc.. (same syntax as 2.5D OGR output)
  • Loading branch information...
rouault committed Jun 11, 2014
1 parent edc64a6 commit 5e6489ebd42bef9315a8c7f70479a2a823b473bf
Showing with 179 additions and 16 deletions.
  1. +179 −16 mapgml.c
View
195 mapgml.c
@@ -128,7 +128,8 @@ static void gmlEndGeometryContainer(FILE *stream, const char *name,
/* GML 2.1.2 */
static int gmlWriteGeometry_GML2(FILE *stream, gmlGeometryListObj *geometryList,
shapeObj *shape, const char *srsname,
- const char *namespace, const char *tab)
+ const char *namespace, const char *tab,
+ int nSRSDimension)
{
int i, j, k;
int *innerlist, *outerlist=NULL, numouters;
@@ -168,7 +169,15 @@ static int gmlWriteGeometry_GML2(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s<gml:Point srsName=\"%s\">\n", tab, srsname_encoded);
else
msIO_fprintf(stream, "%s<gml:Point>\n", tab);
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%s <gml:coordinates>%f,%f,%f</gml:coordinates>\n",
+ tab, shape->line[i].point[j].x, shape->line[i].point[j].y, shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%s <gml:coordinates>%f,%f</gml:coordinates>\n", tab, shape->line[i].point[j].x, shape->line[i].point[j].y);
+
msIO_fprintf(stream, "%s</gml:Point>\n", tab);
gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab);
@@ -187,6 +196,14 @@ static int gmlWriteGeometry_GML2(FILE *stream, gmlGeometryListObj *geometryList,
for(j=0; j<shape->line[i].numpoints; j++) {
msIO_fprintf(stream, "%s <gml:pointMember>\n", tab);
msIO_fprintf(stream, "%s <gml:Point>\n", tab);
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%s <gml:coordinates>%f,%f,%f</gml:coordinates>\n",
+ tab, shape->line[i].point[j].x, shape->line[i].point[j].y,
+ shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%s <gml:coordinates>%f,%f</gml:coordinates>\n", tab, shape->line[i].point[j].x, shape->line[i].point[j].y);
msIO_fprintf(stream, "%s </gml:Point>\n", tab);
msIO_fprintf(stream, "%s </gml:pointMember>\n", tab);
@@ -221,7 +238,16 @@ static int gmlWriteGeometry_GML2(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:coordinates>", tab);
for(j=0; j<shape->line[i].numpoints; j++)
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f,%f,%f ", shape->line[i].point[j].x, shape->line[i].point[j].y,
+ shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%f,%f ", shape->line[i].point[j].x, shape->line[i].point[j].y);
+ }
msIO_fprintf(stream, "</gml:coordinates>\n");
msIO_fprintf(stream, "%s</gml:LineString>\n", tab);
@@ -243,7 +269,16 @@ static int gmlWriteGeometry_GML2(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:coordinates>", tab);
for(i=0; i<shape->line[j].numpoints; i++)
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f,%f,%f ", shape->line[j].point[i].x, shape->line[j].point[i].y,
+ shape->line[j].point[i].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%f,%f ", shape->line[j].point[i].x, shape->line[j].point[i].y);
+ }
msIO_fprintf(stream, "</gml:coordinates>\n");
msIO_fprintf(stream, "%s </gml:LineString>\n", tab);
msIO_fprintf(stream, "%s </gml:lineStringMember>\n", tab);
@@ -292,7 +327,16 @@ static int gmlWriteGeometry_GML2(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:coordinates>", tab);
for(j=0; j<shape->line[i].numpoints; j++)
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f,%f,%f ", shape->line[i].point[j].x, shape->line[i].point[j].y,
+ shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%f,%f ", shape->line[i].point[j].x, shape->line[i].point[j].y);
+ }
msIO_fprintf(stream, "</gml:coordinates>\n");
msIO_fprintf(stream, "%s </gml:LinearRing>\n", tab);
@@ -305,7 +349,16 @@ static int gmlWriteGeometry_GML2(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:coordinates>", tab);
for(j=0; j<shape->line[k].numpoints; j++)
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f,%f,%f ", shape->line[k].point[j].x, shape->line[k].point[j].y,
+ shape->line[k].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%f,%f ", shape->line[k].point[j].x, shape->line[k].point[j].y);
+ }
msIO_fprintf(stream, "</gml:coordinates>\n");
msIO_fprintf(stream, "%s </gml:LinearRing>\n", tab);
@@ -341,7 +394,16 @@ static int gmlWriteGeometry_GML2(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:coordinates>", tab);
for(j=0; j<shape->line[i].numpoints; j++)
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f,%f,%f ", shape->line[i].point[j].x, shape->line[i].point[j].y,
+ shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%f,%f ", shape->line[i].point[j].x, shape->line[i].point[j].y);
+ }
msIO_fprintf(stream, "</gml:coordinates>\n");
msIO_fprintf(stream, "%s </gml:LinearRing>\n", tab);
@@ -354,7 +416,16 @@ static int gmlWriteGeometry_GML2(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:coordinates>", tab);
for(j=0; j<shape->line[k].numpoints; j++)
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f,%f,%f ", shape->line[k].point[j].x, shape->line[k].point[j].y,
+ shape->line[k].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%f,%f ", shape->line[k].point[j].x, shape->line[k].point[j].y);
+ }
msIO_fprintf(stream, "</gml:coordinates>\n");
msIO_fprintf(stream, "%s </gml:LinearRing>\n", tab);
@@ -407,7 +478,8 @@ static char* gmlCreateGeomId(OWSGMLVersion nGMLVersion, const char* pszFID, int*
/* GML 3.1 or GML 3.2 (MapServer limits GML encoding to the level 0 profile) */
static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList, shapeObj *shape,
const char *srsname, const char *namespace, const char *tab,
- const char *pszFID, OWSGMLVersion nGMLVersion )
+ const char *pszFID, OWSGMLVersion nGMLVersion,
+ int nSRSDimension)
{
int i, j, k, id = 1;
int *innerlist, *outerlist=NULL, numouters;
@@ -449,7 +521,15 @@ static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:Point%s srsName=\"%s\">\n", tab, pszGMLId, srsname_encoded);
else
msIO_fprintf(stream, "%s <gml:Point%s>\n", tab, pszGMLId);
+
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%s <gml:pos srsDimension=\"3\">%f %f %f</gml:pos>\n", tab, shape->line[i].point[j].x, shape->line[i].point[j].y, shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%s <gml:pos>%f %f</gml:pos>\n", tab, shape->line[i].point[j].x, shape->line[i].point[j].y);
+
msIO_fprintf(stream, "%s </gml:Point>\n", tab);
gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab);
@@ -473,6 +553,12 @@ static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList,
for(j=0; j<shape->line[i].numpoints; j++) {
pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id);
msIO_fprintf(stream, "%s <gml:Point%s>\n", tab, pszGMLId);
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%s <gml:pos srsDimension=\"3\">%f %f %f</gml:pos>\n", tab, shape->line[i].point[j].x, shape->line[i].point[j].y, shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%s <gml:pos>%f %f</gml:pos>\n", tab, shape->line[i].point[j].x, shape->line[i].point[j].y);
msIO_fprintf(stream, "%s </gml:Point>\n", tab);
msFree(pszGMLId);
@@ -508,9 +594,17 @@ static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:LineString%s>\n", tab, pszGMLId);
msFree(pszGMLId);
- msIO_fprintf(stream, "%s <gml:posList srsDimension=\"2\">", tab);
+ msIO_fprintf(stream, "%s <gml:posList srsDimension=\"%d\">", tab, nSRSDimension);
for(j=0; j<shape->line[i].numpoints; j++)
- msIO_fprintf(stream, "%f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y);
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f %f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y, shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
+ msIO_fprintf(stream, "%f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y);
+ }
msIO_fprintf(stream, "</gml:posList>\n");
msIO_fprintf(stream, "%s </gml:LineString>\n", tab);
@@ -534,9 +628,18 @@ static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:LineString%s>\n", tab, pszGMLId); /* no srsname at this point */
msFree(pszGMLId);
- msIO_fprintf(stream, "%s <gml:posList srsDimension=\"2\">", tab);
+ msIO_fprintf(stream, "%s <gml:posList srsDimension=\"%d\">", tab, nSRSDimension);
for(j=0; j<shape->line[i].numpoints; j++)
- msIO_fprintf(stream, "%f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y);
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f %f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y, shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
+ msIO_fprintf(stream, "%f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y);
+ }
+
msIO_fprintf(stream, "</gml:posList>\n");
msIO_fprintf(stream, "%s </gml:LineString>\n", tab);
}
@@ -586,9 +689,18 @@ static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:exterior>\n", tab);
msIO_fprintf(stream, "%s <gml:LinearRing>\n", tab);
- msIO_fprintf(stream, "%s <gml:posList srsDimension=\"2\">", tab);
+ msIO_fprintf(stream, "%s <gml:posList srsDimension=\"%d\">", tab, nSRSDimension);
for(j=0; j<shape->line[i].numpoints; j++)
- msIO_fprintf(stream, "%f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y);
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f %f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y, shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
+ msIO_fprintf(stream, "%f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y);
+ }
+
msIO_fprintf(stream, "</gml:posList>\n");
msIO_fprintf(stream, "%s </gml:LinearRing>\n", tab);
@@ -599,9 +711,18 @@ static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:interior>\n", tab);
msIO_fprintf(stream, "%s <gml:LinearRing>\n", tab);
- msIO_fprintf(stream, "%s <gml:posList srsDimension=\"2\">", tab);
+ msIO_fprintf(stream, "%s <gml:posList srsDimension=\"%d\">", tab, nSRSDimension);
for(j=0; j<shape->line[k].numpoints; j++)
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f %f %f ", shape->line[k].point[j].x, shape->line[k].point[j].y, shape->line[k].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%f %f ", shape->line[k].point[j].x, shape->line[k].point[j].y);
+ }
+
msIO_fprintf(stream, "</gml:posList>\n");
msIO_fprintf(stream, "%s </gml:LinearRing>\n", tab);
@@ -643,9 +764,18 @@ static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:exterior>\n", tab);
msIO_fprintf(stream, "%s <gml:LinearRing>\n", tab);
- msIO_fprintf(stream, "%s <gml:posList srsDimension=\"2\">", tab);
+ msIO_fprintf(stream, "%s <gml:posList srsDimension=\"%d\">", tab, nSRSDimension);
for(j=0; j<shape->line[i].numpoints; j++)
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f %f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y, shape->line[i].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%f %f ", shape->line[i].point[j].x, shape->line[i].point[j].y);
+ }
+
msIO_fprintf(stream, "</gml:posList>\n");
msIO_fprintf(stream, "%s </gml:LinearRing>\n", tab);
@@ -656,9 +786,17 @@ static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList,
msIO_fprintf(stream, "%s <gml:interior>\n", tab);
msIO_fprintf(stream, "%s <gml:LinearRing>\n", tab);
- msIO_fprintf(stream, "%s <gml:posList srsDimension=\"2\">", tab);
+ msIO_fprintf(stream, "%s <gml:posList srsDimension=\"%d\">", tab, nSRSDimension);
for(j=0; j<shape->line[k].numpoints; j++)
+ {
+#ifdef USE_POINT_Z_M
+ if( nSRSDimension == 3 )
+ msIO_fprintf(stream, "%f %f %f ", shape->line[k].point[j].x, shape->line[k].point[j].y, shape->line[k].point[j].z);
+ else
+ /* fall-through */
+#endif
msIO_fprintf(stream, "%f %f ", shape->line[k].point[j].x, shape->line[k].point[j].y);
+ }
msIO_fprintf(stream, "</gml:posList>\n");
msIO_fprintf(stream, "%s </gml:LinearRing>\n", tab);
@@ -719,15 +857,15 @@ static int gmlWriteBounds(FILE *stream, OWSGMLVersion format, rectObj *rect,
static int gmlWriteGeometry(FILE *stream, gmlGeometryListObj *geometryList,
OWSGMLVersion format, shapeObj *shape,
const char *srsname, const char *namespace,
- const char *tab, const char* pszFID)
+ const char *tab, const char* pszFID, int nSRSDimension)
{
switch(format) {
case(OWS_GML2):
- return gmlWriteGeometry_GML2(stream, geometryList, shape, srsname, namespace, tab);
+ return gmlWriteGeometry_GML2(stream, geometryList, shape, srsname, namespace, tab, nSRSDimension);
break;
case(OWS_GML3):
case(OWS_GML32):
- return gmlWriteGeometry_GML3(stream, geometryList, shape, srsname, namespace, tab, pszFID, format);
+ return gmlWriteGeometry_GML3(stream, geometryList, shape, srsname, namespace, tab, pszFID, format, nSRSDimension);
break;
default:
msSetError(MS_IOERR, "Unsupported GML format.", "gmlWriteGeometry()");
@@ -1289,6 +1427,9 @@ int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces)
/* step through the layers looking for query results */
for(i=0; i<map->numlayers; i++) {
const char *pszOutputSRS = NULL;
+ int nSRSDimension = 2;
+ const char* geomtype;
+
lp = (GET_LAYER(map, map->layerorder[i]));
if(lp->resultcache && lp->resultcache->numresults > 0) { /* found results */
@@ -1316,6 +1457,16 @@ int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces)
msOWSPrintMetadata(stream, &(lp->metadata), namespaces, "title", OWS_NOERR, "\t<gml:name>%s</gml:name>\n", value);
}
+ geomtype = msOWSLookupMetadata(&(lp->metadata), "OFG", "geomtype");
+ if( geomtype != NULL && (strstr(geomtype, "25d") != NULL || strstr(geomtype, "25D") != NULL) )
+ {
+#ifdef USE_POINT_Z_M
+ nSRSDimension = 3;
+#else
+ msIO_fprintf(stream, "<!-- WARNING: 25d requested forn typename '%s' but MapServer compiled without USE_POINT_Z_M support. -->\n", lp->name);
+#endif
+ }
+
/* populate item and group metadata structures */
itemList = msGMLGetItems(lp, namespaces);
constantList = msGMLGetConstants(lp, namespaces);
@@ -1359,7 +1510,7 @@ int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces)
if(!(geometryList && geometryList->numgeometries == 1 && strcasecmp(geometryList->geometries[0].name, "none") == 0)) {
gmlWriteBounds(stream, OWS_GML2, &(shape.bounds), pszOutputSRS, "\t\t\t", "gml");
if (geometryList && geometryList->numgeometries > 0 )
- gmlWriteGeometry(stream, geometryList, OWS_GML2, &(shape), pszOutputSRS, NULL, "\t\t\t", "");
+ gmlWriteGeometry(stream, geometryList, OWS_GML2, &(shape), pszOutputSRS, NULL, "\t\t\t", "", nSRSDimension);
}
/* write any item/values */
@@ -1513,10 +1664,22 @@ int msGMLWriteWFSQuery(mapObj *map, FILE *stream, const char *default_namespace_
int featureIdIndex=-1; /* no feature id */
char* srs = NULL;
int bOutputGMLIdOnly = MS_FALSE;
+ int nSRSDimension = 2;
+ const char* geomtype;
/* setup namespace, a layer can override the default */
namespace_prefix = msOWSLookupMetadata(&(lp->metadata), "OFG", "namespace_prefix");
if(!namespace_prefix) namespace_prefix = default_namespace_prefix;
+
+ geomtype = msOWSLookupMetadata(&(lp->metadata), "OFG", "geomtype");
+ if( geomtype != NULL && (strstr(geomtype, "25d") != NULL || strstr(geomtype, "25D") != NULL) )
+ {
+#ifdef USE_POINT_Z_M
+ nSRSDimension = 3;
+#else
+ msIO_fprintf(stream, "<!-- WARNING: 25d requested forn typename '%s' but MapServer compiled without USE_POINT_Z_M support. -->\n", lp->name);
+#endif
+ }
value = msOWSLookupMetadata(&(lp->metadata), "OFG", "featureid");
if(value) { /* find the featureid amongst the items for this layer */
@@ -1646,7 +1809,7 @@ int msGMLWriteWFSQuery(mapObj *map, FILE *stream, const char *default_namespace_
if( !bGetPropertyValueRequest )
gmlWriteBounds(stream, outputformat, &(shape.bounds), srs, " ", "gml");
gmlWriteGeometry(stream, geometryList, outputformat, &(shape), srs,
- namespace_prefix, " ", pszFID);
+ namespace_prefix, " ", pszFID, nSRSDimension);
}
/* write any item/values */

0 comments on commit 5e6489e

Please sign in to comment.