Go 中的 S2 几何库
概述
S2 是一个球面几何的库,它的目标是具有与最好的平面几何库相同的鲁棒性、灵活性和性能。
这是一个用于操作几何形状的库。与许多几何库不同的是,S2 主要是为了处理球面几何,即在球面上绘制的形状,而不是在平面 2D 地图上绘制的形状。(事实上,S2 的名字来自于单位球体 S² 的数学符号)。这使得它特别适合处理地理数据。
关于 S2 的更多细节,请访问 S2 几何网站 s2geometry.io。
适用范围
该库提供了以下内容:
- 角度、间隔、经纬点、单位向量等的表示,以及对这些类型的各种操作。
- 单位球面上的几何图形,如球面盖("圆盘")、经纬度矩形、多直线和多边形。这些统称为 "区域"。
- 将球体分层分解为区域,称为 "单元"。层次结构从投影立方体的六个面开始,并以类似四树的方式递归地将它们细分。
- 健壮的构造操作(如联合)和布尔谓词(如包含),适用于任意点、多线和多边形的集合。
- 点、多棱线和多边形集合的快速内存索引。
- 用于测量距离和查找附近对象的算法。
- 稳健的算法,用于捕捉和简化几何体(保证精度和拓扑结构)。
- 一组高效而精确的数学预言,用于测试几何对象之间的关系。
- 支持空间索引,包括将区域近似为离散 "S2单元" 集合的能力。这一特性使得建立大型分布式空间索引变得容易。
另一方面,以下内容不在 S2 的范围内:
- 平面几何学。
- 转换为/从普通GIS格式。
- 稳健性
什么叫 "健壮"?
在 S2 库中,核心操作被设计为 100% 健壮。这意味着每个操作都对其输出做出了严格的数学保证,并以这样的方式实现,即对于所有可能的有效输入都能满足这些保证。例如,如果你计算两个多边形的交点,不仅保证输出是拓扑正确的(直到产生退化),而且还保证输出的边界保持在用户指定的真实、数学上精确的结果公差范围内。
在构建更高级别的算法时,鲁棒性是非常重要的,因为低级别的操作所产生的意外结果是很难处理的。S2 使用计算几何学的技术组合来实现这一目标,包括保守的误差边界、精确的几何谓词和快取舍。
在数学定义(例如,区域是否包括其边界,以及如何处理退化)和数值精度(例如,最小化取消误差)方面,该实现都试图做到精确。
请注意,这个库的意图是将几何学作为一个数学抽象来表示。例如,虽然单位球体显然是地球表面的一个有用的近似值,但与地理学特别相关的函数并不是核心库的一部分(例如,东/北纬转换,椭球体近似,大地坐标与地心坐标等)。
具体的软件包文档参见 http://godoc.org/github.com/golang/geo。
C++ 中的类似库见 https://github.com/google/s2geometry,Java中见 https://github.com/google/s2-geometry-library-java,Python中见 https://github.com/google/s2geometry/tree/master/src/python
Go 库的现状
这个库主要是对 C++ S2 库的移植,在有意义的地方适应了 Go 习语。下面我们详细介绍一下这个移植库相对于那个 C++ 库的进展。
ℝ¹ -- 一维笛卡尔座标(One-dimensional Cartesian coordinates)
与 C++ 完全对等。
ℝ² -- 二维笛卡尔坐标(Two-dimensional Cartesian coordinates)
与 C++ 完全对等。
ℝ³ -- 三维笛卡尔坐标(Three-dimensional Cartesian coordinates)
与 C++ 完全对等。
S¹ -- 圆形几何学(Circular Geometry)
与 C++ 完全对等。
S² -- 球面几何学(Spherical Geometry)
大约完成 40%。
Complete(完成) 这些文件与 C++ 实现完全对等。
- Cap
- Cell
- CellID
- CellUnion
- ContainsVertexQuery
- ConvexHullQuery
- CrossingEdgeQuery
- LatLng
- matrix3x3
- Metric
- PaddedCell
- Point
- PointCompression
- Region
- RegionCoverer
- RegionUnion
- s2edge_clipping
- s2edge_crosser
- s2edge_crossings
- s2edge_distances
- edgeVectorShape
- laxLoop
- laxPolyline
- s2projections -- 在 R2 和 S2 之间投影点的辅助工具。
- s2rect_bounder
- s2stuv.go (s2coords.h in C++) -- 这个文件是 ST-space、UV-space 和 XYZ-space 之间的帮助和转换方法的集合。
- s2wedge_relations
- ShapeIndex
- idSetLexicon,sequenceLexicon
Mostly Complete(大部分完整)的文件,几乎拥有原始 C++ 代码的所有功能,并且足够完整,可以在实际代码中使用。在每个文件的末尾都有最新的不完整方法列表。
- EdgeQuery/Closest/Furthest -- 缺少Project,GetEdge。
- ContainsPointQuery -- 缺少访问边缘
- laxPolygon
- Loop -- Loop 现已基本完成。缺少 Project, Distance, Union 等。
- Polyline -- 缺少 InitTo... 方法,NearlyCoversPolyline。
- Rect (C++ 中又称 s2latlngrect) -- 缺少Centroid和InteriorContains。
- s2_test.go (在 C++ 中又称 s2testing 和 s2textformat) -- 缺少 Fractal 测试形状生成。这个文件是一个测试辅助方法的集合。
- s2edge_distances -- 缺少交点测试方法.
In Progress 文件,这些文件已经完成了一些工作,但可能还不够完整,无法在生产代码中普遍使用。
- CellIndex -- 一个可查询的 CellIDs 索引。
- Polygon -- 支持多循环的多边形。它完全实现了 Shape 和 Region,但缺少了大多数其他方法。(Area, Centroid, Distance, Projection, Intersection, Union, Contains, Normalized, etc.)
- PolylineSimplifier -- 已经开始了初步工作。
- s2predicates.go -- 这个文件是库中其他部分使用的辅助方法的集合。
- s2shapeutil -- 添加了初始元素。缺少 VisitCrossings。
Not Started Yet(还没有开始)。这些文件(及其相关的单元测试)在开始启动之前,需要依赖大部分的 In Progress 文件。
- BooleanOperation -- 在组装多边形和循环时使用。
- Builder -- 这是一个强大的工具,用于从简单的S2类型集合中创建各种形状类型。
- BuilderClosedSetNormalizer
- BuilderFindPolygonDegneracies
- BuilderGraph
- BuilderLayers
- BuilderSnapFunctions
- BuilderTesting
- Centroids
- ClosestPointQuery
- EdgeTesselator
- LoopMeasures
- PointIndex
- PointRegion
- PointUtil
- PolygonMeasures
- RegionIntersection
- RegionTermIndexer
- ShapeIndexRegion -- 允许 ShapeIndexes 作为区域来使用
编码/解码
S2 类型的编码和解码完全实现了与 C++ 和 Java 的互操作。