Changes between Initial Version and Version 1 of MapGuideRfc161


Ignore:
Timestamp:
Jun 13, 2017, 9:47:38 AM (7 years ago)
Author:
jng
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • MapGuideRfc161

    v1 v1  
     1
     2= !MapGuide RFC XYZ - Geo-Processing Services =
     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 Jun 2017||
     11||Last Modified||||
     12||Author||Jackie Ng||
     13||RFC Status||draft||
     14||Implementation Status||||
     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 geo-processing capabilities to the mapagent and enhance MgGeometry with additional capabilities offered by the underlying GEOS library we're wrapping.
     27
     28== Motivation ==
     29
     30The mapagent in its current form offers no services for geo-processing. Such capabilities require custom code using MgGeometry from the MapGuide Web API.
     31
     32For 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.
     33
     34== Proposed Solution ==
     35
     36This RFC enhances the mapagent with support for the following operations:
     37
     38=== Buffer ===
     39
     40Performs a buffer of the given input geometry in with the specified distance.
     41
     42This is the mapagent equivalent of `MgGeometry::Buffer()`
     43
     44|| '''Name''' || '''Value'''  || '''Required''' || '''Description''' ||
     45|| OPERATION || GEO.BUFFER || Yes || Operation to execute ||
     46|| VERSION || 3.3.0 || Yes || Operation version ||
     47|| CLIENTAGENT || text || Optional || Descriptive text for client ||
     48|| GEOMETRY || string || Yes || The Well-Known Text of the geometry to buffer ||
     49|| DISTANCE || number || Yes || The buffer distance in the specific units ||
     50|| UNITS || mi/km/ft/m || Yes || miles/kilometers/feet/meters ||
     51|| FORMAT || WKT/GEOJSON || Yes || Output the buffer result as WKT or GeoJSON ||
     52|| COORDINATESYSTEM || string || Yes || The coordinate system (CS-Map code) of the input geometry ||
     53|| 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  ||
     54
     55=== Simplify ===
     56
     57Returns a simplified form of the given input geometry.
     58
     59This is the mapagent equivalent of `MgGeometrySimplifier::Simplify()`
     60
     61|| '''Name''' || '''Value'''  || '''Required''' || '''Description''' ||
     62|| OPERATION || GEO.SIMPLIFY || Yes || Operation to execute ||
     63|| VERSION || 3.3.0 || Yes || Operation version ||
     64|| CLIENTAGENT || text || Optional || Descriptive text for client ||
     65|| GEOMETRY || string || Yes || The Well-Known Text of the geometry to simplify ||
     66|| TOLERANCE || number || Yes || The simplification tolerance ||
     67|| ALGORITHM || 0/1 || Yes || 0=Douglas-Peucker, 1=Topology Preserving ||
     68|| FORMAT || WKT/GEOJSON || Yes || Output the simplification result as WKT or GeoJSON ||
     69|| 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 ||
     70|| 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  ||
     71
     72=== Binary Operation ===
     73
     74Performs the given binary operation against the 2 input geometries specified (in WKT) as WKT or GeoJSON with optional transformation.
     75
     76The following binary operations are supported:
     77
     78 * Union
     79 * Difference
     80 * Intersection
     81 * SymmetricDifference
     82
     83|| '''Name''' || '''Value'''  || '''Required''' || '''Description''' ||
     84|| OPERATION || GEO.BINARYOPERATION|| Yes || Operation to execute ||
     85|| VERSION || 3.3.0 || Yes || Operation version ||
     86|| CLIENTAGENT || text || Optional || Descriptive text for client ||
     87|| GEOMETRYA || string || Yes || The Well-Known Text of the first input geometry ||
     88|| GEOMETRYB || string || Yes || The Well-Known Text of the second input geometry ||
     89|| OPERATOR || UNION/DIFFERENCE/INTERSECTION/SYMMETRICDIFFERENCE || Yes || The desired operator for this operation ||
     90|| FORMAT || WKT/GEOJSON || Yes || Output the operation result as WKT or GeoJSON ||
     91|| 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 ||
     92|| 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 ||
     93
     94=== Spatial Predicate ===
     95
     96Tests and returns whether the 2 input geometries specified (in WKT) passes the given spatial predicate.
     97
     98The following spatial predicates are supported:
     99
     100 * Contains
     101 * Crosses
     102 * Disjoint
     103 * Equals
     104 * Intersects
     105 * Overlaps
     106 * Touches
     107 * Within
     108
     109|| '''Name''' || '''Value'''  || '''Required''' || '''Description''' ||
     110|| OPERATION || GEO.BINARYOPERATION|| Yes || Operation to execute ||
     111|| VERSION || 3.3.0 || Yes || Operation version ||
     112|| CLIENTAGENT || text || Optional || Descriptive text for client ||
     113|| GEOMETRYA || string || Yes || The Well-Known Text of the first input geometry ||
     114|| GEOMETRYB || string || Yes || The Well-Known Text of the second input geometry ||
     115|| OPERATOR || CONTAINS/CROSSES/DISJOINT/EQUALS/INTERSECTS/OVERLAPS/TOUCHES/WITHIN || Yes || The desired operator for this spatial predicate test ||result ||
     116
     117== MgGeometry enhancements ==
     118
     119In addition to mapagent enhancements, this RFC enhances the `MgGeometry` class with support for "prepared" geometries.
     120
     121Prepared 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.
     122
     123The RFC introduces a new `MgPreparedGeometry` class to the MapGuide API
     124
     125{{{
     126////////////////////////////////////////////////////////////////
     127/// \brief
     128/// MgPreparedGeometry is an prepared form of MgGeometry optimized for the case of
     129/// repeated evaluation of spatial predicates against it and any other geometry
     130///
     131class MG_GEOMETRY_API MgPreparedGeometry : public MgGuardDisposable
     132{
     133PUBLISHED_API:
     134    ////////////////////////////////////////////////////////////////////////////////////////////////////////
     135    /// \brief
     136    /// This is a convenience method. Given 2 geometries a and b,
     137    /// a.Contains(b) is true if and only if b.MgGeometry::Within(a)
     138    /// is true.
     139    ///
     140    /// <!-- Syntax in .Net, Java, and PHP -->
     141    /// \htmlinclude DotNetSyntaxTop.html
     142    /// virtual bool Contains(MgGeometry other);
     143    /// \htmlinclude SyntaxBottom.html
     144    /// \htmlinclude JavaSyntaxTop.html
     145    /// virtual boolean Contains(MgGeometry other);
     146    /// \htmlinclude SyntaxBottom.html
     147    /// \htmlinclude PHPSyntaxTop.html
     148    /// virtual bool Contains(MgGeometry other);
     149    /// \htmlinclude SyntaxBottom.html
     150    ///
     151    /// \param other (MgGeometry)
     152    /// The MgGeometry to test against this one.
     153    ///
     154    /// \return
     155    /// True if the other geometry is within this geometry, false
     156    /// otherwise.
     157    ///
     158    virtual bool Contains(MgGeometry* other);
     159
     160    //////////////////////////////////////////////////////////////////////
     161    /// \brief
     162    /// Given 2 geometries a and b, a.Crosses(b) is true if and only
     163    /// if the dimension of the intersection of the interior of a and
     164    /// the interior of b is less than the greater of the dimension
     165    /// of the interior of a and the dimension of the interior of b
     166    /// and the intersection of a and b is neither a nor b.
     167    ///
     168    /// \remarks
     169    /// A Point cannot cross another geometry because the
     170    /// intersection of the Point with the other geometry is the
     171    /// Point.
     172    /// \n
     173    /// Two MultiPoint geometries cannot cross one another because
     174    /// the dimension of the intersection of their interiors, namely
     175    /// the 0-dimension, is not less than the greater of the
     176    /// dimensions of their interiors, namely the 0-dimension.
     177    /// \n
     178    /// [\link OGC99049 OGC99-049 \endlink] implicitly excludes a Crosses
     179    /// relationship between 2 polygons. According to the definition,
     180    /// the possibility of such a relationship would require that the
     181    /// intersection of the interior of one polygon with that of
     182    /// another be a Point or Line.
     183    /// <h2>Illustration</h2>
     184    /// d, e and f are MultiPoint geometries.
     185    /// \n
     186    /// \image html crosses.png
     187    ///
     188    /// <!-- Syntax in .Net, Java, and PHP -->
     189    /// \htmlinclude DotNetSyntaxTop.html
     190    /// virtual bool Crosses(MgGeometry other);
     191    /// \htmlinclude SyntaxBottom.html
     192    /// \htmlinclude JavaSyntaxTop.html
     193    /// virtual boolean Crosses(MgGeometry other);
     194    /// \htmlinclude SyntaxBottom.html
     195    /// \htmlinclude PHPSyntaxTop.html
     196    /// virtual bool Crosses(MgGeometry other);
     197    /// \htmlinclude SyntaxBottom.html
     198    ///
     199    /// \param other (MgGeometry)
     200    /// The MgGeometry to test against this
     201    /// one.
     202    ///
     203    /// \return
     204    /// True if this geometry spatially crosses the other geometry,
     205    /// false otherwise.
     206    ///
     207    virtual bool Crosses(MgGeometry* other);
     208
     209    /////////////////////////////////////////////////////////////////////////
     210    /// \brief
     211    /// Given 2 geometries a and b, a.Disjoint(b)is true if and only
     212    /// if the intersection of a and b is empty.
     213    ///
     214    /// <!-- Syntax in .Net, Java, and PHP -->
     215    /// \htmlinclude DotNetSyntaxTop.html
     216    /// virtual bool Disjoint(MgGeometry other);
     217    /// \htmlinclude SyntaxBottom.html
     218    /// \htmlinclude JavaSyntaxTop.html
     219    /// virtual boolean Disjoint(MgGeometry other);
     220    /// \htmlinclude SyntaxBottom.html
     221    /// \htmlinclude PHPSyntaxTop.html
     222    /// virtual bool Disjoint(MgGeometry other);
     223    /// \htmlinclude SyntaxBottom.html
     224    ///
     225    /// \param other (MgGeometry)
     226    /// The MgGeometry to test against this one.
     227    ///
     228    /// \return
     229    /// True if this geometry is spatially disjoint from the other
     230    /// geometry, false otherwise.
     231    ///
     232    virtual bool Disjoint(MgGeometry* other);
     233
     234    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
     235    /// \brief
     236    /// This is a convenience method. Given 2 geometries a and b,
     237    /// a.Intersects(b) is true if and only if a.\link MgGeometry::Disjoint Disjoint \endlink(b)
     238    /// is false.
     239    ///
     240    /// <!-- Syntax in .Net, Java, and PHP -->
     241    /// \htmlinclude DotNetSyntaxTop.html
     242    /// virtual bool Intersects(MgGeometry other);
     243    /// \htmlinclude SyntaxBottom.html
     244    /// \htmlinclude JavaSyntaxTop.html
     245    /// virtual boolean Intersects(MgGeometry other);
     246    /// \htmlinclude SyntaxBottom.html
     247    /// \htmlinclude PHPSyntaxTop.html
     248    /// virtual bool Intersects(MgGeometry other);
     249    /// \htmlinclude SyntaxBottom.html
     250    ///
     251    /// \param other (MgGeometry)
     252    /// The MgGeometry to test against this one.
     253    ///
     254    /// \return
     255    /// True if this geometry is not disjoint with respect to the
     256    /// other geometry, false otherwise.
     257    ///
     258    virtual bool Intersects(MgGeometry* other);
     259
     260    /////////////////////////////////////////////////////////////////////////
     261    /// \brief
     262    /// Given 2 geometries a and b, a.Overlaps(b) is true if and only
     263    /// if the dimension of the interior of a equals the dimension of
     264    /// the interior of b equals the dimension of the intersection of
     265    /// the interior of a and the interior of b and the intersection
     266    /// of a and b is neither a nor b.
     267    ///
     268    /// \remarks
     269    /// A Point cannot overlap a Point, and a MultiPoint cannot
     270    /// overlap a Point but a MultiPoint can overlap a MultiPoint.
     271    /// <h2>Illustration</h2>
     272    /// c and d are MultiPoint geometries.
     273    /// \image html overlaps.png
     274    ///
     275    /// <!-- Syntax in .Net, Java, and PHP -->
     276    /// \htmlinclude DotNetSyntaxTop.html
     277    /// virtual bool Overlaps(MgGeometry other);
     278    /// \htmlinclude SyntaxBottom.html
     279    /// \htmlinclude JavaSyntaxTop.html
     280    /// virtual boolean Overlaps(MgGeometry other);
     281    /// \htmlinclude SyntaxBottom.html
     282    /// \htmlinclude PHPSyntaxTop.html
     283    /// virtual bool Overlaps(MgGeometry other);
     284    /// \htmlinclude SyntaxBottom.html
     285    ///
     286    /// \param other (MgGeometry)
     287    /// The MgGeometry to test against this one.
     288    ///
     289    /// \return
     290    /// True if this geometry spatially overlaps the other geometry,
     291    /// false otherwise.
     292    ///
     293    virtual bool Overlaps(MgGeometry* other);
     294
     295    //////////////////////////////////////////////////////////////////////
     296    /// \brief
     297    /// Given 2 geometries a and b, a.Touches(b) is true if and only
     298    /// if the intersection of the interior of a and the interior of
     299    /// b is empty and the intersection of a and b is not empty.
     300    ///
     301    /// \remarks
     302    /// A Point cannot touch a Point because a Point has no boundary
     303    /// and so the intersection of the interiors of the two
     304    /// geometries is not empty.
     305    /// \n
     306    /// A Point can touch a non-closed Line at one of the end points
     307    /// of the Line.
     308    /// \n
     309    /// A Point cannot touch a closed Line because all of the points
     310    /// in the Line are interior to it.
     311    /// <h2>Illustration</h2>
     312    /// e are MultiPoint geometries and f is a LineString.
     313    /// \image html touches.png
     314    ///
     315    /// <!-- Syntax in .Net, Java, and PHP -->
     316    /// \htmlinclude DotNetSyntaxTop.html
     317    /// virtual bool Touches(MgGeometry other);
     318    /// \htmlinclude SyntaxBottom.html
     319    /// \htmlinclude JavaSyntaxTop.html
     320    /// virtual boolean Touches(MgGeometry other);
     321    /// \htmlinclude SyntaxBottom.html
     322    /// \htmlinclude PHPSyntaxTop.html
     323    /// virtual bool Touches(MgGeometry other);
     324    /// \htmlinclude SyntaxBottom.html
     325    ///
     326    /// \param other (MgGeometry)
     327    /// The MgGeometry to test against this
     328    /// one.
     329    ///
     330    /// \return
     331    /// True if this geometry spatially touches the other geometry,
     332    /// false otherwise.
     333    ///
     334    virtual bool Touches(MgGeometry* other);
     335
     336    //////////////////////////////////////////////////////////////////////
     337    /// \brief
     338    /// Given 2 geometries a and b, a.Within(b) is true if and only
     339    /// if the intersection of a and b is a and the intersection of
     340    /// the interior of a and the interior of b is not empty.
     341    ///
     342    /// \remarks
     343    /// If the entire point-set of a geometry intersects the boundary
     344    /// of another geometry, the former is not within the latter.
     345    /// <h2>Illustration</h2>
     346    /// The end point of d and the end point of e intersect. a, b, i,
     347    /// j, k, and m are MultiPoints. The concentric circles represent
     348    /// intersecting points. The polygon n1n2n3n4 is within the
     349    /// polygon p1p2p3p4 and vice versa. The LineString q1q2 is
     350    /// within the LineString r1r2 and vice versa. The MultiPoint j
     351    /// is within the MultiPoint k and vice versa. The Point f is
     352    /// within the point g and vice versa.
     353    /// \n
     354    /// \image html within.png
     355    ///
     356    /// <!-- Syntax in .Net, Java, and PHP -->
     357    /// \htmlinclude DotNetSyntaxTop.html
     358    /// virtual bool Within(MgGeometry other);
     359    /// \htmlinclude SyntaxBottom.html
     360    /// \htmlinclude JavaSyntaxTop.html
     361    /// virtual boolean Within(MgGeometry other);
     362    /// \htmlinclude SyntaxBottom.html
     363    /// \htmlinclude PHPSyntaxTop.html
     364    /// virtual bool Within(MgGeometry other);
     365    /// \htmlinclude SyntaxBottom.html
     366    ///
     367    /// \param other (MgGeometry)
     368    /// The MgGeometry to test against this
     369    /// one.
     370    ///
     371    /// \return
     372    /// True if this geometry is spatially within the other geometry,
     373    /// false otherwise.
     374    ///
     375    virtual bool Within(MgGeometry* other);
     376};
     377}}}
     378
     379`MgPreparedGeometry` instances are obtained by calling a new `Prepare` method on a `MgGeometry` instance
     380
     381{{{
     382class MG_GEOMETRY_API MgGeometry : public MgGeometricEntity
     383{
     384PUBLISHED_API:
     385   ...
     386
     387   ///////////////////////////////////////////////////////////////////////
     388    /// \brief
     389    /// Returns a prepared version of this geometry that is optimized for
     390    /// repeated evaluation of spatial predicate operations
     391    ///
     392    /// <!-- Syntax in .Net, Java, and PHP -->
     393    /// \htmlinclude DotNetSyntaxTop.html
     394    /// virtual MgGeometry Prepare();
     395    /// \htmlinclude SyntaxBottom.html
     396    /// \htmlinclude JavaSyntaxTop.html
     397    /// virtual MgGeometry Prepare();
     398    /// \htmlinclude SyntaxBottom.html
     399    /// \htmlinclude PHPSyntaxTop.html
     400    /// virtual MgGeometry Prepare();
     401    /// \htmlinclude SyntaxBottom.html
     402    ///
     403    /// \return
     404    /// An MgPreparedGeometry representing the prepared version of this geometry
     405    ///
     406    MgPreparedGeometry* Prepare();
     407};
     408}}}
     409
     410It is important to note that the use-case of `MgPreparedGeometry` is primarily for fast/repeated evaluation of spatial predicates. As such, `MgPreparedGeometry` does not follow the geometry class hierarchy like its `MgGeometry` counterpart. If one wants to know the actual geometric information about the `MgPreparedGeometry`, they should retain a reference to the original `MgGeometry` that they `Prepare()`'d from.
     411
     412Implementation-wise, `MgPreparedGeometry` wraps the underlying `PreparedGeometry` class provided by GEOS. We use the pimpl pattern to avoid leaking out the `PreparedGeometry` dependency (and consequently any geos headers) in the public header of `MgPreparedGeometry`.
     413
     414== Implications ==
     415
     416These are new API additions.
     417
     418== Test Plan ==
     419
     420Test new mapagent geo-processing operations and verify that their output is the same as the results provided by using `MgGeometry` APIs directly.
     421
     422Benchmark repeated evaluation of spatial operations using `MgGeometry` vs `MgPreparedGeometry`. Verify that using `MgPreparedGeometry` provides noticeable performance over using `MgGeometry`
     423
     424== Funding / Resources ==
     425
     426Community