Skip to content

Commit

Permalink
Initial wfs2 commit with GetCapabilities, DescribeFeatureType and Get…
Browse files Browse the repository at this point in the history
…Feature/GML3.2 support
  • Loading branch information
rouault committed Oct 26, 2013
1 parent 5102de2 commit 562796a
Show file tree
Hide file tree
Showing 14 changed files with 2,747 additions and 1,481 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down Expand Up @@ -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)
Expand Down
240 changes: 162 additions & 78 deletions mapgml.c

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions mapgml.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
98 changes: 57 additions & 41 deletions mapogcfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
/* */
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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 &&
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion mapows.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
35 changes: 26 additions & 9 deletions mapows.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -61,6 +62,8 @@ typedef struct {
char *pszPropertyName;
int nStartIndex;
char *pszAcceptVersions;
char *pszSections;
char *pszSortBy; /* Not implemented yet */
} wfsParamsObj;

/*
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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


Expand Down Expand Up @@ -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,
Expand All @@ -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

/*====================================================================
Expand Down
66 changes: 60 additions & 6 deletions mapowscommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;

Expand Down
Loading

0 comments on commit 562796a

Please sign in to comment.