>>> from env_helper import info; info()
页面更新时间: 2024-01-13 11:28:36
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-16-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

15.2. GeoJSON

GeoJSON是一种用于编码各种地理数据结构的格式。GeoJSON对象可以表示几何形状,特征或特征集合。 GeoJSON支持以下几何类型:点,线,多边形,点集合,线集合,多边形集合和几何体集合。 GeoJSON中的特性包含几何对象和其他属性,并且要素集合由要素列表表示。

GeoJSON是基于JavaScript对象表示法(JSON)的地理空间信息数据交换格式,其术语对象,名称,值,数组与数字在IETF RFC 4627中均有定义。

一个完整的GeoJSON数据结构是一个以JSON术语表示的对象。 在GeoJSON中,对象由名称/值对(也称为成员)的集合组成。对于每个成员,名字总是字符串。 成员值可以是字符串,数字,对象,数组也可以是以下文本常量中的一个:true,false和null。 数组由元素组成,每个元素是上述值。

python-geojson与Python 2.6,2.7,3.2,3.3,3.4和3.5兼容。 源代码网址: https://github.com/frewsxcv/python-geojson 。 它在PyPi上被列为“geojson”。 推荐的安装方式是通过pip:

pip install geojson

在 Debian / Ubuntu 中可以通过:

sudo apt install python3-geojson

15.2.1. GeoJSON几何对象

GeoJSON通常是由单个对象组成。 此对象(以下称为GeoJSON对象)表示几何,要素或要素集合。

  • GeoJSON对象可能是具有任意数量的成员(名称/值对)。GeoJSON库中,每一个GeoJSON格式规范的描述均表示一个完整的GeoJSON对象。

  • GeoJSON对象必须是名为“type”的成员。 此成员的值是由GeoJSON对象的类型所确定的字符串。type成员的值必须是下面之一: PointMultiPointLineStringMultiLineStringPolygonMultiPolygonGeometryCollectionFeatureFeatureCollection 。 注意 type 成员值的大小写。

  • GeoJSON对象可能有一个可选的“crs”成员,其值必须是坐标参考系统对象(请参阅3.坐标参考系统对象)。

  • GeoJSON对象可能有一个“bbox”成员,其值必须是边界框数组。

坐标位置

坐标位置是基本的几何结构。 几何对象的“coordinates”成员由一个位置(在此情况下是几何Point), 位置数组(线或几何点集合),位置数组的数组(多边形,线集合)或位置的多维数组(面集合)组成。

位置由数字数组表示。至少有两个元素,可以有更多元素。元素的顺序必须遵循 x,y, z 顺序(东坐标,北坐标,投影坐标系中坐标的高度,或地理坐标系中坐标的经度,纬度,高度)。 允许任何数量的附加元件 (附加元件的解释和含义请自行检索 ) 。

除“GeometryCollection”外的其他任何类型的GeoJSON几何对象必须有一个名为“coordinates”的成员。“coordinates”成员的值总是一个数组。 此数组中元素的结构由几何的类型来确定。

点(Point)

对类型“Point”来说,“coordinates”成员必须是一个单独位置。

点坐标为x,y顺序(其中,northing代表投影坐标;经度、纬度代表地理坐标):

>>> from geojson import Point
>>> p = Point((-115.81, 37.24))
>>> p
{"coordinates": [-115.81, 37.24], "type": "Point"}

GeoJson对象可以直接像上面一样查看结果。为了方便,使用 Shapely 库来辅助进行可视化查看:

>>> from shapely.geometry import shape
>>> point = shape(p)
>>> shape(point)
_images/sec2_geojson_8_0.svg

点集合(MultiPoint)

对类型“MultiPoint”来说,“coordinates”成员必须是位置数组。

多点的坐标是一个位置数组:

>>> from geojson import MultiPoint
>>> mpt = MultiPoint([(-155.52, 19.61), (-156.22, 20.74), (-157.97, 21.46)])
>>> shape(mpt)
_images/sec2_geojson_11_0.svg

可视化上述示例的结果。 关于Point的一般信息可以在GeoJSON格式规范的第2.1.2节和附录A:点中找到。

线(LineString)

对类型“LineString”来说,“coordinates”成员必须是两个或多个位置的数组。

线环是关闭有4个或多个位置的线。第一个和最后一个位置是相等的(它们表示相同点)。 虽然线环不作为GeoJSON几何类型,但在多边形几何类型定义中有提到它。

>>> from geojson import LineString
>>> linestr = LineString([(8.919, 44.4074), (8.923, 44.4075)])  # doctest: +ELLIPSIS
>>> shape(linestr)
_images/sec2_geojson_15_0.svg

有关LineString的信息,请参见GeoJSON格式规范中的第2.1.4节和附录A:LineString。

线集合(MultiLineString)

对类型“MultiLineString”来说,“coordinates”成员必须是线坐标数组的数组。

MultiLineString的坐标是一个LineString坐标数组的数组:

>>> from geojson import MultiLineString
>>> foo = MultiLineString([
>>>     [(3.75, 9.25), (-130.95, 1.52)],
>>>     [(23.15, -34.25), (-1.35, -4.65), (3.45, 77.95)]
>>> ])
>>> shape(foo)
_images/sec2_geojson_19_0.svg

多边形(Polygon)

对类型“Polygon”来说,“coordinates”成员必须是线环坐标数组的数组。对拥有多个环的多边形来说,第一个必须是外部环,其他任何环必须是内部环或孔。

无孔的例子:

>>> from geojson import Polygon
>>> foo = Polygon([[(2.38, 57.322), (23.194, -20.28), (-120.43, 19.15), (2.38, 57.322)]])
>>> shape(foo)
_images/sec2_geojson_22_0.svg

带孔的例子:

>>> foo = Polygon([
>>>     [(2.38, 57.322), (23.194, -20.28), (-120.43, 19.15), (2.38, 57.322)],
>>>     [(-5.21, 23.51), (15.21, -10.81), (-20.51, 1.51), (-5.21, 23.51)]
>>> ])
>>> shape(foo)
_images/sec2_geojson_25_0.svg

多边形集合(MultiPolygon)

对类型“MultiPolygon”来说,“coordinates”成员必须是多边形坐标数组的数组。

MultiPolygon的坐标是多边形坐标数组的数组:

>>> from geojson import MultiPolygon
>>> foo = MultiPolygon([
>>>     ([(3.78, 9.28), (-130.91, 1.52), (35.12, 72.234), (3.78, 9.28)],),
>>>     ([(23.18, -34.29), (-1.31, -4.61), (3.41, 77.91), (23.18, -34.29)],)
>>> ])  # doctest: +ELLIPSIS
>>> shape(foo)
_images/sec2_geojson_28_0.svg

几何集合(GeometryCollection)

类型“GeometryCollection”的GeoJSON对象是一个集合对象,它表示几何对象集合。

几何集合必须具有名为“geometries”的成员。对应于“geometries”的值是一个数组。此数组中的每个元素都是一个GeoJSON几何对象。

GeometryCollection的geometry数组中的每个元素是上述几何对象之一:

>>> from geojson import GeometryCollection, Point, LineString
>>> my_point = Point((23.532, -63.12))
>>> my_line = LineString([(-152.62, 51.21), (5.21, 10.69)])
>>> foo = GeometryCollection([my_point, my_line])  # doctest: +ELLIPSIS
>>> shape(foo)
_images/sec2_geojson_31_0.svg

15.2.2. 要素对象(Feature)

类型为“Feature”的GeoJSON对象是要素对象。

  • 要素对象必须是名为“geometry”的成员。 geometry成员的值是上面定义的几何对象或JSON的Null值。

  • 要素对象必须是名为“properties”的成员。 properties成员的值是一个对象(任意JSON对象或JSON的Null值)。

  • 如果要素是常用的标识符,那么该标识符应当包含名为“id”的要素对象成员。

>>> from geojson import Feature, Point
>>> my_point = Point((-3.68, 40.41))
>>> fea1 = Feature(geometry=my_point)  # doctest: +ELLIPSIS
>>> uu = fea1.__geo_interface__
>>> Feature(geometry=my_point, properties={"country": "Spain"})  # doctest: +ELLIPSIS
{"geometry": {"coordinates": [-3.68, 40.41], "type": "Point"}, "properties": {"country": "Spain"}, "type": "Feature"}
>>> Feature(geometry=my_point, id=27)  # doctest: +ELLIPSIS
{"geometry": {"coordinates": [-3.68, 40.41], "type": "Point"}, "id": 27, "properties": {}, "type": "Feature"}

要素集合对象(FeatureCollection)

类型为“FeatureCollection”的GeoJSON对象是要素集合对象。

类型为“FeatureCollection”的对象必须是名为“features”的成员。对应于“features”的值是一个数组。此数组中的每个元素均是上面定义的特征对象。

>>> from geojson import Feature, Point, FeatureCollection
>>> my_feature = Feature(geometry=Point((1.6432, -19.123)))
>>> my_other_feature = Feature(geometry=Point((-80.234, -22.532)))
>>> fea2 = FeatureCollection([my_feature, my_other_feature])  # doctest: +ELLIPSIS
>>> fea2
{"features": [{"geometry": {"coordinates": [1.6432, -19.123], "type": "Point"}, "properties": {}, "type": "Feature"}, {"geometry": {"coordinates": [-80.234, -22.532], "type": "Point"}, "properties": {}, "type": "Feature"}], "type": "FeatureCollection"}

15.2.3. 坐标参考系统对象

GeoJSON对象的坐标参考系(CRS , coordinate reference system)是由它的“crs”成员(以下称为CRS对象)来确定的。 如果对象没有crs成员,那么它的父对象或祖父对象的crs成员可能会作为它的crs。 如果这样,还没有获取到crs成员,默认的CRS将应用到GeoJSON对象。

  • 默认的CRS是地理坐标参考系统,使用的是WGS84基准数据,并具有十进制度的经度和纬度单位。

  • 名为“crs”的成员的值必须是JSON对象(以下称为CRS对象)或JSON null。如果CRS的值为null,那么就假定没有CRS了。

  • crs成员应位于(要素集合,要素,几何顺序)层级结构里GeoJSON对象的最顶级,并且在对象的子对象或孙子对象不应该重复或覆盖。

  • 非空CRS对象有两个强制成员:“类型”和“属性”。

  • type成员的值必须是字符串,指示CRS对象的类型。

  • properties成员的值必须是一个对象。

  • CRS不应改变坐标顺序

命名CRS

CRS对象可以通过名称指定坐标参考系统。在这种情况下,其“type”成员的值必须是字符串“name”。 其“properties”成员的值必须是包含“name”成员的对象。 该“name”成员的值必须是标识坐标参考系统的字符串。 诸如“urn:ogc:def:crs:OGC:1.3:CRS84”的OGC CRS的URN应优先于旧的标识符号“EPSG:4326” 。

链接CRS

CRS对象可以链接到Web上的CRS参数。 在这种情况下,其“type”成员的值必须是字符串“link”,并且其“properties”成员的值必须是链接对象。

链接对象有一个必需的成员:“href”,和一个可选成员:“type”。

必需的“href”成员的值必须是可解除引用的URI。

可选的“类型”成员的值必须是一个字符串,它提示了所用于在提供的URI处用来表示CRS参数的格式。 建议值为:“proj4”,“ogcwkt”,“esriwkt”,不过也可以使用其他值:

链接也可以辅助文件中的CRS的直接处理器:

15.2.4. 边界框

为了包括几何,要素或要素集合的坐标范围信息,GeoJSON对可能有名为 bbox 的成员。 bbox 成员的值必须是 \(2 \times n\) 数组,其中 n 是在所包含的几何对象的维数,所有坐标轴的最低值后面都跟着最高值。 bbox 的坐标轴顺序遵循几何坐标轴顺序。此外,假设 bbox 的坐标参考系与其所属的GeoJSON对象的坐标参考系匹配。

要素对象上的bbox成员示例:

>>> feature =Feature( { "type": "Feature",
>>>   "bbox": [-180.0, -90.0, 180.0, 90.0],
>>>   "geometry": {
>>>     "type": "Polygon",
>>>     "coordinates": [[
>>>       [-180.0, 10.0], [20.0, 90.0], [180.0, -5.0], [-30.0, -90.0]
>>>       ]]
>>>     }
>>>
>>>   } )

要素集合对象上的 bbox 成员示例:

>>> feature_collect =  FeatureCollection(
>>> { "type": "FeatureCollection",
>>>   "bbox": [100.0, 0.0, 105.0, 1.0],
>>>   "features": [
>>>    feature
>>>     ]
>>>   })

15.2.5. GeoJSON encoding/decoding

GeoJSON库中所有的GeoJSON对象都可以使用geojson.dump,geojson.dumps,geojson.load和geojson.loads函数进行编码并解码为原始的GeoJSON。

>>> import geojson
>>> my_point = geojson.Point((43.24, -1.532))
>>> my_point  # doctest: +ELLIPSIS
{"coordinates": [43.24, -1.532], "type": "Point"}
>>> dump = geojson.dumps(my_point, sort_keys=True)
>>> dump  # doctest: +ELLIPSIS
'{"coordinates": [43.24, -1.532], "type": "Point"}'
>>> geojson.loads(dump)  # doctest: +ELLIPSIS
{"coordinates": [43.24, -1.532], "type": "Point"}

15.2.6. 自定义类

以前的编码/解码功能可以使用__geo_interface__规范描述的接口扩展到自定义类。

>>> import geojson
>>> class MyPoint():
>>>     def __init__(self, x, y):
>>>         self.x = x
>>>         self.y = y
>>>
>>>     @property
>>>     def __geo_interface__(self):
>>>         return {'type': 'Point', 'coordinates': (self.x, self.y)}
>>>
>>> point_instance = MyPoint(52.235, -19.234)
>>>
>>> geojson.dumps(point_instance, sort_keys=True)  # doctest: +ELLIPSIS
'{"coordinates": [52.235, -19.234], "type": "Point"}'

15.2.7. 实用程序

可使用coords geojson.utils.coords 方法生成几何或特征对象的所有坐标元组。

>>> import geojson
>>> my_line = LineString([(-152.62, 51.21), (5.21, 10.69)])
>>> my_feature = geojson.Feature(geometry=my_line)
>>> list(geojson.utils.coords(my_feature))  # doctest: +ELLIPSIS
[(-152.62, 51.21), (5.21, 10.69)]

map_coords: geojson.utils.map_coords 是将函数映射到所有坐标元组上,并返回相同类型的几何形状。 用于解译空间几何或坐标顺序。

>>> import geojson
>>> new_point = geojson.utils.map_coords(lambda x: x/2, geojson.Point((-115.81, 37.24)))
>>> geojson.dumps(new_point, sort_keys=True)  # doctest: +ELLIPSIS
'{"coordinates": [-57.905, 18.62], "type": "Point"}'

generate_random: geojson.utils.generate_random 生成具有随机数据的几何类型。

>>> import geojson
>>> geojson.utils.generate_random("LineString")  # doctest: +ELLIPSIS
{"coordinates": [[176.15481, 19.3065], [-95.710846, -50.808824], [-53.160259, 32.179151]], "type": "LineString"}