Permalink
Browse files

Initial wfs2 commit with GetCapabilities, DescribeFeatureType and Get…

…Feature/GML3.2 support
  • Loading branch information...
rouault committed Oct 26, 2013
1 parent 5102de2 commit 562796a4a4c81b792f7c048389daf35060ee1143
Showing with 2,747 additions and 1,481 deletions.
  1. +2 −2 CMakeLists.txt
  2. +162 −78 mapgml.c
  3. +0 −3 mapgml.h
  4. +57 −41 mapogcfilter.c
  5. +1 −1 mapows.c
  6. +26 −9 mapows.h
  7. +60 −6 mapowscommon.c
  8. +25 −2 mapowscommon.h
  9. +11 −5 mapquery.c
  10. +1 −0 mapserver.h
  11. +1,795 −1,312 mapwfs.c
  12. +20 −21 mapwfs11.c
  13. +586 −0 mapwfs20.c
  14. +1 −1 msautotest
@@ -198,7 +198,7 @@ mapdraw.c maplibxml2.c mapquery.c maputil.c strptime.c mapdrawgdal.c
mapraster.c mapuvraster.c mapdummyrenderer.c mapobject.c maprasterquery.c
mapwcs.c maperror.c mapogcfilter.c mapregex.c mapwcs11.c mapfile.c
mapogcfiltercommon.c maprendering.c mapwcs20.c mapogcsld.c
mapresample.c mapwfs.c mapgdal.c mapogcsos.c mapscale.c mapwfs11.c
mapresample.c mapwfs.c mapgdal.c mapogcsos.c mapscale.c mapwfs11.c mapwfs20.c
mapgeomtransform.c mapogroutput.c mapsde.c mapwfslayer.c mapagg.cpp mapkml.cpp
mapgeomutil.cpp mapkmlrenderer.cpp fontcache.c textlayout.c maputfgrid.cpp
mapogr.cpp mapcontour.c mapsmoothing.c mapv8.cpp ${REGEX_SOURCES})
@@ -442,7 +442,7 @@ if(WITH_SDE)
set(SDE64 1)
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
else(SDE_FOUND)
MESSAGE(WARNING "Could not find (all?) sde files. Try setting -DSDE_DIR=/path/to/sde and/or -DSDE_VERSION=91|92|100")
MESSAGE(WARNING "Could not find (all?) sde files. Try setting -DSDE_DIR=/path/to/sde and/or -DSDE_VERSION=91|92|100")
report_optional_not_found(SDE)
endif(SDE_FOUND)
endif(WITH_SDE)
240 mapgml.c

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -36,9 +36,6 @@
#include<libxml/parser.h>
#include<libxml/tree.h>
#define MS_GML_NAMESPACE_URI "http://www.opengis.net/gml"
#define MS_GML_NAMESPACE_PREFIX "gml"
xmlNodePtr msGML3BoundedBy(xmlNsPtr psNs, double minx, double miny, double maxx, double maxy, const char *psEpsg);
xmlNodePtr msGML3TimePeriod(xmlNsPtr psNs, char *pszStart, char *pszEnd);
xmlNodePtr msGML3TimeInstant(xmlNsPtr psNs, char *timeInstant);
@@ -931,6 +931,50 @@ FilterEncodingNode *FLTCreateBinaryCompFilterEncodingNode(void)
return psFilterNode;
}
/************************************************************************/
/* FLTFindGeometryNode */
/* */
/************************************************************************/
static CPLXMLNode* FLTFindGeometryNode(CPLXMLNode* psXMLNode,
int* pbPoint,
int* pbLine,
int* pbPolygon)
{
CPLXMLNode *psGMLElement = NULL;
psGMLElement = CPLGetXMLNode(psXMLNode, "Point");
if (!psGMLElement)
psGMLElement = CPLGetXMLNode(psXMLNode, "PointType");
if (psGMLElement)
*pbPoint =1;
else {
psGMLElement= CPLGetXMLNode(psXMLNode, "Polygon");
if (psGMLElement)
*pbPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiPolygon")))
*pbPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "Surface")))
*pbPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiSurface")))
*pbPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "Box")))
*pbPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "LineString")))
*pbLine = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiLineString")))
*pbLine = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "Curve")))
*pbLine = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiCurve")))
*pbLine = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiPoint")))
*pbPoint = 1;
}
return psGMLElement;
}
/************************************************************************/
/* FLTInsertElementInNode */
/* */
@@ -1100,6 +1144,8 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode,
int bCoordinatesValid = 0;
psPropertyName = CPLGetXMLNode(psXMLNode, "PropertyName");
if( psPropertyName == NULL )
psPropertyName = CPLGetXMLNode(psXMLNode, "ValueReference");
psBox = CPLGetXMLNode(psXMLNode, "Box");
if (!psBox)
psBox = CPLGetXMLNode(psXMLNode, "BoxType");
@@ -1148,30 +1194,9 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode,
char *pszUnits = NULL;
char *pszSRS = NULL;
CPLXMLNode *psGMLElement = NULL, *psDistance=NULL;
psGMLElement = CPLGetXMLNode(psXMLNode, "Point");
if (!psGMLElement)
psGMLElement = CPLGetXMLNode(psXMLNode, "PointType");
if (psGMLElement)
bPoint =1;
else {
psGMLElement= CPLGetXMLNode(psXMLNode, "Polygon");
if (psGMLElement)
bPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiPolygon")))
bPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiSurface")))
bPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "Box")))
bPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "LineString")))
bLine = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiPoint")))
bPoint = 1;
}
psGMLElement = FLTFindGeometryNode(psXMLNode, &bPoint, &bLine, &bPolygon);
psDistance = CPLGetXMLNode(psXMLNode, "Distance");
if (psGMLElement && psDistance && psDistance->psChild &&
@@ -1227,24 +1252,7 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode,
CPLXMLNode *psGMLElement = NULL;
psGMLElement = CPLGetXMLNode(psXMLNode, "Polygon");
if (psGMLElement)
bPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiPolygon")))
bPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiSurface")))
bPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "Box")))
bPolygon = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "LineString")))
bLine = 1;
else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiPoint")))
bPoint = 1;
else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "Point")))
bPoint = 1;
else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "PointType")))
bPoint = 1;
psGMLElement = FLTFindGeometryNode(psXMLNode, &bPoint, &bLine, &bPolygon);
if (psGMLElement) {
psShape = (shapeObj *)msSmallMalloc(sizeof(shapeObj));
@@ -1542,20 +1550,27 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode,
/* Note that for FES1.1.0 the featureid has been depricated in */
/* favor of GmlObjectId */
/* <GmlObjectId gml:id="TREESA_1M.1234"/> */
/* */
/* And in FES 2.0, in favor of <fes:ResourceId rid="foo.1234"/> */
/* -------------------------------------------------------------------- */
else if (FLTIsFeatureIdFilterType(psXMLNode->pszValue)) {
psFilterNode->eType = FILTER_NODE_TYPE_FEATUREID;
pszFeatureId = (char *)CPLGetXMLValue(psXMLNode, "fid", NULL);
/*for FE 1.1.0 GmlObjectId */
if (pszFeatureId == NULL)
pszFeatureId = (char *)CPLGetXMLValue(psXMLNode, "id", NULL);
/*for FE 2.0 ResourceId */
if (pszFeatureId == NULL)
pszFeatureId = (char *)CPLGetXMLValue(psXMLNode, "rid", NULL);
pszFeatureIdList = NULL;
psFeatureIdNode = psXMLNode;
while (psFeatureIdNode) {
pszFeatureId = (char *)CPLGetXMLValue(psFeatureIdNode, "fid", NULL);
if (!pszFeatureId)
pszFeatureId = (char *)CPLGetXMLValue(psFeatureIdNode, "id", NULL);
if (!pszFeatureId)
pszFeatureId = (char *)CPLGetXMLValue(psFeatureIdNode, "rid", NULL);
if (pszFeatureId) {
if (pszFeatureIdList)
@@ -1650,7 +1665,8 @@ int FLTIsComparisonFilterType(char *pszValue)
int FLTIsFeatureIdFilterType(char *pszValue)
{
if (pszValue && (strcasecmp(pszValue, "FeatureId") == 0 ||
strcasecmp(pszValue, "GmlObjectId") == 0))
strcasecmp(pszValue, "GmlObjectId") == 0 ||
strcasecmp(pszValue, "ResourceId") == 0))
return MS_TRUE;
@@ -1016,7 +1016,7 @@ int msOWSMakeAllLayersUnique(mapObj *map)
**
*/
int msOWSNegotiateVersion(int requested_version, int supported_versions[], int num_supported_versions)
int msOWSNegotiateVersion(int requested_version, const int supported_versions[], int num_supported_versions)
{
int i;
@@ -51,6 +51,7 @@ typedef struct {
char *pszService;
char *pszTypeName;
char *pszFilter;
char *pszFilterLanguage;
char *pszGeometryName;
int nMaxFeatures;
char *pszBbox; /* only used with a Get Request */
@@ -61,6 +62,8 @@ typedef struct {
char *pszPropertyName;
int nStartIndex;
char *pszAcceptVersions;
char *pszSections;
char *pszSortBy; /* Not implemented yet */
} wfsParamsObj;
/*
@@ -156,7 +159,7 @@ MS_DLL_EXPORT const char *msOWSGetVersionString(int nVersion, char *pszBuffer);
#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || defined(USE_WFS_LYR)
MS_DLL_EXPORT int msOWSMakeAllLayersUnique(mapObj *map);
MS_DLL_EXPORT int msOWSNegotiateVersion(int requested_version, int supported_versions[], int num_supported_versions);
MS_DLL_EXPORT int msOWSNegotiateVersion(int requested_version, const int supported_versions[], int num_supported_versions);
MS_DLL_EXPORT char *msOWSTerminateOnlineResource(const char *src_url);
MS_DLL_EXPORT char *msOWSGetOnlineResource(mapObj *map, const char *namespaces, const char *metadata_name, cgiRequestObj *req);
MS_DLL_EXPORT char *msOWSGetOnlineResource2(mapObj *map, const char *namespaces, const char *metadata_name, cgiRequestObj *req, const char *validated_language);
@@ -293,8 +296,13 @@ outputFormatObj *msOwsIsOutputFormatValid(mapObj *map, const char *format, hashT
/*====================================================================
* mapgml.c
*====================================================================*/
#define OWS_GML2 0 /* Supported GML formats */
#define OWS_GML3 1
typedef enum
{
OWS_GML2, /* 2.1.2 */
OWS_GML3, /* 3.1.1 */
OWS_GML32 /* 3.2.1 */
} OWSGMLVersion;
#define OWS_WFS_FEATURE_COLLECTION_NAME "msFeatureCollection"
#define OWS_GML_DEFAULT_GEOMETRY_NAME "msGeometry"
@@ -388,7 +396,8 @@ MS_DLL_EXPORT int msGMLWriteQuery(mapObj *map, char *filename, const char *names
#ifdef USE_WFS_SVR
MS_DLL_EXPORT int msGMLWriteWFSQuery(mapObj *map, FILE *stream, char *wfs_namespace, int outputformat);
MS_DLL_EXPORT int msGMLWriteWFSQuery(mapObj *map, FILE *stream, const char *wfs_namespace,
OWSGMLVersion outputformat, int nWFSVersion, int bUseURN);
#endif
@@ -430,15 +439,12 @@ int msWMSLayerExecuteRequest(mapObj *map, int nOWSLayers, int nClickX, int nClic
* mapwfs.c
*====================================================================*/
/* Supported DescribeFeature formats */
#define OWS_DEFAULT_SCHEMA 0 /* basically a GML 2.1 schema */
#define OWS_SFE_SCHEMA 1 /* GML for simple feature exchange (formerly GML3L0) */
MS_DLL_EXPORT int msWFSDispatch(mapObj *map, cgiRequestObj *requestobj,
owsRequestObj *ows_request, int force_wfs_mode);
int msWFSParseRequest(mapObj *map, cgiRequestObj *, owsRequestObj *ows_request,
wfsParamsObj *, int force_wfs_mode);
wfsParamsObj *msWFSCreateParamsObj(void);
int msWFSHandleUpdateSequence(mapObj *map, wfsParamsObj *wfsparams, const char* pszFunction);
void msWFSFreeParamsObj(wfsParamsObj *wfsparams);
int msWFSIsLayerSupported(layerObj *lp);
int msWFSException(mapObj *map, const char *locator, const char *code,
@@ -451,7 +457,18 @@ int msWFSException11(mapObj *map, const char *locator,
const char *exceptionCode, const char *version);
int msWFSGetCapabilities11(mapObj *map, wfsParamsObj *wfsparams,
cgiRequestObj *req, owsRequestObj *ows_request);
char *msWFSGetOutputFormatList(mapObj *map, layerObj *layer,const char*version);
#ifdef USE_LIBXML2
#include<libxml/tree.h>
xmlNodePtr msWFSDumpLayer11(mapObj *map, layerObj *lp, xmlNsPtr psNsOws,
int nWFSVersion);
#endif
char *msWFSGetOutputFormatList(mapObj *map, layerObj *layer, int nWFSVersion);
int msWFSException20(mapObj *map, const char *locator,
const char *exceptionCode);
int msWFSGetCapabilities20(mapObj *map, wfsParamsObj *params,
cgiRequestObj *req, owsRequestObj *ows_request);
#endif
/*====================================================================
@@ -635,11 +635,65 @@ int msOWSSchemaValidation(const char* xml_schema, const char* xml)
schema = NULL;
ret = -1;
/* Open XML Schema File */
ctxt = xmlSchemaNewParserCtxt(xml_schema);
/*
else ctxt = xmlSchemaNewMemParserCtxt(xml_schema);
*/
/* To valide WFS 2.0 requests, we might need to explicitely import */
/* GML and FES 2.0 */
if( strlen(xml_schema) > strlen(MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION) &&
strcmp(xml_schema + strlen(xml_schema) -
strlen(MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION), MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION) == 0 )
{
char szInMemSchema[2048];
char szBaseLocation[256];
strncpy(szBaseLocation, xml_schema, strlen(xml_schema) - strlen(MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION));
szBaseLocation[strlen(xml_schema) - strlen(MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION)] = '\0';
strcpy(szInMemSchema, "<schema elementFormDefault=\"qualified\" version=\"1.0.0\" "
"xmlns=\"http://www.w3.org/2001/XMLSchema\">\n");
sprintf(szInMemSchema + strlen(szInMemSchema),
"<import namespace=\"%s\" schemaLocation=\"%s\" />\n",
MS_OWSCOMMON_WFS_20_NAMESPACE_URI, xml_schema);
if( strstr(xml, MS_OWSCOMMON_FES_20_NAMESPACE_URI) != NULL )
{
sprintf(szInMemSchema + strlen(szInMemSchema),
"<import namespace=\"%s\" schemaLocation=\"%s%s\" />\n",
MS_OWSCOMMON_FES_20_NAMESPACE_URI, szBaseLocation, MS_OWSCOMMON_FES_20_SCHEMA_LOCATION);
}
if( strstr(xml, MS_OWSCOMMON_GML_32_NAMESPACE_URI) != NULL )
{
sprintf(szInMemSchema + strlen(szInMemSchema),
"<import namespace=\"%s\" schemaLocation=\"%s%s\" />\n",
MS_OWSCOMMON_GML_32_NAMESPACE_URI, szBaseLocation, MS_OWSCOMMON_GML_321_SCHEMA_LOCATION);
}
else if( strstr(xml, MS_OWSCOMMON_GML_NAMESPACE_URI) != NULL )
{
if( strstr(xml, MS_OWSCOMMON_GML_212_SCHEMA_LOCATION) != NULL )
{
sprintf(szInMemSchema + strlen(szInMemSchema),
"<import namespace=\"%s\" schemaLocation=\"%s%s\" />\n",
MS_OWSCOMMON_GML_NAMESPACE_URI, szBaseLocation, MS_OWSCOMMON_GML_212_SCHEMA_LOCATION);
}
else if( strstr(xml, MS_OWSCOMMON_GML_311_SCHEMA_LOCATION) != NULL )
{
sprintf(szInMemSchema + strlen(szInMemSchema),
"<import namespace=\"%s\" schemaLocation=\"%s%s\" />\n",
MS_OWSCOMMON_GML_NAMESPACE_URI, szBaseLocation, MS_OWSCOMMON_GML_311_SCHEMA_LOCATION);
}
}
strcat(szInMemSchema, "</schema>\n");
/*fprintf(stderr, "%s\n", szInMemSchema);*/
ctxt = xmlSchemaNewMemParserCtxt(szInMemSchema, strlen(szInMemSchema));
}
else
{
/* Open XML Schema File */
ctxt = xmlSchemaNewParserCtxt(xml_schema);
}
/*
xmlSchemaSetParserErrors(ctxt,
(xmlSchemaValidityErrorFunc) libxml2_callback,
@@ -695,7 +749,7 @@ int msOWSSchemaValidation(const char* xml_schema, const char* xml)
*
*/
int msOWSCommonNegotiateVersion(int requested_version, int supported_versions[], int num_supported_versions)
int msOWSCommonNegotiateVersion(int requested_version, const int supported_versions[], int num_supported_versions)
{
int i;
Oops, something went wrong.

0 comments on commit 562796a

Please sign in to comment.