wiki:rfc61_support_for_measured_geometries

Version 2 (modified by Ari Jolma, 8 years ago) ( diff )

--

RFC 61 : Support for measured geometries

Author: Ari Jolma

Contact: ari.jolma at gmail.com

Status: Draft

Implementation version: 2.1 or 2.2

Summary

This RFC defines how to implement measured geometries (geometries, where the points have M coordinate, i.e., they are XYM or XYZM).

Rationale

M coordinate is in the OGC simple feature model and it is used in many vector data formats.

Changes

Changes are required into the C++ API and the C API needs to be enhanced. Several drivers need to be changed to take advantage of this enhancement but also due to the changes in the C++ API.

Common API

New OGRwkbGeometryType values are needed - that is a rather complex system due to history. SFSQL 1.2 and ISO SQL/MM Part 3 will be used, i.e., 2D type + 2000 for M and 2D type + 3000 for ZM. (Also types such as Tin and PolyhedralSurface types can be added for completeness, even if unimplemented currently)

C++ API

The property int nCoordinateDimension in class OGRGeometry will be replaced by int flags. It may have the following flags:

#define OGR_G_NOT_EMPTY 0x1
#define OGR_G_3D 0x2
#define OGR_G_MEASURED 0x4

Currently hacks such as nCoordDimension == -2 are used to denote empty geometries. This implies many changes to drivers etc. which get or set nCoordinateDimension.

IsEmpty = !(flags & OGR_G_NOT_EMPTY), Is3D = flags & OGR_G_3D, IsMeasured = flags & OGR_G_MEASURED.

Keep, but deprecate

getCoordinateDimension();
setCoordinateDimension();

class OGRGeometry:

//Add methods:
int CoordinateDimension();
OGRBoolean Is3D();
OGRBoolean IsMeasured();
virtual void set3D(OGRBoolean bIs3D);
virtual void setMeasured(OGRBoolean bIsMeasured);

//Add now or later methods:
virtual OGRGeometry *LocateAlong(double mValue);
virtual OGRGeometry *LocateBetween(double mStart, double mEnd);

Add property double m to class OGRPoint. Add constructor, getters, and setters for it.

Add property double *padfM to class OGRSimpleCurce. Add constructor, getters, and setters for it. The getters and setters can take advantage of the flags to determine whether Z or M is to be set in some of them. For backwards compatibility Z is preferred.

Override methods set3D and setMeasured in those classes where setCoordinateDimension is overridden.

C API

ogr_core.h:

OGRwkbGeometryType CPL_DLL OGR_GT_SetM( OGRwkbGeometryType eType );
int                CPL_DLL OGR_GT_HasM( OGRwkbGeometryType eType );

ogr_api.h: (new versions of some functions are needed, use postfix M)

void   CPL_DLL OGR_G_Is3D( OGRGeometryH );
void   CPL_DLL OGR_G_IsMeasured( OGRGeometryH );

void   CPL_DLL OGR_G_Set3D( OGRGeometryH, int );
void   CPL_DLL OGR_G_SetMeasured( OGRGeometryH, int );

int    CPL_DLL OGR_G_GetPointsM( OGRGeometryH hGeom,
                                 void* pabyX, int nXStride,
                                 void* pabyY, int nYStride,
                                 void* pabyZ, int nZStride,
                                 void* pabyM, int nMStride);
double CPL_DLL OGR_G_GetM( OGRGeometryH, int );
void   CPL_DLL OGR_G_GetPointM( OGRGeometryH, int iPoint, 
                                double *, double *, double *, double * );
void   CPL_DLL OGR_G_SetPointM( OGRGeometryH, int iPoint, 
                                double, double, double, double );
void   CPL_DLL OGR_G_AddPointM( OGRGeometryH, double, double, double, double );
void   CPL_DLL OGR_G_SetPointsM( OGRGeometryH hGeom, int nPointsIn,
                                 void* pabyX, int nXStride,
                                 void* pabyY, int nYStride,
                                 void* pabyZ, int nZStride,
                                 void* pabyM, int nMStride );

ogr_p.g

const char CPL_DLL * OGRWktReadPointsM( const char * pszInput,
                                       OGRRawPoint **ppaoPoints, 
                                       double **ppadfZ,
                                        double **ppadfM,
                                       int * pnMaxPoints,
                                       int * pnReadPoints );
void CPL_DLL OGRMakeWktCoordinateM( char *, double, double, double, double, int );

pggeometry.h is internal, so we can change the function prototype

void OGRCreateFromMultiPatchPart(OGRMultiPolygon *poMP,
                                 OGRPolygon*& poLastPoly,
                                 int nPartType,
                                 int nPartPoints,
                                 double* padfX,
                                 double* padfY,
                                 double* padfZ,
                                 double* padfM);

SWIG bindings (Python / Java / C# / Perl) changes

The new C API functions need to be exposed through swig. Further changes depend on whether the language bindings are aware of coordinates. At least Python and Perl are.

Drivers

Drivers that are probably affected by the C++ changes are at least (these use the CoordinateDimension API) pg, mssqlspatial, sqlite, db2, mysql, gml, pgdump, geojson, libkml, gpkg, wasp, gpx, filegdb, vfk, bna, dxf.

Utilities

to do

Documentation

All new methods/functions are documented.

Test Suite

to do

Compatibility Issues

Many drivers (actually datasets and layers) which support measures need to have the support added. Support should be advertised using

#define ODsCMeasuredGeometries   "MeasuredGeometries"
#define OLCMeasuredGeometries    "MeasuredGeometries"

ICreateLayer, which all(?) drivers implement, have geometry type as an argument. The method should call CPLError() with CPLE_NotSupported and return NULL if the driver does not support measures. Similarly for ICreateFeature and ISetFeature.

Related tickets

https://trac.osgeo.org/gdal/ticket/6063 https://trac.osgeo.org/gdal/ticket/6331

Implementation

The implementation will be done by Ari Jolma.

The proposed implementation will be in https://github.com/ajolma/GDAL-XYZM

Voting history

Note: See TracWiki for help on using the wiki.