Go中的S2几何库

S2几何库在Go中的应用。(S2 geometry library in Go)

Github stars Tracking Chart

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++ 完全对等。

-- 圆形几何学(Circular Geometry)

与 C++ 完全对等。

-- 球面几何学(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 的互操作。


Main metrics

Overview
Name With Ownergolang/geo
Primary LanguageGo
Program languageGo (Language Count: 1)
PlatformLinux, Mac, Windows
License:Apache License 2.0
所有者活动
Created At2014-12-03 23:02:15
Pushed At2025-07-07 18:12:42
Last Commit At2025-07-07 12:12:42
Release Count0
用户参与
Stargazers Count1.8k
Watchers Count73
Fork Count188
Commits Count463
Has Issues Enabled
Issues Count99
Issue Open Count24
Pull Requests Count57
Pull Requests Open Count9
Pull Requests Close Count30
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private

Overview

S2 is a library for spherical geometry that aims to have the same robustness,
flexibility, and performance as the best planar geometry libraries.

This is a library for manipulating geometric shapes. Unlike many geometry
libraries, S2 is primarily designed to work with spherical geometry, i.e.,
shapes drawn on a sphere rather than on a planar 2D map. (In fact, the name S2
is derived from the mathematical notation for the unit sphere .) This makes
it especially suitable for working with geographic data.

More details about S2 in general are available on the S2 Geometry Website
s2geometry.io.

Scope

The library provides the following:

  • Representations of angles, intervals, latitude-longitude points, unit
    vectors, and so on, and various operations on these types.

  • Geometric shapes over the unit sphere, such as spherical caps ("discs"),
    latitude-longitude rectangles, polylines, and polygons. These are
    collectively known as "regions".

  • A hierarchical decomposition of the sphere into regions called "cells". The
    hierarchy starts with the six faces of a projected cube and recursively
    subdivides them in a quadtree-like fashion.

  • Robust constructive operations (e.g., union) and boolean predicates (e.g.,
    containment) for arbitrary collections of points, polylines, and polygons.

  • Fast in-memory indexing of collections of points, polylines, and polygons.

  • Algorithms for measuring distances and finding nearby objects.

  • Robust algorithms for snapping and simplifying geometry (with accuracy and
    topology guarantees).

  • A collection of efficient yet exact mathematical predicates for testing
    relationships among geometric objects.

  • Support for spatial indexing, including the ability to approximate regions
    as collections of discrete "S2 cells". This feature makes it easy to build
    large distributed spatial indexes.

On the other hand, the following are outside the scope of S2:

  • Planar geometry.

  • Conversions to/from common GIS formats.

Robustness

What do we mean by "robust"?

In the S2 library, the core operations are designed to be 100% robust. This
means that each operation makes strict mathematical guarantees about its output,
and is implemented in such a way that it meets those guarantees for all possible
valid inputs. For example, if you compute the intersection of two polygons, not
only is the output guaranteed to be topologically correct (up to the creation of
degeneracies), but it is also guaranteed that the boundary of the output stays
within a user-specified tolerance of true, mathematically exact result.

Robustness is very important when building higher-level algorithms, since
unexpected results from low-level operations can be very difficult to handle. S2
achieves this goal using a combination of techniques from computational
geometry, including conservative error bounds, exact geometric predicates,
and snap rounding.

The implementation attempts to be precise both in terms of mathematical
definitions (e.g. whether regions include their boundaries, and how degeneracies
are handled) and numerical accuracy (e.g. minimizing cancellation error).

Note that the intent of this library is to represent geometry as a mathematical
abstraction. For example, although the unit sphere is obviously a useful
approximation for the Earth's surface, functions that are specifically related
to geography are not part of the core library (e.g. easting/northing
conversions, ellipsoid approximations, geodetic vs. geocentric coordinates,
etc).

See http://godoc.org/github.com/golang/geo for specific package documentation.

For an analogous library in C++, see https://github.com/google/s2geometry, in
Java, see https://github.com/google/s2-geometry-library-java, and Python, see
https://github.com/google/s2geometry/tree/master/src/python

Status of the Go Library

This library is principally a port of the
C++ S2 library, adapting to Go idioms
where it makes sense. We detail the progress of this port below relative to that
C++ library.

ℝ¹ - One-dimensional Cartesian coordinates

Full parity with C++.

ℝ² - Two-dimensional Cartesian coordinates

Full parity with C++.

ℝ³ - Three-dimensional Cartesian coordinates

Full parity with C++.

- Circular Geometry

Full parity with C++.

- Spherical Geometry

Approximately ~40% complete.

Complete These files have full parity with the C++ implementation.

  • Cap
  • Cell
  • CellID
  • CellUnion
  • ContainsVertexQuery
  • ConvexHullQuery
  • CrossingEdgeQuery
  • LatLng
  • matrix3x3
  • Metric
  • PaddedCell
  • Point
  • PointCompression
  • Region
  • s2edge_clipping
  • s2edge_crosser
  • s2edge_crossings
  • s2edge_distances
  • edgeVectorShape
  • laxLoop
  • laxPolyline
  • s2projections - Helpers for projecting points between R2 and S2.
  • s2rect_bounder
  • s2stuv.go (s2coords.h in C++) - This file is a collection of helper and
    conversion methods to and from ST-space, UV-space, and XYZ-space.
  • s2wedge_relations
  • ShapeIndex

Mostly Complete Files that have almost all of the features of the original
C++ code, and are reasonably complete enough to use in live code. Up to date
listing of the incomplete methods are documented at the end of each file.

  • EdgeQuery/Closest/Furthest - missing Project, GetEdge
  • ContainsPointQuery - missing visit edges
  • laxPolygon
  • Loop - Loop is mostly complete now. Missing Project, Distance, Union, etc.
  • Polyline - Missing Interpolate, etc.
  • Rect (AKA s2latlngrect in C++) - Missing Centroid, InteriorContains.
  • RegionCoverer - canonicalize
  • s2_test.go (AKA s2testing and s2textformat in C++) - Missing Fractal test
    shape generation. This file is a collection of testing helper methods.
  • s2edge_distances - Missing Intersection

In Progress Files that have some work done, but are probably not complete
enough for general use in production code.

  • Polygon - Polygons with multiple loops are supported. It fully implements
    Shape and Region, but it's missing most other methods. (Area, Centroid,
    Distance, Projection, Intersection, Union, Contains, Normalized, etc.)
  • PolylineSimplifier - Initial work has begun on this.
  • s2predicates.go - This file is a collection of helper methods used by other
    parts of the library.
  • s2shapeutil - Initial elements added. Missing VisitCrossings.

Not Started Yet. These files (and their associated unit tests) have
dependencies on most of the In Progress files before they can begin to be
started.

  • BooleanOperation - used when assembling polygons and loops.
  • Builder - This is a robust tool for creating the various Shape types from
    collection of simpler S2 types.
  • BuilderClosedSetNormalizer
  • BuilderFindPolygonDegneracies
  • BuilderGraph
  • BuilderLayers
  • BuilderSnapFunctions
  • BuilderTesting
  • Centroids
  • ClosestPointQuery
  • EdgeTesselator
  • LoopMeasures
  • MinDistanceTargets
  • PointIndex
  • PointRegion
  • PointUtil
  • PolygonMeasures
  • RegionIntersection
  • RegionTermIndexer
  • RegionUnion
  • ShapeIndexRegion - Allows ShapeIndexes to be used as Regions for things like
  • lexicon

Encode/Decode

Encoding and decoding of S2 types is fully implemented and interoperable with
C++ and Java.