Skip to content
Permalink
Browse files

Merge pull request #5836 from rouault/auto_add_numberMatched_to_geojs…

…on_output

GeoJSON output: automatically add a numberMatched property for WFS 2.0 GetFeature responses when wfs_compute_number_matched=true
  • Loading branch information...
rouault committed Jul 11, 2019
2 parents f42d7d1 + 2b66c35 commit eb9c49c68ecbd8639d7cd8a338c17b3ae8b5e27a
@@ -699,16 +699,23 @@ int msOGRWriteFromQuery( mapObj *map, outputFormatObj *format, int sendheaders )
int iLayer, i;
int bDataSourceNameIsRequestDir = FALSE;
int bUseFeatureId = MS_FALSE;
const char* pszMatchingFeatures;
int nMatchingFeatures = -1;
const char* pszFormatName = format->driver+4;

pszMatchingFeatures = msGetOutputFormatOption(format, "_matching_features_", "");
if( pszMatchingFeatures[0] != '\0' )
nMatchingFeatures = atoi(pszMatchingFeatures);

/* -------------------------------------------------------------------- */
/* Fetch the output format driver. */
/* -------------------------------------------------------------------- */
msOGRInitialize();

hDriver = OGRGetDriverByName( format->driver+4 );
hDriver = OGRGetDriverByName( pszFormatName );
if( hDriver == NULL ) {
msSetError( MS_MISCERR, "No OGR driver named `%s' available.",
"msOGRWriteFromQuery()", format->driver+4 );
"msOGRWriteFromQuery()", pszFormatName );
return MS_FAILURE;
}

@@ -723,6 +730,29 @@ int msOGRWriteFromQuery( mapObj *map, outputFormatObj *format, int sendheaders )
ds_options = CSLAddString( ds_options,
format->formatoptions[i] + 5 );
}
if( EQUAL(pszFormatName, "GeoJSON") && nMatchingFeatures >= 0 )
{
const char* pszNativeData =
CSLFetchNameValueDef(layer_options, "NATIVE_DATA", "{}");
if( pszNativeData[strlen(pszNativeData)-1] == '}' )
{
char szTemp[32];
char* pszTemplate = msSmallMalloc(strlen(pszNativeData) + 32);
strcpy(pszTemplate, pszNativeData);
pszTemplate[strlen(pszTemplate)-1] = 0;
if( strlen(pszNativeData) > 2 )
strcat(pszTemplate, ",");
sprintf(szTemp, "\"numberMatched\":%d}", nMatchingFeatures);
strcat(pszTemplate, szTemp);
layer_options = CSLSetNameValue(layer_options,
"NATIVE_MEDIA_TYPE",
"application/vnd.geo+json");
layer_options = CSLSetNameValue(layer_options,
"NATIVE_DATA",
pszTemplate);
msFree(pszTemplate);
}
}
if(!strcasecmp("true",msGetOutputFormatOption(format,"USE_FEATUREID","false"))) {
bUseFeatureId = MS_TRUE;
}
@@ -3976,6 +3976,17 @@ int msWFSGetFeature(mapObj *map, wfsParamsObj *paramsObj, cgiRequestObj *req,
mapserv->request = req;
map->querymap.status = MS_FALSE;

if( nMatchingFeatures >= 0 )
{
char szMatchingFeatures[12];
sprintf(szMatchingFeatures, "%d", nMatchingFeatures);
msSetOutputFormatOption( psFormat, "_matching_features_",
szMatchingFeatures);
}
else
{
msSetOutputFormatOption( psFormat, "_matching_features_", "");
}
status = msReturnTemplateQuery( mapserv, psFormat->name, NULL );

mapserv->request = NULL;
@@ -0,0 +1,20 @@
Content-Type: application/json; subtype=geojson; charset=utf-8

{
"type": "FeatureCollection",
"numberMatched": 28,
"name": "popplace_fid",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::3978" } },
"features": [
{ "type": "Feature", "id": 0, "properties": { "UNIQUE_KEY": "BACMK", "NAME": "\"Tignish", "CAPITAL": 0, "POP_CLASS": 1 }, "geometry": { "type": "Point", "coordinates": [ 2281604.25, 340848.9375 ] } },
{ "type": "Feature", "id": 1215011, "properties": { "UNIQUE_KEY": "CAGYX", "NAME": "'Cheticamp", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2503805.5, 427872.65625 ] } },
{ "type": "Feature", "id": 1209036, "properties": { "UNIQUE_KEY": "CBIKA", "NAME": "Sheet Harbour", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2499190.0, 194088.23438 ] } },
{ "type": "Feature", "id": 1101036, "properties": { "UNIQUE_KEY": "BACII", "NAME": "'Souris'", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2434957.0, 347013.59375 ] } },
{ "type": "Feature", "id": 1213006, "properties": { "UNIQUE_KEY": "CAGBW", "NAME": "\"Canso\"", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2578914.25, 292073.09375 ] } },
{ "type": "Feature", "id": 1215002, "properties": { "UNIQUE_KEY": "CBELL", "NAME": "Port Hawkesbury", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2536072.75, 311524.96875 ] } },
{ "type": "Feature", "id": 1214002, "properties": { "UNIQUE_KEY": "CAATB", "NAME": "Antigonish", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2494520.0, 285855.40625 ] } },
{ "type": "Feature", "id": 1211008, "properties": { "UNIQUE_KEY": "CBKDH", "NAME": "Springhill", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2348711.75, 204294.0625 ] } },
{ "type": "Feature", "id": 1208002, "properties": { "UNIQUE_KEY": "CBPAK", "NAME": "\"Wind\"sor", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2377598.0, 135734.70312 ] } },
{ "type": "Feature", "id": 1206006, "properties": { "UNIQUE_KEY": "CAWAZ", "NAME": "Lunenburg", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2398677.25, 70608.14062 ] } }
]
}
@@ -0,0 +1,21 @@
Content-Type: application/json; subtype=geojson; charset=utf-8

{
"type": "FeatureCollection",
"foo": "bar",
"numberMatched": 28,
"name": "popplace_fid",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::3978" } },
"features": [
{ "type": "Feature", "id": 0, "properties": { "UNIQUE_KEY": "BACMK", "NAME": "\"Tignish", "CAPITAL": 0, "POP_CLASS": 1 }, "geometry": { "type": "Point", "coordinates": [ 2281604.25, 340848.9375 ] } },
{ "type": "Feature", "id": 1215011, "properties": { "UNIQUE_KEY": "CAGYX", "NAME": "'Cheticamp", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2503805.5, 427872.65625 ] } },
{ "type": "Feature", "id": 1209036, "properties": { "UNIQUE_KEY": "CBIKA", "NAME": "Sheet Harbour", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2499190.0, 194088.23438 ] } },
{ "type": "Feature", "id": 1101036, "properties": { "UNIQUE_KEY": "BACII", "NAME": "'Souris'", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2434957.0, 347013.59375 ] } },
{ "type": "Feature", "id": 1213006, "properties": { "UNIQUE_KEY": "CAGBW", "NAME": "\"Canso\"", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2578914.25, 292073.09375 ] } },
{ "type": "Feature", "id": 1215002, "properties": { "UNIQUE_KEY": "CBELL", "NAME": "Port Hawkesbury", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2536072.75, 311524.96875 ] } },
{ "type": "Feature", "id": 1214002, "properties": { "UNIQUE_KEY": "CAATB", "NAME": "Antigonish", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2494520.0, 285855.40625 ] } },
{ "type": "Feature", "id": 1211008, "properties": { "UNIQUE_KEY": "CBKDH", "NAME": "Springhill", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2348711.75, 204294.0625 ] } },
{ "type": "Feature", "id": 1208002, "properties": { "UNIQUE_KEY": "CBPAK", "NAME": "\"Wind\"sor", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2377598.0, 135734.70312 ] } },
{ "type": "Feature", "id": 1206006, "properties": { "UNIQUE_KEY": "CAWAZ", "NAME": "Lunenburg", "CAPITAL": 0, "POP_CLASS": 2 }, "geometry": { "type": "Point", "coordinates": [ 2398677.25, 70608.14062 ] } }
]
}
@@ -5,6 +5,11 @@
#
# Test OGR geojson output.
# RUN_PARMS: wfsogr10_geojson.json [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=popplace_fid&OUTPUTFORMAT=geojson" > [RESULT]
#
# RUN_PARMS: wfsogr20_geojson.json [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=popplace_fid&OUTPUTFORMAT=geojson&COUNT=10" > [RESULT]
#
# RUN_PARMS: wfsogr20_geojson_with_predefine_native_data.json [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=popplace_fid&OUTPUTFORMAT=geojson_with_predefined_native_data&COUNT=10" > [RESULT]

MAP

NAME WFS_OGROUT_TEST
@@ -24,6 +29,20 @@ OUTPUTFORMAT
FORMATOPTION "USE_FEATUREID=true"
FORMATOPTION "LCO:COORDINATE_PRECISION=5"
END


OUTPUTFORMAT
NAME "geojson_with_predefined_native_data"
DRIVER "OGR/GEOJSON"
MIMETYPE "application/json; subtype=geojson; charset=utf-8"
FORMATOPTION "STORAGE=stream"
FORMATOPTION "FORM=SIMPLE"
FORMATOPTION "USE_FEATUREID=true"
FORMATOPTION "LCO:COORDINATE_PRECISION=5"
FORMATOPTION "LCO:NATIVE_MEDIA_TYPE=application/vnd.geo+json"
FORMATOPTION "LCO:NATIVE_DATA={\"foo\":\"bar\"}"
END

#
WEB

@@ -60,6 +79,7 @@ WEB
"ows_role" "staff"
"wms_feature_info_mime_type" "text/csv"
"ows_enable_request" "*"
"wfs_compute_number_matched" "true"
END
END

@@ -78,7 +98,7 @@ LAYER
"wfs_title" "popplace"
"wfs_description" "populated places"
"wfs_featureid" "SGC_CODE"
"wfs_getfeature_formatlist" "geojson"
"wfs_getfeature_formatlist" "geojson,geojson_with_predefined_native_data"
"gml_include_items" "NAME,UNIQUE_KEY,CAPITAL,POP_RANGE"
"gml_POP_RANGE_alias" "POP_CLASS"
"gml_types" "auto"

0 comments on commit eb9c49c

Please sign in to comment.
You can’t perform that action at this time.