[mapguide-commits] r9256 - in trunk/MgDev: . Common/MapGuideCommon/Services Common/PlatformBase/Services Common/Stylization Server/src/Services/Feature Server/src/Services/Kml Server/src/Services/Mapping Server/src/Services/Rendering Server/src/Wfs Server/src/Wms UnitTest/TestData/Wfs UnitTest/WebTier/MapAgent/MapAgentForms Web/src/HttpHandler
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Sun Nov 26 14:22:40 PST 2017
Author: jng
Date: 2017-11-26 14:22:40 -0800 (Sun, 26 Nov 2017)
New Revision: 9256
Added:
trunk/MgDev/Server/src/Services/Feature/OpGetWfsReader.cpp
trunk/MgDev/Server/src/Services/Feature/OpGetWfsReader.h
trunk/MgDev/Server/src/Services/Feature/WfsQueryAdapter.cpp
trunk/MgDev/Server/src/Services/Feature/WfsQueryAdapter.h
trunk/MgDev/Web/src/HttpHandler/WmsFeatureGeometry.cpp
trunk/MgDev/Web/src/HttpHandler/WmsFeatureGeometry.h
Modified:
trunk/MgDev/
trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureService.cpp
trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureService.h
trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.cpp
trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.h
trunk/MgDev/Common/MapGuideCommon/Services/RenderingDefs.h
trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.cpp
trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.h
trunk/MgDev/Common/PlatformBase/Services/FeatureDefs.h
trunk/MgDev/Common/PlatformBase/Services/FeatureService.h
trunk/MgDev/Common/PlatformBase/Services/GeoJsonWriter.h
trunk/MgDev/Common/Stylization/RendererStyles.h
trunk/MgDev/Server/src/Services/Feature/FeatureOperationFactory.cpp
trunk/MgDev/Server/src/Services/Feature/Makefile.am
trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.cpp
trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.h
trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcxproj
trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcxproj.filters
trunk/MgDev/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp
trunk/MgDev/Server/src/Services/Kml/ServerKmlService.cpp
trunk/MgDev/Server/src/Services/Mapping/MappingUtil.cpp
trunk/MgDev/Server/src/Services/Rendering/FeaturePropRenderer.cpp
trunk/MgDev/Server/src/Services/Rendering/FeaturePropRenderer.h
trunk/MgDev/Server/src/Services/Rendering/OpQueryFeatureProperties.cpp
trunk/MgDev/Server/src/Services/Rendering/RenderingOperationFactory.cpp
trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.cpp
trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.h
trunk/MgDev/Server/src/Wfs/OgcWfsService.config.awd
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/Server/src/Wms/OgcWmsService.config.awd
trunk/MgDev/UnitTest/TestData/Wfs/WfsTest.dump
trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeatureinfowmsform.html
trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeaturewfsform.html
trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj
trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters
trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp
trunk/MgDev/Web/src/HttpHandler/HttpWfsGetFeature.cpp
trunk/MgDev/Web/src/HttpHandler/HttpWmsGetFeatureInfo.cpp
trunk/MgDev/Web/src/HttpHandler/Makefile.am
trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.cpp
trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.h
trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.cpp
trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.h
trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.cpp
trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.h
trunk/MgDev/Web/src/HttpHandler/WmsFeatureProperties.cpp
trunk/MgDev/Web/src/HttpHandler/WmsFeatureProperties.h
Log:
Merge in RFC 163 sandbox
Property changes on: trunk/MgDev
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/2.4/MgDev:6749-6756,6777-6783,6785-6787,6789,6791-6794,6796-6801,6954-6962,6986-7006
/branches/2.6/MgDev:8276-8286,8288-8292,8297,8299,8301,8303,8314-8315,8318,8335,8340,8354-8355,8365,8373
/branches/3.0/MgDev:8658,8705,8710
/branches/3.1/MgDev:9026,9058-9059,9067-9068
/sandbox/VC140:8684-8759
/sandbox/adsk/2.6l:8727
/sandbox/adsk/3.0m:8563,8584,8607,8625,8694-8695
/sandbox/adsk/3.1n:8871,8895,8901,8912-8913,8921-8922,8942,9019-9020
/sandbox/jng/clean_json:8818-9180
/sandbox/jng/cmdline:9199-9217
/sandbox/jng/convenience_apis:8262-8268,8271-8363
/sandbox/jng/coordsys_mapagent:9231-9254
/sandbox/jng/createruntimemap:7486-7555
/sandbox/jng/dwftk:8321-8324,8328-8329,8331,8352
/sandbox/jng/geoprocessing:9205-9229
/sandbox/jng/geos34x:8256-8259
/sandbox/jng/php56x:8975-8985
/sandbox/jng/rfc155:8872-8884
/sandbox/jng/simplify:8814-9141
/sandbox/jng/tiling:8174-8208
/sandbox/jng/utfgrid:9179-9212
/sandbox/jng/v30:8212-8227
/sandbox/rfc94:5099-5163
+ /branches/2.4/MgDev:6749-6756,6777-6783,6785-6787,6789,6791-6794,6796-6801,6954-6962,6986-7006
/branches/2.6/MgDev:8276-8286,8288-8292,8297,8299,8301,8303,8314-8315,8318,8335,8340,8354-8355,8365,8373
/branches/3.0/MgDev:8658,8705,8710
/branches/3.1/MgDev:9026,9058-9059,9067-9068
/sandbox/VC140:8684-8759
/sandbox/adsk/2.6l:8727
/sandbox/adsk/3.0m:8563,8584,8607,8625,8694-8695
/sandbox/adsk/3.1n:8871,8895,8901,8912-8913,8921-8922,8942,9019-9020
/sandbox/jng/clean_json:8818-9180
/sandbox/jng/cmdline:9199-9217
/sandbox/jng/convenience_apis:8262-8268,8271-8363
/sandbox/jng/coordsys_mapagent:9231-9254
/sandbox/jng/createruntimemap:7486-7555
/sandbox/jng/dwftk:8321-8324,8328-8329,8331,8352
/sandbox/jng/geoprocessing:9205-9229
/sandbox/jng/geos34x:8256-8259
/sandbox/jng/ogc:9240-9255
/sandbox/jng/php56x:8975-8985
/sandbox/jng/rfc155:8872-8884
/sandbox/jng/simplify:8814-9141
/sandbox/jng/tiling:8174-8208
/sandbox/jng/utfgrid:9179-9212
/sandbox/jng/v30:8212-8227
/sandbox/rfc94:5099-5163
Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureService.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureService.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureService.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -1473,7 +1473,38 @@
return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
}
+MgFeatureReader* MgProxyFeatureService::GetWfsReader(MgResourceIdentifier* featureSourceId,
+ CREFSTRING featureClass,
+ MgStringCollection* requiredProperties,
+ CREFSTRING srs,
+ CREFSTRING filter,
+ CREFSTRING sortCriteria)
+{
+ MgCommand cmd;
+ cmd.ExecuteCommand(m_connProp, // Connection
+ MgCommand::knObject, // Return type expected
+ MgFeatureServiceOpId::GetWfsReader_Id, // Command Code
+ 6, // No of arguments
+ Feature_Service, // Service Id
+ BUILD_VERSION(3,3,0), // Operation version
+ MgCommand::knObject, featureSourceId, // Argument#1
+ MgCommand::knString, &featureClass, // Argument#2
+ MgCommand::knObject, requiredProperties, // Argument#3
+ MgCommand::knString, &srs, // Argument#4
+ MgCommand::knString, &filter, // Argument#5
+ MgCommand::knString, &sortCriteria, // Argument#6
+ MgCommand::knNone); // End of argument
+ SetWarning(cmd.GetWarningObject());
+
+ Ptr<MgProxyFeatureReader> featReader = (MgProxyFeatureReader*)cmd.GetReturnValue().val.m_obj;
+
+ if (featReader != NULL)
+ featReader->SetService(this); // Feature reader on proxy side would store proxy service to call GetFeatures()
+
+ return SAFE_ADDREF((MgProxyFeatureReader*)featReader);
+}
+
//////////////////////////////////////////////////////////////////
MgBatchPropertyCollection* MgProxyFeatureService::GetFeatures(CREFSTRING featureReader)
{
Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureService.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureService.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -1507,6 +1507,62 @@
CREFSTRING namespacePrefix,
CREFSTRING namespaceUrl);
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Retrieves feature information based on the supplied criteria.
+ ///
+ /// \note1
+ ///
+ /// <!-- Syntax in .Net, Java, and PHP -->
+ /// \htmlinclude DotNetSyntaxTop.html
+ /// virtual MgFeatureReader GetWfsReader(MgResourceIdentifier featureSourceId, string featureClass, MgStringCollection requiredProperties, string srs, string filter, int maxFeatures, string outputFormat, string sortCriteria);
+ /// \htmlinclude SyntaxBottom.html
+ /// \htmlinclude JavaSyntaxTop.html
+ /// virtual MgFeatureReader GetWfsReader(MgResourceIdentifier featureSourceId, string featureClass, MgStringCollection requiredProperties, string srs, string filter, int maxFeatures, string outputFormat, string sortCriteria);
+ /// \htmlinclude SyntaxBottom.html
+ /// \htmlinclude PHPSyntaxTop.html
+ /// virtual MgFeatureReader GetWfsReader(MgResourceIdentifier featureSourceId, string featureClass, MgStringCollection requiredProperties, string srs, string filter, int maxFeatures, string outputFormat, string sortCriteria);
+ /// \htmlinclude SyntaxBottom.html
+ ///
+ /// \param featureSourceId (MgResourceIdentifier)
+ /// The resource identifier defining the
+ /// location of the feature source in
+ /// the repository.
+ /// \param featureClass (String/string)
+ /// The feature class containing the features to retrieve.
+ /// \param requiredProperties (MgStringCollection)
+ /// The collection of properties to retrieve for each feature. If the
+ /// collection is null or empty, all properties will be retrieved.
+ /// \param srs (String/string)
+ /// The spatial reference system in which to return feature geometries
+ /// \param filter (String/string)
+ /// An XML string containing the definition for an OGC filter
+ /// \param maxFeatures (int)
+ /// The maximum number of features to retrieve. If the value is less
+ /// than or equal to zero, all features will be retrieved.
+ /// \param sortCriteria (String/string)
+ /// A string identifying the sort criteria
+ ///
+ /// \remarks
+ /// The purpose of this method, as opposed to GetWfsFeature is to return the base reader using the same input parameters
+ /// allowing for the caller to determine the desired output format and the desired content transformations required from
+ /// the reader.
+ ///
+ /// The main use case for this method is for providing the base feature reader for outputting WFS GetFeature responses in
+ /// formats other than GML
+ ///
+ /// \return
+ /// Returns an MgByteReader containing the requested feature information.
+ ///
+ /// \exception MgInvalidArgumentException
+ ///
+ MgFeatureReader* GetWfsReader(MgResourceIdentifier* featureSourceId,
+ CREFSTRING featureClass,
+ MgStringCollection* requiredProperties,
+ CREFSTRING srs,
+ CREFSTRING filter,
+ CREFSTRING sortCriteria);
+
////////////////////////////////////////////////////////////////////////////////
/// \brief
/// This method enumerates all the providers and if they are FDO enabled for
Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -1065,6 +1065,74 @@
return (MgBatchPropertyCollection*)cmd.GetReturnValue().val.m_obj;
}
+/////////////////////////////////////////////////////////////////
+/// \brief
+/// The QueryFeatureProperties operation identifies those features that
+/// meet the specified spatial selection criteria. This operation
+/// is used to implement WMS feature info and returns property values
+/// for all features which match the spatial query
+///
+/// \param map
+/// Input
+/// map object containing current state of map.
+/// \param layerNames
+/// Input
+/// Active layer names for which to query features
+/// \param filterGeometry
+/// Input
+/// geometry object specifying the selection area
+/// \param selectionVariant
+/// Input
+/// selection criterion - integer value corresponding to one of
+/// the MgFeatureSpatialOperations values
+/// \param featureFilter
+/// Input
+/// an XML selection string containing the required feature IDs
+/// \param maxFeatures
+/// Input
+/// the maximum number of features to return
+/// \param layerAttributeFilter
+/// Input
+/// bitmask values - 1=Visible, 2=Selectable, 4=HasTooltips
+///
+/// \return
+/// An MgSelection instance identifying the features that meet the
+/// selection criteria. Returns null if no features are identified.
+///
+MgBatchPropertyCollection* MgProxyRenderingService::QueryFeatureProperties(
+ MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX,
+ bool bIncludeGeometry)
+{
+ MgCommand cmd;
+ cmd.ExecuteCommand(m_connProp, // Connection
+ MgCommand::knObject, // Return type expected
+ MgRenderingServiceOpId::QueryFeatureProperties3,// Command Code
+ 9, // No of arguments
+ Rendering_Service, // Service Id
+ BUILD_VERSION(3, 3, 0), // Operation version
+ MgCommand::knObject, map, // Argument#1
+ MgCommand::knObject, layerNames, // Argument#2
+ MgCommand::knObject, filterGeometry, // Argument#3
+ MgCommand::knInt32, selectionVariant, // Argument#4
+ MgCommand::knString, &featureFilter, // Argument#5
+ MgCommand::knInt32, maxFeatures, // Argument#6
+ MgCommand::knInt32, layerAttributeFilter, // Argument#7
+ MgCommand::knInt8, (INT8)bIncludeFeatureBBOX, // Argument#8
+ MgCommand::knInt8, (INT8)bIncludeGeometry, // Argument#9
+ MgCommand::knNone); // End of arguments
+
+ SetWarning(cmd.GetWarningObject());
+
+ return (MgBatchPropertyCollection*)cmd.GetReturnValue().val.m_obj;
+}
+
//////////////////////////////////////////////////////////////////
/// \brief
/// Sets the connection properties for the Proxy Service. This
Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -954,6 +954,57 @@
INT32 layerAttributeFilter,
bool bIncludeFeatureBBOX);
+ /////////////////////////////////////////////////////////////////
+ /// \brief
+ /// The QueryFeatureProperties operation identifies those features that
+ /// meet the specified spatial selection criteria. This operation
+ /// is used to implement WMS feature info and returns property values
+ /// for all features which match the spatial query
+ ///
+ /// \param map
+ /// Input
+ /// map object containing current state of map.
+ /// \param layerNames
+ /// Input
+ /// Active layer names for which to query features
+ /// \param filterGeometry
+ /// Input
+ /// geometry object specifying the selection area
+ /// \param selectionVariant
+ /// Input
+ /// selection criterion - integer value corresponding to one of
+ /// the MgFeatureSpatialOperations values
+ /// \param featureFilter
+ /// Input
+ /// an XML selection string containing the required feature IDs
+ /// \param maxFeatures
+ /// Input
+ /// the maximum number of features to return
+ /// \param layerAttributeFilter
+ /// Input
+ /// bitmask values - 1=Visible, 2=Selectable, 4=HasTooltips
+ /// \param bIncludeFeatureBBOX
+ /// Input
+ /// Indicates whether a bounding box should be included. If true, bounding box is recorded as a special property named _MgFeatureBoundingBox
+ /// \param bIncludeGeometry
+ /// Input
+ /// Indicates whether a bounding box should be included. If true, bounding box is recorded as a special property named _MgFeatureBoundingBox
+ ///
+ /// \return
+ /// An MgSelection instance identifying the features that meet the
+ /// selection criteria. Returns null if no features are identified.
+ ///
+ virtual MgBatchPropertyCollection* QueryFeatureProperties(
+ MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX,
+ bool bIncludeGeometry);
+
protected:
//////////////////////////////////////////////////////////////////
Modified: trunk/MgDev/Common/MapGuideCommon/Services/RenderingDefs.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/RenderingDefs.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/MapGuideCommon/Services/RenderingDefs.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -46,6 +46,7 @@
static const int RenderMap6 = 0x1111E912;
static const int RenderMap7 = 0x1111E913;
static const int RenderTileUTFGrid = 0x1111E914;
+ static const int QueryFeatureProperties3 = 0x1111E915;
};
/// \endcond
Modified: trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -47,17 +47,4 @@
void MgRenderingService::Dispose()
{
delete this;
-}
-
-MgBatchPropertyCollection* MgRenderingService::QueryFeatureProperties(
- MgMap* map,
- MgStringCollection* layerNames,
- MgGeometry* filterGeometry,
- INT32 selectionVariant,
- CREFSTRING featureFilter,
- INT32 maxFeatures,
- INT32 layerAttributeFilter,
- bool bIncludeFeatureBBOX)
-{
- throw new MgNotImplementedException(L"MgRenderingService.QueryFeatureProperties", __LINE__, __WFILE__, NULL, L"", NULL);
}
\ No newline at end of file
Modified: trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -948,6 +948,9 @@
/// \param layerAttributeFilter
/// Input
/// bitmask values - 1=Visible, 2=Selectable, 4=HasTooltips
+ /// \param bIncludeFeatureBBOX
+ /// Input
+ /// Indicates whether a bounding box should be included. If true, bounding box is recorded as a special property named _MgFeatureBoundingBox
///
/// \return
/// An MgSelection instance identifying the features that meet the
@@ -961,8 +964,59 @@
CREFSTRING featureFilter,
INT32 maxFeatures,
INT32 layerAttributeFilter,
- bool bIncludeFeatureBBOX);
+ bool bIncludeFeatureBBOX) = 0;
+ /////////////////////////////////////////////////////////////////
+ /// \brief
+ /// The QueryFeatureProperties operation identifies those features that
+ /// meet the specified spatial selection criteria. This operation
+ /// is used to implement WMS feature info and returns property values
+ /// for all features which match the spatial query
+ ///
+ /// \param map
+ /// Input
+ /// map object containing current state of map.
+ /// \param layerNames
+ /// Input
+ /// Active layer names for which to query features
+ /// \param filterGeometry
+ /// Input
+ /// geometry object specifying the selection area
+ /// \param selectionVariant
+ /// Input
+ /// selection criterion - integer value corresponding to one of
+ /// the MgFeatureSpatialOperations values
+ /// \param featureFilter
+ /// Input
+ /// an XML selection string containing the required feature IDs
+ /// \param maxFeatures
+ /// Input
+ /// the maximum number of features to return
+ /// \param layerAttributeFilter
+ /// Input
+ /// bitmask values - 1=Visible, 2=Selectable, 4=HasTooltips
+ /// \param bIncludeFeatureBBOX
+ /// Input
+ /// Indicates whether a bounding box should be included. If true, bounding box is recorded as a special property named _MgFeatureBoundingBox
+ /// \param bIncludeGeometry
+ /// Input
+ /// Indicates whether a bounding box should be included. If true, bounding box is recorded as a special property named _MgFeatureBoundingBox
+ ///
+ /// \return
+ /// An MgSelection instance identifying the features that meet the
+ /// selection criteria. Returns null if no features are identified.
+ ///
+ virtual MgBatchPropertyCollection* QueryFeatureProperties(
+ MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX,
+ bool bIncludeGeometry) = 0;
+
protected:
/////////////////////////////////////////////////////////////////
Modified: trunk/MgDev/Common/PlatformBase/Services/FeatureDefs.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/FeatureDefs.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/PlatformBase/Services/FeatureDefs.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -83,6 +83,8 @@
static const int UpdateMatchingFeatures = 0x1111ED33;
static const int DeleteFeatures = 0x1111ED34;
static const int SelectFeaturesWithTransform = 0x1111ED35;
+
+ static const int GetWfsReader_Id = 0x1111ED36;
};
/// \endcond
Modified: trunk/MgDev/Common/PlatformBase/Services/FeatureService.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/FeatureService.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/PlatformBase/Services/FeatureService.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -2038,6 +2038,60 @@
CREFSTRING namespacePrefix,
CREFSTRING namespaceUrl) = 0;
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Retrieves feature information based on the supplied criteria.
+ ///
+ /// \note1
+ ///
+ /// <!-- Syntax in .Net, Java, and PHP -->
+ /// \htmlinclude DotNetSyntaxTop.html
+ /// virtual MgFeatureReader GetWfsReader(MgResourceIdentifier featureSourceId, string featureClass, MgStringCollection requiredProperties, string srs, string filter, int maxFeatures, string outputFormat, string sortCriteria);
+ /// \htmlinclude SyntaxBottom.html
+ /// \htmlinclude JavaSyntaxTop.html
+ /// virtual MgFeatureReader GetWfsReader(MgResourceIdentifier featureSourceId, string featureClass, MgStringCollection requiredProperties, string srs, string filter, int maxFeatures, string outputFormat, string sortCriteria);
+ /// \htmlinclude SyntaxBottom.html
+ /// \htmlinclude PHPSyntaxTop.html
+ /// virtual MgFeatureReader GetWfsReader(MgResourceIdentifier featureSourceId, string featureClass, MgStringCollection requiredProperties, string srs, string filter, int maxFeatures, string outputFormat, string sortCriteria);
+ /// \htmlinclude SyntaxBottom.html
+ ///
+ /// \param featureSourceId (MgResourceIdentifier)
+ /// The resource identifier defining the
+ /// location of the feature source in
+ /// the repository.
+ /// \param featureClass (String/string)
+ /// The feature class containing the features to retrieve.
+ /// \param requiredProperties (MgStringCollection)
+ /// The collection of properties to retrieve for each feature. If the
+ /// collection is null or empty, all properties will be retrieved.
+ /// \param srs (String/string)
+ /// The spatial reference system in which to return feature geometries
+ /// \param filter (String/string)
+ /// An XML string containing the definition for an OGC filter
+ /// \param sortCriteria (String/string)
+ /// A string identifying the sort criteria
+ ///
+ /// \remarks
+ /// The purpose of this method, as opposed to GetWfsFeature is to return the base reader using the same input parameters
+ /// allowing for the caller to determine the desired output format and the desired content transformations required from
+ /// the reader.
+ ///
+ /// The main use case for this method is for providing the base feature reader for outputting WFS GetFeature responses in
+ /// formats other than GML
+ ///
+ /// \return
+ /// Returns an MgByteReader containing the requested feature information.
+ ///
+ /// \exception MgInvalidArgumentException
+ ///
+ /// \since 3.3
+ virtual MgFeatureReader* GetWfsReader(MgResourceIdentifier* featureSourceId,
+ CREFSTRING featureClass,
+ MgStringCollection* requiredProperties,
+ CREFSTRING srs,
+ CREFSTRING filter,
+ CREFSTRING sortCriteria) = 0;
+
////////////////////////////////////////////////////////////////////////////////
/// \brief
/// This method enumerates all the providers and if they are FDO enabled for
Modified: trunk/MgDev/Common/PlatformBase/Services/GeoJsonWriter.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/GeoJsonWriter.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/PlatformBase/Services/GeoJsonWriter.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -195,6 +195,7 @@
INTERNAL_API:
STRING GeometryToGeoJson(MgGeometry* geom);
+ void ToGeoJson(MgGeometry* geom, REFSTRING str, bool bIncludePrefix = true);
protected:
virtual void Dispose();
@@ -202,7 +203,6 @@
private:
static STRING EscapeJsonString(CREFSTRING str);
void ValueToString(MgReader* reader, INT32 index, REFSTRING str);
- void ToGeoJson(MgGeometry* geom, REFSTRING str, bool bIncludePrefix = true);
void CoordinateToGeoJson(MgCoordinate* coord, REFSTRING str);
void CoordinatesToGeoJson(MgCoordinateIterator* coords, REFSTRING str);
void PolygonToGeoJson(MgPolygon* poly, REFSTRING str);
Modified: trunk/MgDev/Common/Stylization/RendererStyles.h
===================================================================
--- trunk/MgDev/Common/Stylization/RendererStyles.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Common/Stylization/RendererStyles.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -728,12 +728,12 @@
{
public:
RS_FeatureClassInfo() :
- m_name(L""), m_source(L"")
+ m_name(L""), m_source(L""), m_geometry(L"")
{
}
- RS_FeatureClassInfo(const RS_String& name, const RS_String& source) :
- m_name(name), m_source(source)
+ RS_FeatureClassInfo(const RS_String& name, const RS_String& source, const RS_String& geometry) :
+ m_name(name), m_source(source), m_geometry(geometry)
{
}
@@ -751,10 +751,12 @@
inline RS_String& name() { return m_name; }
inline std::vector<RS_String>& mappings() { return m_propMappings; }
inline RS_String& source() { return m_source; }
+ inline RS_String& geometry() { return m_geometry; }
private:
RS_String m_source;
RS_String m_name;
+ RS_String m_geometry;
std::vector<RS_String> m_propMappings;
};
Modified: trunk/MgDev/Server/src/Services/Feature/FeatureOperationFactory.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/FeatureOperationFactory.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Feature/FeatureOperationFactory.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -58,6 +58,7 @@
#include "OpGetIdentityProperties.h"
#include "OpDescribeWfsFeatureType.h"
#include "OpGetWfsFeature.h"
+#include "OpGetWfsReader.h"
#include "OpEnumerateDataStores.h"
#include "OpGetSchemaMapping.h"
#include "OpGetFdoCacheInfo.h"
@@ -579,6 +580,18 @@
}
break;
+ case MgFeatureServiceOpId::GetWfsReader_Id:
+ switch (VERSION_NO_PHASE(operationVersion))
+ {
+ case VERSION_SUPPORTED(3, 3):
+ handler.reset(new MgOpGetWfsReader());
+ break;
+ default:
+ throw new MgInvalidOperationVersionException(
+ L"MgFeatureOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+ break;
+
case MgFeatureServiceOpId::EnumerateDataStores_Id:
switch (VERSION_NO_PHASE(operationVersion))
{
@@ -677,11 +690,11 @@
}
break;
- case MgFeatureServiceOpId::AddSavePoint_Id:
- switch (VERSION_NO_PHASE(operationVersion))
+ case MgFeatureServiceOpId::AddSavePoint_Id:
+ switch (VERSION_NO_PHASE(operationVersion))
{
case VERSION_SUPPORTED(1,0):
- handler.reset(new MgOpAddSavePoint());
+ handler.reset(new MgOpAddSavePoint());
break;
default:
throw new MgInvalidOperationVersionException(
@@ -693,7 +706,7 @@
switch (VERSION_NO_PHASE(operationVersion))
{
case VERSION_SUPPORTED(1,0):
- handler.reset(new MgOpRollbackSavePoint());
+ handler.reset(new MgOpRollbackSavePoint());
break;
default:
throw new MgInvalidOperationVersionException(
@@ -702,7 +715,7 @@
break;
case MgFeatureServiceOpId::ReleaseSavePoint_Id:
- switch (VERSION_NO_PHASE(operationVersion))
+ switch (VERSION_NO_PHASE(operationVersion))
{
case VERSION_SUPPORTED(1,0):
handler.reset(new MgOpReleaseSavePoint());
Modified: trunk/MgDev/Server/src/Services/Feature/Makefile.am
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/Makefile.am 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Feature/Makefile.am 2017-11-26 22:22:40 UTC (rev 9256)
@@ -105,7 +105,9 @@
ByteSourceRasterStreamImpl.cpp \
OpDescribeWfsFeatureType.cpp \
OpGetWfsFeature.cpp \
+ OpGetWfsReader.cpp \
FilterUtil.cpp \
+ WfsQueryAdapter.cpp \
OpEnumerateDataStores.cpp \
OpGetSchemaMapping.cpp \
ServerEnumerateDataStores.cpp \
@@ -216,7 +218,9 @@
DateTimeDataReaderCreator.h \
OpDescribeWfsFeatureType.h \
OpGetWfsFeature.h \
+ OpGetWfsReader.h \
FilterUtil.h \
+ WfsQueryAdapter.h \
OpEnumerateDataStores.h \
OpGetSchemaMapping.h \
ServerEnumerateDataStores.h \
Copied: trunk/MgDev/Server/src/Services/Feature/OpGetWfsReader.cpp (from rev 9255, sandbox/jng/ogc/Server/src/Services/Feature/OpGetWfsReader.cpp)
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/OpGetWfsReader.cpp (rev 0)
+++ trunk/MgDev/Server/src/Services/Feature/OpGetWfsReader.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -0,0 +1,140 @@
+//
+// Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "ServerFeatureServiceDefs.h"
+#include "OpGetWfsFeature.h"
+#include "ServerFeatureService.h"
+#include "LogManager.h"
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Constructs the object.
+/// </summary>
+///----------------------------------------------------------------------------
+MgOpGetWfsReader::MgOpGetWfsReader()
+{
+}
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Destructs the object.
+/// </summary>
+///----------------------------------------------------------------------------
+MgOpGetWfsReader::~MgOpGetWfsReader()
+{
+}
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Executes the operation.
+/// </summary>
+///
+/// <exceptions>
+/// MgException
+/// </exceptions>
+///----------------------------------------------------------------------------
+void MgOpGetWfsReader::Execute()
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT(" (%t) MgOpGetWfsReader::Execute()\n")));
+
+ MG_LOG_OPERATION_MESSAGE(L"GetWfsFeature");
+
+ MG_FEATURE_SERVICE_TRY()
+
+ MG_LOG_OPERATION_MESSAGE_INIT(m_packet.m_OperationVersion, m_packet.m_NumArguments);
+
+ ACE_ASSERT(m_stream != NULL);
+
+ if (6 == m_packet.m_NumArguments)
+ {
+ // Get the feature source
+ Ptr<MgResourceIdentifier> featureSourceId = (MgResourceIdentifier*)m_stream->GetObject();
+
+ // Get the schema name
+ STRING featureClass;
+ m_stream->GetString(featureClass);
+
+ // Get the required properties
+ Ptr<MgStringCollection> requiredProperties = (MgStringCollection*)m_stream->GetObject();
+
+ // Get the srs
+ STRING srs;
+ m_stream->GetString(srs);
+
+ // Get the filter
+ STRING filter;
+ m_stream->GetString(filter);
+
+ // Get the sort criteria
+ STRING sortCriteria;
+ m_stream->GetString(sortCriteria);
+
+ BeginExecution();
+
+ MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(featureSourceId->ToString().c_str());
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(featureClass.c_str());
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(L"MgStringCollection");
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(srs.c_str());
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(filter.c_str());
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(sortCriteria.c_str());
+ MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+ Validate();
+
+ // Execute the operation
+ Ptr<MgFeatureReader> fr = m_service->GetWfsReader(featureSourceId, featureClass, requiredProperties, srs, filter, sortCriteria);
+
+ // Write the response
+ EndExecution(fr);
+ }
+ else
+ {
+ MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+ MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+ }
+
+ if (!m_argsRead)
+ {
+ throw new MgOperationProcessingException(L"MgOpGetWfsReader.Execute",
+ __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ // Successful operation
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
+
+ MG_FEATURE_SERVICE_CATCH(L"MgOpGetWfsReader.Execute")
+
+ if (mgException != NULL)
+ {
+ // Failed operation
+ MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Failure.c_str());
+ }
+
+ // Add access log entry for operation
+ MG_LOG_OPERATION_MESSAGE_ACCESS_ENTRY();
+
+ MG_FEATURE_SERVICE_THROW()
+}
Copied: trunk/MgDev/Server/src/Services/Feature/OpGetWfsReader.h (from rev 9255, sandbox/jng/ogc/Server/src/Services/Feature/OpGetWfsReader.h)
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/OpGetWfsReader.h (rev 0)
+++ trunk/MgDev/Server/src/Services/Feature/OpGetWfsReader.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef MG_OP_GET_WFS_READER_H
+#define MG_OP_GET_WFS_READER_H
+
+#include "FeatureOperation.h"
+
+class MgOpGetWfsReader : public MgFeatureOperation
+{
+public:
+ MgOpGetWfsReader();
+ virtual ~MgOpGetWfsReader();
+
+public:
+ virtual void Execute();
+};
+
+#endif
Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -48,6 +48,7 @@
#include "ServerSqlDataReader.h"
#include "ServerFeatureTransaction.h"
#include "TransformedGeometryFeatureReader.h"
+#include "WfsQueryAdapter.h"
#include <Fdo/Xml/FeatureSerializer.h>
#include <Fdo/Xml/FeatureWriter.h>
@@ -2043,7 +2044,29 @@
return msds.GetIdentityProperties(resource, schemaName, classNames);
}
+MgFeatureReader* MgServerFeatureService::GetWfsReader(MgResourceIdentifier* fs,
+ CREFSTRING featureClass,
+ MgStringCollection* propNames,
+ CREFSTRING srs,
+ CREFSTRING wfsFilter,
+ CREFSTRING sortCriteria)
+{
+ MG_LOG_TRACE_ENTRY(L"MgServerFeatureService::GetWfsReader()");
+ Ptr<MgFeatureReader> mgfReader;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ MgWfsQueryAdapter wfsQuery(this);
+ wfsQuery.SetOptions(fs, featureClass, propNames, srs, wfsFilter, sortCriteria);
+ mgfReader = wfsQuery.GetWfsReader();
+
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(fs, L"MgServerFeatureService.GetWfsReader")
+
+ return mgfReader.Detach();
+}
+
+
////////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief
/// Retrieves feature information based on the supplied criteria with specified format.
@@ -2110,163 +2133,19 @@
MG_LOG_TRACE_ENTRY(L"MgServerFeatureService::GetWfsFeature()");
Ptr<MgByteReader> byteReader;
- TransformCacheMap transformCache;
MG_FEATURE_SERVICE_TRY()
- STRING lfeatureName = featureClass;
- STRING schemaName, className;
- MgUtil::ParseQualifiedClassName(lfeatureName, schemaName, className);
+ MgWfsQueryAdapter wfsQuery(this);
+ wfsQuery.SetOptions(fs, featureClass, propNames, srs, wfsFilter, sortCriteria);
- bool hashed = (0 == schemaName.find_first_of(
- MG_SCHEMA_NAME_HASH_PREFIX.c_str(), 0, MG_SCHEMA_NAME_HASH_PREFIX.length()));
- Ptr<MgStringCollection> classNames = new MgStringCollection();
+ Ptr<MgFeatureReader> mgfReader = wfsQuery.GetWfsReader();
+ Ptr<MgCoordinateSystemTransform> trans = wfsQuery.GetTransform();
+ Ptr<MgCoordinateSystem> mapCs = wfsQuery.GetMapCs();
+ Ptr<MgClassDefinition> fc = wfsQuery.GetClassDefinition();
- if (!className.empty())
- {
- classNames->Add(className);
- }
-
- // Find the needed class definition.
- Ptr<MgFeatureSchemaCollection> fsc = DescribeSchema(
- fs, hashed ? L"" : schemaName, classNames);
- Ptr<MgFeatureSchema> schema;
- Ptr<MgClassDefinition> fc;
- STRING schemaHash;
-
- FindClassDefinition(fsc, schemaName, className, schemaHash, schema, fc);
-
- if (hashed && NULL != schema.p)
- {
- MgUtil::FormatQualifiedClassName(schema->GetName(), className, lfeatureName);
- }
-
- MgCoordinateSystemFactory fact;
- std::wstring wkt = srs;
- if (wkt.empty())
- {
- //If there is no coordinate system pass in, get the default one in resource header.
- MgServiceManager* serviceMan = MgServiceManager::GetInstance();
- assert(NULL != serviceMan);
- Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(serviceMan->RequestService(MgServiceType::ResourceService));
- assert(resourceService != NULL);
- Ptr<MgByteReader> byteReaderHeader = resourceService->GetResourceHeader(fs);
- Ptr<MgByteSink> byteSinkHeader = new MgByteSink(byteReaderHeader);
- std::string resourceHeader;
- byteSinkHeader->ToStringUtf8(resourceHeader);
- //parse for default SRS of this WFS, the format is:
- //<Property xsi:noNamespaceSchemaLocation="Property-1.0.0.xsd">
- // <Name>_PrimarySRS</Name>
- // <Value>EPSG:4326</Value>
- //</Property>
- std::string primary("<Name>_PrimarySRS</Name>");
- std::size_t primaryPos = resourceHeader.find(primary);
- if (primaryPos != std::string::npos)
- {
- std::string begin("<Value>EPSG:");
- std::size_t beginPos = resourceHeader.find(begin, primaryPos);
- if (beginPos != std::string::npos)
- {
- std::size_t endPos = resourceHeader.find("</Value>", beginPos);
- if (endPos != std::string::npos)
- {
- std::string primarySRS = resourceHeader.substr(beginPos+begin.length(), endPos-beginPos-begin.length());
- int epsgCode = atoi(primarySRS.c_str());
- wkt = fact.ConvertEpsgCodeToWkt(epsgCode);
- }
- }
- }
- }
-
- Ptr<MgCoordinateSystem> mapCs = NULL;
- if (!wkt.empty())
- {
- MG_TRY();
- mapCs = fact.Create(wkt);
- MG_CATCH_AND_RELEASE();
- }
-
- //get a transform from feature space to mapping space
- TransformCache* item = TransformCache::GetLayerToMapTransform(transformCache, lfeatureName, fs, mapCs, &fact, this, false);
- Ptr<MgCoordinateSystemTransform> trans = item? item->GetMgTransform() : NULL;
FdoPtr<MgGMLCsTransform> transform = new MgGMLCsTransform(trans);
- assert(fc != NULL);
- if (fc == NULL)
- return NULL;
-
- //execute the spatial query
- Ptr<MgFeatureQueryOptions> options = new MgFeatureQueryOptions();
-
- //add the properties we need from FDO
- if (propNames)
- {
- for (int i=0; i<propNames->GetCount(); i++)
- options->AddFeatureProperty(propNames->GetItem(i));
- }
-
- //convert the WFS filter to an FDO filter
- //and set it to the FDO feature query
- if (!wfsFilter.empty())
- {
- STRING GEOM_PROP_TAG = L"%MG_GEOM_PROP%"; //NOXLATE
- STRING fdoFilterString = L""; //NOXLATE
-
- Ptr<MgPropertyDefinitionCollection> properties = fc->GetProperties();
- MgOgcFilterUtil u;
-
- for(int i = 0; i<properties->GetCount(); i++)
- {
- Ptr<MgPropertyDefinition> prop = properties->GetItem(i);
- if(prop->GetPropertyType() == MgFeaturePropertyType::GeometricProperty)
- {
- STRING ogcFilter = wfsFilter;
-
- if(wfsFilter.find(GEOM_PROP_TAG, 0) != STRING::npos)
- {
- ogcFilter = MgUtil::ReplaceString(wfsFilter,GEOM_PROP_TAG.c_str(),prop->GetName().c_str());
- }
- if(!fdoFilterString.empty())
- {
- fdoFilterString += L" OR "; //NOXLATE
- }
- TransformCache* itemFilter = TransformCache::GetLayerToMapTransform(transformCache, lfeatureName, fs, mapCs, &fact, this, true);
- Ptr<MgCoordinateSystemTransform> transFilter = itemFilter? itemFilter->GetMgTransform() : NULL;
- fdoFilterString += u.Ogc2FdoFilter(ogcFilter, transFilter, prop->GetName(), properties);
- }
- }
-
- options->SetFilter(fdoFilterString);
- }
-
- if(!sortCriteria.empty())
- {
- Ptr<MgStringCollection> orderByProperties = new MgStringCollection();
- int orderOption = MgOrderingOption::Ascending;
-
- STRING sSortCriteria = sortCriteria;
- STRING::size_type pos = sSortCriteria.find_last_of(L" ");
- if(pos != STRING::npos)
- {
- STRING sSortByProperty = sSortCriteria.substr(0, pos);
- orderByProperties->Add(sSortByProperty);
-
- STRING sSortOption = MgUtil::ToUpper(sSortCriteria.substr(pos+1));
- if(sSortOption == L"D")
- {
- orderOption = MgOrderingOption::Descending;
- }
- }
- else
- {
- orderByProperties->Add(sortCriteria);
- }
-
- options->SetOrderingFilter(orderByProperties,orderOption);
- }
- // TODO: can FeatureName be an extension name rather than a FeatureClass?
- Ptr<MgFeatureReader> mgfReader = SelectFeatures(fs, lfeatureName, options);
-
//get underlying FDO feature reader
FdoPtr<FdoIFeatureReader> fdoReader = (NULL == mgfReader.p) ? NULL : ((MgServerFeatureReader*)(mgfReader.p))->GetInternalReader();
@@ -2394,12 +2273,8 @@
src->SetMimeType(MgMimeType::Xml);
byteReader = src->GetReader();
- MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH(fs, L"MgServerFeatureService.GetWfsFeature")
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(fs, L"MgServerFeatureService.GetWfsFeature")
- TransformCache::Clear(transformCache);
-
- MG_FEATURE_SERVICE_THROW()
-
return byteReader.Detach();
}
Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -23,8 +23,12 @@
#include <set>
+class MgWfsQueryAdapter;
+
class MG_SERVER_FEATURE_API MgServerFeatureService : public MgFeatureService
{
+ friend class MgWfsQueryAdapter;
+
DECLARE_CLASSNAME(MgServerFeatureService)
public:
@@ -941,6 +945,13 @@
CREFSTRING filter,
INT32 maxFeatures);
+ MgFeatureReader* GetWfsReader(MgResourceIdentifier* featureSourceId,
+ CREFSTRING featureClass,
+ MgStringCollection* requiredProperties,
+ CREFSTRING srs,
+ CREFSTRING filter,
+ CREFSTRING sortCriteria);
+
////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// This method enumerates all the providers and if they are FDO enabled for
Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcxproj
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcxproj 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcxproj 2017-11-26 22:22:40 UTC (rev 9256)
@@ -415,6 +415,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
+ <ClCompile Include="OpGetWfsReader.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
<ClCompile Include="OpInsertFeatures.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -816,6 +822,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
+ <ClCompile Include="WfsQueryAdapter.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="FdoForcedOneToOneFeatureReader.h" />
@@ -852,6 +864,7 @@
<ClInclude Include="OpGetSpatialContexts.h" />
<ClInclude Include="OpGetSqlRows.h" />
<ClInclude Include="OpGetWfsFeature.h" />
+ <ClInclude Include="OpGetWfsReader.h" />
<ClInclude Include="OpInsertFeatures.h" />
<ClInclude Include="OpInsertFeaturesBatched.h" />
<ClInclude Include="OpReleaseSavePoint.h" />
@@ -885,6 +898,7 @@
<ClInclude Include="FeatureStringFunctions.h" />
<ClInclude Include="FilterUtil.h" />
<ClInclude Include="GeometryDataReaderCreator.h" />
+ <ClInclude Include="WfsQueryAdapter.h" />
<CustomBuildStep Include="GwsConnectionPool.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcxproj.filters
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcxproj.filters 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcxproj.filters 2017-11-26 22:22:40 UTC (rev 9256)
@@ -201,6 +201,10 @@
<Filter>Ops</Filter>
</ClCompile>
<ClCompile Include="TransformedGeometryFeatureReader.cpp" />
+ <ClCompile Include="OpGetWfsReader.cpp">
+ <Filter>Ops</Filter>
+ </ClCompile>
+ <ClCompile Include="WfsQueryAdapter.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="FeatureOperation.h">
@@ -411,6 +415,10 @@
<Filter>Ops</Filter>
</ClInclude>
<ClInclude Include="TransformedGeometryFeatureReader.h" />
+ <ClInclude Include="OpGetWfsReader.h">
+ <Filter>Ops</Filter>
+ </ClInclude>
+ <ClInclude Include="WfsQueryAdapter.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ServerFeatureService.rc" />
Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureServiceBuild.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -86,7 +86,9 @@
#include "OpGetIdentityProperties.cpp"
#include "OpDescribeWfsFeatureType.cpp"
#include "OpGetWfsFeature.cpp"
+#include "OpGetWfsReader.cpp"
#include "FilterUtil.cpp"
+#include "WfsQueryAdapter.cpp"
#include "ServerGwsFeatureReader.cpp"
#include "GwsConnectionPool.cpp"
#include "OpEnumerateDataStores.cpp"
@@ -111,4 +113,4 @@
#include "OpInsertFeaturesBatched.cpp"
#include "OpUpdateMatchingFeatures.cpp"
#include "OpDeleteFeatures.cpp"
-#include "TransformedGeometryFeatureReader.cpp"
+#include "TransformedGeometryFeatureReader.cpp"
\ No newline at end of file
Copied: trunk/MgDev/Server/src/Services/Feature/WfsQueryAdapter.cpp (from rev 9255, sandbox/jng/ogc/Server/src/Services/Feature/WfsQueryAdapter.cpp)
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/WfsQueryAdapter.cpp (rev 0)
+++ trunk/MgDev/Server/src/Services/Feature/WfsQueryAdapter.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -0,0 +1,216 @@
+//
+// Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "ServerFeatureServiceDefs.h"
+#include "WfsQueryAdapter.h"
+
+MgWfsQueryAdapter::MgWfsQueryAdapter(MgServerFeatureService* featSvc)
+{
+ m_featSvc = SAFE_ADDREF(featSvc);
+}
+
+MgWfsQueryAdapter::~MgWfsQueryAdapter()
+{
+ TransformCache::Clear(m_transformCache);
+ m_classDef = NULL;
+ m_fs = NULL;
+ m_options = NULL;
+ m_featSvc = NULL;
+ m_mapCs = NULL;
+ m_xform = NULL;
+}
+
+bool MgWfsQueryAdapter::SetOptions(MgResourceIdentifier* fs,
+ CREFSTRING featureClass,
+ MgStringCollection* propNames,
+ CREFSTRING srs,
+ CREFSTRING wfsFilter,
+ CREFSTRING sortCriteria)
+{
+ m_fs = SAFE_ADDREF(fs);
+ m_className = featureClass;
+ STRING schemaName, className;
+ MgUtil::ParseQualifiedClassName(m_className, schemaName, className);
+
+ bool hashed = (0 == schemaName.find_first_of(MG_SCHEMA_NAME_HASH_PREFIX.c_str(), 0, MG_SCHEMA_NAME_HASH_PREFIX.length()));
+ Ptr<MgStringCollection> classNames = new MgStringCollection();
+
+ if (!className.empty())
+ {
+ classNames->Add(className);
+ }
+
+ // Find the needed class definition.
+ Ptr<MgFeatureSchemaCollection> fsc = m_featSvc->DescribeSchema(m_fs, hashed ? L"" : schemaName, classNames);
+ Ptr<MgFeatureSchema> schema;
+ STRING schemaHash;
+
+ m_featSvc->FindClassDefinition(fsc, schemaName, className, schemaHash, schema, m_classDef);
+
+ if (hashed && NULL != schema.p)
+ {
+ MgUtil::FormatQualifiedClassName(schema->GetName(), className, m_className);
+ }
+
+ MgCoordinateSystemFactory fact;
+ std::wstring wkt = srs;
+ if (wkt.empty())
+ {
+ //If there is no coordinate system pass in, get the default one in resource header.
+ MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+ assert(NULL != serviceMan);
+ Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(serviceMan->RequestService(MgServiceType::ResourceService));
+ assert(resourceService != NULL);
+ Ptr<MgByteReader> byteReaderHeader = resourceService->GetResourceHeader(m_fs);
+ Ptr<MgByteSink> byteSinkHeader = new MgByteSink(byteReaderHeader);
+ std::string resourceHeader;
+ byteSinkHeader->ToStringUtf8(resourceHeader);
+ //parse for default SRS of this WFS, the format is:
+ //<Property xsi:noNamespaceSchemaLocation="Property-1.0.0.xsd">
+ // <Name>_PrimarySRS</Name>
+ // <Value>EPSG:4326</Value>
+ //</Property>
+ std::string primary("<Name>_PrimarySRS</Name>");
+ std::size_t primaryPos = resourceHeader.find(primary);
+ if (primaryPos != std::string::npos)
+ {
+ std::string begin("<Value>EPSG:");
+ std::size_t beginPos = resourceHeader.find(begin, primaryPos);
+ if (beginPos != std::string::npos)
+ {
+ std::size_t endPos = resourceHeader.find("</Value>", beginPos);
+ if (endPos != std::string::npos)
+ {
+ std::string primarySRS = resourceHeader.substr(beginPos + begin.length(), endPos - beginPos - begin.length());
+ int epsgCode = atoi(primarySRS.c_str());
+ wkt = fact.ConvertEpsgCodeToWkt(epsgCode);
+ }
+ }
+ }
+ }
+
+ if (!wkt.empty())
+ {
+ MG_TRY();
+ m_mapCs = fact.Create(wkt);
+ MG_CATCH_AND_RELEASE();
+ }
+
+ //get a transform from feature space to mapping space
+ TransformCache* item = TransformCache::GetLayerToMapTransform(m_transformCache, m_className, m_fs, m_mapCs, &fact, m_featSvc, false);
+ m_xform = item ? item->GetMgTransform() : NULL;
+
+ assert(m_classDef.p != NULL);
+ if (NULL == m_classDef.p)
+ return false;
+
+ //execute the spatial query
+ Ptr<MgFeatureQueryOptions> options = new MgFeatureQueryOptions();
+
+ //add the properties we need from FDO
+ if (propNames)
+ {
+ for (int i = 0; i<propNames->GetCount(); i++)
+ options->AddFeatureProperty(propNames->GetItem(i));
+ }
+
+ //convert the WFS filter to an FDO filter
+ //and set it to the FDO feature query
+ if (!wfsFilter.empty())
+ {
+ STRING GEOM_PROP_TAG = L"%MG_GEOM_PROP%"; //NOXLATE
+ STRING fdoFilterString = L""; //NOXLATE
+
+ Ptr<MgPropertyDefinitionCollection> properties = m_classDef->GetProperties();
+ MgOgcFilterUtil u;
+
+ for (int i = 0; i<properties->GetCount(); i++)
+ {
+ Ptr<MgPropertyDefinition> prop = properties->GetItem(i);
+ if (prop->GetPropertyType() == MgFeaturePropertyType::GeometricProperty)
+ {
+ STRING ogcFilter = wfsFilter;
+
+ if (wfsFilter.find(GEOM_PROP_TAG, 0) != STRING::npos)
+ {
+ ogcFilter = MgUtil::ReplaceString(wfsFilter, GEOM_PROP_TAG.c_str(), prop->GetName().c_str());
+ }
+ if (!fdoFilterString.empty())
+ {
+ fdoFilterString += L" OR "; //NOXLATE
+ }
+ TransformCache* itemFilter = TransformCache::GetLayerToMapTransform(m_transformCache, m_className, m_fs, m_mapCs, &fact, m_featSvc, true);
+ Ptr<MgCoordinateSystemTransform> transFilter = itemFilter ? itemFilter->GetMgTransform() : NULL;
+ fdoFilterString += u.Ogc2FdoFilter(ogcFilter, transFilter, prop->GetName(), properties);
+ }
+ }
+
+ options->SetFilter(fdoFilterString);
+ }
+
+ if (!sortCriteria.empty())
+ {
+ Ptr<MgStringCollection> orderByProperties = new MgStringCollection();
+ int orderOption = MgOrderingOption::Ascending;
+
+ STRING sSortCriteria = sortCriteria;
+ STRING::size_type pos = sSortCriteria.find_last_of(L" ");
+ if (pos != STRING::npos)
+ {
+ STRING sSortByProperty = sSortCriteria.substr(0, pos);
+ orderByProperties->Add(sSortByProperty);
+
+ STRING sSortOption = MgUtil::ToUpper(sSortCriteria.substr(pos + 1));
+ if (sSortOption == L"D")
+ {
+ orderOption = MgOrderingOption::Descending;
+ }
+ }
+ else
+ {
+ orderByProperties->Add(sortCriteria);
+ }
+
+ options->SetOrderingFilter(orderByProperties, orderOption);
+ }
+ return true;
+}
+
+MgClassDefinition* MgWfsQueryAdapter::GetClassDefinition()
+{
+ return SAFE_ADDREF(m_classDef.p);
+}
+
+MgCoordinateSystemTransform* MgWfsQueryAdapter::GetTransform()
+{
+ return SAFE_ADDREF(m_xform.p);
+}
+
+MgCoordinateSystem* MgWfsQueryAdapter::GetMapCs()
+{
+ return SAFE_ADDREF(m_mapCs.p);
+}
+
+MgFeatureReader* MgWfsQueryAdapter::GetWfsReader()
+{
+ Ptr<MgFeatureReader> fr;
+ MG_FEATURE_SERVICE_TRY()
+ // TODO: can FeatureName be an extension name rather than a FeatureClass?
+ fr = m_featSvc->SelectFeatures(m_fs, m_className, m_options);
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(m_fs, L"MgWfsQueryAdapter.GetWfsReader")
+ return fr.Detach();
+}
\ No newline at end of file
Copied: trunk/MgDev/Server/src/Services/Feature/WfsQueryAdapter.h (from rev 9255, sandbox/jng/ogc/Server/src/Services/Feature/WfsQueryAdapter.h)
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/WfsQueryAdapter.h (rev 0)
+++ trunk/MgDev/Server/src/Services/Feature/WfsQueryAdapter.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -0,0 +1,52 @@
+//
+// Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_WFS_QUERY_ADAPTER_H_
+#define _MG_WFS_QUERY_ADAPTER_H_
+
+class MgServerFeatureService;
+
+// This is a helper class that contains most of the boilerplate for translating WFS GetFeature request parameters
+// to our feature service queries
+class MgWfsQueryAdapter
+{
+public:
+ MgWfsQueryAdapter(MgServerFeatureService* featSvc);
+ ~MgWfsQueryAdapter();
+ bool SetOptions(MgResourceIdentifier* fs,
+ CREFSTRING featureClass,
+ MgStringCollection* propNames,
+ CREFSTRING srs,
+ CREFSTRING wfsFilter,
+ CREFSTRING sortCriteria);
+ MgFeatureReader* GetWfsReader();
+ MgCoordinateSystem* GetMapCs();
+ MgCoordinateSystemTransform* GetTransform();
+ MgClassDefinition* GetClassDefinition();
+
+private:
+ Ptr<MgClassDefinition> m_classDef;
+ Ptr<MgResourceIdentifier> m_fs;
+ Ptr<MgFeatureQueryOptions> m_options;
+ Ptr<MgServerFeatureService> m_featSvc;
+ Ptr<MgCoordinateSystem> m_mapCs;
+ Ptr<MgCoordinateSystemTransform> m_xform;
+ STRING m_className;
+ TransformCacheMap m_transformCache;
+};
+
+#endif
\ No newline at end of file
Modified: trunk/MgDev/Server/src/Services/Kml/ServerKmlService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Kml/ServerKmlService.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Kml/ServerKmlService.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -480,7 +480,7 @@
if (NULL != fdoReader.p)
{
- RS_FeatureClassInfo fcInfo(vl->GetFeatureName(), vl->GetResourceID());
+ RS_FeatureClassInfo fcInfo(vl->GetFeatureName(), vl->GetResourceID(), vl->GetGeometry());
MdfModel::NameStringPairCollection* pmappings = vl->GetPropertyMappings();
for (int j=0; j<pmappings->GetCount(); j++)
{
Modified: trunk/MgDev/Server/src/Services/Mapping/MappingUtil.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/MappingUtil.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Mapping/MappingUtil.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -549,7 +549,7 @@
//string the viewer should be displaying as the name of each
//feature property
// TODO: check to see if name is FeatureClass or Extension name
- RS_FeatureClassInfo fcinfo(vl->GetFeatureName(), vl->GetResourceID());
+ RS_FeatureClassInfo fcinfo(vl->GetFeatureName(), vl->GetResourceID(), vl->GetGeometry());
MdfModel::NameStringPairCollection* pmappings = vl->GetPropertyMappings();
for (int j=0; j<pmappings->GetCount(); j++)
@@ -661,7 +661,7 @@
//string the viewer should be displaying as the name of each
//feature property
// TODO: check to see if name is FeatureClass or Extension name
- RS_FeatureClassInfo fcinfo(gl->GetFeatureName(), gl->GetResourceID());
+ RS_FeatureClassInfo fcinfo(gl->GetFeatureName(), gl->GetResourceID(), gl->GetGeometry());
//check for overridden feature query filter and remember it.
//we will use this when making feature queries
Property changes on: trunk/MgDev/Server/src/Services/Mapping/MappingUtil.cpp
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/2.4/MgDev/Server/src/Services/Mapping/MappingUtil.cpp:6738-6741,6749-6756,6777-6783,6785-6787,6789,6791-6794,6796-6801,6954-6962,6986-7006
/branches/2.6/MgDev/Server/src/Services/Mapping/MappingUtil.cpp:8365
/sandbox/adsk/2.4j/Server/src/Services/Mapping/MappingUtil.cpp:6327-6535
/sandbox/adsk/3.1n/Server/src/Services/Mapping/MappingUtil.cpp:8942
/sandbox/jng/clean_json/Server/src/Services/Mapping/MappingUtil.cpp:8818-9180
/sandbox/jng/createruntimemap/Server/src/Services/Mapping/MappingUtil.cpp:7486-7555
/sandbox/rfc94/Server/src/Services/Mapping/MappingUtil.cpp:5099-5163
+ /branches/2.4/MgDev/Server/src/Services/Mapping/MappingUtil.cpp:6738-6741,6749-6756,6777-6783,6785-6787,6789,6791-6794,6796-6801,6954-6962,6986-7006
/branches/2.6/MgDev/Server/src/Services/Mapping/MappingUtil.cpp:8365
/sandbox/adsk/2.4j/Server/src/Services/Mapping/MappingUtil.cpp:6327-6535
/sandbox/adsk/3.1n/Server/src/Services/Mapping/MappingUtil.cpp:8942
/sandbox/jng/clean_json/Server/src/Services/Mapping/MappingUtil.cpp:8818-9180
/sandbox/jng/createruntimemap/Server/src/Services/Mapping/MappingUtil.cpp:7486-7555
/sandbox/jng/ogc/Server/src/Services/Mapping/MappingUtil.cpp:9240-9255
/sandbox/rfc94/Server/src/Services/Mapping/MappingUtil.cpp:5099-5163
Modified: trunk/MgDev/Server/src/Services/Rendering/FeaturePropRenderer.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/FeaturePropRenderer.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Rendering/FeaturePropRenderer.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -24,9 +24,11 @@
#define SPECIAL_PROP_LAYER_NAME L"_MgLayerName"
#define SPECIAL_PROP_BOUNDING_BOX L"_MgFeatureBoundingBox"
+#define SPECIAL_PROP_GEOMETRY L"_MgGeometry"
FeaturePropRenderer::FeaturePropRenderer(MgSelection* selection, int maxFeatures, double mapScale, bool bIncludeFeatureBBOX)
-: FeatureInfoRenderer(selection, maxFeatures, mapScale)
+: FeatureInfoRenderer(selection, maxFeatures, mapScale),
+ m_bCaptureGeometry(false)
{
m_featprops = new MgBatchPropertyCollection();
m_currentFeature = NULL;
@@ -93,6 +95,47 @@
featureProps->Add(boundingBoxProperty);
}
+ //Add geometry if we're instructed to capture it
+ if (m_bCaptureGeometry)
+ {
+ FdoPtr<FdoIFeatureReader> fr = feature->GetInternalReader();
+ const FdoString* geomName = m_fcInfo->geometry().c_str();
+ Ptr<MgGeometryProperty> geomProp = new MgGeometryProperty();
+ //Not using geometry prop name here as we want to specially denote the designated geometry value
+ geomProp->SetName(SPECIAL_PROP_GEOMETRY);
+ try
+ {
+ if (!fr->IsNull(geomName))
+ {
+ FdoInt32 len = 0;
+ const FdoByte* data = fr->GetGeometry(geomName, &len);
+
+ if (data != NULL)
+ {
+ Ptr<MgByte> mgBytes = new MgByte((BYTE_ARRAY_IN)data, len);
+ Ptr<MgByteSource> bSource = new MgByteSource(mgBytes);
+ bSource->SetMimeType(MgMimeType::Agf);
+ Ptr<MgByteReader> agf = bSource->GetReader();
+ geomProp->SetValue(agf);
+ }
+ else
+ {
+ geomProp->SetNull(true);
+ }
+ }
+ else
+ {
+ geomProp->SetNull(true);
+ }
+ }
+ catch (FdoException* ex)
+ {
+ FDO_SAFE_RELEASE(ex);
+ }
+
+ featureProps->Add(geomProp);
+ }
+
//for each property in the property mapping, add to the
//return property collection
@@ -175,6 +218,11 @@
bbox->SetValue(val);
}
+void FeaturePropRenderer::SetGeometryCapture(bool bCaptureGeometry)
+{
+ m_bCaptureGeometry = bCaptureGeometry;
+}
+
void FeaturePropRenderer::ProcessPolygon(LineBuffer* lb,
RS_FillStyle& fill)
{
Modified: trunk/MgDev/Server/src/Services/Rendering/FeaturePropRenderer.h
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/FeaturePropRenderer.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Rendering/FeaturePropRenderer.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -74,6 +74,8 @@
void GetGeometryBounds(const LineBuffer* lb, RS_Bounds& bounds);
void SetBBOXProperty(const RS_Bounds& bounds, MgStringProperty* bbox);
+ void SetGeometryCapture(bool bCaptureGeometry);
+
MgBatchPropertyCollection* GetProperties()
{
return SAFE_ADDREF(m_featprops);
@@ -83,6 +85,7 @@
MgBatchPropertyCollection* m_featprops;
MgPropertyCollection* m_currentFeature;
bool m_bIncludeFeatureBBOX;
+ bool m_bCaptureGeometry;
};
#endif
Modified: trunk/MgDev/Server/src/Services/Rendering/OpQueryFeatureProperties.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/OpQueryFeatureProperties.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Rendering/OpQueryFeatureProperties.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -60,7 +60,7 @@
ACE_ASSERT(m_stream != NULL);
- if (7 == m_packet.m_NumArguments || 8 == m_packet.m_NumArguments)
+ if (7 == m_packet.m_NumArguments || 8 == m_packet.m_NumArguments || 9 == m_packet.m_NumArguments)
{
Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
Ptr<MgResourceIdentifier> resource = map->GetResourceId();
@@ -82,10 +82,15 @@
m_stream->GetInt32(layerAttributeFilter);
bool bIncludeFeatureBBOX = false;
- if (8 == m_packet.m_NumArguments)
+ if (8 <= m_packet.m_NumArguments)
{
m_stream->GetBoolean(bIncludeFeatureBBOX);
}
+ bool bIncludeGeometry = false;
+ if (9 == m_packet.m_NumArguments)
+ {
+ m_stream->GetBoolean(bIncludeGeometry);
+ }
BeginExecution();
MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
@@ -102,19 +107,29 @@
MG_LOG_OPERATION_MESSAGE_ADD_INT32(maxFeatures);
MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
MG_LOG_OPERATION_MESSAGE_ADD_INT32(layerAttributeFilter);
- if (8 == m_packet.m_NumArguments)
+ if (8 <= m_packet.m_NumArguments)
{
MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
MG_LOG_OPERATION_MESSAGE_ADD_BOOL(bIncludeFeatureBBOX);
}
+ if (9 == m_packet.m_NumArguments)
+ {
+ MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+ MG_LOG_OPERATION_MESSAGE_ADD_BOOL(bIncludeGeometry);
+ }
MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
Validate();
Ptr<MgBatchPropertyCollection> info;
- if (8 == m_packet.m_NumArguments)
+ if (9 == m_packet.m_NumArguments)
{
info = m_service->QueryFeatureProperties(map, layerNames, geom, selectionVariant,
+ featureFilter, maxFeatures, layerAttributeFilter, bIncludeFeatureBBOX, bIncludeGeometry);
+ }
+ else if (8 == m_packet.m_NumArguments)
+ {
+ info = m_service->QueryFeatureProperties(map, layerNames, geom, selectionVariant,
featureFilter, maxFeatures, layerAttributeFilter, bIncludeFeatureBBOX);
}
else
Modified: trunk/MgDev/Server/src/Services/Rendering/RenderingOperationFactory.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/RenderingOperationFactory.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Rendering/RenderingOperationFactory.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -260,6 +260,17 @@
L"MgRenderingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
}
break;
+ case MgRenderingServiceOpId::QueryFeatureProperties3:
+ switch (VERSION_NO_PHASE(operationVersion))
+ {
+ case VERSION_SUPPORTED(3, 3):
+ handler.reset(new MgOpQueryFeatureProperties());
+ break;
+ default:
+ throw new MgInvalidOperationVersionException(
+ L"MgRenderingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+ break;
case MgRenderingServiceOpId::RenderMapLegend:
switch (VERSION_NO_PHASE(operationVersion))
{
Modified: trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -1328,6 +1328,20 @@
INT32 layerAttributeFilter,
bool bIncludeFeatureBBOX)
{
+ return QueryFeatureProperties(map, layerNames, filterGeometry, selectionVariant, L"", maxFeatures, layerAttributeFilter, bIncludeFeatureBBOX, false);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+MgBatchPropertyCollection* MgServerRenderingService::QueryFeatureProperties(MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant, // Within, Touching, Topmost
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX,
+ bool bIncludeGeometry)
+{
Ptr<MgBatchPropertyCollection> ret;
MG_TRY()
@@ -1339,6 +1353,8 @@
Ptr<MgSelection> sel; //TODO: do we need this for this API? new MgSelection(map);
FeaturePropRenderer fpr(sel, maxFeatures, map->GetViewScale(), bIncludeFeatureBBOX);
+ fpr.SetGeometryCapture(bIncludeGeometry);
+
RenderForSelection(map, layerNames, filterGeometry, selectionVariant, featureFilter, maxFeatures, layerAttributeFilter, &fpr);
ret = fpr.GetProperties();
@@ -1901,7 +1917,7 @@
//string the viewer should be displaying as the name of each
//feature property
// TODO: can FeatureName be an extension name rather than a FeatureClass?
- RS_FeatureClassInfo fcinfo(vl->GetFeatureName(), vl->GetResourceID());
+ RS_FeatureClassInfo fcinfo(vl->GetFeatureName(), vl->GetResourceID(), vl->GetGeometry());
MdfModel::NameStringPairCollection* pmappings = vl->GetPropertyMappings();
for (int i=0; i<pmappings->GetCount(); i++)
Modified: trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.h
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -232,6 +232,17 @@
INT32 layerAttributeFilter,
bool bIncludeFeatureBBOX);
+ virtual MgBatchPropertyCollection* QueryFeatureProperties(
+ MgMap* map,
+ MgStringCollection* layerNames,
+ MgGeometry* filterGeometry,
+ INT32 selectionVariant,
+ CREFSTRING featureFilter,
+ INT32 maxFeatures,
+ INT32 layerAttributeFilter,
+ bool bIncludeFeatureBBOX,
+ bool bIncludeGeometry);
+
private:
static void ComputeXYZTileExtents(MgMap* map, INT32 x, INT32 y, INT32 z, RS_Bounds& extent);
// used for tile generation
Modified: trunk/MgDev/Server/src/Wfs/OgcWfsService.config.awd
===================================================================
--- trunk/MgDev/Server/src/Wfs/OgcWfsService.config.awd 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Wfs/OgcWfsService.config.awd 2017-11-26 22:22:40 UTC (rev 9256)
@@ -158,6 +158,7 @@
<item>text/xml; subtype=gml/2.1.2</item>
<item>GML3</item>
<item>text/xml; subtype=gml/3.1.1</item>
+ <item>application/json</item>
</Define>
<Define item="Formats.GetFeature.default.1.0.0">text/xml; subtype=gml/2.1.2</Define>
Modified: trunk/MgDev/Server/src/Wms/1.0.0.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.0.0.xml.awd 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Wms/1.0.0.xml.awd 2017-11-26 22:22:40 UTC (rev 9256)
@@ -75,6 +75,7 @@
<FeatureInfo>
<?Endif?>
<?EnumFeatureProperties using="&FeatureProperty.xml;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.xml;" ?>
</FeatureInfo>
</Define>
@@ -83,6 +84,7 @@
<td>
<table>
<?EnumFeatureProperties using="&FeatureProperty.html;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.html;" ?>
</table>
</td>
</tr>
@@ -91,9 +93,16 @@
<Define item="FeatureInfo.text">
FeatureInfo:
<?EnumFeatureProperties using="&FeatureProperty.text;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.text;" ?>
</Define>
+ <Define item="FeatureInfo.json">{
+ "type": "Feature",
+ "properties": {<?EnumFeatureProperties using="&FeatureProperty.json;" ?>}
+ <?EnumFeatureGeometries using="&FeatureGeometry.json;" ?>
+}<?If l="&FeatureInfo.IsLast" op="eq" r="0"?>,<?Endif?></Define>
+
<Define item="FeatureProperty.xml">
<Property name="&FeatureProperty.Name;" value="&FeatureProperty.Value;"></Property>
</Define>
@@ -117,7 +126,25 @@
<Define item="Layer.Title">(Untitled Layer)</Define>
<Define item="Layer.Abstract"></Define>
<Define item="Layer.Name"></Define>
+ <!-- Output all non-geometry properties -->
+ <Define item="FeatureProperty.json">"&FeatureProperty.Name;": "&FeatureProperty.Value;"<?If l="&FeatureProperty.IsLast" op="eq" r="0"?>,<?Endif?></Define>
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.json">,"geometry": &FeatureGeometry.Value;</Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.text">Geometry=&FeatureGeometry.Value;</Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.html">
+ <tr><td class="name">Geometry</td><td>&FeatureGeometry.Value;</td></tr>
+ </Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.xml">
+ <Property name="Geometry" value="&FeatureGeometry.Value;"></Property>
+ </Define>
+
<!-- We're currently not supporting child layers... -->
<Define item="Layer.Sublayers"></Define>
@@ -355,9 +382,10 @@
<html>
<head>
<title>GetFeatureInfo</title>
+&html.stylesheet;
</head>
<body>
-<table border="1">
+<table>
<?EnumFeatureInfo using="&FeatureInfo.html;" ?>
</table>
</body>
@@ -374,7 +402,16 @@
<?EnumFeatureInfo using="&FeatureInfo.text;" ?>
</Response>
+<!--
+ WMS GetFeatureInfo - (Geo)JSON
+
+-->
+<Response request="GetFeatureInfo" content-type="application/json">{
+ "type": "FeatureCollection",
+ "features": [<?EnumFeatureInfo using="&FeatureInfo.json;" ?>]
+}</Response>
+
<!--
Exception format - XML
Modified: trunk/MgDev/Server/src/Wms/1.1.0.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.1.0.xml.awd 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Wms/1.1.0.xml.awd 2017-11-26 22:22:40 UTC (rev 9256)
@@ -77,6 +77,7 @@
<FeatureInfo>
<?Endif?>
<?EnumFeatureProperties using="&FeatureProperty.xml;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.xml;" ?>
</FeatureInfo>
</Define>
@@ -85,6 +86,7 @@
<td>
<table>
<?EnumFeatureProperties using="&FeatureProperty.html;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.html;" ?>
</table>
</td>
</tr>
@@ -93,9 +95,16 @@
<Define item="FeatureInfo.text">
FeatureInfo:
<?EnumFeatureProperties using="&FeatureProperty.text;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.text;" ?>
</Define>
+ <Define item="FeatureInfo.json">{
+ "type": "Feature",
+ "properties": {<?EnumFeatureProperties using="&FeatureProperty.json;" ?>}
+ <?EnumFeatureGeometries using="&FeatureGeometry.json;" ?>
+}<?If l="&FeatureInfo.IsLast" op="eq" r="0"?>,<?Endif?></Define>
+
<Define item="FeatureProperty.xml">
<Property name="&FeatureProperty.Name;" value="&FeatureProperty.Value;"></Property>
</Define>
@@ -123,6 +132,25 @@
<item>EPSG:4326</item>
</Define>
+ <!-- Output all non-geometry properties -->
+ <Define item="FeatureProperty.json">"&FeatureProperty.Name;": "&FeatureProperty.Value;"<?If l="&FeatureProperty.IsLast" op="eq" r="0"?>,<?Endif?></Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.json">,"geometry": &FeatureGeometry.Value;</Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.text">Geometry=&FeatureGeometry.Value;</Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.html">
+ <tr><td class="name">Geometry</td><td>&FeatureGeometry.Value;</td></tr>
+ </Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.xml">
+ <Property name="Geometry" value="&FeatureGeometry.Value;"></Property>
+ </Define>
+
<!-- We're currently not supporting child layers... -->
<Define item="Layer.Sublayers"></Define>
@@ -398,8 +426,17 @@
<?EnumFeatureInfo using="&FeatureInfo.text;" ?>
</Response>
+<!--
+ WMS GetFeatureInfo - (Geo)JSON
+-->
+<Response request="GetFeatureInfo" content-type="application/json">{
+ "type": "FeatureCollection",
+ "features": [<?EnumFeatureInfo using="&FeatureInfo.json;" ?>]
+}</Response>
+
+
<!--
Exception Format - XML
Modified: trunk/MgDev/Server/src/Wms/1.1.1.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.1.1.xml.awd 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Wms/1.1.1.xml.awd 2017-11-26 22:22:40 UTC (rev 9256)
@@ -78,6 +78,7 @@
<FeatureInfo>
<?Endif?>
<?EnumFeatureProperties using="&FeatureProperty.xml;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.xml;" ?>
</FeatureInfo>
</Define>
@@ -86,6 +87,7 @@
<td>
<table>
<?EnumFeatureProperties using="&FeatureProperty.html;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.html;" ?>
</table>
</td>
</tr>
@@ -94,9 +96,16 @@
<Define item="FeatureInfo.text">
FeatureInfo:
<?EnumFeatureProperties using="&FeatureProperty.text;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.text;" ?>
</Define>
+ <Define item="FeatureInfo.json">{
+ "type": "Feature",
+ "properties": {<?EnumFeatureProperties using="&FeatureProperty.json;" ?>}
+ <?EnumFeatureGeometries using="&FeatureGeometry.json;" ?>
+}<?If l="&FeatureInfo.IsLast" op="eq" r="0"?>,<?Endif?></Define>
+
<Define item="FeatureProperty.xml">
<Property name="&FeatureProperty.Name;" value="&FeatureProperty.Value;"></Property>
</Define>
@@ -109,6 +118,25 @@
&FeatureProperty.Name;=&FeatureProperty.Value;
</Define>
+ <!-- Output all non-geometry properties -->
+ <Define item="FeatureProperty.json">"&FeatureProperty.Name;": "&FeatureProperty.Value;"<?If l="&FeatureProperty.IsLast" op="eq" r="0"?>,<?Endif?></Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.json">,"geometry": &FeatureGeometry.Value;</Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.text">Geometry=&FeatureGeometry.Value;</Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.html">
+ <tr><td class="name">Geometry</td><td>&FeatureGeometry.Value;</td></tr>
+ </Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.xml">
+ <Property name="Geometry" value="&FeatureGeometry.Value;"></Property>
+ </Define>
+
<!-- We're currently not supporting child layers... -->
<Define item="Layer.Sublayers"></Define>
@@ -358,9 +386,10 @@
<html>
<head>
<title>GetFeatureInfo</title>
+&html.stylesheet;
</head>
<body>
-<table border="1">
+<table>
<?EnumFeatureInfo using="&FeatureInfo.html;" ?>
</table>
</body>
@@ -377,7 +406,17 @@
<?EnumFeatureInfo using="&FeatureInfo.text;" ?>
</Response>
+<!--
+ WMS GetFeatureInfo - (Geo)JSON
+
+-->
+<Response request="GetFeatureInfo" content-type="application/json">{
+ "type": "FeatureCollection",
+ "features": [<?EnumFeatureInfo using="&FeatureInfo.json;" ?>]
+}</Response>
+
+
<!--
Exception format - XML
Modified: trunk/MgDev/Server/src/Wms/1.3.0.xml.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/1.3.0.xml.awd 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Wms/1.3.0.xml.awd 2017-11-26 22:22:40 UTC (rev 9256)
@@ -88,6 +88,7 @@
<FeatureInfo>
<?Endif?>
<?EnumFeatureProperties using="&FeatureProperty.xml;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.xml;" ?>
</FeatureInfo>
</Define>
@@ -96,6 +97,7 @@
<td>
<table>
<?EnumFeatureProperties using="&FeatureProperty.html;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.html;" ?>
</table>
</td>
</tr>
@@ -104,9 +106,16 @@
<Define item="FeatureInfo.text">
FeatureInfo:
<?EnumFeatureProperties using="&FeatureProperty.text;" ?>
+ <?EnumFeatureGeometries using="&FeatureGeometry.text;" ?>
</Define>
+ <Define item="FeatureInfo.json">{
+ "type": "Feature",
+ "properties": {<?EnumFeatureProperties using="&FeatureProperty.json;" ?>}
+ <?EnumFeatureGeometries using="&FeatureGeometry.json;" ?>
+}<?If l="&FeatureInfo.IsLast" op="eq" r="0"?>,<?Endif?></Define>
+
<Define item="FeatureProperty.xml">
<Property name="&FeatureProperty.Name;" value="&FeatureProperty.Value;"></Property>
</Define>
@@ -119,6 +128,25 @@
&FeatureProperty.Name;=&FeatureProperty.Value;
</Define>
+ <!-- Output all non-geometry properties -->
+ <Define item="FeatureProperty.json">"&FeatureProperty.Name;": "&FeatureProperty.Value;"<?If l="&FeatureProperty.IsLast" op="eq" r="0"?>,<?Endif?></Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.json">,"geometry": &FeatureGeometry.Value;</Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.text">Geometry=&FeatureGeometry.Value;</Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.html">
+ <tr><td class="name">Geometry</td><td>&FeatureGeometry.Value;</td></tr>
+ </Define>
+
+ <!-- Only output if property name is the designated geometry -->
+ <Define item="FeatureGeometry.xml">
+ <Property name="Geometry" value="&FeatureGeometry.Value;"></Property>
+ </Define>
+
<!-- We're currently not supporting child layers... -->
<Define item="Layer.Sublayers"></Define>
@@ -365,9 +393,10 @@
<html>
<head>
<title>GetFeatureInfo</title>
+&html.stylesheet;
</head>
<body>
-<table border="1">
+<table>
<?EnumFeatureInfo using="&FeatureInfo.html;" ?>
</table>
</body>
@@ -384,7 +413,17 @@
<?EnumFeatureInfo using="&FeatureInfo.text;" ?>
</Response>
+<!--
+ WMS GetFeatureInfo - (Geo)JSON
+
+-->
+<Response request="GetFeatureInfo" content-type="application/json">{
+ "type": "FeatureCollection",
+ "features": [<?EnumFeatureInfo using="&FeatureInfo.json;" ?>]
+}</Response>
+
+
<!--
Exception format - XML
Modified: trunk/MgDev/Server/src/Wms/OgcWmsService.config.awd
===================================================================
--- trunk/MgDev/Server/src/Wms/OgcWmsService.config.awd 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Server/src/Wms/OgcWmsService.config.awd 2017-11-26 22:22:40 UTC (rev 9256)
@@ -180,6 +180,7 @@
<item>text/xml</item>
<item>text/html</item>
<item>text/plain</item>
+ <item>application/json</item>
</Define>
<!-- These are the supported Exception formats
Modified: trunk/MgDev/UnitTest/TestData/Wfs/WfsTest.dump
===================================================================
--- trunk/MgDev/UnitTest/TestData/Wfs/WfsTest.dump 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/UnitTest/TestData/Wfs/WfsTest.dump 2017-11-26 22:22:40 UTC (rev 9256)
@@ -239,6 +239,7 @@
<ows:Parameter>
<ows:Value>GML2</ows:Value>
<ows:Value>GML3</ows:Value>
+ <ows:Value>application/json</ows:Value>
<ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
</ows:Parameter>
@@ -330,6 +331,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -350,6 +352,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -370,6 +373,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -388,6 +392,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -406,6 +411,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -424,6 +430,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -440,6 +447,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -456,6 +464,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -522,6 +531,7 @@
<ows:Parameter>
<ows:Value>GML2</ows:Value>
<ows:Value>GML3</ows:Value>
+ <ows:Value>application/json</ows:Value>
<ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
</ows:Parameter>
@@ -613,6 +623,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -633,6 +644,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -653,6 +665,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -671,6 +684,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -689,6 +703,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -707,6 +722,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -723,6 +739,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -739,6 +756,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -805,6 +823,7 @@
<ows:Parameter>
<ows:Value>GML2</ows:Value>
<ows:Value>GML3</ows:Value>
+ <ows:Value>application/json</ows:Value>
<ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
</ows:Parameter>
@@ -896,6 +915,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -916,6 +936,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -936,6 +957,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -954,6 +976,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -972,6 +995,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -990,6 +1014,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1006,6 +1031,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1022,6 +1048,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1088,6 +1115,7 @@
<ows:Parameter>
<ows:Value>GML2</ows:Value>
<ows:Value>GML3</ows:Value>
+ <ows:Value>application/json</ows:Value>
<ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
</ows:Parameter>
@@ -1179,6 +1207,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1199,6 +1228,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1219,6 +1249,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1237,6 +1268,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1255,6 +1287,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1273,6 +1306,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1289,6 +1323,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1305,6 +1340,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1371,6 +1407,7 @@
<ows:Parameter>
<ows:Value>GML2</ows:Value>
<ows:Value>GML3</ows:Value>
+ <ows:Value>application/json</ows:Value>
<ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
</ows:Parameter>
@@ -1462,6 +1499,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1482,6 +1520,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1502,6 +1541,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1520,6 +1560,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1538,6 +1579,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1556,6 +1598,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1572,6 +1615,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
@@ -1588,6 +1632,7 @@
<wfs:OutputFormats>
<Format>GML2</Format>
<Format>GML3</Format>
+ <Format>application/json</Format>
<Format>text/xml; subtype=gml/2.1.2</Format>
<Format>text/xml; subtype=gml/3.1.1</Format>
</wfs:OutputFormats>
Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeatureinfowmsform.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeatureinfowmsform.html 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeatureinfowmsform.html 2017-11-26 22:22:40 UTC (rev 9256)
@@ -21,7 +21,7 @@
<p> Info Format:
<select name="INFO_FORMAT">
<option value="text/xml">text/xml</option>
-<option value="itext/html">text/html</option>
+<option value="text/html">text/html</option>
<option value="text/plain">text/plain</option>
</select>
<p> Map Layers (comma-separated):
Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeaturewfsform.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeaturewfsform.html 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getfeaturewfsform.html 2017-11-26 22:22:40 UTC (rev 9256)
@@ -30,6 +30,7 @@
<select name="OUTPUTFORMAT">
<option value="GML3">GML3</option>
<option value="GML2">GML2</option>
+<option value="application/json">application/json</option>
</select>
<p>
<input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
Modified: trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj 2017-11-26 22:22:40 UTC (rev 9256)
@@ -790,6 +790,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
+ <ClCompile Include="WmsFeatureGeometry.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
<ClCompile Include="WmsFeatureInfo.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -1108,6 +1114,7 @@
<ClInclude Include="WfsFeatureDefinitions.h" />
<ClInclude Include="WfsGetFeatureParams.h" />
<ClInclude Include="WmsFeatureInfo.h" />
+ <ClInclude Include="WmsFeatureGeometry.h" />
<ClInclude Include="WmsFeatureProperties.h" />
<ClInclude Include="WmsLayerDefinitions.h" />
<ClInclude Include="WmsMapUtil.h" />
Modified: trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters 2017-11-26 22:22:40 UTC (rev 9256)
@@ -416,6 +416,9 @@
<ClCompile Include="HttpGeoBoundary.cpp">
<Filter>GeoProcessing</Filter>
</ClCompile>
+ <ClCompile Include="WmsFeatureGeometry.cpp">
+ <Filter>Ogc</Filter>
+ </ClCompile>
<ClCompile Include="HttpCsTransformCoordinates.cpp">
<Filter>Coordinate System</Filter>
</ClCompile>
@@ -817,6 +820,9 @@
<ClInclude Include="HttpGeoBoundary.h">
<Filter>GeoProcessing</Filter>
</ClInclude>
+ <ClInclude Include="WmsFeatureGeometry.h">
+ <Filter>Ogc</Filter>
+ </ClInclude>
<ClInclude Include="HttpCsTransformCoordinates.h">
<Filter>Coordinate System</Filter>
</ClInclude>
Modified: trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -152,6 +152,7 @@
#include "WmsLayerDefinitions.cpp"
#include "WmsFeatureInfo.cpp"
#include "WmsFeatureProperties.cpp"
+#include "WmsFeatureGeometry.cpp"
#include "WfsFeatureDefinitions.cpp"
#include "XmlParser.cpp"
#include "Dictionary.cpp"
Modified: trunk/MgDev/Web/src/HttpHandler/HttpWfsGetFeature.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpWfsGetFeature.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/HttpWfsGetFeature.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -291,20 +291,37 @@
sSortCriteria = sSortCriteria.substr(pos+1);
}
- // Call the C++ API
- // NOTE: I updated the maxFeatures value from numFeaturesToRetrieve to numFeaturesToRetrieve-1
- // Because the MgServerFdoFeatureReader in MapGuide server uses -1 to mark empty, while MgWfsFeatures
- // in MapGuide web tier uses 0
- resultReader = featureService->GetWfsFeature(featureSourceId, ((sSchemaHash.size()==0) ? sClass : sSchemaHash + _(":") + sClass),
- requiredProperties, m_getFeatureParams->GetSrs(), filter, numFeaturesToRetrieve-1, sVersion, sOutputFormat, sSortCriteria, sPrefix, oFeatureTypes.GetNamespaceUrl());
+ //For GeoJSON, use the new GetWfsReader API
+ if (sOutputFormat == MgMimeType::Json)
+ {
+ // NOTE: This API doesn't accept WFS version, format and XML namepaces because these are GML-isms baked into the GetWfsFeature API itself, making
+ // it unsuitable for non-GML output, hence the need for this new GetWfsReader API
+ Ptr<MgFeatureReader> fr = featureService->GetWfsReader(featureSourceId, ((sSchemaHash.size() == 0) ? sClass : sSchemaHash + _(":") + sClass),
+ requiredProperties, m_getFeatureParams->GetSrs(), filter, sSortCriteria);
+
+ //MgByteSource owns this and will clean it up when done
+ MgReaderByteSourceImpl* bsImpl = new MgReaderByteSourceImpl(fr, MgMimeType::Json, true, false, -1);
+ bsImpl->SetMaxFeatures(numFeaturesToRetrieve - 1);
+ Ptr<MgByteSource> bs = new MgByteSource(bsImpl);
+ resultReader = bs->GetReader();
+ }
+ else
+ {
+ // Call the C++ API
+ // NOTE: I updated the maxFeatures value from numFeaturesToRetrieve to numFeaturesToRetrieve-1
+ // Because the MgServerFdoFeatureReader in MapGuide server uses -1 to mark empty, while MgWfsFeatures
+ // in MapGuide web tier uses 0
+ resultReader = featureService->GetWfsFeature(featureSourceId, ((sSchemaHash.size() == 0) ? sClass : sSchemaHash + _(":") + sClass),
+ requiredProperties, m_getFeatureParams->GetSrs(), filter, numFeaturesToRetrieve - 1, sVersion, sOutputFormat, sSortCriteria, sPrefix, oFeatureTypes.GetNamespaceUrl());
- // Store the MgByteReader directly for retrieval
- //
- // DO NOT PASS THROUGH OGC XML TEMPLATE PROCESSING CODE!
- // DO NOT PASS GO!
- // DO NOT COLLECT MEMORY SPIKES NEEDLESSLY BUFFERING XML TEMPLATE CONTENT AS A RESULT!
- //
- // This *is* already the WFS GetFeature response. There is nothing to post-process through the XML templates!
+ // Store the MgByteReader directly for retrieval
+ //
+ // DO NOT PASS THROUGH OGC XML TEMPLATE PROCESSING CODE!
+ // DO NOT PASS GO!
+ // DO NOT COLLECT MEMORY SPIKES NEEDLESSLY BUFFERING XML TEMPLATE CONTENT AS A RESULT!
+ //
+ // This *is* already the WFS GetFeature response. There is nothing to post-process through the XML templates!
+ }
}
else //Cannot resolve feature source from feature type name
{
Modified: trunk/MgDev/Web/src/HttpHandler/HttpWmsGetFeatureInfo.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpWmsGetFeatureInfo.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/HttpWmsGetFeatureInfo.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -154,9 +154,9 @@
Ptr<MgCoordinate> mcsLowerLeft = mcsExtent->GetLowerLeftCoordinate();
Ptr<MgCoordinate> mcsUpperRight = mcsExtent->GetUpperRightCoordinate();
- //When GetFeatureInfo for point or line geometry, simply using click point to query cannot get any matching.
- //Expand selection geometry a little to be a linearRing so that can query point and line.
- double margin = 2;
+ //When GetFeatureInfo for point or line geometry, simply using click point to query cannot get any matching.
+ //Expand selection geometry a little to be a linearRing so that can query point and line.
+ double margin = 2;
// Convert the pixel coords to MCS coords
double mcsMinX = mcsLowerLeft->GetX() + ((double)m_iCoord - margin) * mcsExtent->GetWidth() / map->GetDisplayWidth();
double mcsMaxY = mcsUpperRight->GetY() -((double)m_jCoord - margin) * mcsExtent->GetHeight() / map->GetDisplayHeight();
@@ -229,13 +229,17 @@
// Get the selection geometry
Ptr<MgGeometry> selectionGeometry = GetSelectionGeometry(map);
+ bool bCaptureGeometry = true;
+
// Call the C++ API
Ptr<MgBatchPropertyCollection> propertyCollection = service->QueryFeatureProperties(map, queryLayers, selectionGeometry,
- MgFeatureSpatialOperations::Intersects, L"", m_featureCount, 1 /*Any visible features*/);
+ MgFeatureSpatialOperations::Intersects, L"", m_featureCount, 1 /*Any visible features*/, false /* no bbox */, bCaptureGeometry);
// Create the object to store the feature info
Ptr<MgWmsFeatureInfo> wmsFeatureInfo = new MgWmsFeatureInfo(propertyCollection);
+ wmsFeatureInfo->SetFormat(m_infoFormat);
+
// The WMS Server takes ownership of the feature info
wmsServer->SetFeatureInfo(wmsFeatureInfo);
}
Modified: trunk/MgDev/Web/src/HttpHandler/Makefile.am
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/Makefile.am 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/Makefile.am 2017-11-26 22:22:40 UTC (rev 9256)
@@ -144,6 +144,7 @@
ReaderByteSourceImpl.cpp \
WfsFeatureDefinitions.cpp \
WfsGetFeatureParams.cpp \
+ WmsFeatureGeometry.cpp \
WmsFeatureInfo.cpp \
WmsFeatureProperties.cpp \
WmsLayerDefinitions.cpp \
@@ -290,6 +291,7 @@
StringStream.h \
WfsFeatureDefinitions.h \
WfsGetFeatureParams.h \
+ WmsFeatureGeometry.h \
WmsFeatureInfo.h \
WmsFeatureProperties.h \
WmsLayerDefinitions.h \
Modified: trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -93,6 +93,7 @@
CPSZ kpszPiEnumLayers = _("EnumLayers");
CPSZ kpszPiEnumFeatureProperties = _("EnumFeatureProperties");
+CPSZ kpszPiEnumFeatureGeometries = _("EnumFeatureGeometries");
CPSZ kpszPiEnumFeatureInfo = _("EnumFeatureInfo");
extern CPSZ kpszPiAttributeUsing; // for consistency, borrow the "using" attribute from base class.
CPSZ kpszPiEnumLayersDefaultFormat = _("&Layer.Name;\n");
@@ -784,6 +785,10 @@
{
ProcedureEnumFeatureInfo(PI);
}
+ else if (sProc == kpszPiEnumFeatureGeometries)
+ {
+ ProcedureEnumFeatureGeometries(PI);
+ }
else
{
return false;
@@ -863,6 +868,67 @@
}
}
+// Interpret a <?EnumFeatureGeometries using= ?> processing instruction
+// This will enumerate all feature geometries (only one)
+void MgOgcWmsServer::ProcedureEnumFeatureGeometries(MgXmlProcessingInstruction& PIEnum)
+{
+ STRING sFormat;
+ if (!PIEnum.GetAttribute(kpszPiAttributeUsing, sFormat))
+ sFormat = kpszPiEnumFeaturePropertiesDefaultFormat;
+
+ bool bIsGeometryEnabled = false;
+ if (m_pFeatureInfo != NULL && m_pLayers != NULL)
+ {
+ STRING layerName;
+ Ptr<MgWmsFeatureProperties> pProps = m_pFeatureInfo->GetCurrentProperties();
+ if (pProps != NULL)
+ {
+ layerName = pProps->GetLayerName();
+ }
+
+ //This will have been iterated previously, so rewind
+ m_pLayers->Reset();
+
+ while (m_pLayers->Next())
+ {
+ MgUtilDictionary currentDef(NULL);
+ m_pLayers->GenerateDefinitions(currentDef);
+
+ //We're at the layer of interest
+ CPSZ pszCurrentLayerName = currentDef[L"Layer.Name"];
+ if (SZ_EQ(pszCurrentLayerName, layerName.c_str()))
+ {
+ //Geometry data is only emitted if permitted by Layer.EnableGeometry
+ CPSZ pszEnableGeometry = currentDef[L"Layer.EnableGeometry"];
+ if (pszEnableGeometry != NULL && SZ_EQ(pszEnableGeometry, _("1")))
+ {
+ bIsGeometryEnabled = true;
+ break;
+ }
+ }
+ }
+ }
+
+ CDictionaryStackFrame forFeatureGeometries(this);
+
+ if (m_pFeatureInfo != NULL)
+ {
+ Ptr<MgWmsFeatureProperties> pProps = m_pFeatureInfo->GetCurrentProperties();
+ if (pProps != NULL)
+ {
+ if (bIsGeometryEnabled)
+ {
+ Ptr<MgWmsFeatureGeometry> geom = pProps->GetGeometry();
+ while (geom->Next())
+ {
+ geom->GenerateDefinitions(*m_pTopOfDefinitions);
+ ProcessExpandableText(sFormat);
+ }
+ }
+ }
+ }
+}
+
// Set the feature info (used for generating GetFeatureInfo response)
void MgOgcWmsServer::SetFeatureInfo(MgWmsFeatureInfo* pFeatureInfo)
{
Modified: trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/OgcWmsServer.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -24,6 +24,7 @@
#include "WmsLayerDefinitions.h"
#include "WmsFeatureInfo.h"
#include "WmsFeatureProperties.h"
+#include "WmsFeatureGeometry.h"
class MgOgcWmsServer: public MgOgcServer
{
@@ -88,6 +89,7 @@
void ProcedureEnumLayers (MgXmlProcessingInstruction& PIEnum);
void ProcedureEnumFeatureProperties (MgXmlProcessingInstruction& PIEnum);
void ProcedureEnumFeatureInfo (MgXmlProcessingInstruction& PIEnum);
+ void ProcedureEnumFeatureGeometries (MgXmlProcessingInstruction& PIEnum);
bool ValidateGetCapabilitiesParameters();
bool ValidateGetFeatureInfoParameters();
Modified: trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -18,6 +18,8 @@
#include "PlatformBase.h"
MgReaderByteSourceImpl::MgReaderByteSourceImpl(MgReader* reader, CREFSTRING format, bool bCleanJson, bool bEnablePrecision, INT32 precision, MgTransform* xform)
+ : m_maxFeatures(-1),
+ m_featureIndex(-1)
{
m_reader = SAFE_ADDREF(reader);
m_format = format;
@@ -42,6 +44,24 @@
m_xform = NULL;
}
+void MgReaderByteSourceImpl::SetMaxFeatures(INT32 maxFeatures)
+{
+ m_maxFeatures = maxFeatures;
+}
+
+bool MgReaderByteSourceImpl::ReadNextInternal()
+{
+ if (m_maxFeatures < 0 || m_featureIndex < m_maxFeatures)
+ {
+ m_featureIndex++;
+ return m_reader->ReadNext();
+ }
+ else
+ {
+ return false;
+ }
+}
+
///////////////////////////////////////////////////////////////////////////
/// \brief
/// Reads a buffer
@@ -163,7 +183,7 @@
if (m_bInternalReaderHasMore && bAdvanceReader)
{
- m_bInternalReaderHasMore = m_reader->ReadNext();
+ m_bInternalReaderHasMore = ReadNextInternal();
if (m_bInternalReaderHasMore)
{
if (m_format == MgMimeType::Json)
Modified: trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -80,7 +80,10 @@
///
virtual void Rewind();
+ void SetMaxFeatures(INT32 maxFeatures);
+
private:
+ bool ReadNextInternal();
INT32 ReadInternalBuffer(BYTE_ARRAY_OUT buffer, INT32 fromIndex, INT32 length);
Ptr<MgReader> m_reader;
@@ -91,6 +94,8 @@
bool m_bInternalReaderHasMore;
bool m_bFirstRecord;
bool m_bEnablePrecision;
+ INT32 m_maxFeatures;
+ INT32 m_featureIndex;
std::string m_buf;
INT32 m_bufOffset;
Copied: trunk/MgDev/Web/src/HttpHandler/WmsFeatureGeometry.cpp (from rev 9255, sandbox/jng/ogc/Web/src/HttpHandler/WmsFeatureGeometry.cpp)
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WmsFeatureGeometry.cpp (rev 0)
+++ trunk/MgDev/Web/src/HttpHandler/WmsFeatureGeometry.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -0,0 +1,77 @@
+//
+// Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "OgcFramework.h"
+#include "WmsFeatureGeometry.h"
+
+MgWmsFeatureGeometry::MgWmsFeatureGeometry(MgGeometry * geom)
+ : m_bRead(false), m_format(MgMimeType::Text)
+{
+ m_geom = SAFE_ADDREF(geom);
+}
+
+MgWmsFeatureGeometry::~MgWmsFeatureGeometry()
+{
+ m_geom = NULL;
+}
+
+void MgWmsFeatureGeometry::SetFormat(CREFSTRING format)
+{
+ m_format = format;
+}
+
+bool MgWmsFeatureGeometry::Next()
+{
+ // Per the IOgcResourceEnumerator contract, we have to iterate, but we only want to iterate once
+ if (!m_bRead)
+ {
+ m_bRead = true;
+ return true;
+ }
+ return false;
+}
+
+void MgWmsFeatureGeometry::GenerateDefinitions(MgUtilDictionary& dictionary)
+{
+ if (NULL != m_geom.p)
+ {
+ if (MgMimeType::Json == m_format) //Give GeoJSON geometry to json
+ {
+ MgGeoJsonWriter gjw;
+ STRING value;
+ gjw.ToGeoJson(m_geom, value, false);
+ dictionary.AddDefinition(_("FeatureGeometry.Value"), value);
+ }
+ else //Give everything else WKT
+ {
+ MgWktReaderWriter wktRw;
+ STRING value = wktRw.Write(m_geom);
+ dictionary.AddDefinition(_("FeatureGeometry.Value"), value);
+ }
+ }
+ else
+ {
+ if (MgMimeType::Json == m_format)
+ {
+ dictionary.AddDefinition(_("FeatureGeometry.Value"), _("null"));
+ }
+ else
+ {
+ dictionary.AddDefinition(_("FeatureGeometry.Value"), _(""));
+ }
+ }
+}
Copied: trunk/MgDev/Web/src/HttpHandler/WmsFeatureGeometry.h (from rev 9255, sandbox/jng/ogc/Web/src/HttpHandler/WmsFeatureGeometry.h)
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WmsFeatureGeometry.h (rev 0)
+++ trunk/MgDev/Web/src/HttpHandler/WmsFeatureGeometry.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -0,0 +1,49 @@
+//
+// Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MgWmsFeatureInfoGeometry_h
+#define _MgWmsFeatureInfoGeometry_h
+
+#include "XmlParser.h"
+#include "Dictionary.h"
+
+class MgWmsFeatureGeometry : public IOgcResourceEnumerator, public MgDisposable
+{
+public:
+ MgWmsFeatureGeometry(MgGeometry* geom);
+ //Default constructor to keep Ptr<> happy
+ MgWmsFeatureGeometry() {};
+ virtual ~MgWmsFeatureGeometry();
+
+ void SetFormat(CREFSTRING format);
+
+ bool Next();
+ void GenerateDefinitions(MgUtilDictionary& Dictionary);
+
+protected:
+ virtual void Dispose()
+ {
+ delete this;
+ }
+
+private:
+ Ptr<MgGeometry> m_geom;
+ bool m_bRead;
+ STRING m_format;
+};
+
+#endif
\ No newline at end of file
Modified: trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -19,6 +19,7 @@
#include "WmsFeatureInfo.h"
#include "WmsFeatureProperties.h"
+CPSZ kpszIsLast = _("FeatureInfo.IsLast");
CPSZ kpszDefinitionFeatureInfoLayerName = _("FeatureInfo.LayerName");
CPSZ kpszLayerNameProperty = _("_MgLayerName");
@@ -59,9 +60,15 @@
dictionary.AddDefinition(kpszDefinitionFeatureInfoLayerName, value);
}
}
+ dictionary.AddDefinition(kpszIsLast, (m_index < m_propertyCollection->GetCount() - 1) ? L"0" : L"1");
}
}
+void MgWmsFeatureInfo::SetFormat(CREFSTRING format)
+{
+ m_format = format;
+}
+
MgWmsFeatureProperties* MgWmsFeatureInfo::GetCurrentProperties()
{
MgWmsFeatureProperties* wmsProps = NULL;
@@ -71,6 +78,7 @@
if(props != NULL)
{
wmsProps = new MgWmsFeatureProperties(props);
+ wmsProps->SetFormat(m_format);
}
}
return wmsProps;
Modified: trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/WmsFeatureInfo.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -32,6 +32,8 @@
MgWmsFeatureInfo(){};
virtual ~MgWmsFeatureInfo();
+ void SetFormat(CREFSTRING format);
+
bool Next();
void GenerateDefinitions(MgUtilDictionary& Dictionary);
MgWmsFeatureProperties* GetCurrentProperties();
@@ -45,6 +47,7 @@
private:
Ptr<MgBatchPropertyCollection> m_propertyCollection;
int m_index;
+ STRING m_format;
};
#endif//_MgWmsFeatureInfo_h
Modified: trunk/MgDev/Web/src/HttpHandler/WmsFeatureProperties.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WmsFeatureProperties.cpp 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/WmsFeatureProperties.cpp 2017-11-26 22:22:40 UTC (rev 9256)
@@ -20,7 +20,8 @@
MgWmsFeatureProperties::MgWmsFeatureProperties(MgPropertyCollection* propertyCollection)
-: m_index(-1)
+: m_index(-1),
+ m_format(MgMimeType::Xml)
{
m_propertyCollection = SAFE_ADDREF(propertyCollection);
}
@@ -29,15 +30,78 @@
{
}
+void MgWmsFeatureProperties::SetFormat(CREFSTRING format)
+{
+ m_format = format;
+}
+
+STRING MgWmsFeatureProperties::GetLayerName()
+{
+ STRING ret;
+ if (m_propertyCollection != NULL)
+ {
+ INT32 gidx = m_propertyCollection->IndexOf(_("_MgLayerName"));
+ if (gidx >= 0)
+ {
+ Ptr<MgProperty> prop = m_propertyCollection->GetItem(gidx);
+ if (prop->GetPropertyType() == MgPropertyType::String)
+ {
+ MgStringProperty* sp = static_cast<MgStringProperty*>(prop.p);
+ if (!sp->IsNull())
+ {
+ ret = sp->GetValue();
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+MgWmsFeatureGeometry* MgWmsFeatureProperties::GetGeometry()
+{
+ Ptr<MgWmsFeatureGeometry> ret;
+ Ptr<MgGeometry> geom = NULL;
+ if (m_propertyCollection != NULL)
+ {
+ INT32 gidx = m_propertyCollection->IndexOf(_("_MgGeometry"));
+ if (gidx >= 0)
+ {
+ Ptr<MgProperty> prop = m_propertyCollection->GetItem(gidx);
+ if (prop->GetPropertyType() == MgPropertyType::Geometry)
+ {
+ MgGeometryProperty* gp = static_cast<MgGeometryProperty*>(prop.p);
+ if (!gp->IsNull())
+ {
+ Ptr<MgByteReader> agf = gp->GetValue();
+ MgAgfReaderWriter agfRw;
+ geom = agfRw.Read(agf);
+ }
+ }
+ }
+ }
+
+ ret = new MgWmsFeatureGeometry(geom);
+ ret->SetFormat(m_format);
+
+ return ret.Detach();
+}
+
+bool MgWmsFeatureProperties::IsSpecialProperty(MgProperty* prop)
+{
+ return (szcmp(prop->GetName().c_str(), _("_MgLayerName")) == 0)
+ || (szcmp(prop->GetName().c_str(), _("_MgGeometry")) == 0)
+ || (szcmp(prop->GetName().c_str(), _("_MgFeatureBoundingBox")) == 0);
+}
+
bool MgWmsFeatureProperties::Next()
{
if(m_propertyCollection != NULL && m_index < m_propertyCollection->GetCount() - 1)
{
m_index++;
- // Skip the special layer name property
+ // Skip the special properties
Ptr<MgProperty> prop = m_propertyCollection->GetItem(m_index);
- if(szcmp(prop->GetName().c_str(), _("_MgLayerName")) == 0)
+ if (IsSpecialProperty(prop))
{
return Next();
}
@@ -53,18 +117,24 @@
{
if(m_propertyCollection != NULL && m_index >= 0 && m_index < m_propertyCollection->GetCount())
{
- Ptr<MgStringProperty> stringProp = (MgStringProperty*)m_propertyCollection->GetItem(m_index);
- if(stringProp != NULL)
+ Ptr<MgProperty> prop = m_propertyCollection->GetItem(m_index);
+ STRING name = MgUtil::ReplaceEscapeCharInXml(prop->GetName());
+ // Skip the special properties
+ if (!IsSpecialProperty(prop))
{
- STRING name = MgUtil::ReplaceEscapeCharInXml(stringProp->GetName());
-
- // Skip the special layer name property
- if(szcmp(name.c_str(), _("_MgLayerName")) != 0)
+ STRING sIndex;
+ MgUtil::Int32ToString(m_index, sIndex);
+ if (prop->GetPropertyType() == MgPropertyType::String)
{
+ MgStringProperty* stringProp = static_cast<MgStringProperty*>(prop.p);
STRING value = MgUtil::ReplaceEscapeCharInXml(stringProp->GetValue());
dictionary.AddDefinition(_("FeatureProperty.Name"), name.c_str());
dictionary.AddDefinition(_("FeatureProperty.Value"), value.c_str());
+ //A bit hack-ish but we need this for formats like GeoJSON so we know whether to insert a "," or not
+ //The server implementation will ensure that all the non-special properties are at the end of the collection
+ //ie. _MgLayerName, _MgGeometry, etc will never be the last property
+ dictionary.AddDefinition(_("FeatureProperty.IsLast"), (m_index == m_propertyCollection->GetCount() - 1) ? _("1") : _("0"));
}
}
}
Modified: trunk/MgDev/Web/src/HttpHandler/WmsFeatureProperties.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/WmsFeatureProperties.h 2017-11-26 22:17:19 UTC (rev 9255)
+++ trunk/MgDev/Web/src/HttpHandler/WmsFeatureProperties.h 2017-11-26 22:22:40 UTC (rev 9256)
@@ -21,6 +21,8 @@
#include "XmlParser.h"
#include "Dictionary.h"
+class MgWmsFeatureGeometry;
+
class MgWmsFeatureProperties: public IOgcResourceEnumerator, public MgDisposable
{
public:
@@ -30,8 +32,12 @@
MgWmsFeatureProperties(){};
virtual ~MgWmsFeatureProperties();
+ void SetFormat(CREFSTRING format);
+
bool Next();
void GenerateDefinitions(MgUtilDictionary& Dictionary);
+ MgWmsFeatureGeometry* GetGeometry();
+ STRING GetLayerName();
protected:
virtual void Dispose()
@@ -40,8 +46,10 @@
}
private:
- Ptr<MgPropertyCollection> m_propertyCollection;
- int m_index;
+ static bool IsSpecialProperty(MgProperty* prop);
+ Ptr<MgPropertyCollection> m_propertyCollection;
+ int m_index;
+ STRING m_format;
};
#endif//_MgWmsFeatureProperties_h
More information about the mapguide-commits
mailing list