Changes between Initial Version and Version 1 of MapGuideRfc163


Ignore:
Timestamp:
Nov 13, 2017, 6:22:50 AM (6 years ago)
Author:
jng
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • MapGuideRfc163

    v1 v1  
     1
     2= !MapGuide RFC 163 - GeoJSON support for WFS/WMS =
     3
     4This page contains a change request (RFC) for the !MapGuide Open Source project.
     5More !MapGuide RFCs can be found on the [wiki:MapGuideRfcs RFCs] page.
     6
     7== Status ==
     8
     9||RFC Template Version||(1.0)||
     10||Submission Date||14 Nov 2017||
     11||Last Modified||14 Nov 2017||
     12||Author||Jackie Ng||
     13||RFC Status||draft||
     14||Implementation Status||pending||
     15||Proposed Milestone||3.3||
     16||Assigned PSC guide(s)||(when determined)||
     17||'''Voting History'''||(vote date)||
     18||+1||||
     19||+0||||
     20||-0||||
     21||-1||||
     22||no vote|| ||
     23
     24== Overview ==
     25
     26This RFC proposes to add support for GeoJSON as an output format for:
     27
     28 * WFS `GetFeatures`
     29 * WMS `GetFeatureInfo`
     30
     31Along with required infrastructure changes needed to support the above 2 cases.
     32
     33== Motivation ==
     34
     35WFS/WMS support in MapGuide is very bare-bones. The usability of WFS/WMS services can be greatly enhanced with support for GeoJSON as an output format, especially for WMS `GetFeatureInfo`, where a GeoJSON response can function as a client-side feature selection overlay with geometry data present.
     36
     37== Proposed Solution ==
     38
     39`application/json` will be advertised as a supported output format for WFS `GetFeatures` and WMS `GetFeatureInfo`
     40
     41=== GeoJSON Support for WFS GetFeatures ===
     42
     43The current `GetWfsFeature` method of `MgFeatureService` is the method that WFS `GetFeatures` ultimately calls to return data for feature data in a WFS `GetFeatures` response.
     44
     45However this method is not re-usable for implementing alternate output formats for WFS `GetFeatures` because the API itself is GML-centric:
     46
     47 * Various input parameters have GML-isms
     48 * The return value is an `MgByteReader` with GML content
     49
     50To support GeoJSON output for WFS `GetFeatures`, we need a method that gives us the underlying feature reader primitive, which we can then convert to our desired output format of choice in the Web Tier.
     51
     52We'll add a new `GetWfsReader` method for this very purpose:
     53
     54{{{
     55class MG_PLATFORMBASE_API MgFeatureService : public MgService
     56{
     57PUBLISHED_API:
     58    ////////////////////////////////////////////////////////////////////////////////////////////////////////
     59    /// \brief
     60    /// Retrieves feature information based on the supplied criteria.
     61    ///
     62    /// \note1
     63    ///
     64    /// <!-- Syntax in .Net, Java, and PHP -->
     65    /// \htmlinclude DotNetSyntaxTop.html
     66    /// virtual MgFeatureReader GetWfsReader(MgResourceIdentifier featureSourceId, string featureClass, MgStringCollection requiredProperties, string srs, string filter, int maxFeatures, string outputFormat, string sortCriteria);
     67    /// \htmlinclude SyntaxBottom.html
     68    /// \htmlinclude JavaSyntaxTop.html
     69    /// virtual MgFeatureReader GetWfsReader(MgResourceIdentifier featureSourceId, string featureClass, MgStringCollection requiredProperties, string srs, string filter, int maxFeatures, string outputFormat, string sortCriteria);
     70    /// \htmlinclude SyntaxBottom.html
     71    /// \htmlinclude PHPSyntaxTop.html
     72    /// virtual MgFeatureReader GetWfsReader(MgResourceIdentifier featureSourceId, string featureClass, MgStringCollection requiredProperties, string srs, string filter, int maxFeatures, string outputFormat, string sortCriteria);
     73    /// \htmlinclude SyntaxBottom.html
     74    ///
     75    /// \param featureSourceId (MgResourceIdentifier)
     76    /// The resource identifier defining the
     77    /// location of the feature source in
     78    /// the repository.
     79    /// \param featureClass (String/string)
     80    /// The feature class containing the features to retrieve.
     81    /// \param requiredProperties (MgStringCollection)
     82    /// The collection of properties to retrieve for each feature. If the
     83    /// collection is null or empty, all properties will be retrieved.
     84    /// \param srs (String/string)
     85    /// The spatial reference system in which to return feature geometries
     86    /// \param filter (String/string)
     87    /// An XML string containing the definition for an OGC filter
     88    /// \param sortCriteria (String/string)
     89    /// A string identifying the sort criteria
     90    ///
     91    /// \remarks
     92    /// The purpose of this method, as opposed to GetWfsFeature is to return the base reader using the same input parameters
     93    /// allowing for the caller to determine the desired output format and the desired content transformations required from
     94    /// the reader.
     95    ///
     96    /// The main use case for this method is for providing the base feature reader for outputting WFS GetFeature responses in
     97    /// formats other than GML
     98    ///
     99    /// \return
     100    /// Returns an MgByteReader containing the requested feature information.
     101    ///
     102    /// \exception MgInvalidArgumentException
     103    ///
     104    /// \since 3.3
     105    virtual MgFeatureReader* GetWfsReader(MgResourceIdentifier* featureSourceId,
     106                                          CREFSTRING featureClass,
     107                                          MgStringCollection* requiredProperties,
     108                                          CREFSTRING srs,
     109                                          CREFSTRING filter,
     110                                          CREFSTRING sortCriteria) = 0;
     111};
     112}}}
     113
     114From the Web Tier, the `MgHttpWfsGetFeature` implementation will call this method instead of `MgFeatureService::GetWfsFeature` if the `INFO_FORMAT` parameter passed in is `application/json`. The returned reader is then housed in our existing GeoJSON output adapter (introduced in MapGuideRfc158) to convert the feature reader data to GeoJSON.
     115
     116=== GeoJSON Support for WMS GetFeatureInfo ===
     117
     118For WMS `GetFeatureInfo`, there are cases where being able to return geometry data is useful. However there is only one format where the geometry data would be consumable: GeoJSON.
     119
     120To support GeoJSON output, we must first support the ability to output geometry data in a WMS `GetFeatureInfo`. The `QueryFeatureProperties` method of `MgRenderingService` is the method that provides this data. We will add a new internal overload that allows including geometry data as `MgGeometryProperty` instances for each `MgPropertyCollection` of the returned `MgBatchPropertyCollection`
     121
     122{{{
     123class MG_MAPGUIDE_API MgRenderingService : public MgService
     124{
     125INTERNAL_API:
     126    /////////////////////////////////////////////////////////////////
     127    /// \brief
     128    /// The QueryFeatureProperties operation identifies those features that
     129    /// meet the specified spatial selection criteria. This operation
     130    /// is used to implement WMS feature info and returns property values
     131    /// for all features which match the spatial query
     132    ///
     133    /// \param map
     134    /// Input
     135    /// map object containing current state of map.
     136    /// \param layerNames
     137    /// Input
     138    /// Active layer names for which to query features
     139    /// \param filterGeometry
     140    /// Input
     141    /// geometry object specifying the selection area
     142    /// \param selectionVariant
     143    /// Input
     144    /// selection criterion - integer value corresponding to one of
     145    /// the MgFeatureSpatialOperations values
     146    /// \param featureFilter
     147    /// Input
     148    /// an XML selection string containing the required feature IDs
     149    /// \param maxFeatures
     150    /// Input
     151    /// the maximum number of features to return
     152    /// \param layerAttributeFilter
     153    /// Input
     154    /// bitmask values - 1=Visible, 2=Selectable, 4=HasTooltips
     155    /// \param bIncludeFeatureBBOX
     156    /// Input
     157    /// Indicates whether a bounding box should be included. If true, bounding box is recorded as a special property named _MgFeatureBoundingBox
     158    /// \param bIncludeGeometry
     159    /// Input
     160    /// Indicates whether a bounding box should be included. If true, bounding box is recorded as a special property named _MgFeatureBoundingBox
     161    ///
     162    /// \return
     163    /// An MgSelection instance identifying the features that meet the
     164    /// selection criteria. Returns null if no features are identified.
     165    ///
     166    virtual MgBatchPropertyCollection* QueryFeatureProperties(
     167        MgMap* map,
     168        MgStringCollection* layerNames,
     169        MgGeometry* filterGeometry,
     170        INT32 selectionVariant,
     171        CREFSTRING featureFilter,
     172        INT32 maxFeatures,
     173        INT32 layerAttributeFilter,
     174        bool bIncludeFeatureBBOX,
     175        bool bIncludeGeometry) = 0;
     176};
     177}}}
     178
     179The geometry data will be stored as a `MgGeometryProperty` instance within each child `MgPropertyCollection` of the `MgBatchPropertyCollection` as a special property named `_MgGeometry`
     180
     181The `MgHttpWmsGetFeatureInfo` class in the `HttpHandler` project will be modified to call this new overload.
     182
     183=== New OGC XML template engine directives and definitions ===
     184
     185Now that we have the infrastructure to return geometry data, we'll add new directives and definitions in the OGC XML templating engine that can detect and output this geometry data.
     186
     187 * `EnumFeatureGeometries` - Enumerates all geometry properties of the current feature. Will only enumerate once at most for each feature if geometry data is present.
     188 * `FeatureInfo.IsLast` - Defines if the current feature is the last one in the iteration. This is needed for GeoJSON so we know when it is needed to insert the delimiting `,` between GeoJSON features.
     189 * `FeatureProperty.IsLast` - Defines if the current property is the last one in the iteration. This is needed for GeoJSON so we know when it is needed to insert the delimiting `,` between GeoJSON properties.
     190 * `FeatureGeometry.Value` - Defines the geometry value. The source of the definition (A new `MgWmsFeatureGeometry` class) will output a GeoJSON geometry fragment if the `INFO_FORMAT` is `application/json`. Otherwise it outputs the geometry as WKT text.
     191
     192To illustrate how these directives and definitions are used. These are the additions to the WMS XML template (all versions) to support GeoJSON output for WMS `GetFeatureInfo`
     193
     194{{{
     195<!-- WMS GetFeatureInfo GeoJSON response body  -->
     196<Response request="GetFeatureInfo" content-type="application/json">{
     197  "type": "FeatureCollection",
     198  "features": [<?EnumFeatureInfo using="&FeatureInfo.json;" ?>]
     199}</Response>
     200
     201<!-- Definition for a GeoJSON feature -->
     202<Define item="FeatureInfo.json">{
     203    "type": "Feature",
     204    "properties": {<?EnumFeatureProperties using="&FeatureProperty.json;" ?>}
     205    <?EnumFeatureGeometries using="&FeatureGeometry.json;" ?>
     206}<?If l="&FeatureInfo.IsLast" op="eq" r="0"?>,<?Endif?></Define>
     207
     208<!-- Definition for a GeoJSON property -->
     209<Define item="FeatureProperty.json">"&FeatureProperty.Name;": "&FeatureProperty.Value;"<?If l="&FeatureProperty.IsLast" op="eq" r="0"?>,<?Endif?></Define>
     210
     211<!-- Definition for a GeoJSON geometry -->
     212<Define item="FeatureGeometry.json">,"geometry": &FeatureGeometry.Value;</Define>
     213}}}
     214
     215To ensure formats other than GeoJSON can output geometry data, `GetFeatureInfo` response templates for other templates will be modified as such:
     216
     217 * `text/plain` - Geometry data is output as WKT on another line item
     218 * `text/html` - Geometry data is output as WKT in its own `Geometry` table cell value
     219 * `text/xml` - Geometry data is output as WKT in its own `<Property>` element named `Geometry`
     220
     221=== Configurable Geometry output ===
     222
     223Although we now enable geometry output for WMS `GetFeatureInfo` with the RFC, it may not be desirable to have this enabled unconditionally.
     224
     225To control whether to emit geometry data in a WMS `GetFeatureInfo` response, we define a new `_EnableGeometry` simple metadata property in the resource header XML of a Layer Definition. If set to `1` in a layer's resource header XML, the WMS `GetFeatureInfo` requests against this layer will include geometry data in its response, otherwise geometry data is omitted.
     226
     227The `_EnableGeometry` property has no effect if the `_Queryable` property is not set to `1` (ie. The layer is not published for WMS consumption).
     228
     229As this is a new metadata property, this has the effect of geometry output for WMS `GetFeatureInfo` being opt-in. By default, no geometry data is output unless `_EnableGeometry` is defined in the layer resource header with a value of `1` (in addition to `_Queryable` being set to `1`)
     230
     231== Implications ==
     232
     233These are new output formats advertised in WFS and WMS capabilities. Existing output formats are not affected.
     234
     235Geometry output is opt-in, so existing WMS `GetFeatureInfo` response will look as they are until the user *chooses* to enable geometry output.
     236
     237== Test Plan ==
     238
     239Verify GeoJSON output is present for `GetFeature` for all supported WFS versions.
     240
     241Verify GeoJSON output is present for `GetFeatureInfo` for all supported WMS versions.
     242
     243Verify geometry data is output only for WMS published layer where `_EnableGeometry` is set to `1`
     244
     245== Funding / Resources ==
     246
     247Community