[mapserver-commits] r9534 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Mon Nov 9 15:19:08 EST 2009
Author: assefa
Date: 2009-11-09 15:19:06 -0500 (Mon, 09 Nov 2009)
New Revision: 9534
Modified:
trunk/mapserver/HISTORY.TXT
trunk/mapserver/mapows.h
trunk/mapserver/mapwfs.c
Log:
Parse PropertyName parameter for wfs requests (#675)
Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT 2009-11-09 14:42:17 UTC (rev 9533)
+++ trunk/mapserver/HISTORY.TXT 2009-11-09 20:19:06 UTC (rev 9534)
@@ -14,6 +14,8 @@
Current Version (SVN trunk):
----------------------------
+- Parse PropertyName parameter for wfs requests (#675)
+
- Fixed when saving a map, layer->transform isn't written properly in all cases. (#3198)
- Fixed buffer overflow in oracle spatial driver with large sql data (#2694)
Modified: trunk/mapserver/mapows.h
===================================================================
--- trunk/mapserver/mapows.h 2009-11-09 14:42:17 UTC (rev 9533)
+++ trunk/mapserver/mapows.h 2009-11-09 20:19:06 UTC (rev 9534)
@@ -108,6 +108,7 @@
char *pszFeatureId;
char *pszSrs;
char *pszResultType;
+ char *pszPropertyName;
} wfsParamsObj;
/*
Modified: trunk/mapserver/mapwfs.c
===================================================================
--- trunk/mapserver/mapwfs.c 2009-11-09 14:42:17 UTC (rev 9533)
+++ trunk/mapserver/mapwfs.c 2009-11-09 20:19:06 UTC (rev 9534)
@@ -1022,6 +1022,8 @@
int iResultTypeHits = 0;
gmlNamespaceListObj *namespaceList=NULL; /* for external application schema support */
+ char **papszPropertyName = NULL;
+ int nPropertyNames = 0;
/* Default filter is map extents */
bbox = map->extent;
@@ -1048,10 +1050,12 @@
}
if(paramsObj->pszTypeName) {
- int j, k;
+ int j, k, z;
const char *pszMapSRS = NULL;
char **tokens;
int n=0, i=0;
+ char szTmp[256];
+ const char *pszFullName = NULL;
/* keep a ref for layer use. */
typename = paramsObj->pszTypeName;
@@ -1064,7 +1068,7 @@
/* ==================================================================== */
/* TODO: check if the typename contains namespaces (ex cdf:Other), */
- /* If that is the case extarct only the layer name. */
+ /* If that is the case extract only the layer name. */
/* ==================================================================== */
if (layers==NULL || numlayers < 1) {
@@ -1107,7 +1111,8 @@
for (j=0; j<map->numlayers; j++) {
layerObj *lp;
-
+ char *pszPropertyName = NULL;
+
lp = GET_LAYER(map, j);
if (msWFSIsLayerSupported(lp) && lp->name && strcasecmp(lp->name, layers[k]) == 0) {
@@ -1121,6 +1126,91 @@
lp->template = strdup("ttt.html");
}
+ /* set the gml_include_items METADATA */
+ if (paramsObj->pszPropertyName)
+ {
+ pszPropertyName = paramsObj->pszPropertyName;
+
+ /*we parse the propertyname parameter only once*/
+ if (papszPropertyName == NULL)
+ {
+ if (strlen(pszPropertyName) > 0 && pszPropertyName[0] == '(')
+ {
+ tokens = msStringSplit(pszPropertyName+1, '(', &nPropertyNames);
+ /*expecting to always have a list of property names equal to
+ the number of layers(typename)*/
+ if (nPropertyNames != numlayers)
+ {
+ if (tokens)
+ msFreeCharArray(tokens, nPropertyNames);
+ msSetError(MS_WFSERR,
+ "Optional PROPERTYNAME parameter. A list of properties may be specified for each type name. Example TYPENAME=name1&name2&PROPERTYNAME=(prop1,prop2)(prop1)",
+ "msWFSGetFeature()");
+ return msWFSException(map, "PROPERTYNAME", "InvalidParameterValue", paramsObj->pszVersion);
+ }
+
+ papszPropertyName = (char **)malloc(sizeof(char *)*nPropertyNames);
+ for (i=0; i<nPropertyNames; i++)
+ {
+ if (strlen(tokens[i]) > 0)
+ {
+ papszPropertyName[i] = strdup(tokens[i]);
+ /* remove trailing ) */
+ papszPropertyName[i][strlen(papszPropertyName[i])-1] = '\0';
+ }
+ else
+ papszPropertyName[i] = NULL; /*should return an error*/
+ }
+ if (tokens)
+ msFreeCharArray(tokens, nPropertyNames);
+ }
+ else
+ {
+ msSetError(MS_WFSERR,
+ "Optional PROPERTYNAME parameter. A list of properties may be specified for each type name. Example TYPENAME=name1&name2&PROPERTYNAME=(prop1,prop2)(prop1)",
+ "msWFSGetFeature()");
+ return msWFSException(map, "PROPERTYNAME", "InvalidParameterValue", paramsObj->pszVersion);
+ }
+ }
+ /*do an alias replace for the current layer*/
+ if (papszPropertyName && msLayerOpen(lp) == MS_SUCCESS && msLayerGetItems(lp) == MS_SUCCESS)
+ {
+ for(z=0; z<lp->numitems; z++)
+ {
+ if (!lp->items[z] || strlen(lp->items[z]) <= 0)
+ continue;
+ sprintf(szTmp, "%s_alias", lp->items[z]);
+ pszFullName = msOWSLookupMetadata(&(lp->metadata), "G", szTmp);
+ if (pszFullName)
+ papszPropertyName[k] = msReplaceSubstring(papszPropertyName[i], pszFullName, lp->items[z]);
+
+ }
+ }
+
+
+ if (papszPropertyName)
+ {
+ if (strlen(papszPropertyName[k]) > 0)
+ {
+ msInsertHashTable(&(lp->metadata), "GML_INCLUDE_ITEMS", papszPropertyName[k]);
+
+ /* exclude geometry if it was not asked for */
+ if (msOWSLookupMetadata(&(lp->metadata), "OFG", "geometries") != NULL)
+ sprintf(szTmp, "%s", msOWSLookupMetadata(&(lp->metadata), "OFG", "geometries"));
+ else
+ sprintf(szTmp, OWS_GML_DEFAULT_GEOMETRY_NAME);
+
+ if (strstr(papszPropertyName[k], szTmp) == NULL)
+ msInsertHashTable(&(lp->metadata), "GML_GEOMETRIES", "none");
+ }
+ else /*empty string*/
+ msInsertHashTable(&(lp->metadata), "GML_GEOMETRIES", "none");
+
+ }
+ }
+
+
+
/* See comments in msWFSGetCapabilities() about the rules for SRS. */
if ((pszThisLayerSRS = pszMapSRS) == NULL) {
pszThisLayerSRS = msOWSGetEPSGProj(&(lp->projection), &(lp->metadata), "FO", MS_TRUE);
@@ -1183,7 +1273,15 @@
}
}
}
+ if (papszPropertyName && nPropertyNames > 0)
+ {
+ for (i=0; i<nPropertyNames; i++)
+ msFree(papszPropertyName[i]);
+ msFree(papszPropertyName);
+ }
+
+
/* Validate outputformat */
if (paramsObj->pszOutputFormat) {
/* We support only GML2 and GML3 for now. */
@@ -2013,6 +2111,9 @@
else if (strcasecmp(request->ParamNames[i], "FEATUREID") == 0)
wfsparams->pszFeatureId = strdup(request->ParamValues[i]);
+
+ else if (strcasecmp(request->ParamNames[i], "PROPERTYNAME") == 0)
+ wfsparams->pszPropertyName = strdup(request->ParamValues[i]);
}
}
/* version is optional is the GetCapabilities. If not */
@@ -2028,12 +2129,12 @@
#ifdef USE_OGR
if (request->postrequest)
{
- CPLXMLNode *psRoot, *psQuery, *psFilter, *psTypeName = NULL;
+ CPLXMLNode *psRoot, *psQuery, *psFilter, *psTypeName, *psPropertyName = NULL;
CPLXMLNode *psGetFeature = NULL;
CPLXMLNode *psGetCapabilities = NULL;
CPLXMLNode *psDescribeFeature = NULL;
CPLXMLNode *psOperation = NULL;
- char *pszValue, *pszSerializedFilter, *pszTmp = NULL;
+ char *pszValue, *pszSerializedFilter, *pszTmp, *pszTmp2 = NULL;
int bMultiLayer = 0;
psRoot = CPLParseXMLString(request->postrequest);
@@ -2142,6 +2243,7 @@
/* typenames will be build with comma between thme */
/* (typename1,typename2,...) and filters will be build with */
/* bracets enclosinf the filters :(filter1)(filter2)... */
+/* propertynames are stored like (property1,property2)(property1) */
/* -------------------------------------------------------------------- */
while (psQuery && psQuery->pszValue &&
strcasecmp(psQuery->pszValue, "Query") == 0)
@@ -2173,7 +2275,59 @@
free(pszTmp);
}
}
+
+ /*parse property name*/
+ psPropertyName = CPLGetXMLNode(psQuery, "PropertyName");
+ pszTmp2= NULL;
+ /*when there is no PropertyName, we outpout () so that it is parsed properly in GetFeature*/
+ if (psPropertyName == NULL)
+ pszTmp2 = strdup("");
+
+ while (psPropertyName)
+ {
+ if (!psPropertyName->pszValue ||
+ strcasecmp(psPropertyName->pszValue, "PropertyName") != 0)
+ {
+ psPropertyName = psPropertyName->psNext;
+ continue;
+ }
+ pszValue = (char *) CPLGetXMLValue(psPropertyName, NULL, NULL);
+ if (pszTmp2 == NULL) {
+ pszTmp2 = strdup(pszValue);
+ }
+ else
+ {
+ pszTmp = strdup(pszTmp2);
+ pszTmp2 = (char *)realloc(pszTmp2, sizeof(char)* (strlen(pszTmp)+ strlen(pszValue)+2));
+ sprintf(pszTmp2,"%s,%s",pszTmp, pszValue);
+ msFree(pszTmp);
+ }
+ psPropertyName = psPropertyName->psNext;
+ }
+ if (pszTmp2)
+ {
+ pszTmp = strdup(pszTmp2);
+ pszTmp2 = (char *)realloc(pszTmp2, sizeof(char)* (strlen(pszTmp)+ 3));
+ sprintf(pszTmp2,"(%s)", pszTmp);
+ msFree(pszTmp);
+
+ if (wfsparams->pszPropertyName == NULL)
+ wfsparams->pszPropertyName = strdup(pszTmp2);
+ else
+ {
+ pszTmp = strdup(wfsparams->pszPropertyName);
+ wfsparams->pszPropertyName =
+ (char *)realloc(wfsparams->pszPropertyName,
+ sizeof(char)*(strlen(pszTmp)+ strlen(pszTmp2)+1));
+ sprintf(wfsparams->pszPropertyName,"%s%s",wfsparams->pszPropertyName,
+ pszTmp2);
+ msFree(pszTmp);
+ }
+ msFree(pszTmp2);
+ pszTmp2 = NULL;
+ }
+
/* parse filter */
psFilter = CPLGetXMLNode(psQuery, "Filter");
More information about the mapserver-commits
mailing list