[mapguide-commits] r10029 - in trunk/MgDev: Server/src/Wms Web/src/HttpHandler Web/src/WebTestRunner

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue Mar 14 04:39:52 PDT 2023


Author: jng
Date: 2023-03-14 04:39:51 -0700 (Tue, 14 Mar 2023)
New Revision: 10029

Modified:
   trunk/MgDev/Server/src/Wms/1.0.0.xml.awd
   trunk/MgDev/Server/src/Wms/1.1.0.xml.awd
   trunk/MgDev/Server/src/Wms/1.1.1.xml.awd
   trunk/MgDev/Server/src/Wms/1.3.0.xml.awd
   trunk/MgDev/Web/src/HttpHandler/HttpWmsGetFeatureInfo.cpp
   trunk/MgDev/Web/src/HttpHandler/OgcFramework.h
   trunk/MgDev/Web/src/HttpHandler/OgcServer.cpp
   trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.cpp
   trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.cpp
   trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.h
   trunk/MgDev/Web/src/WebTestRunner/OgcTest.cpp
   trunk/MgDev/Web/src/WebTestRunner/main.cpp
Log:
When generating WMS GetFeatureInfo responses in GeoJSON format, generate the CRS information if possible.

Add new WebTestRunner test cases to test GetFeatureInfo and check for expected CRS

Fixes #2858

Modified: trunk/MgDev/Server/src/Wms/1.0.0.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.0.0.xml.awd	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Server/src/Wms/1.0.0.xml.awd	2023-03-14 11:39:51 UTC (rev 10029)
@@ -118,7 +118,7 @@
   &FeatureProperty.Name;=&FeatureProperty.Value;
  </Define>
 
- <!-- Default definitions -- superceded by metadata in each layer -->
+ <!-- Default definitions, superceded by metadata in each layer -->
  <Define item="Layer.Queryable">1</Define>
  <Define item="Layer.Cascaded">0</Define>
  <Define item="Layer.NoSubsets">0</Define>
@@ -408,7 +408,17 @@
 
 -->
 <Response request="GetFeatureInfo" content-type="application/json">{
-  "type": "FeatureCollection",
+  "type": "FeatureCollection",<?Ifdef item="FeatureInfo.CRS"?>
+  "crs": {
+    "type": "name",
+    "properties": {<?If l="&FeatureInfo.CRS;" op="eq" r="4326"?>
+      "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
+    <?Else?>
+      "name": "urn:ogc:def:crs:EPSG::&FeatureInfo.CRS;"
+    <?Endif?>
+    }
+  },<?Else?>
+  "crs": null,<?Endif?>
   "features": [<?EnumFeatureInfo using="&FeatureInfo.json;" ?>]
 }</Response>
 

Modified: trunk/MgDev/Server/src/Wms/1.1.0.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.1.0.xml.awd	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Server/src/Wms/1.1.0.xml.awd	2023-03-14 11:39:51 UTC (rev 10029)
@@ -432,7 +432,17 @@
 
 -->
 <Response request="GetFeatureInfo" content-type="application/json">{
-  "type": "FeatureCollection",
+  "type": "FeatureCollection",<?Ifdef item="FeatureInfo.CRS"?>
+  "crs": {
+    "type": "name",
+    "properties": {<?If l="&FeatureInfo.CRS;" op="eq" r="4326"?>
+      "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
+    <?Else?>
+      "name": "urn:ogc:def:crs:EPSG::&FeatureInfo.CRS;"
+    <?Endif?>
+    }
+  },<?Else?>
+  "crs": null,<?Endif?>
   "features": [<?EnumFeatureInfo using="&FeatureInfo.json;" ?>]
 }</Response>
 

Modified: trunk/MgDev/Server/src/Wms/1.1.1.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.1.1.xml.awd	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Server/src/Wms/1.1.1.xml.awd	2023-03-14 11:39:51 UTC (rev 10029)
@@ -412,7 +412,17 @@
 
 -->
 <Response request="GetFeatureInfo" content-type="application/json">{
-  "type": "FeatureCollection",
+  "type": "FeatureCollection",<?Ifdef item="FeatureInfo.CRS"?>
+  "crs": {
+    "type": "name",
+    "properties": {<?If l="&FeatureInfo.CRS;" op="eq" r="4326"?>
+      "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
+    <?Else?>
+      "name": "urn:ogc:def:crs:EPSG::&FeatureInfo.CRS;"
+    <?Endif?>
+    }
+  },<?Else?>
+  "crs": null,<?Endif?>
   "features": [<?EnumFeatureInfo using="&FeatureInfo.json;" ?>]
 }</Response>
 

Modified: trunk/MgDev/Server/src/Wms/1.3.0.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.3.0.xml.awd	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Server/src/Wms/1.3.0.xml.awd	2023-03-14 11:39:51 UTC (rev 10029)
@@ -419,7 +419,17 @@
 
 -->
 <Response request="GetFeatureInfo" content-type="application/json">{
-  "type": "FeatureCollection",
+  "type": "FeatureCollection",<?Ifdef item="FeatureInfo.CRS"?>
+  "crs": {
+    "type": "name",
+    "properties": {<?If l="&FeatureInfo.CRS;" op="eq" r="4326"?>
+      "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
+    <?Else?>
+      "name": "urn:ogc:def:crs:EPSG::&FeatureInfo.CRS;"
+    <?Endif?>
+    }
+  },<?Else?>
+  "crs": null,<?Endif?>
   "features": [<?EnumFeatureInfo using="&FeatureInfo.json;" ?>]
 }</Response>
 

Modified: trunk/MgDev/Web/src/HttpHandler/HttpWmsGetFeatureInfo.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpWmsGetFeatureInfo.cpp	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Web/src/HttpHandler/HttpWmsGetFeatureInfo.cpp	2023-03-14 11:39:51 UTC (rev 10029)
@@ -244,8 +244,14 @@
         Ptr<MgBatchPropertyCollection> propertyCollection = service->QueryFeatureProperties(map, queryLayers, selectionGeometry,
             MgFeatureSpatialOperations::Intersects, L"", m_featureCount, 1 /*Any visible features*/, false /* no bbox */, bCaptureGeometry);
 
+        // Try to extract the EPSG code of the map SRS
+        INT32 epsg = 0;
+        Ptr<MgCoordinateSystemFactory> csFactory = new MgCoordinateSystemFactory();
+        STRING mapSRS = map->GetMapSRS();
+        epsg = csFactory->ConvertWktToEpsgCode(mapSRS);
+
         // Create the object to store the feature info
-        Ptr<MgWmsFeatureInfo> wmsFeatureInfo = new MgWmsFeatureInfo(propertyCollection);
+        Ptr<MgWmsFeatureInfo> wmsFeatureInfo = new MgWmsFeatureInfo(propertyCollection, epsg);
 
         wmsFeatureInfo->SetFormat(m_infoFormat);
 

Modified: trunk/MgDev/Web/src/HttpHandler/OgcFramework.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/OgcFramework.h	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Web/src/HttpHandler/OgcFramework.h	2023-03-14 11:39:51 UTC (rev 10029)
@@ -169,4 +169,6 @@
 
 extern CPSZ kpszOpenLayersMimeType         ;// = _("application/openlayers");
 
+extern CPSZ kpszFeatureInfoCRS				;// = _("FeatureInfo.CRS");
+
 #endif//_OgcFramework_h

Modified: trunk/MgDev/Web/src/HttpHandler/OgcServer.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/OgcServer.cpp	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Web/src/HttpHandler/OgcServer.cpp	2023-03-14 11:39:51 UTC (rev 10029)
@@ -222,6 +222,7 @@
                                                          // the highest version possible.
 
 CPSZ kpszOpenLayersMimeType          = _("application/openlayers"); //OpenLayers mime type
+CPSZ kpszFeatureInfoCRS              = _("FeatureInfo.CRS"); // EPSG code for GetFeatureInfo response
 
 DocLoaderFunc MgOgcServer::ms_fnDocLoader = NULL;
 

Modified: trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.cpp	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.cpp	2023-03-14 11:39:51 UTC (rev 10029)
@@ -311,6 +311,11 @@
     if(pszFormat == NULL)
       pszFormat = kpszMimeTypeXml;
 
+    // Add top-level FeatureInfo.CRS defn if we have a non-zero EPSG code
+    INT32 epsg = m_pFeatureInfo->GetEpsgCode();
+    if (epsg != 0)
+        AddDefinition(kpszFeatureInfoCRS, epsg);
+
     if(GenerateResponse(kpszQueryValueGetFeatureInfo,pszFormat))
         return;
 

Modified: trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.cpp	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.cpp	2023-03-14 11:39:51 UTC (rev 10029)
@@ -23,8 +23,8 @@
 CPSZ kpszDefinitionFeatureInfoLayerName = _("FeatureInfo.LayerName");
 CPSZ kpszLayerNameProperty = _("_MgLayerName");
 
-MgWmsFeatureInfo::MgWmsFeatureInfo(MgBatchPropertyCollection* propertyCollection)
-:   m_index(-1)
+MgWmsFeatureInfo::MgWmsFeatureInfo(MgBatchPropertyCollection* propertyCollection, INT32 epsg)
+:   m_index(-1), m_epsg(epsg)
 {
     m_propertyCollection = SAFE_ADDREF(propertyCollection);
 }
@@ -64,6 +64,11 @@
     }
 }
 
+INT32 MgWmsFeatureInfo::GetEpsgCode()
+{
+    return m_epsg;
+}
+
 void MgWmsFeatureInfo::SetFormat(CREFSTRING format)
 {
     m_format = format;

Modified: trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.h	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.h	2023-03-14 11:39:51 UTC (rev 10029)
@@ -26,12 +26,13 @@
 class MgWmsFeatureInfo: public IOgcResourceEnumerator, public MgDisposable
 {
 public:
-    MgWmsFeatureInfo(MgBatchPropertyCollection* propertyCollection);
+    MgWmsFeatureInfo(MgBatchPropertyCollection* propertyCollection, INT32 epsg);
 
     //Default constructor to keep Ptr<> happy
     MgWmsFeatureInfo(){};
     virtual ~MgWmsFeatureInfo();
 
+    INT32 GetEpsgCode();
     void SetFormat(CREFSTRING format);
 
     bool Next();
@@ -47,6 +48,7 @@
 private:
    Ptr<MgBatchPropertyCollection> m_propertyCollection;
    int m_index;
+   INT32 m_epsg;
    STRING m_format;
 };
 

Modified: trunk/MgDev/Web/src/WebTestRunner/OgcTest.cpp
===================================================================
--- trunk/MgDev/Web/src/WebTestRunner/OgcTest.cpp	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Web/src/WebTestRunner/OgcTest.cpp	2023-03-14 11:39:51 UTC (rev 10029)
@@ -125,4 +125,168 @@
     Ptr<MgByteReader> reader = dynamic_cast<MgByteReader*>(result->GetResultObject());
     REQUIRE(reader.p != nullptr);
     REQUIRE((L"text/html" == result->GetResultContentType()));
+}
+
+TEST_CASE("Wms_GetFeatureInfo_1_0_0_GeoJson_WGS84", "[Wms]")
+{
+    STRING uri = L"";
+    Ptr<MgHttpRequest> req = new MgHttpRequest(uri);
+    Ptr<MgHttpRequestParam> param = req->GetRequestParam();
+
+    MgConfiguration* cfg = MgConfiguration::GetInstance();
+    STRING pwd;
+    cfg->GetStringValue(MgConfigProperties::OgcPropertiesSection, MgConfigProperties::WmsPassword, pwd, L"");
+
+    param->AddParameter(L"USERNAME", MgUser::WmsUser);
+    param->AddParameter(L"PASSWORD", pwd);
+
+    param->AddParameter(L"SERVICE", L"WMS");
+    param->AddParameter(L"REQUEST", L"GETFEATUREINFO");
+    param->AddParameter(L"VERSION", L"1.0.0");
+    param->AddParameter(L"LAYERS", L"Samples/Sheboygan/Layers/Parcels");
+    param->AddParameter(L"QUERY_LAYERS", L"Samples/Sheboygan/Layers/Parcels");
+    param->AddParameter(L"X", L"50");
+    param->AddParameter(L"Y", L"50");
+    param->AddParameter(L"BBOX", L"-87.70944759286215,43.75184488425595,-87.70855788913056,43.75273458798754");
+    param->AddParameter(L"SRS", L"EPSG:4326");
+    param->AddParameter(L"WIDTH", L"101");
+    param->AddParameter(L"HEIGHT", L"101");
+    param->AddParameter(L"FORMAT", L"image/png");
+    param->AddParameter(L"INFO_FORMAT", L"application/json");
+
+    Ptr<MgHttpResponse> resp = req->Execute();
+    Ptr<MgHttpResult> result = resp->GetResult();
+
+    STRING err = result->GetDetailedErrorMessage();
+    REQUIRE(err.empty());
+
+    Ptr<MgByteReader> reader = dynamic_cast<MgByteReader*>(result->GetResultObject());
+    REQUIRE(reader.p != nullptr);
+    STRING respContent = reader->ToString();
+    REQUIRE((L"application/json" == result->GetResultContentType()));
+    // This CRS string should be in the GeoJSON
+    REQUIRE(respContent.find(L"urn:ogc:def:crs:OGC:1.3:CRS84") != STRING::npos);
+}
+
+TEST_CASE("Wms_GetFeatureInfo_1_1_0_GeoJson_WGS84", "[Wms]")
+{
+    STRING uri = L"";
+    Ptr<MgHttpRequest> req = new MgHttpRequest(uri);
+    Ptr<MgHttpRequestParam> param = req->GetRequestParam();
+
+    MgConfiguration* cfg = MgConfiguration::GetInstance();
+    STRING pwd;
+    cfg->GetStringValue(MgConfigProperties::OgcPropertiesSection, MgConfigProperties::WmsPassword, pwd, L"");
+
+    param->AddParameter(L"USERNAME", MgUser::WmsUser);
+    param->AddParameter(L"PASSWORD", pwd);
+
+    param->AddParameter(L"SERVICE", L"WMS");
+    param->AddParameter(L"REQUEST", L"GETFEATUREINFO");
+    param->AddParameter(L"VERSION", L"1.1.0");
+    param->AddParameter(L"LAYERS", L"Samples/Sheboygan/Layers/Parcels");
+    param->AddParameter(L"QUERY_LAYERS", L"Samples/Sheboygan/Layers/Parcels");
+    param->AddParameter(L"X", L"50");
+    param->AddParameter(L"Y", L"50");
+    param->AddParameter(L"BBOX", L"-87.70944759286215,43.75184488425595,-87.70855788913056,43.75273458798754");
+    param->AddParameter(L"SRS", L"EPSG:4326");
+    param->AddParameter(L"WIDTH", L"101");
+    param->AddParameter(L"HEIGHT", L"101");
+    param->AddParameter(L"FORMAT", L"image/png");
+    param->AddParameter(L"INFO_FORMAT", L"application/json");
+
+    Ptr<MgHttpResponse> resp = req->Execute();
+    Ptr<MgHttpResult> result = resp->GetResult();
+
+    STRING err = result->GetDetailedErrorMessage();
+    REQUIRE(err.empty());
+
+    Ptr<MgByteReader> reader = dynamic_cast<MgByteReader*>(result->GetResultObject());
+    REQUIRE(reader.p != nullptr);
+    STRING respContent = reader->ToString();
+    REQUIRE((L"application/json" == result->GetResultContentType()));
+    // This CRS string should be in the GeoJSON
+    REQUIRE(respContent.find(L"urn:ogc:def:crs:OGC:1.3:CRS84") != STRING::npos);
+}
+
+TEST_CASE("Wms_GetFeatureInfo_1_1_1_GeoJson_WGS84", "[Wms]")
+{
+    STRING uri = L"";
+    Ptr<MgHttpRequest> req = new MgHttpRequest(uri);
+    Ptr<MgHttpRequestParam> param = req->GetRequestParam();
+
+    MgConfiguration* cfg = MgConfiguration::GetInstance();
+    STRING pwd;
+    cfg->GetStringValue(MgConfigProperties::OgcPropertiesSection, MgConfigProperties::WmsPassword, pwd, L"");
+
+    param->AddParameter(L"USERNAME", MgUser::WmsUser);
+    param->AddParameter(L"PASSWORD", pwd);
+
+    param->AddParameter(L"SERVICE", L"WMS");
+    param->AddParameter(L"REQUEST", L"GETFEATUREINFO");
+    param->AddParameter(L"VERSION", L"1.1.1");
+    param->AddParameter(L"LAYERS", L"Samples/Sheboygan/Layers/Parcels");
+    param->AddParameter(L"QUERY_LAYERS", L"Samples/Sheboygan/Layers/Parcels");
+    param->AddParameter(L"X", L"50");
+    param->AddParameter(L"Y", L"50");
+    param->AddParameter(L"BBOX", L"-87.70944759286215,43.75184488425595,-87.70855788913056,43.75273458798754");
+    param->AddParameter(L"SRS", L"EPSG:4326");
+    param->AddParameter(L"WIDTH", L"101");
+    param->AddParameter(L"HEIGHT", L"101");
+    param->AddParameter(L"FORMAT", L"image/png");
+    param->AddParameter(L"INFO_FORMAT", L"application/json");
+
+    Ptr<MgHttpResponse> resp = req->Execute();
+    Ptr<MgHttpResult> result = resp->GetResult();
+
+    STRING err = result->GetDetailedErrorMessage();
+    REQUIRE(err.empty());
+
+    Ptr<MgByteReader> reader = dynamic_cast<MgByteReader*>(result->GetResultObject());
+    REQUIRE(reader.p != nullptr);
+    STRING respContent = reader->ToString();
+    REQUIRE((L"application/json" == result->GetResultContentType()));
+    // This CRS string should be in the GeoJSON
+    REQUIRE(respContent.find(L"urn:ogc:def:crs:OGC:1.3:CRS84") != STRING::npos);
+}
+
+TEST_CASE("Wms_GetFeatureInfo_1_3_0_GeoJson_WGS84", "[Wms]")
+{
+    STRING uri = L"";
+    Ptr<MgHttpRequest> req = new MgHttpRequest(uri);
+    Ptr<MgHttpRequestParam> param = req->GetRequestParam();
+
+    MgConfiguration* cfg = MgConfiguration::GetInstance();
+    STRING pwd;
+    cfg->GetStringValue(MgConfigProperties::OgcPropertiesSection, MgConfigProperties::WmsPassword, pwd, L"");
+
+    param->AddParameter(L"USERNAME", MgUser::WmsUser);
+    param->AddParameter(L"PASSWORD", pwd);
+
+    param->AddParameter(L"SERVICE", L"WMS");
+    param->AddParameter(L"REQUEST", L"GETFEATUREINFO");
+    param->AddParameter(L"VERSION", L"1.3.0");
+    param->AddParameter(L"LAYERS", L"Samples/Sheboygan/Layers/Parcels");
+    param->AddParameter(L"QUERY_LAYERS", L"Samples/Sheboygan/Layers/Parcels");
+    param->AddParameter(L"I", L"50");
+    param->AddParameter(L"J", L"50");
+    param->AddParameter(L"BBOX", L"43.75184488425595,-87.70944759286215,43.75273458798754,-87.70855788913056");
+    param->AddParameter(L"CRS", L"EPSG:4326");
+    param->AddParameter(L"WIDTH", L"101");
+    param->AddParameter(L"HEIGHT", L"101");
+    param->AddParameter(L"FORMAT", L"image/png");
+    param->AddParameter(L"INFO_FORMAT", L"application/json");
+
+    Ptr<MgHttpResponse> resp = req->Execute();
+    Ptr<MgHttpResult> result = resp->GetResult();
+
+    STRING err = result->GetDetailedErrorMessage();
+    REQUIRE(err.empty());
+
+    Ptr<MgByteReader> reader = dynamic_cast<MgByteReader*>(result->GetResultObject());
+    REQUIRE(reader.p != nullptr);
+    STRING respContent = reader->ToString();
+    REQUIRE((L"application/json" == result->GetResultContentType()));
+    // This CRS string should be in the GeoJSON
+    REQUIRE(respContent.find(L"urn:ogc:def:crs:OGC:1.3:CRS84") != STRING::npos);
 }
\ No newline at end of file

Modified: trunk/MgDev/Web/src/WebTestRunner/main.cpp
===================================================================
--- trunk/MgDev/Web/src/WebTestRunner/main.cpp	2023-02-13 10:07:24 UTC (rev 10028)
+++ trunk/MgDev/Web/src/WebTestRunner/main.cpp	2023-03-14 11:39:51 UTC (rev 10029)
@@ -66,6 +66,9 @@
     if (bInit)
     {
         Catch::Session session;
+        // TODO: This test suite assumes the Sheboygan dataset is already loaded and that certain
+        // layers have WMS metadata changed from the defaults. Perhaps this runner should take the Sheboygan.mgp
+        // path as a parameter and do this setup before running the test suite
         result = session.run(argc, argv);
     }
 



More information about the mapguide-commits mailing list