= !MapGuide RFC 161 - Geo-Processing Services = This page contains a change request (RFC) for the !MapGuide Open Source project. More !MapGuide RFCs can be found on the [wiki:MapGuideRfcs RFCs] page. == Status == ||RFC Template Version||(1.0)|| ||Submission Date||14 Jun 2017|| ||Last Modified||14 Jun 2017|| ||Author||Jackie Ng|| ||RFC Status||draft|| ||Implementation Status|||| ||Proposed Milestone||3.3|| ||Assigned PSC guide(s)||(when determined)|| ||'''Voting History'''||(vote date)|| ||+1|||| ||+0|||| ||-0|||| ||-1|||| ||no vote|| || == Overview == This RFC proposes to add geo-processing capabilities to the mapagent and enhance MgGeometry with additional capabilities offered by the underlying GEOS library we're wrapping. == Motivation == The mapagent in its current form offers no services for geo-processing. Such capabilities require custom code using MgGeometry from the MapGuide Web API. For basic geo-processing such as geometry manipulation (union/buffer/etc) or testing of common spatial predicates (contains/intersects/etc), we should be able to tap into such functionality in the mapagent. == Proposed Solution == This RFC enhances the mapagent with support for the following operations: === Buffer === Performs a buffer of the given input geometry in with the specified distance. This is the mapagent equivalent of `MgGeometry::Buffer()` || '''Name''' || '''Value''' || '''Required''' || '''Description''' || || OPERATION || GEO.BUFFER || Yes || Operation to execute || || VERSION || 3.3.0 || Yes || Operation version || || CLIENTAGENT || text || Optional || Descriptive text for client || || GEOMETRY || string || Yes || The Well-Known Text of the geometry to buffer || || DISTANCE || number || Yes || The buffer distance in the specific units || || UNITS || mi/km/ft/m || Yes || miles/kilometers/feet/meters || || FORMAT || WKT/GEOJSON || Yes || Output the buffer result as WKT or GeoJSON || || COORDINATESYSTEM || string || Yes || The coordinate system (CS-Map code) of the input geometry || || TRANSFORMTO || string || Optional || The coordinate system (CS-Map code) to transform the buffer geometry into. If not specified, the buffer geometry will be in the input coordinate system || === Simplify === Returns a simplified form of the given input geometry. This is the mapagent equivalent of `MgGeometrySimplifier::Simplify()` || '''Name''' || '''Value''' || '''Required''' || '''Description''' || || OPERATION || GEO.SIMPLIFY || Yes || Operation to execute || || VERSION || 3.3.0 || Yes || Operation version || || CLIENTAGENT || text || Optional || Descriptive text for client || || GEOMETRY || string || Yes || The Well-Known Text of the geometry to simplify || || TOLERANCE || number || Yes || The simplification tolerance || || ALGORITHM || 0/1 || Yes || 0=Douglas-Peucker, 1=Topology Preserving || || FORMAT || WKT/GEOJSON || Yes || Output the simplification result as WKT or GeoJSON || || COORDINATESYSTEM || string || Optional || The coordinate system (CS-Map code) of the input geometry. Only required in combination with `TRANSFORMTO` if you intend to transform the simplified geometry || || TRANSFORMTO || string || Optional || The coordinate system (CS-Map code) to transform the simplified geometry into. Only required in combination with `COORDINATESYSTEM ` if you intend to transform the simplified geometry || === Binary Operation === Performs the given binary operation against the 2 input geometries specified (in WKT) as WKT or GeoJSON with optional transformation. The following binary operations are supported: * Union * Difference * Intersection * SymmetricDifference || '''Name''' || '''Value''' || '''Required''' || '''Description''' || || OPERATION || GEO.BINARYOPERATION|| Yes || Operation to execute || || VERSION || 3.3.0 || Yes || Operation version || || CLIENTAGENT || text || Optional || Descriptive text for client || || GEOMETRYA || string || Yes || The Well-Known Text of the first input geometry || || GEOMETRYB || string || Yes || The Well-Known Text of the second input geometry || || OPERATOR || UNION/DIFFERENCE/INTERSECTION/SYMMETRICDIFFERENCE || Yes || The desired operator for this operation || || FORMAT || WKT/GEOJSON || Yes || Output the operation result as WKT or GeoJSON || || COORDINATESYSTEM || string || Optional || The coordinate system (CS-Map code) of the input geometries. Only required in combination with `TRANSFORMTO` if you intend to transform the geometry result || || TRANSFORMTO || string || Optional || The coordinate system (CS-Map code) to transform the simplified geometry into. Only required in combination with `COORDINATESYSTEM ` if you intend to transform the geometry result || All operators are invoked in the form of {{{GEOMETRYA OPERATOR GEOMETRYB}}}. Where ordering of input geometries matters (the operator is not commutative), refer to this rule. === Spatial Predicate === Tests and returns whether the 2 input geometries specified (in WKT) passes the given spatial predicate. The following spatial predicates are supported: * Contains * Crosses * Disjoint * Equals * Intersects * Overlaps * Touches * Within || '''Name''' || '''Value''' || '''Required''' || '''Description''' || || OPERATION || GEO.BINARYOPERATION|| Yes || Operation to execute || || VERSION || 3.3.0 || Yes || Operation version || || CLIENTAGENT || text || Optional || Descriptive text for client || || GEOMETRYA || string || Yes || The Well-Known Text of the first input geometry || || GEOMETRYB || string || Yes || The Well-Known Text of the second input geometry || || OPERATOR || CONTAINS/CROSSES/DISJOINT/EQUALS/INTERSECTS/OVERLAPS/TOUCHES/WITHIN || Yes || The desired operator for this spatial predicate test ||result || All operators are invoked in the form of {{{GEOMETRYA OPERATOR GEOMETRYB}}}. Where ordering of input geometries matters (the operator is not commutative), refer to this rule. == MgGeometry enhancements == In addition to mapagent enhancements, this RFC enhances the `MgGeometry` class with support for "prepared" geometries. Prepared geometries is a performance optimization that improves the performance of operations between a single target geometry and a batch of test geometries. By preparing the target geometry, various internal data structures of the prepared geometry can be pre-computed, which then allows subsequent geometric operations to be evaluated with maximum efficiency. The RFC introduces a new `MgPreparedGeometry` class to the MapGuide API {{{ //////////////////////////////////////////////////////////////// /// \brief /// MgPreparedGeometry is an prepared form of MgGeometry optimized for the case of /// repeated evaluation of spatial predicates against it and any other geometry /// class MG_GEOMETRY_API MgPreparedGeometry : public MgGuardDisposable { PUBLISHED_API: //////////////////////////////////////////////////////////////////////////////////////////////////////// /// \brief /// This is a convenience method. Given 2 geometries a and b, /// a.Contains(b) is true if and only if b.MgGeometry::Within(a) /// is true. /// /// /// \htmlinclude DotNetSyntaxTop.html /// virtual bool Contains(MgGeometry other); /// \htmlinclude SyntaxBottom.html /// \htmlinclude JavaSyntaxTop.html /// virtual boolean Contains(MgGeometry other); /// \htmlinclude SyntaxBottom.html /// \htmlinclude PHPSyntaxTop.html /// virtual bool Contains(MgGeometry other); /// \htmlinclude SyntaxBottom.html /// /// \param other (MgGeometry) /// The MgGeometry to test against this one. /// /// \return /// True if the other geometry is within this geometry, false /// otherwise. /// virtual bool Contains(MgGeometry* other); ////////////////////////////////////////////////////////////////////// /// \brief /// Given 2 geometries a and b, a.Crosses(b) is true if and only /// if the dimension of the intersection of the interior of a and /// the interior of b is less than the greater of the dimension /// of the interior of a and the dimension of the interior of b /// and the intersection of a and b is neither a nor b. /// /// \remarks /// A Point cannot cross another geometry because the /// intersection of the Point with the other geometry is the /// Point. /// \n /// Two MultiPoint geometries cannot cross one another because /// the dimension of the intersection of their interiors, namely /// the 0-dimension, is not less than the greater of the /// dimensions of their interiors, namely the 0-dimension. /// \n /// [\link OGC99049 OGC99-049 \endlink] implicitly excludes a Crosses /// relationship between 2 polygons. According to the definition, /// the possibility of such a relationship would require that the /// intersection of the interior of one polygon with that of /// another be a Point or Line. ///