RFC 61:测量几何图形的支持
作者:Ari Jolma
联系人:ari.jolma,gmail.com
状态:通过
版本实现:2.1
总结
此RFC定义了如何实现测量的几何图形(几何图形,其中点具有M坐标,即它们是XYM或XYZM)。
理论基础
M坐标,也称为“测量”,是可以为几何图形的每个点存储的附加值(IBM技术说明, https://www-304.ibm.com/support/docview.wss?uid=swg21054384 )
M坐标在OGC简单特征模型中,它被用于多种矢量数据格式。
变化
在C++ API中需要进行更改,需要增强C API。一些驱动程序需要改变以利用这种增强,但也由于C++ API的改变。
通用API
需要新的OGRwkbGeometryType值。将使用SFSQL 1.2和ISO SQL/MM第3部分,即M为2D类型+2000,ZM为2D类型+3000。(也可以添加类型,如Tin、多面体曲面和三角形类型以获得完整性,即使当前未实现)。wkbCurve和wkbSurface已从“define”移到“OGRwkbGeometryType”枚举,并添加了它们的Z/M/ZM变体(根据6401)
总的来说,有可能(应该?)成为使用一组干净值的路径,并将遗留支持作为异常。
抽象类型是定义的,而不是枚举的一部分。
// additions to enum OGRwkbGeometryType
wkbCurve = 13, /**< Curve (abstract type). ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbSurface = 14, /**< Surface (abstract type). ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbPolyhedralSurface = 15,/**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbTIN = 16, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbTriangle = 17, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbCurveZ = 1013, /**< wkbCurve with Z component. ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbSurfaceZ = 1014, /**< wkbSurface with Z component. ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbPolyhedralSurfaceZ = 1015, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbTINZ = 1016, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbTriangleZ = 1017, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbPointM = 2001, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbLineStringM = 2002, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbPolygonM = 2003, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbMultiPointM = 2004, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbMultiLineStringM = 2005, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbMultiPolygonM = 2006, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbGeometryCollectionM = 2007, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbCircularStringM = 2008, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbCompoundCurveM = 2009, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbCurvePolygonM = 2010, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbMultiCurveM = 2011, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbMultiSurfaceM = 2012, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbCurveM = 2013, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbSurfaceM = 2014, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbPolyhedralSurfaceM = 2015, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbTINM = 2016, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbTriangleM = 2017, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbPointZM = 3001, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbLineStringZM = 3002, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbPolygonZM = 3003, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbMultiPointZM = 3004, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbMultiLineStringZM = 3005, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbMultiPolygonZM = 3006, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbGeometryCollectionZM = 3007, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbCircularStringZM = 3008, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbCompoundCurveZM = 3009, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbCurvePolygonZM = 3010, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbMultiCurveZM = 3011, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbMultiSurfaceZM = 3012, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbCurveZM = 3013, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbSurfaceZM = 3014, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbPolyhedralSurfaceZM = 3015, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbTINZM = 3016, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
wkbTriangleZM = 3017, /**< ISO SQL/MM Part 3. GDAL >= 2.1 */
// add tests for M
#define wkbHasM(x) OGR_GT_HasM(x)
#define wkbSetM(x) OGR_GT_SetM(x)
OGRwkbGeometryType CPL_DLL OGR_GT_SetM( OGRwkbGeometryType eType );
int CPL_DLL OGR_GT_HasM( OGRwkbGeometryType eType );
C++ API
类OGRGeometry中的属性int ncordinatedimmension将被int flags替换。它可能有以下标志:
#define OGR_G_NOT_EMPTY_POINT 0x1
#define OGR_G_3D 0x2
#define OGR_G_MEASURED 0x4
#define OGR_G_IGNORE_MEASURED 0x8
为了向后兼容,内部需要使用“ignore”标志。标志OGR_G_NOT_EMPTY_POINT仅用于表示OGRPoint对象的空性。
目前,设置nCoordDimension负数的技巧用于表示一个空点。
删除不协调维度可能意味着获取或设置它的驱动程序等发生更改。
测试是
Is3D = flags & OGR_G_3D
IsMeasured = flags & OGR_G_MEASURED
setter和getter是用|=和&=实现的。
当这些标志中的任何一个被设置或取消设置时,相应的数据将无效并可能被丢弃。
保留以下具有原始语义的方法,即坐标维为2或3,但不推荐。文件中有一些不符之处。他们的文档说,在ogrpoint.cpp中,空点可能返回零,而在ogrpoint.cpp中,空点使用负nCoordDimension值,点的getcoorderedimension方法返回nCoordDimension的绝对值,因此不是零。医生的治疗也许就足够了。
int getCoordinateDimension();
void setCoordinateDimension(int nDimension);
void flattenTo2D()
提出了一种新的方法来代替getCoordinateDimension。set3D和setMeasured将替换setCoordinateDimension并展平到2d。请参见下文。
类几何测量:
//Possibly add methods (SF Common Architecture):
int Dimension(); // -1 for empty geometries (to denote undefined), 0 for points, 1 for curves, 2 for surfaces, max of components for collections
char *GeometryType(); // calls OGRToOGCGeomType (which needs to be enhanced)
//Add methods (SF Common Architecture) see above for implementation:
int CoordinateDimension(); // 2 if not 3D and not measured, 3 if 3D or measured, 4 if 3D and measured
OGRBoolean Is3D() const;
OGRBoolean IsMeasured() const;
//Add methods (non-standard; note the use of one method instead of second unset* method):
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);
//Remove b3D from importPreambleFromWkb: it is not used, the flags are managed within the method.
int CoordinateDimension()应该有新的语义。简单特征文档中的方法名实际上没有前缀get。
set3D和setMeasured是否应该影响集合中的子几何图形是一个问题。目前setCoordinateDimension的doc说“设置几何集合的维度将影响子几何图形”,因此我们已经承诺在集合中维护子几何图形的维度。建议set3D和setMeasured向几何体(包括可能的子对象)添加或删除Z或M值。一般来说,战略应遵循关于Z的现有战略(即删除或添加)。
将属性double m添加到类OGRPoint中。为它添加构造函数、getter和setter。
添加属性double * padfM到OGRSimpleCurve类。为它添加构造函数、getter和setter。XY M数据需要具有postfix M的新setter,因为在setters中对象可能从XY升级到XYZ。Add还使用与Make3D和Make2D具有类似语义的RemoveM()和AddM()方法。
在重写setCoordinatedDimension的类中重写方法set3D和setMeasured。
更改名称以开头的方法的语义 _ 并有一个参数“int b3D”。参数将是“int coordinates”,即一个类似int的标志,它表示Z和M。
计算机辅助编程接口
ogr_core.h:核心
OGRwkbGeometryType CPL_DLL OGR_GT_SetM( OGRwkbGeometryType eType );
int CPL_DLL OGR_GT_HasM( OGRwkbGeometryType eType );
当前的行为是,对具有坐标尺寸2的几何体调用设定点会升级坐标尺寸3。为了保持2D点,必须使用2D设定点。因此,对于M和ZM几何,我们需要单独的函数。建议使用后缀M和ZM,即SetPointM和SetPointZM。AddPoint也一样。
目前没有设置点2 D功能。pabyZ param at SetPoints的doc注释为“对于2D对象默认为空”,但情况似乎并非如此。见#6344。如果按照这里写的那样修复,那么只需要SetPointsZM。
GetPoint和GetPoints没有2D版本,因此只有 * 需要ZM版本。
ogr_api.h:美国石油天然气协会
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 );
double CPL_DLL OGR_G_GetM( OGRGeometryH, int );
ogr_p.h(这是公共头,因此需要新函数)
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 ); // int = flags OGR_G_3D OGR_G_MEASURED
// Change the semantics of OGRReadWKBGeometryType: b3D is not used and the returned eGeometryType may may any valid type
h是内部的,所以我们可以改变函数原型
void OGRCreateFromMultiPatchPart(OGRMultiPolygon *poMP,
OGRPolygon*& poLastPoly,
int nPartType,
int nPartPoints,
double* padfX,
double* padfY,
double* padfZ,
double* padfM);
使用padfM需要更改openfilegdb驱动程序。
地理信息、过滤器和其他问题
将具有度量值的几何图形发送到GEOS或用作过滤器时,将忽略M坐标。
LocateAlong和LocateBetween是唯一的标准方法,它们使用M,但也可能有其他方法,例如获取M的范围。现在不打算添加这些方法,但以后可以添加它们。
SWIG绑定(Python/Java/C#/Perl)更改
新的C API函数需要通过swig公开。进一步的更改取决于语言绑定是否知道坐标。至少Python和Perl是。
新的几何图形类型将包含在i文件中。
需要为M.Is3D、IsMeasured、Set3D和SetMeasured方法添加一些新的setter和getter。同样的。
驱动程序
至少受C++更改影响的驱动程序至少是(使用Stand Advsiple API)PG、MSSQLSPACE、SQLite、DB2、MySQL、GML、PGDUMP、GEJSON、LIKKML、GPKG、WASP、GPX、FILGDB、VFK、BNA、DXF。
现在不推荐使用的coordinatedimmensionapi被替换为调用 * 3D和 * 仔细斟酌的。
一旦M坐标的支持到位,驱动程序将公布支持。
在这个RFC的工作中,支持被内置到内存、shape和pg驱动程序中。对其他司机的支持还有待进一步工作。
公用事业
有一个最低要求和新的可能性。
ogrinfo:报告测量的几何类型,报告测量
ogr2ogr:支持测量的几何类型
ogrlineref:似乎是专门处理措施的,需要更多的思考
gdal_rasterize:测量值可用于老化值
gdal_contour:测量值可用作“高程”值
gdal_grid:measure可以用作“Z”值
文档
所有新的方法/功能都记录在案。
测试套件
至少最初的测试将使用Perl单元测试(swi/Perl/t/measures)完成- * .t)。稍后将扩展自动测试套件。现有的测试不应失败。
兼容性问题
许多支持度量的驱动程序(实际上是数据集和层)需要添加支持。应使用
#define ODsCMeasuredGeometries "MeasuredGeometries"
#define OLCMeasuredGeometries "MeasuredGeometries"
创建层的入口点是GDALDataset中的CreateLayer方法。如果数据集不支持测量的几何图形,它将从作为参数获取的几何图形类型中除去测量标志。这符合当前行为非线性几何类型和不支持它们的数据集。
ICreateLayer是所有具有创建层功能的驱动程序实现的,它的参数是几何类型。该方法应使用CPLE_NotSupported调用CPLError(),如果驱动程序不支持度量值,则返回NULL。对于ICreateFeature和ISetFeature也一样。
面向用户的API函数(CreateLayer、CreateFeature和SetFeature)在继续I * 不支持措施的驱动程序中的方法。这种(副作用)可能不是某些使用场景所需要的,但它将遵循非线性几何已经完成的模式。这应该记录在案。
另一种方法是将M个值(或WKT或WKB)存储为属性(标量或向量,具体取决于几何类型)。
需要一个决定。
一定会引入一些不相容性。例如,当当前的XYM as XYZ hack in shape将被适当的XYM替换时。
实施
执行工作将由arijolma完成。
投票历史
+1个来自Even,Tamas,Jukka和Daniel