)
GIS遥感数据工程【免费下载链接】gdalGDAL is an open source MIT licensed translator library for raster and vector geospatial data formats.项目地址https://gitcode.com/gh_mirrors/gd/gdal点击查看免费下载导读本文围绕 GDAL/OGR 历史 RFC 18doc/source/development/rfc/rfc18_ogr_styles_c_api.rst展开系统讲解 OGR 特征样式Feature Style信息如何从 C 类封装走向 C API包括枚举定义的下沉、OGR_SM_*样式管理器与OGR_ST_*样式工具两族函数的完整签名、参数语义与落地差异。读完本文你将掌握如何仅用 C API 完成样式字符串的解析、拆分、参数读写与颜色解析并能对照当前仓库源码ogr/ogr_core.h、ogr/ogr_api.h、ogr/ogr_featurestyle.h理解其真实实现状态。一、RFC 背景为什么需要一个样式 C APIOGR 早在 1.4.x 及更早版本中就拥有若干处理样式Style编码与挂接的 C 类用于在矢量要素Feature上携带如何渲染的描述信息例如线的颜色与宽度、面的填充与影线、点符号、标注文字等。这类信息的完整规范在 OGR 的 Feature Style 文档即 RFC 中的:ref:ogr_feature_style被 doc/source/drivers/vector/dgn.rst 等多个驱动引用中说明。然而在 GDAL/OGR 1.4.x 及更早的版本中C API 用户无法接触任何样式信息——样式功能被锁定在 C 类体系内。而 GDAL 的核心定位是以 C API 为稳定对外接口的翻译库大量第三方应用如 MapServer通过 C 接口使用 OGR。因此 RFC 18 提出在 GDAL/OGR 1.5 中向 C API 增加一组操作样式信息的函数由作者 Daniel Morissette 实现并于 2007-12-05 被 PSC 全体成员FrankW、DanielM、HowardB、TamasS、AndreyK一致通过1。二、设计核心把枚举定义下沉到 ogr_core.hRFC 18 的第一步是把样式相关的枚举从ogr_featurestyle.h移到ogr_core.h因为 C API 的头文件ogr_api.h、ogr_core.h不允许依赖 OGR 内部的 C 类头文件而这些枚举的取值必须能被 C 代码直接引用。需要迁移的枚举共 5 个见 ogr/ogr_core.h 第 1091 行起的 ogr_featurestyle.h related definitions 区块枚举用途当前取值见 ogr_core.hOGRSTClassId样式工具StyleTool的类型OGRSTCNone0、OGRSTCPen1、OGRSTCBrush2、OGRSTCSymbol3、OGRSTCLabel4、OGRSTCVector5OGRSTUnitId样式工具使用的单位OGRSTUGround0、OGRSTUPixel1、OGRSTUPoints2、OGRSTUMM3、OGRSTUCM4、OGRSTUInches5OGRSTPenParam线样式Pen参数索引OGRSTPenColor0、OGRSTPenWidth1、OGRSTPenPattern2、OGRSTPenId3、OGRSTPenPerOffset4、OGRSTPenCap5、OGRSTPenJoin6、OGRSTPenPriority7OGRSTBrushParam面样式Brush参数索引OGRSTBrushFColor0、OGRSTBrushBColor1、OGRSTBrushId2、OGRSTBrushAngle3、OGRSTBrushSize4、OGRSTBrushDx5、OGRSTBrushDy6、OGRSTBrushPriority7OGRSTSymbolParam点符号样式Symbol参数索引OGRSTSymbolId0、OGRSTSymbolAngle1、OGRSTSymbolColor2、OGRSTSymbolSize3、OGRSTSymbolDx4、OGRSTSymbolDy5、OGRSTSymbolStep6、OGRSTSymbolPerp7、OGRSTSymbolOffset8、OGRSTSymbolPriority9、OGRSTSymbolFontName10、OGRSTSymbolOColor11OGRSTLabelParam标注样式Label参数索引OGRSTLabelFontName0、OGRSTLabelSize1、OGRSTLabelTextString2、OGRSTLabelAngle3、OGRSTLabelFColor4、OGRSTLabelBColor5、OGRSTLabelPlacement6、OGRSTLabelAnchor7、OGRSTLabelDx8、OGRSTLabelDy9、OGRSTLabelPerp10、OGRSTLabelBold11、OGRSTLabelItalic12、OGRSTLabelUnderline13、OGRSTLabelPriority14、OGRSTLabelStrikeout15、OGRSTLabelStretch16、OGRSTLabelHColor19、OGRSTLabelOColor20其中OGRSTLabelAdjHor17、OGRSTLabelAdjVert18已被标记为 OBSOLETE勿再使用需要特别说明的是OGRSTVectorParam枚举与OGRStyleVector类。RFC 指出虽然ogr_featurestyle.h中还存在OGRSTVectorParam及对应类但该类当时尚未被使用且可能在未来被移除因此不为它在 C API 中实现支持OGRSTVectorParam也不迁移到ogr_core.h——这是 RFC 对 API 面刻意收敛的例证。三、OGRStyleMgr 的 C API 封装OGR_SM_* 函数族RFC 18 为对应 C 类OGRStyleMgr定义于 ogr/ogr_featurestyle.h新增OGRStyleMgrH句柄类型及以下函数RFC 原文提案签名OGRStyleMgrH OGR_SM_Create() void OGR_SM_Destroy(OGRStyleMgrH hSM) const char *OGR_SM_InitFromFeature(OGRStyleMgrH hSM) int OGR_SM_InitFromStyleString(const char *pszStyleString) int OGR_SM_GetPartCount(OGRStyleMgrH hSM) OGRStyleToolH OGR_SM_GetPart(OGRStyleMgrH hSM) int OGR_SM_AddPart(OGRStyleMgrH hSM, OGRStyleTool *sPart)对照当前仓库 ogr/ogr_api.h 第 890–902 行实际落地的签名已发生演进比 RFC 提案更完整、更健壮OGRStyleMgrH OGR_SM_Create(OGRStyleTableH hStyleTable) CPL_WARN_UNUSED_RESULT; void OGR_SM_Destroy(OGRStyleMgrH hSM); const char *OGR_SM_InitFromFeature(OGRStyleMgrH hSM, OGRFeatureH hFeat); int OGR_SM_InitStyleString(OGRStyleMgrH hSM, const char *pszStyleString); int OGR_SM_GetPartCount(OGRStyleMgrH hSM, const char *pszStyleString); OGRStyleToolH OGR_SM_GetPart(OGRStyleMgrH hSM, int nPartId, const char *pszStyleString); int OGR_SM_AddPart(OGRStyleMgrH hSM, OGRStyleToolH hST); int OGR_SM_AddStyle(OGRStyleMgrH hSM, const char *pszStyleName, const char *pszStyleString);落地版本的关键差异与语义如下OGR_SM_Create接受可选的OGRStyleTableH hStyleTable参数用于关联一个样式表Style Table——这与 C 类构造函数OGRStyleMgr(OGRStyleTable *poStyleTable nullptr)的形态一致返回的句柄带CPL_WARN_UNUSED_RESULT警告属性提醒调用方检查创建结果OGR_SM_InitFromFeature(hSM, hFeat)从要素读取样式字符串并初始化管理器返回样式字符串本身函数名由 RFC 提案的OGR_SM_InitFromStyleString调整为OGR_SM_InitStyleString且显式传入样式字符串OGR_SM_GetPartCount与OGR_SM_GetPart都需要传入样式字符串参数GetPart还需nPartId指定取第几个样式部件——因为一个样式字符串可由多个部件Part用;连接OGR_SM_AddPart(hSM, hST)把一个OGRStyleToolH追加进管理器对应 C 的AddPart(OGRStyleTool *)见 ogr/ogr_featurestyle.h 第 133 行额外提供OGR_SM_AddStyle用于把命名样式写入关联的样式表。四、OGRStyleTool 的 C API 封装OGR_ST_* 函数族RFC 18 为 C 基类OGRStyleToologr/ogr_featurestyle.h 第 98 行前向声明派生体系见下文新增OGRStyleToolH句柄及函数族这是整个 C API 中直接面对具体样式参数的部分。RFC 提案的签名如下OGRStyleToolH OGR_ST_Create(OGRSTClassId eClassId) void OGR_ST_Destroy(OGRStyleToolH hST) OGRSTClassId OGR_ST_GetType(OGRStyleToolH hST) OGRSTUnitId OGR_ST_GetUnit(OGRStyleToolH hST) void OGR_ST_SetUnit(OGRStyleToolH hST, OGRSTUnitId eUnit, double dfGroundPaperScale) int OGR_ST_GetParamIsNull(OGRStyleToolH hST, int eParam) const char *OGR_ST_GetParamStr(OGRStyleToolH hST, int eParam) int OGR_ST_GetParamNum(OGRStyleToolH hST, int eParam) double OGR_ST_GetParamDbl(OGRStyleToolH hST, int eParam) void OGR_ST_SetParamStr(OGRStyleToolH hST, int eParam, const char *pszParamString) void OGR_ST_SetParamNum(OGRStyleToolH hST, int eParam, int nParam) void OGR_ST_SetParamDbl(OGRStyleToolH hST, int eParam, double dfParam) const char *OGR_ST_GetStyleString(OGRStyleToolH hST) int OGR_ST_GetRGBFromString(OGRStyleToolH hST, const char *pszColor, int *nRed, int *nGreen, int *nBlue, int *nAlpha)对照 ogr/ogr_api.h 第 906–930 行的实际实现有一个 RFC 中明确记录的落地时变更OGR_ST_GetParamIsNull()在实现阶段被移除取而代之的是在OGR_ST_GetParamStr/Num/Dbl三个函数上增加int *bValueIsNull输出参数用于更贴近 C 方法的语义C 中GetParamStr(...)通过引用参数返回值是否为 NULL标记。实际签名const char *OGR_ST_GetParamStr(OGRStyleToolH hST, int eParam, int *bValueIsNull); int OGR_ST_GetParamNum(OGRStyleToolH hST, int eParam, int *bValueIsNull); double OGR_ST_GetParamDbl(OGRStyleToolH hST, int eParam, int *bValueIsNull);这套 API 的用法逻辑是先OGR_ST_Create(OGRSTCPen)等创建指定类型的样式工具用OGR_ST_SetParam*逐个写入参数eParam取第二节中的OGRST*Param枚举值再用OGR_ST_GetStyleString得到可写入要素的样式字符串反向流程则是解析样式字符串、按索引读取参数。OGR_ST_GetRGBFromString则是把255,0,0或#ff0000形式的颜色字符串拆成红/绿/蓝/透明度四个整数供渲染端直接使用。五、为什么不需要为派生类单独写封装RFC 明确说明OGRStylePen、OGRStyleBrush、OGRStyleSymbol、OGRStyleLabel这四个 C 类不需要各自的 C API 封装。它们在 ogr/ogr_featurestyle.h 中均以class CPL_DLL OGRStyleXxx : public OGRStyleTool形式继承自OGRStyleToolclass CPL_DLL OGRStylePen : public OGRStyleTool // 第 271 行 class CPL_DLL OGRStyleBrush : public OGRStyleTool // 第 389 行 class CPL_DLL OGRStyleSymbol : public OGRStyleTool // 第 498 行 class CPL_DLL OGRStyleLabel : public OGRStyleTool // 第 649 行由于派生类只新增参数定义参数索引由第二节枚举给出不改变对象模型因此通过OGR_ST_Create(OGRSTClassId)指定类型即可创建任意派生对象全部参数读写都收敛到OGR_ST_*通用函数族上——这正是枚举OGRSTClassId存在的意义C 调用方用整型类型标识替代 C 多态。六、语言绑定与落地历史RFC 18 明确指出初始实现仅限 C API不会同步移植或测试 Python 及其他脚本语言绑定脚本语言支持要等到后续版本从当前仓库 swig 目录的完整绑定体系看OGR 样式相关绑定已在后续版本中随 SWIG 绑定整体演进但这属于 RFC 之后的发展。RFC 还给出了第一个真实检验场景MapServer 的mapogr.cpp将率先改用这些新 C API 函数以验证接口在真实渲染栈中的可用性。相关 Ticket 为 #2061。从 ogr/ogrfeaturestyle.cppOGR_SM_*/OGR_ST_*的 C 封装实现所在同时被 ogr/ogrsf_frmts/mitab/mitab_feature.cpp 等驱动在内部使用以及 ogr/ogr_api.h 中完整的OGR_STBL_*样式表函数族可以推断该 RFC 的成果不仅完整落地还在此后继续扩展。七、实践一段典型的 C API 样式读写流程结合以上分析与当前仓库签名一个典型的读取要素样式 → 拆部件 → 读参数 → 修改 → 写回C 语言流程可组织如下#include ogr_api.h #include ogr_core.h OGRStyleMgrH hSM OGR_SM_Create(NULL); OGRFeatureH hFeat /* 从图层读取的要素 */; /* 1. 从要素初始化样式管理器得到样式字符串 */ const char *pszStyle OGR_SM_InitFromFeature(hSM, hFeat); /* 2. 拆分部件逐个处理 */ int nParts OGR_SM_GetPartCount(hSM, pszStyle); for (int i 0; i nParts; i) { OGRStyleToolH hST OGR_SM_GetPart(hSM, i, pszStyle); if (OGR_ST_GetType(hST) OGRSTCPen) { int bIsNull 0; const char *pszColor OGR_ST_GetParamStr(hST, OGRSTPenColor, bIsNull); int nR, nG, nB, nA; if (!bIsNull OGR_ST_GetRGBFromString(hST, pszColor, nR, nG, nB, nA) 1) { /* 修改颜色并写回 */ OGR_ST_SetParamStr(hST, OGRSTPenColor, 0,255,0,255); OGR_ST_SetUnit(hST, OGRSTUPoints, 1.0); } } OGR_ST_Destroy(hST); } /* 3. 用新的样式字符串更新要素 */ OGR_F_SetStyleString(hFeat, OGR_SM_GetPart(hSM, 0, pszStyle)); /* 示意取首个部件 */ OGR_SM_Destroy(hSM);注意事项OGR_ST_GetParamStr等读取函数必须传入bValueIsNull指针返回值在*bValueIsNull为真时不代表有效值这是 RFC 实现阶段为贴近 C 语义做的调整务必先判断再使用枚举参数eParam必须与OGR_ST_Create创建的类型匹配如 Pen 只用OGRSTPen*否则属于越界使用从源码结构看所有OGR_ST_*函数都会对传入句柄做有效性检查但返回的字符串/数值含义仍取决于样式字符串本身是否合法。八、总结RFC 18 是 OGR 样式体系从纯 C 内部机制走向对外 C API的里程碑它通过把OGRSTClassId、OGRSTUnitId与四组参数枚举下沉到 ogr/ogr_core.h并新增OGR_SM_*与OGR_ST_*两族函数让任何 C 语言程序都能完成样式字符串的初始化、部件拆分、参数读写和颜色解析。落地时OGR_ST_GetParamIsNull被bValueIsNull输出参数取代以及后续补充的OGR_STBL_*样式表函数都体现了以实际使用为驱动持续修正 API的演进风格。对需要在 C/C 生态中读取或生成 OGR 特征样式如对接 DGN、EDIGEO、JML 等支持样式导出的驱动见 doc/source/drivers/vector/edigeo.rst的开发者而言这套接口至今仍是解析与生成样式信息的基础入口。参考路径速查RFC 原文doc/source/development/rfc/rfc18_ogr_styles_c_api.rst枚举定义下沉目标ogr/ogr_core.hC API 声明 ogr/ogr_api.hC 类定义封装对象模型ogr/ogr_featurestyle.hC 封装实现ogr/ogrfeaturestyle.cpp赞分享GIS遥感数据工程【免费下载链接】gdalGDAL is an open source MIT licensed translator library for raster and vector geospatial data formats.项目地址https://gitcode.com/gh_mirrors/gd/gdal点击查看免费下载相关推荐GDAL OGR 多几何字段支持全解析RFC 41 的数据模型设计、C API 与驱动实现GDAL OGR 多几何字段支持全解析RFC 41 的数据模型设计、C API 与驱动实现 GDAL 的 OGR 数据模型长期一个要素、一个几何而 PoGIS遥感数据工程GDAL RFC 66 详解OGR 数据集级随机图层读写 APIGetNextFeature 与 ODsCRandomLayerRead/WriteGDAL RFC 66 详解OGR 数据集级随机图层读写 APIGetNextFeature 与 ODsCRandomLayerRead/Write 本文GIS遥感数据工程GDAL OGR 字段毫秒级精度解析RFC 56 如何让 OFTTime/OFTDateTime 支持小数秒GDAL OGR 字段毫秒级精度解析RFC 56 如何让 OFTTime/OFTDateTime 支持小数秒 GDAL 的 OGR 矢量模型中日期时间 OGIS遥感数据工程上一篇跨平台协作新标杆import_3dm如何实现Rhino与Blender数据无损转换下一篇3个颠覆性突破的智能工具Jasminum让中文文献管理自动化处理更高效创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考