Changes between Initial Version and Version 1 of rfc49_curve_geometries


Ignore:
Timestamp:
Nov 5, 2014, 6:39:58 AM (10 years ago)
Author:
Even Rouault
Comment:

Initial version of RFC 49

Legend:

Unmodified
Added
Removed
Modified
  • rfc49_curve_geometries

    v1 v1  
     1= RFC 49: Curve geometries =
     2
     3Author: Even Rouault[[BR]]
     4Contact: even dot rouault at spatialys dot com[[BR]]
     5Status: In development
     6
     7== Summary ==
     8
     9The current geometry model in GDAL 1.X makes use of points, lines, polygons and
     10aggregations of them (multipoints, multilines, multipolygons and geometry collections).
     11It was modeled from the geometry class hierarchy of the
     12"OpenGIS Simple Feature Access Part 1 : Common Architecture" (in its 1.1.0 version).
     13
     14This RFC covers the addition of new geometry types that have been added in
     15ISO/IEC 13249 Part 3 Spatial (abreviated as ISO SQL/MM Part 3):
     16  * circular string: a circular arc, or a sequence of connected circular arcs,
     17    each of them describe by 3 points: the first point of the arc, an intermediate
     18    point and the final point
     19  * compound curve: a sequence of connected curves, either line strings or
     20    circular strings
     21  * curve polygon: polygon consisting of one outer ring, and zero or more inner ring.
     22    Each ring can be one of the curve implementations: line strings, circular strings,
     23    compound curves.
     24  * multicurve: a collection of curves (line strings, circular strings, compound curves)
     25  * multisurface: a collection of surfaces (polygons, curve polygons)
     26
     27The scope of this RFC consists in :
     28  * adding the new geometry classes to the existing geometry class hierarchy,
     29    with the corresponding importer and exporter of WKT (Well Known Text) and
     30    WKB (Well Known Binary) encodings
     31  * adding methods to convert those curve geometries into their approximated
     32    linear version, and to do the reverse operation
     33  * upgrading some of the drivers that can support such geometries : GML (and
     34    indirectly NAS, WFS), PostGIS/PGDump, GeoPackage, CSV, VRT.
     35
     36== Reference documents ==
     37
     38The following documents have been used for the implementation :
     39
     40  * [http://jtc1sc32.org/doc/N1101-1150/32N1107-WD13249-3--spatial.pdf Old draft version of ISO/IEC 13249 Part 3 Spatial, dating from 2004-05-09], a.k.a SQL/MM Part 3 : Caution the WKB codes given at page 137 and following are not the latest ones used. Refer to SFA 1.2.1
     41
     42  * [http://portal.opengeospatial.org/files/?artifact_id=25355 OpenGIS Simple Feature Access Part 1 : Common Architecture,v 1.2.1], a.k.a. SFA 1.2.1
     43
     44  * [https://github.com/postgis/postgis/blob/svn-trunk/doc/bnf-wkt.txt BNF of WKT encoding]: extracted from SQL/MM Part 3
     45
     46  * [https://github.com/postgis/postgis/blob/svn-trunk/doc/bnf-wkt.txt BNF of WKB encoding]: extracted from SQL/MM Part 3
     47
     48== Core changes ==
     49
     50=== New cass hierarchy ===
     51
     52The new class hierarchy is the following and is mostly consistant with SQL/MM Part 3
     53
     54[ diagram ]
     55
     56The only exceptions are :
     57  * OGRLinearRing: this class present in GDAL 1.X is kept for backward compatibility
     58    and also because it is still present in SFA 1.2.1, even if absent from SQL/MM Part 3
     59  * OGRSimpleCurve: this abstract class is an implementation detail in OGR that simplifies
     60    the implementation of OGRCircularString, by sharing code with what was in
     61    OGRLineString only.
     62
     63=== Geometry types ===
     64
     65The OGRwkbGeometryType enumeration has been extended with the following values :
     66
     67{{{
     68    wkbCircularString = 8,  /**< one or more circular arc segments connected end to end,
     69                             *   ISO SQL/MM Part 3. GDAL >= 2.0 */
     70    wkbCompoundCurve = 9,   /**< sequence of contiguous curves, ISO SQL/MM Part 3. GDAL >= 2.0 */
     71    wkbCurvePolygon = 10,   /**< planar surface, defined by 1 exterior boundary
     72                             *   and zero or more interior boundaries, that are curves.
     73                             *    ISO SQL/MM Part 3. GDAL >= 2.0 */
     74    wkbMultiCurve = 11,     /**< GeometryCollection of Curves, ISO SQL/MM Part 3. GDAL >= 2.0 */
     75    wkbMultiSurface = 12,   /**< GeometryCollection of Surfaces, ISO SQL/MM Part 3. GDAL >= 2.0 */
     76
     77    wkbCircularStringZ = 1008,  /**< wkbCircularString with Z component. ISO SQL/MM Part 3. GDAL >= 2.0 */
     78    wkbCompoundCurveZ = 1009,   /**< wkbCompoundCurve with Z component. ISO SQL/MM Part 3. GDAL >= 2.0 */
     79    wkbCurvePolygonZ = 1010,    /**< wkbCurvePolygon with Z component. ISO SQL/MM Part 3. GDAL >= 2.0 */
     80    wkbMultiCurveZ = 1011,      /**< wkbMultiCurve with Z component. ISO SQL/MM Part 3. GDAL >= 2.0 */
     81    wkbMultiSurfaceZ = 1012,    /**< wkbMultiSurface with Z component. ISO SQL/MM Part 3. GDAL >= 2.0 */
     82}}}
     83
     84The codes have been taken from SFA 1.2.1, and are consistant with the PostGIS 2
     85implementation. Note that ISO SQL/MM Part 3 allows alternates values for wkbCircularString
     86(8 or 1000001) : see Table 15 in the above mentionned draft. The values in the range
     8710000XX probably date back from an earlier draft version. OGR will import them, but
     88will use the values from SFA 1.2.1 when exporting WKB.
     89
     90It has been considered if it would worth to modify the enumeration values of the
     91existing 2.5D geometries (wkbPoint25D, etc...) to conform with the WKB codes of
     92ISO SQL/MM Part 3 / SFA 1.2.1, but there was not a clear advantage in doing so,
     93with respect to the impact on existing users of OGR API.
     94
     95The use of the wkb25DBit value (0x8000000) that was sometimes used to test if
     96a geometry type was 3D is now clearly deprecated since it will not work for
     97the new geometry type. The wkbHasZ() and wkbSetZ() have been added to respectively
     98test if a geometry type is 3D, or modify a geometry type to be 3D. The wkb25DBit
     99constant is now disabled for all code in GDAL (but still accessible by user code)
     100and all drivers have been converted to use the new macros.
     101
     102A new family of functions have been used to operate on geometry types :
     103
     104{{{
     105OGRwkbGeometryType CPL_DLL OGR_GT_Flatten( OGRwkbGeometryType eType );
     106    --> Returns the 2D geometry type corresponding to the passed geometry type.
     107
     108OGRwkbGeometryType CPL_DLL OGR_GT_SetZ( OGRwkbGeometryType eType );
     109    --> Returns the 3D geometry type corresponding to the passed geometry type.
     110
     111OGRwkbGeometryType CPL_DLL OGR_GT_SetModifier( OGRwkbGeometryType eType, int bSetZ, int bSetM );
     112    --> Returns a 2D or 3D geometry type depending on parameter.
     113
     114int                CPL_DLL OGR_GT_HasZ( OGRwkbGeometryType eType );
     115    --> Return if the geometry type is a 3D geometry type.
     116
     117int                CPL_DLL OGR_GT_IsSubClassOf( OGRwkbGeometryType eType,
     118                                                OGRwkbGeometryType eSuperType );
     119    --> Returns if a type is a subclass of another one
     120
     121int                CPL_DLL OGR_GT_IsCurve( OGRwkbGeometryType );
     122    -->  Return if a geometry type is an instance of Curve
     123        (i.e. wkbLineString, wkbCircularString or wkbCompoundCurve)
     124
     125int                CPL_DLL OGR_GT_IsSurface( OGRwkbGeometryType );
     126    -->  Return if a geometry type is an instance of Surface
     127        (i.e. wkbPolygon or wkbCurvePolygon)
     128
     129int                CPL_DLL OGR_GT_IsNonLinear( OGRwkbGeometryType );
     130    --> Return if a geometry type is a non-linear geometry type.
     131        Such geometry type are wkbCircularString, wkbCompoundCurve, wkbCurvePolygon,
     132        wkbMultiCurve, wkbMultiSurface and their 3D variant.
     133
     134OGRwkbGeometryType CPL_DLL OGR_GT_GetCollection( OGRwkbGeometryType eType );
     135    -->  Returns the collection type that can contain the passed geometry type
     136
     137OGRwkbGeometryType CPL_DLL OGR_GT_GetCurve( OGRwkbGeometryType eType );
     138    --> Returns the curve geometry type that can contain the passed geometry type.
     139        Handled conversions are : wkbPolygon -> wkbCurvePolygon,
     140        wkbLineString->wkbCompoundCurve, wkbMultiPolygon->wkbMultiSurface
     141        and wkbMultiLineString->wkbMultiCurve.
     142
     143OGRwkbGeometryType CPL_DLL OGR_GT_GetLinear( OGRwkbGeometryType eType );
     144    --> Returns the non-curve geometry type that can contain the passed geometry type
     145        Handled conversions are : wkbCurvePolygon -> wkbPolygon,
     146        wkbCircularString->wkbLineString, wkbCompoundCurve->wkbLineString,
     147        wkbMultiSurface->wkbMultiPolygon and wkbMultiCurve->wkbMultiLineString.
     148
     149}}}
     150
     151The existing wkbFlatten() is an alias of OGR_GT_Flatten(), the new wkbHasZ()
     152an alias of OGR_GT_HasZ() and wkbSetZ() an alias of OGR_GT_SetZ().
     153
     154=== New methods ===
     155
     156  * In OGRGeometry class :
     157{{{
     158
     159    virtual OGRBoolean hasCurveGeometry(int bLookForNonLinear = FALSE) const;
     160
     161/**
     162 * \brief Returns if this geometry is or has curve geometry.
     163 *
     164 * Returns if a geometry is, contains or may contain a CIRCULARSTRING, COMPOUNDCURVE,
     165 * CURVEPOLYGON, MULTICURVE or MULTISURFACE.
     166 *
     167 * If bLookForNonLinear is set to TRUE, it will be actually looked if the
     168 * geometry or its subgeometries are or contain a non-linear geometry in them. In which
     169 * case, if the method returns TRUE, it means that getLinearGeometry() would
     170 * return an approximate version of the geometry. Otherwise, getLinearGeometry()
     171 * would do a conversion, but with just converting container type, like
     172 * COMPOUNDCURVE -> LINESTRING, MULTICURVE -> MULTILINESTRING or MULTISURFACE -> MULTIPOLYGON,
     173 * resulting in a "loss-less" conversion.
     174 */
     175
     176    virtual OGRGeometry* getCurveGeometry(const char* const* papszOptions = NULL) const;
     177
     178/**
     179 * \brief Return curve version of this geometry.
     180 *
     181 * Returns a geometry that has possibly CIRCULARSTRING, COMPOUNDCURVE, CURVEPOLYGON,
     182 * MULTICURVE or MULTISURFACE in it, by de-approximating curve geometries.
     183 *
     184 * If the geometry has no curve portion, the returned geometry will be a clone
     185 * of it.
     186 *
     187 * The ownership of the returned geometry belongs to the caller.
     188 *
     189 * The reverse method is OGRGeometry::getLinearGeometry().
     190 *
     191 * This function is the same as C function OGR_G_GetCurveGeometry().
     192 *
     193 * @param papszOptions options as a null-terminated list of strings.
     194 *                     Unused for now. Must be set to NULL.
     195 */
     196
     197    virtual OGRGeometry* getLinearGeometry(double dfMaxAngleStepSizeDegrees = 0,
     198                                             const char* const* papszOptions = NULL) const;
     199
     200
     201/**
     202 * \brief Return, possibly approximate, non-curve version of this geometry.
     203 *
     204 * Returns a geometry that has no CIRCULARSTRING, COMPOUNDCURVE, CURVEPOLYGON,
     205 * MULTICURVE or MULTISURFACE in it, by approximating curve geometries.
     206 *
     207 * The ownership of the returned geometry belongs to the caller.
     208 *
     209 * The reverse method is OGRGeometry::getCurveGeometry().
     210 *
     211 * This method is the same as the C function OGR_G_GetLinearGeometry().
     212 *
     213 * @param dfMaxAngleStepSizeDegrees the largest step in degrees along the
     214 * arc, zero to use the default setting.
     215 * @param papszOptions options as a null-terminated list of strings.
     216 *                     See OGRGeometryFactory::curveToLineString() for valid options.
     217 */
     218
     219}}}
     220
     221
     222  * In OGRGeometryFactory class :
     223
     224{{{
     225
     226static OGRLineString* curveToLineString(
     227                                            double x0, double y0, double z0,
     228                                            double x1, double y1, double z1,
     229                                            double x2, double y2, double z2,
     230                                            int bHasZ,
     231                                            double dfMaxAngleStepSizeDegrees,
     232                                            const char*const* papszOptions )
     233/**
     234 * \brief Converts an arc circle into an approximate line string
     235 *
     236 * The arc circle is defined by a first point, an intermediate point and a
     237 * final point.
     238 *
     239 * The provided dfMaxAngleStepSizeDegrees is a hint. The discretization
     240 * algorithm may pick a slightly different value.
     241 *
     242 * So as to avoid gaps when rendering curve polygons that share common arcs,
     243 * this method is guaranteed to return a line with reversed vertex if called
     244 * with inverted first and final point, and identical intermediate point.
     245 *
     246 * @param x0 x of first point
     247 * @param y0 y of first point
     248 * @param z0 z of first point
     249 * @param x1 x of intermediate point
     250 * @param y1 y of intermediate point
     251 * @param z1 z of intermediate point
     252 * @param x2 x of final point
     253 * @param y2 y of final point
     254 * @param z2 z of final point
     255 * @param bHasZ TRUE if z must be taken into account
     256 * @param dfMaxAngleStepSizeDegrees  the largest step in degrees along the
     257 * arc, zero to use the default setting.
     258 * @param papszOptions options as a null-terminated list of strings or NULL.
     259 * Recognized options:
     260 * <ul>
     261 * <li>ADD_INTERMEDIATE_POINT=STEALTH/YES/NO (Default to STEALTH).
     262 *         Determine if and how the intermediate point must be output in the linestring.
     263 *         If set to STEALTH, no explicit intermediate point is added but its
     264 *         properties are encoded in low significant bits of intermediate points
     265 *         and OGRGeometryFactory::curveFromLineString() can decode them.
     266 *         This is the best compromise for round-tripping in OGR and better results
     267 *         with PostGIS <a href="http://postgis.org/docs/ST_LineToCurve.html">ST_LineToCurve()</a>
     268 *         If set to YES, the intermediate point is explicitely added to the linestring.
     269 *         If set to NO, the intermediate point is not explicitely added.
     270 * </li>
     271 * </ul>
     272 */
     273
     274--> This method is used by OGRCircularString::getLinearGeometry()
     275
     276OGRCurve* OGRGeometryFactory::curveFromLineString(const OGRLineString* poLS,
     277                                                  CPL_UNUSED const char*const* papszOptions)
     278
     279/**
     280 * \brief Try to convert a linestring approximating curves into a curve.
     281 *
     282 * This method can return a COMPOUNDCURVE, a CIRCULARSTRING or a LINESTRING.
     283 *
     284 * This method is the reverse of curveFromLineString().
     285 *
     286 * @param poLS handle to the geometry to convert.
     287 * @param papszOptions options as a null-terminated list of strings.
     288 *                     Unused for now. Must be set to NULL.
     289 */
     290
     291--> This method is used by OGRLineString::getCurveGeometry()
     292
     293
     294OGRGeometry* OGRGeometryFactory::forceTo( OGRGeometry* poGeom,
     295                                          OGRwkbGeometryType eTargetType,
     296                                          const char*const* papszOptions )
     297 *
     298 * Tries to force the provided geometry to the specified geometry type.
     299 *
     300 * It can promote 'single' geometry type to their corresponding collection type
     301 * (see OGR_GT_GetCollection()) or the reverse. non-linear geometry type to
     302 * their corresponding linear geometry type (see OGR_GT_GetLinear()), by
     303 * possibly approximating circular arcs they may contain.
     304 * Regarding conversion from linear geometry types to curve geometry types, only
     305 * "wraping" will be done. No attempt to retrieve potential circular arcs by
     306 * de-approximating stroking will be done. For that, OGRGeometry::getCurveGeometry()
     307 * can be used.
     308 *
     309 * The passed in geometry is consumed and a new one returned (or potentially the same one).
     310 *
     311 * @param poGeom the input geometry - ownership is passed to the method.
     312 * @param eTargetType target output geometry type.
     313 * @param papszOptions options as a null-terminated list of strings or NULL.
     314 * @return new geometry.
     315 */
     316
     317--> This method generalizes the existing forceToPolygon(), forceToLineString(),
     318forceToMultiPolygon(), forceToMultiLineString(), that have been extended to
     319deal with the new geometry types. forceTo() and actually calls them if they
     320can be used for the requested conversion, and also deal with conversion between
     321linear and non-linear geometry types.
     322
     323}}}
     324
     325=== Implementation of existing OGRGeometry methods ===
     326
     327As GEOS does not support curve geometries, all GEOS related operations, the ones
     328returning a boolean value such as Intersects(),
     329or the ones returning a new geometry such as Intersection(), have been adapted
     330so that non-linear geometries are first converted to their linear approximation.
     331When GEOS returns a geometry, and that one of the input parameters was a non-linear
     332geometry, the reverse operation is done to attempt retrieving
     333as much as possible of the curve geometry. Of course, the result will not
     334generally perfect, but it is better than nothing.
     335
     336Simple example doing the union of 2 half-circles that are contiguous:
     337{{{
     338    g1 = ogr.CreateGeometryFromWkt('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING (0 0,1 1,2 0),(2 0,0 0)))')
     339    g2 = ogr.CreateGeometryFromWkt('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING (0 0,1 -1,2 0),(2 0,0 0)))')
     340    g3 = g1.Union(g2)
     341    assert g3.ExportToWkt() == 'CURVEPOLYGON (CIRCULARSTRING (0 0,1 1,2 0,1 -1,0 0))'
     342}}}
     343
     344Or using GetCurveGeometry() explicitely on the result of a buffer operation:
     345{{{
     346    g1 = ogr.CreateGeometryFromWkt('POINT(1 2)')
     347    g2 = g1.Buffer(0.5)
     348    g3 = g2.GetCurveGeometry()
     349    assert g3.ExportToWkt() != 'CURVEPOLYGON (CIRCULARSTRING (1.5 2.0,0.5 2.0,1.5 2.0))'
     350}}}
     351
     352The Length() operation on OGRCircularString (and thus OGRCompoundCurve) uses
     353circle geometry to compute the exact length, without falling back to linear
     354approximation.
     355The Area() operation on OGRCurvePolygon will generally need to go to linear
     356approximation. When operating on a full circle, or a curve polygon that is convex,
     357an optimization is done to avoid this (by computing the area of the polygon formed
     358with all the vertex including in the circular parts of the description, and
     359adding the area of the [http://en.wikipedia.org/wiki/Circular_segment circular segments])
     360
     361=== C API changes ===
     362
     363Deprecation:
     364  * wkb25DBit still present, but deprecated since incompatible with the new
     365    geometry type. Use the wkbFlatten(), wkbHasZ(), wkbSetZ() macros instead
     366
     367Additions:
     368  * OGR_GT_xxxx (for Geometry Type): described above
     369  * OGRErr OGR_G_ExportToIsoWkb( OGRGeometryH, OGRwkbByteOrder, unsigned char*) :
     370    Export geometry as WKB conforming to ISO SQL/MM Part 3.
     371  * OGRErr OGR_G_ExportToIsoWkt( OGRGeometryH, char ** ) :
     372    Export geometry as WKT conforming to ISO SQL/MM Part 3, i.e. 2.5D geometries
     373    names are suffixed by " Z", e.g. "POINT Z (1 2 3)".
     374  * OGRGeometryH OGR_G_Value( OGRGeometryH, double dfDistance ) :
     375    mapping of existing OGRGeometry::Value()
     376  * int OGR_G_HasCurveGeometry( OGRGeometryH, int bLookForNonLinear ) :
     377    mapping of OGRGeometry::hasCurveGeometry()
     378  * OGRGeometryH OGR_G_GetLinearGeometry( OGRGeometryH hGeom, double dfMaxAngleStepSizeDegrees, char** papszOptions) :
     379    mapping of OGRGeometry::hasCurveGeometry()
     380  * OGRGeometryH OGR_G_GetCurveGeometry( OGRGeometryH hGeom, char** papszOptions ) :
     381    mapping of OGRGeometry::hasCurveGeometry()
     382  * void OGRSetNonLinearGeometriesEnabledFlag(int bFlag) : discussed in Backward compatibility section
     383  * int OGRGetNonLinearGeometriesEnabledFlag() : discussed in Backward compatibility section
     384
     385== Changes in drivers ==
     386
     387  * GML geometry importer: Arc, ArcString, ArcByBulge, ArcByCenterPoint, Circle
     388    and CircleByCenterPoints GML elements will be returned as circular string OGR geometries.
     389    If they are included in other GML elements such as CurveComposite, MultiCurve, Surface,
     390    corresponding non-linear OGR geometries will be returned as well. When reading geometries
     391    that are made of or consist of Surface, MultiSurface, Curve, MultiCurve, an effort is
     392    made to return the OGR geometry class of a linear type as much as possible, i.e.
     393    OGRCurvePolygon, OGRCompoundCurve, etc... will only be returned if there's a circular
     394    string in the geometry.
     395
     396  * GML geometry exporter: can generate ArcString and Circle GML elements when passed
     397    a geometry with circular string in it.
     398
     399  * GML driver: Can read/write all the new geometry types.
     400    When reading GML3 application schemas, declarations of geometry fields such as
     401    CurvePropertyType, SurfacePropertyType, MultiCurvePropertyType or MultiSurfacePropertyType
     402    will be also interpreted as being potential non-linear geometries, and corresponding
     403    OGR geometry type will be used for the layer geometry type, and the geometries
     404    of the feature will also follow that layer geometry type. This can affect the WFS drivers.
     405
     406  * NAS driver: Can return the new geometry types. NAS layers will use the new geometry
     407    types only if the NAS file contains arcs.
     408
     409  * PG/PostGIS: Can read/write all the new geometry types for both PostGIS 2.X and
     410    PostGIS 1.X. For PostGIS 1.X compatiblity, special processing must be done in
     411    the importFromWkb()/exportToWkb() to deal with the non standard codes used by PostGIS 1.X
     412    for curvepolygon, multicurve and multisurface. This is done with a wkbVariantPostGIS1
     413    value added to OGRwkbVariant enumeration used by those methods.
     414
     415  * PGDump: Can write all new geometry types. Above remark related to the differences
     416    among version make it important to specify correctly the POSTGIS_VERSION dataset creation
     417    option.
     418 
     419  * GeoPackage: Can read/write all the new geometry types. Note: this isn't in
     420    the core of the GeoPackage specification, but it is still a registered
     421    extension.
     422
     423  * MEM: Can read/write all the new geometry types.
     424
     425  * CSV: Can read/write all the new geometry types.
     426
     427  * VRT: Declared as compatible with all the new geometry types. Actual capability
     428    will depend on the underlying layers wrapped by the VRT.
     429
     430
     431== Changes in utilities ==
     432
     433  * ogr2ogr: the new geometry names (CIRCULARSTRING, etc...) are supported in
     434    the -nlt option. "-nlt CONVERT_TO_LINEAR" can also be used to ask curve
     435    geometries to be converted into their linear approximation ( what is used to do that is
     436    forceTo(xxx, OGR_GT_GetLinear()) ). Note: this isn't strictly necessary as
     437    all drivers should be able to deal with the non-linear geometry types with
     438    the compatibility mechanism described in Backward compatibility. But this
     439    might be usefull to produce a PostGIS table or GeoPackage database with linear
     440    geometry types even if the source contains non-linear geometries.
     441    "-nlt CONVERT_TO_LINEAR" can be combined with "-nlt PROMOTE_TO_MULTI".
     442
     443== Changes in SWIG bindings ==
     444
     445Addition of :
     446  * the new geometry types as ogr.wkbXXXXX
     447  * ogr.ForceTo()
     448  * Geometry.ExportToIsoWkt()
     449  * Geometry.ExportToIsoWkb()
     450  * Geometry.HasCurveGeometry(int bLookForCircular = FALSE)
     451  * Geometry.GetLinearGeometry(double dfMaxAngleStepSizeDegrees = 0.0,char** options = NULL)
     452  * Geometry.GetCurveGeometry(char** options = NULL)
     453  * ogr.SetNonLinearGeometriesEnabledFlag(int bFlag)
     454  * ogr.GetNonLinearGeometriesEnabledFlag()
     455
     456== Related changes that are *NOT* included in this RFC ==
     457
     458  * Support for other ISO SQL/MM geometries such as Polyhedral Surface,
     459    Triangulated Irregular Network (TIN), Triangle.
     460  * Support for the M (Measure) dimension of geometries.
     461  * Upgrade of other drivers that could make use of curve geometries : MSSQL Spatial,
     462    Oracle Spatial, DXF, DWG, ...
     463  * Support for arbitrary new geometry types: Conceptually one could hope that
     464    a new class extending OGRCurve (Bezier or Spline curve) for example could be
     465    added without touching OGR core. This isn't currently possible: changes in
     466    OGRGeometryFactory and the OGR_GT_ functions would be needed to remove a
     467    few hardcoded assumptions.
     468
     469== Backward compatibility ==
     470
     471=== Regarding code using GDAL ===
     472
     473Many applications will not be able to properly deal with the new geometry
     474types that may now be returned by some drivers.
     475If they don't want to test the geometry type and explicitely calling
     476the conversion function, they can call OGRSetNonLinearGeometriesEnabledFlag(FALSE)
     477(the default value is TRUE, i.e. non-linear geometries can be returned). In which case, they
     478will be transformed into their closest linear geometry, by doing linear
     479approximation, with OGR_G_ForceTo().
     480
     481This flag has only an effect on the OGR_F_GetGeometryRef(), OGR_F_GetGeomFieldRef(),
     482OGR_L_GetGeomType(), OGR_GFld_GetType() and OGR_FD_GetGeomType() C API, and
     483corresponding methods in the SWIG bindings.
     484
     485Libraries should generally *not* use that method, since that could interfere
     486with other libraries or applications.
     487
     488Note that it does *not* affect the behaviour of the C++ API. It has been deemed
     489dangerous/complicated to try doing that at the C++ level as it could confuse
     490drivers since they might call GetGeomType() for example.
     491
     492=== Regarding OGR drivers ===
     493
     494Drivers that can deal with the new geometry types SHOULD declare the new dataset
     495level ODsCCurveGeometries AND layer level OLCCurveGeometries capabilities. The
     496virtual methods CreateFeature() and SetFeature() implemented by drivers have
     497been renamed ICreateFeature() and ISetFeature(). OGRLayer has now a non-virtual
     498CreateFeature() and SetFeature() that checks if the layer has curve geometry
     499capability. If it has not, and that the passed feature has non-linear geometries,
     500they will be transparently converted to their linear approximation before calling
     501the driver ICreateFeature()/ISetFeature() method.
     502Similarly the CreateLayer() method at datasource level will convert the passed
     503geometry type to a non-linear corresponding type if necessary.
     504
     505All in-tree drivers have been converted to switch from CreateFeature() to
     506ICreateFeature() and SetFeature() to ISetFeature(). Out-of-tree drivers will
     507have to be adapted similarly otherwise those methods will fails (the now non-virtual
     508methods in OGRLayer class will try to create the default implementation of the
     509same class, which will fail).
     510
     511== Documentation ==
     512
     513All new methods and OGR geometry classes are documented. Driver documentation
     514is updated when necessary. MIGRATION_GUIDE.TXT is updated with a summary of
     515the text of this RFC.
     516
     517== Testing ==
     518
     519Very few changes have been made so that the existing autotest suite still
     520passes.
     521Very comprehensive testing of new geometry classes and conversion methods has
     522been added to ogr_geom.py and ogr_gml_geom.py. Updated drivers have received
     523new tests also.
     524
     525== Implementation ==
     526
     527Implementation will be done by Even Rouault.
     528
     529The proposed implementation lies in the "curve_geometries" branch of the
     530https://github.com/rouault/gdal2/tree/curve_geometries repository.
     531
     532The list of changes : https://github.com/rouault/gdal2/compare/curve_geometries
     533
     534== Voting history ==
     535
     536TBD.