# GeoJson

提到 JSON 大家都知道是一种 JavaScript 对象的表示法,被广泛的应用于 WEB 应用的开发中。在 WebGIS 开发中也常常使用这种形式去描述地理信息数据 —— GeoJson (opens new window)

# 数据形式

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}
1
2
3
4
5
6
7
8
9
10

# 相关标准

以下内容来自The GeoJSON Specification (RFC 7946) (opens new window),试着翻译为中文,方便查阅。

# 概要

GeoJSON 是一种基于 JSON 的地理数据交换格式。它定义了几种类型的 JSON 对象,以及它们组合的方式,便于表示有关地理特征、属性和空间范围的数据。GeoJSON 采用地理坐标参考系、1984 世界大地测量系统和十进制的单位。

# 1 介绍

GeoJSON 使用 “JavaScript 对象表示法”(JSON)[RFC7159 (opens new window)]的形式来编码各式各样的地理数据。一个 GeoJSON 对象可以表示一个空间区域(a Geometry),可以表示一个空间中的带有边界的实体(a Feature),还可以表示一个特征列表(a FeatureCollection)。GeoJSON 支持以下几种几何体类型:点(Point)、线(LineString)、多边形(Polygon)、多个点(MultiPoint),多个线(MultiLineString),多个多边形(MultiPolygon)和几何体集合(GeometryCollection)。GeoJSON 中的特征体包含一个几何体对象(geometry)和附加属性值对象(properties),而 FeatureCollection 包含了一个特征列表。

GeoJSON 定义了广义上的地理数据格式,只要是出现在地理空间中带有特征的东西都被认为是一个 Feature,不管它是否具有物理结构。GeoJSON 中的所有概念并不是自创的,它们来自于已有的开放地理信息系统标准,然后进行了精简,以便于更好地适应基于 JSONWeb 应用开发。

GeoJSON 包含了七种已经在 SFSQL (opens new window) 中定义的几何类型:0-维 点和多个点;1-维 曲线、线和多个线;2-维 平面、多边形和多个多边形;以及各种几何类型组合后的几何列表。这些几何类型对应的 GeoJSON 实例表示类似于该规范中描述WKBWKT

GeoJSON 同样包含类型的特征和特征列表。GeoJSON 中的特征对象包含上诉几何类型中的某一种几何对象,以及附加属性。一个特征列表是由特征数组组成。这种结构类似于 WFS 对 WFSv1 (opens new window) 中指定的 GetFeatures 请求的响应,或 Placemarks KMLv2.2 (opens new window)KML 文件夹的响应。WFS规范的一些实现也为GetFeature请求提供了 GeoJSON 格式的响应,但是在 GeoJSON 格式规范中并没有隐含特定的服务模型或特征类型本体。

自从 2008 年首次发布GJ2008 (opens new window) 以来,GeoJSON 格式的规范越来越普及。它被广泛应用于 JavaScriptWeb 映射库、基于 JSON 的文档数据库和 Web API 中。

# 1.1 语言要求

本文档中的关键词 "MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"NOT RECOMMENDED"、"MAY "和 "OPTIONAL "应按照RFC2119 (opens new window)中的描述进行解释。

# 1.2 本文档约定

根据RFC7159 (opens new window)规定,本文档中任意一个 JSON 对象中的属性都是无序的。

有些例子中使用 JavaScript 单行注释(//)后跟省略号()组合作为作者认为无关的内容的占位符。当然,在尝试验证相应的 JSON 代码示例之前,必须删除或替换这些占位符。

本文档的示例中使用了空格来帮助说明数据结构,但这不是必需的。未加引号的空格在 JSON 没有意义。

# 1.3 GeoJSON 规范

本文档取代了原始的 GeoJSON 格式规范GJ2008 (opens new window)

# 1.4 名称解释

  • JSON、术语例如:object,member,name,value,array,number,true,false,null 等都可以在找到RFC9159 (opens new window)解释。
  • 本文档中,提到的“geometry type”对应于七个大小写敏感的字符串:“Point”、“MultiPoint”、“LineString”、“MultiLineString”、“Polygon”、“MultiPolygon”、“GeometryCollection”。
  • “GeoJSON types” 对应于九个大小写敏感的字符串:“Feature”、“FeatureCollection”和上方七个字符串。
  • “FeatureCollection”和“GeometryCollection”中的“Collection”并不是指该 GeoJSON 对象是一个数组对象。而是指其中属性“features”和“geometyies”分别是有序标准的 JSON 对象。

# 1.5 示例

A GeoJSON FeatureCollection:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [102.0, 0.5]
      },
      "properties": {
        "prop0": "value0"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [102.0, 0.0],
          [103.0, 1.0],
          [104.0, 0.0],
          [105.0, 1.0]
        ]
      },
      "properties": {
        "prop0": "value0",
        "prop1": 0.0
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [100.0, 0.0],
            [101.0, 0.0],
            [101.0, 1.0],
            [100.0, 1.0],
            [100.0, 0.0]
          ]
        ]
      },
      "properties": {
        "prop0": "value0",
        "prop1": {
          "this": "that"
        }
      }
    }
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

# 2 GeoJSON 文本

一个 GeoJSON 文本是一个 JSON 文本,包含一个 GeoJSON 对象组成。

# 3 GeoJSON 对象

一个 GeoJSON 对象代表了一个几何体、特征或者特征列表。

  • GeoJSON 对象是 JSON 对象。
  • GeoJSON 对象有一个“type”属性,该属性值必须是 GeoJSON types 中的值。
  • GeoJSON 对象也可以有一个“bbox”属性,其属性值必须是一个边界盒数组(参见 Section 5 (opens new window))。
  • GeoJSON 对象还可以拥有其他属性(参见 Section 6 (opens new window))。

# 3.1 几何对象

几何对象用来表示坐标空间中的点、曲线和曲面。无论几何对象位于GeoJSON 文本中什么位置,它都是一个 GeoJSON 对象。

  • 几何对象中“type”属性的值必须是上述提到的七个几何类型(参见 Section 1.4 (opens new window))。
  • 除“GeometryCollection”以外,其他几何类型的对象都带有“coordinates”属性。该属性的值是一个数组,不同的几何类型,数组的结构也不同。若“coordinates”是空数组时,GeoJSON 处理器会视为这是一个空几何对象。
# 3.1.1 位置

位置是基本的几何结构。几何对象中的“coordinates”属性可以为下面任意一个值: (PS: 每个都举例)

  • 某个点的位置,
  • 形成线或者多个点的位置数组,
  • 形成多边形或者多个线的线位置数组或环状位置(参见Section 3.1.6 (opens new window))数组,
  • 形成多个多边形的多边形位置数组。

一个具体的位置是十进制整数形成的数组。该数组至少拥有两个元素,且头两个元素分别表示经度和纬度,也是常说的“东经”和“北纬”。海拔可以作为第三个可选元素。例如:

// 只有经纬度
{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [102.0, 0.5] // 东经:102.0,北纬:0.5
  }
}
// 带有海拔
{
  "type": "Feature",
  "geometry": {
    "type": "LineString",
    "type": "Point",
    "coordinates": [102.0, 0.5, 100] // 东经:102.0,北纬:0.5,海拔:100
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

编写时不应该将“position”的数组元素超过三个元素,因为多出来的元素在标准中是没有定义的,这会导致含义不明。历史上,出现过使用第四个元素来携带线性参照标准(有时表示为“M”)或时间戳的情况,不过,大多数情况下解析器都不能正确解析这些值。那些不在本规范定义的附加属性,解析器都会把它们忽略掉。

两个位置之间的直线是两点在笛卡尔坐标系中最短的直线(参见 Section 4 (opens new window))。

换句话说,任何一个不与逆子午线相交的直线上的点都可以通过下面这个公式计算:F(lon,lat)=(lon0+(lon1lon0)t,lat0+(lat1lat0)t)F(lon,lat) = (lon_0 + (lon_1 - lon_0)*t, lat_0 + (lat_1 - lat_0)*t), 其中 0t10 \le t \le 1。请注意,这条线可能明显不同于沿参考椭球曲面的大地测量路径。

这同样适用于可选的高度元素,条件是高度的方向必须是坐标参考系中指定的方向。

需要注意的是,这并不意味着高度相等的表面遵循,例如,水体的曲率。等高的表面也不是垂直于垂线。

Appendix A (opens new window) 提供了相关的位置和几何示例。

# 3.1.2 点

当类型为“点”时,其属性“coordinates”的值为单一位置。

# 3.1.3 多个点

当类型为“多个点”时,其属性“coordinates”的值为位置组成的数组。

# 3.1.4 线

当类型为“线”时,其属性“coordinates”的值为 2 个或 2 个以上的位置组成的数组。

# 3.1.5 多个线

当类型为“多个线”时,其属性“coordinates”的值为“线”的“coordinates”属性值组成的数组。

# 3.1.6 多边形

当指定多边形的专有约束时,引入线型环的概念十分有用:

  • 线型环是由 4 个或者 4 个以上的位置组成的线型闭环。
  • 起始和终止是同一个位置,并且它们必须含有相同的值,即它们的表示形式是完全相同的。
  • 线型环是曲面的边界或曲面上孔的边界。
  • 线型环形成的边界区域遵循右手定则,即,外圈为逆时针,孔为顺时针。

注意:在GJ2008 (opens new window)标准中并没有讨论线型环的环绕方向。为了向下兼容,GeoJSON 解析器不应该不处理那些不遵循右手定则的多边形。

尽管,在标准中线型环没有被明确定义为 GeoJSON 的几何类型,但它引导出了 Polygon 几何类型定义的规范表述,如下所示

  • 当类型为“多边形”时,其属性“coordinates”的值为“线型环”的“coordinates”属性值组成的数组。
  • 对于具有多个环的多边形,第一个必须是外环,其他的必须是内环。外环约束表面,内环(如果存在)约束表面内的孔。
# 3.1.7 多个多边形

当类型为“多个多边形”时,其属性“coordinates”的值为“多边形”的“coordinates”属性值组成的数组。

# 3.1.8 几何体集合

带有“GeometryCollection”类型的 GeoJSON 对象是一个几何体对象。一个几何体集合带有一个名为“geometries”的属性,该属性值是一个数组,数组中每一个元素是一个 GeoJSON 几何体对象。当然该数组可以为空。与上面描述的其他几何体类型不同,一个几何体集合可以是一个由较小的几何体对象组成的异构体。例如:一个小写罗马字母 "i "形状的几何体对象可以由一个点和一条线组成。

几何体集合的语法不同于单一类型的几何体对象(点,线,多边形)和多个几何体类型对象(多个点,多条线,多个多边形),但是语义上与它们是一致的。尽管几何体集合不具有“coordinates”属性,但是却拥有坐标数据:集合中每个子元素拥有的坐标数据都属于该集合。几何体集合中的“geometries”属性表明了它的组成部分。实现时不应该对“geometries”数组应用任何额外的语义。

为了最大化的互操作性,实现时要避免嵌套几何体集合。此外,当几何体集合是由某一个或者多个单一类型的对象组成时,应该使用正确的类型对象(例如:多个点、多条线或者多个多边形),而不要使用几何体集合。

# 3.1.9 逆子午线分割

在表达穿过逆子午线的特征时,通过修改它们的几何形状来提高互操作性。任何穿过逆子午线的几何图形都应该通过把图形分成两半来表示,这样任何部分的表示都不会穿过逆子午线。

举个例子,一条从北纬 45°,东经 170° 延伸到北纬 45°,西经 170° 的线应该被切成两段,并用多条线表示:

{
  "type": "MultiLineString",
  "coordinates": [
    [
      [170.0, 45.0], [180.0, 45.0]
    ],
    [
      [-180.0, 45.0], [-170.0, 45.0]
    ]
  ]
}
1
2
3
4
5
6
7
8
9
10
11

另一个例子,一个从北纬 40°,东经 170° 延伸到北纬 50°,西经 170° 的矩形应该被切成两个部分,并用多个多边形表示:

{
  "type": "MultiPolygon",
  "coordinates": [
    [
      [
        [180.0, 40.0], [180.0, 50.0], [170.0, 50.0],
        [170.0, 40.0], [180.0, 40.0]
      ]
    ],
    [
      [
        [-170.0, 40.0], [-170.0, 50.0], [-180.0, 50.0],
        [-180.0, 40.0], [-170.0, 40.0]
      ]
    ]
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3.1.10 不确定性和精度

正如在RFC5870 (opens new window)中所述,坐标位置的位数不能被解释为不确定的指示。