解析MSDN几何数据类型
我有一个数据库,其中有一个字段存储空间坐标。我了解到这个字段是一个序列化的MSDN几何数据类型(http://msdn.microsoft.com/en-us/library/bb933973.aspx)。
我想用Python访问这个数据库,但不太清楚几何数据类型的格式是什么,或者有没有什么库可以把它解析成一组地理坐标。
链接中提到,微软在设计这个数据类型时使用了“开放地理空间联盟(OGC)标准”,这是否意味着这些空间坐标是按照这个标准来定义的呢?
有没有其他人有相关的经验呢?
任何帮助都将非常感谢!
2 个回答
"…如果有人知道几何 [数据类型] 的格式…"
SQL Server 的空间 GEOMETRY
和 GEOGRAPHY
类型的二进制序列化格式在这里有说明:
[MS-SSCLRT]: Microsoft SQL Server CLR 类型序列化格式
"指定了由 SQL Server 管理的 GEOGRAPHY、GEOMETRY、HIERARCHYID 和 CLR 用户定义类型 (UDT) 结构的二进制格式."
这个说明写得很好,二进制格式也很容易理解,所以自己实现一个基本的解析器应该不成问题。
"…或者任何能够将其解析为一组 [地理坐标] 的 Python 库…"
通过 .NET 互操作使用 Microsoft.SqlServer.Types
来反序列化这些类型:
如果你不想自己实现反序列化器(其实应该挺简单的),但你可以找到一种方法从 Python 与 .NET 程序库进行交互——也许可以通过 pythonnet?——那么以下提示可能会对你有帮助:
这两个 T-SQL 类型 GEOMETRY
和 GEOGRAPHY
是通过一个 .NET 程序库(Microsoft.SqlServer.Types
)来实现的,它负责将数据从上面提到的二进制格式进行反序列化和序列化,还有一个非托管的 DLL(SqlServerSpatial….dll
),里面几乎包含了所有其他内容(也就是空间操作的相关功能)。
如果你只对反序列化 SQL Server 的空间数据感兴趣,并且小心不要在 SqlGeometry
或 SqlGeography
上调用任何空间函数,那么你可以使用 Microsoft.SqlServer.Types
来为你反序列化空间二进制数据,然后 使用你需要提供给 SqlGeometry.Populate
方法的 IGeometrySink110
实现来检查它。
Microsoft.SqlServer.Types
和 SqlServerSpatial….dll
可以作为一个 .NET 项目的 NuGet 包,或者作为一个系统范围的 MSI 安装包 (SQLSysClrTypes.msi
)。据我所知,这些 DLL 也会在安装 SQL Server 时自动安装。
已知文本 (WKT) 和已知二进制 (WKB):
还有一个选择是让 SQL Server 将空间值转换为已知文本 (WKT) 或 已知二进制
(WKB),可以使用 SELECT geometryColumn.STAsText()
或 SELECT geometryColumn.STAsBinary()
,然后寻找一个可以解析这些标准交换格式的 Python 库。
(有一点需要注意:如果你选择这个方法,要小心你的数据中是否包含圆弧。WKT 和 WKB 数据格式有不同的版本。它们最初是在开放地理空间联盟的简单特征访问规范中指定的;那个版本不支持圆弧。对圆曲线段的支持是在 SQL/MM 第 3 部分:空间标准中添加的,而 SQL Server 实现了这个标准。)
根据下面评论中的讨论(感谢MarkJ!):
- geometry是一种.NET的数据类型,但它使用了自己特定的序列化格式;你可以选择整个列,然后通过在Reflector中打开Microsoft.SqlServer.Types.dll来重新实现这一点。
- 或者你可以利用SQL Server对这种类型的支持,从数据库中读取geometry数据的属性,比如说可以用
select geocolumn.STX, geocolumn.STY from myTable;
这样的查询。 - 或者你可以将整个值导出为GML格式,比如用
select geocolumn.AsGml() from myTable;
,这样可以被Python的几何库处理,比如http://gispython.org/、http://mapnik.org/和http://www.qgis.org/wiki/Python_Bindings。
我原本以为SQL Server会把CLR数据类型直接作为序列化的.NET对象存储在表中,但事实证明这是错误的。