本文翻译自https://tools.ietf.org/html/rfc7946 ,2018年1月27,28日两个大雪的周末,以序纪念。
译者尽量确保翻译后原文的意思不变,在文中也加入了些许自己的理解说明,去掉了原文中少许译者认为不重要的内容。由于英文水平有限、校对不充分、理解的程度可能会导致有出入,也请发现后不吝指正,译者也不对内容的正确性做任何保证。
本文仅供本译者学习交流使用,未经允许禁止转载。
GeoJSON 是一种基于JSON的地理空间数据交换格式,它定义了一些不同类型的JSON对象以及它们的组织方式,用于表达地理特性、属性和空间范围。GeoJSON使用WGS84(World Geodetic
System 1984)作为地理坐标参考系统,并以10进制为单位。
WGS84 National Imagery and Mapping Agency, "Department of Defense World Geodetic System 1984: Its Definition and Relationships with Local Geodetic Systems", Third Edition, 1984.
GeoJSON是用于对各种地理数据进行编码一种JSON格式。 一个GeoJSON对象可能代表一个空间区域(Geometry),一个空间有限的实体(Feature),或是一个Feature列表(FeatureCollection)。GeoJSON支持如下几何类型:
格式涉及最广义的地理数据;任何具有地理空间界限的特质都可能是一个Feature,不论它是否是一个物理结构。GeoJSON中的这些概念都不是新创建出来的,而是从预先已经存在的开放地理信息系统标准中派生出来的,转化成更符合web程序开发的JSON格式。
GeoJSON由七个具体的几何类型组成,它们在SFSQL中有定义:
SFSQL OpenGIS Consortium, Inc., "OpenGIS Simple Features Specification For SQL Revision 1.1", OGC 99-049, May 1999.
零维的Point和MultiPoint; 一维的曲线 LineString和MultiLineString;二维的曲面Polygon和MultiPolygon;和异构的GeometryCollection。这些几何类型的实例的GeoJSON表示类似于在同一规范中描述的WKB和WKT表示。
wkt(OGC well-known text)和wkb(OGC well-known binary)是OGC制定的空间数据的组织规范,wkt是以文本形式描述,wkb是以二进制形式描述。 使用wkt和wkb能够很好到和其他系统进行数据交换,目前大部分支持空间数据存储的数据库构造空间数据都采用这两种方式。https://en.wikipedia.org/wiki/Well-known_text
GeoJSON也可以由Feature和FeatureCollection组成。GeoJSON中Feature对象包含一个上面说的七种几何类型的Geometry对象和一些额外的成员。 一个FeatureCollection对象包含一个Feature对象数组。 这个结构类似于WFSv1(the Web Feature Service) 中GetFeatures请求的响应。也类似KML(a Keyhole Markup Language)的位置标记文件夹。一些WFS规范的实现为GetFeature请求也提供了GeoJSON格式的响应,但是在GeoJSON格式规范中没有服务模型或是Feature类型本体的意味。
WFSv1 Vretanos, P., "Web Feature Service Implementation Specification", OGC 04-094, Version 1.1.0, May 2005.
KMLv2.2 Wilson, T., "OGC KML", OGC 07-147r2, Version 2.2.0, April 2008.
自从2008年初次发表 (GJ2008) 以来,GeoJSON格式规范已经稳步的流行起来。它被广泛的用于JavaScript web映射库, 和基于JSON的文档数据库,以及Web API中。
GJ2008 Butler, H., Daly, M., Doyle, A., Gillies, S., Schaub, T., and C. Schmidt, "The GeoJSON Format Specification", June 2008.
略
JSON对象中的成员必须是顺序无关的。
一些示例使用JavaScript单行注释(//)后跟省略号(...)作为占位符符号的组合,作为与作者无关的内容。在尝试验证这些JSON代码示例之前,这些占位符当然必须要删掉或者以其他方式被替换掉。
为了便于说明数据结构,会在文档的示例中使用到空格,但是空格不是必须的。没有用引号括起来的空格是无意义的。
本文档取代了原始的GeoJSON格式规范 GJ2008。
一个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"
}
}
}
]
}
一个 GeoJSON文本是一个JSON文本,且由一个单个的GeoJSON对象组成。
一个GeoJSON对象表示一个Geometry(几何),Feature(特性),或Feature集合。
一个Geometry对象代表坐标空间中的:点、曲线、曲面。每个几何对象都是一个GeoJSON对象,不管它在GeoJSON文本中出现的位置。
position是基本的几何构造。几何对象的”coordinates“成员由下面任何一个组成:
一个position是一个数值数组,必须有两个或更多的元素。头两个元素是经度和纬度,或者是东距或北距(应该是测量学上的概念),按照这个顺序并且使用十进制。海拔可能被作为可选的第三个元素。
实现不应该扩展位置超过三个元素,因为三个元素后的额外元素是语义不明容易引起歧义的。从历史来看,一些实现用到了第四个元素来放置线性参考度量(有时表示为”M“)或者一个数值时间戳,但是在绝大部分情况下一个解析器是不能正确解释这些值的。这些额外的元素的解释和含义超出了本规范的范围,并且额外的元素可能会被解析器忽略。
两个position之间的线是一条直的笛卡尔线, 也是坐标参考系统(参考 第4节)中两个点之间最短的线。
换句话说,在一个点(lon0,lat0)和(lon1,lat1)之间的一条线上的每一个不穿过反子午线的点,可以被计算做:
F(lon, lat) = (lon0 + (lon1 - lon0) * t, lat0 + (lat1 - lat0) * t)
t是一个实数,范围是: 0 <= t <= 1。
请注意,这条线可能与沿参考椭球曲面的测地线路径明显不同。
译者思考: “这条线可能与沿参考椭球曲面的测地线路径明显不同”, 这句话的意思我的理解是,上述的线是基于经纬度的,而不是基于地理距离的,不同纬度上的经度地理距离是不一样的。
同样适用于可选的高度元素,条件是高度的方向与坐标参考系统中的规定相同。
再次注意: 这并不意味着具有相同高度就是一个平面,比如水体的曲率,同样具有垂直于铅垂线相同高度也不是一个平面。
下面提供了position和几何形状的示例, 见附录A "Geometry示例"
对于类型”Point“, ”coordinates“ 成员是一个position。
对于类型”MultiPoint“, ”coordinates"成员是一个position数组。
对于类型“LineString”, “coordinates”成员是两个或更多position的数组。
对于类型“MultiLineString”,“coordinates”成员是LineString坐标数组。
去指定一个多边形的约束规范,引入线性环的概念是有用的:
注意:【GJ2008】规范没有规范线性环缠绕的顺序。为了向后兼容,解析器不应该拒绝解析没有按照右边规则组织的多边形。
尽管一个线性环没有明确表示成一个GeoJSON几何类型,但是它导出了一个多边形几何类型定义的权限构想如下:
对于类型”MultiPolygon“, ”coordinates“成员是一个Polygon的坐标数组。
一个”GeometryCollection“类型的GeoJSON对象是一个Geometry对象。一个GeometryCollection对象有一个”geometries“成员,它的值是一个数组,每个数组元素都是一个Geometry对象。这个数组也有可能为空。不同于上面描述的其他geometry types,GeometryCollection可以由很多不同的小的Geometry对象组成。举个例子,一个小写的罗马字符”i“形状的Geometry对象可以又一个Point和一个LineString组成。
GeometryCollection虽然和其他的几种Geometry对象有不同的语法,但是语义是一样的。尽管GeometryCollection对象没有”coordinates“成员,但是它有坐标,所有组成它的部分的坐标都属于这个集合。GeometryCollection的”geometries“成员描述了组成了它的组成部分。实现不应该给”geometries“成员附加任何额外的语义。
为了最大的互操作性,实现应该尽量避免嵌套的GeometryCollections, 此外应该避免由一个单一部分或者是单一几何类型组成的GeometryCollection,可以用一个单一的Geometry类型代替或是用一个多部件的Geometry类型(MultiPoint, MultiLineString, MultiPolygon)代替。
译者注: ”反子午线“,英文原单词是”Antimeridian“,”反子午线“这个翻译可能不是很准确,可能叫”反本初子午线“可能更合适,指的是地球经度为0度的子午线的反面也就是东经或西经180度。
在表示跨越反子午线的特征中,可以通过修改它们的几何形状来提高互操作性。任何跨越反子午线的几何形状都应该被切割成两个都不会跨越反子午线的几何形状。
举个例子,一条线从北纬45度,东经170度,延伸跨越反子午线到北纬45度,西经170度 应该被切割成两条线表示成MultiLineString。
{
"type": "MultiLineString",
"coordinates": [
[
[170.0, 45.0], [180.0, 45.0]
], [
[-180.0, 45.0], [-170.0, 45.0]
]
]
}
一个从北纬40度,东经170度跨越反子午线到北纬50度,西经170度的矩形应该被切割成两个矩形可以表示成MultiPolygon。
{
"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]
]
]
]
}
就像在RFC5870中提到的,坐标位置的数值位数不能被解释为对级别的指示不明确。
一个Feature代表了一个空间有限的事物。每个Feature对象都是一个GeoJSON对象,不管它出现在GeoJSON文本的任何位置。
一个FeatureCollection对象是一个“type”成员值为“FeatureCollection“的GeoJSON对象。 一个FeatureCollection对象有一个成员”features“,它的值是一个JSON数组,数组的每个元素都是一个上面定义的Feature对象,这个数组也有可能为空。
GeoJSON坐标的坐标参考系统是一个地理坐标参考系统,使用WGS 84(World Geodetic
System 1984)基准,经纬度单位为10进制。这相当于由开放地理空间联盟(OGC)确定的坐标参考系统URN urn:ogc:def:crs:OGC :: CRS84。可选的第三个position元素应该是基于WGS 84参考椭球体的以米为单位的上方或下方的高度。一个对高度或深度敏感的应用在缺少海拔高度值的时候,应该将高度解释为当地的高度或是海平面的高度。
注意: GJ2008规范中使用了可选的坐标参考系统,但是在本规范中被移除了,因为在GJ2008中已经证明不同的坐标参考系统的使用带来了互操作性的问题。一般情况下,GeoJSON处理软件是不希望在访问坐标参考系统数据库或是通过网络访问坐标参考系统时去转换参数。然而,如果所有相关方都事先做出安排,在不会有数据被误解的风险的前提下则可以使用替代的坐标参考系统。
一个GeoJSON对象可能会有一个”bbox“成员去囊括这个GeoJSON对象的Geometries, Features, 或者FeatureCollections的坐标范围。”bbox"成员的值必须是一个长度为2*n的数组,n是它要囊括的几何形状的维数。所有最西南点的轴坐标紧跟所有最东北点的轴坐标,并且轴坐标顺序是和几何形状的轴坐标顺序是一样的。
“bbox”值定义了具有恒定经度,纬度和高程线的边缘形状。
Feature中2D的bbox成员的例子:
{
"type": "Feature",
"bbox": [-10.0, -10.0, 10.0, 10.0],
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-10.0, -10.0],
[10.0, -10.0],
[10.0, 10.0],
[-10.0, -10.0]
]
]
}
//...
}
FeatureCollection中2D的bbox成员的例子:
{
"type": "FeatureCollection",
"bbox": [100.0, 0.0, 105.0, 1.0],
"features": [
//...
]
}
100米深度的3D的bbox成员的例子:
{
"type": "FeatureCollection",
"bbox": [100.0, 0.0, -100.0, 105.0, 1.0, 0.0],
"features": [
//...
]
}
边界框的4条线是完全定义在坐标参考系统内的, 也就是一个框被东南西北四个值限定,最北的每个点可以用表达式表达如下:
(lon, lat) = (west + (east - west) * t, north), 0 <= t <= 1.
以斐济群岛内Features点集合来说明,在南纬16度到20度之间跨越反子午线,包含这些Features的框的西南角是南纬20度,东经177度,东北角是南纬16度,西经178度。这个FeatureCollection的GeoJSON边界框反子午线跨度为:
"bbox": [177.0, -20.0, -178.0, -16.0]
覆盖了5度的经度。
相同纬度带的互补边界框没有跨越反子午线:
"bbox": [-178.0, -20.0, 177.0, -16.0]
覆盖了355度的经度。
东北角的纬度总是比西南角的纬度大,但是跨越反子午线的边界框的东北角的经度是小于西南角的经度的。
一个边界框包含北极点,从西南角北纬最小的纬度,西经180度,延伸到东北角北纬90度,东经180度。从地球仪上看,这个边界框近似于一个由“minlat”圈定界的球冠。
"bbox": [-180.0, minlat, 180.0, 90.0]
一个边界框包含南极点,从西南角南纬90度,西经180度,延伸到东北角南纬最大的纬度,东经180度:
"bbox": [-180.0, -90.0, 180.0, maxlat]
在地球仪上观看时,一个刚好接触北极并形成一个近似球冠的切片的边界框从西南角北纬最小纬度,西经“westlon”度延伸到东北角北纬90度,东经“eastlon”度:
"bbox": [westlon, minlat, eastlon, 90.0]
相似的,在地球仪上观看时,一个刚好接触南极并形成一个近似球冠的切片的边界框在GeoJSON中表达为:
"bbox": [westlon, -90.0, eastlon, maxlat]
实现者不得使用大于90或小于-90的纬度值来表示不是球冠的范围。
那些在本规范中没有描述的成员(外部成员)可能会在GeoJSON文档中使用。请注意,对于外部成员的支持可以在不同的实现中有所不同,并且没有定义针对外部成员的规范处理模型。相应的,过重的依赖外部成员的实现可能会导致与其他实现的互操作性减弱。
比如,如下简化的Feature对象:
{
"type": "Feature",
"id": "f1",
"geometry": {...},
"properties": {...},
"title": "Example Feature"
}
键值对"title": "Example Feature" 是一个外部成员,当外部成员的值是一个对象的时候,这个对象的所有子孙成员都是它们的外部成员。
GeoJSON语义是不支持外部成员和它们的子孙成员的,并且会忽略它们的名称和值。比如一个简化的Feature对象如下:
{
"type": "Feature",
"id": "f2",
"geometry": {...},
"properties": {...},
"centerline": {
"type": "LineString",
"coordinates": [
[-170, 10],
[170, 11]
]
}
}
“centerline”成员不是一个GeoJSON Geometry对象。
实现不可以扩展已经固定的GeoJSON类型:FeatureCollection, Feature, Point, LineString, MultiPoint, Polygon, MultiLineString, MultiPolygon, and GeometryCollection.
实现不可以改变GeoJSON的成员和类型的语义。
GeoJSON中“coordinates”和“geometries”成员定义了Geometry对象集。FeatureCollection 和Feature 对象分别都不可以包含“coordinates” 和 “geometries”成员。
GeoJSON中“geometry” 和 “properties” 成员定义了Feature对象。 FeatureCollection 和Geometry对象各自都不可以包含“geometry” 和 “properties” 成员。
GeoJSON中“features” 成员定义了FeatureCollection对象。 Feature 和Geometry 对象各自都不可以包含“features” 成员。
GeoJSON格式可以像这里定义的那样扩展,但是没有定义明确的版本方案。一个改变GeoJSON成员的语义或者修改了格式的规范不会创建成GeoJSON的新版本; 相反,它定义了一个全新的格式,不能被标识为GeoJSON。
‘geo’ URIs [ RFC5870 ] 确定了地理位置和精确的位置可以被映射成GeoJSON的Geometry对象。
在 [ RFC5870 ]中,"lat", "lon", "alt", 和 "unc" 分别是'geo' URI 纬度,经度,和不确定值的占位符。
一个带有两个坐标值和一个不存在或是为0的不确定的参数的 ‘geo' URI, 和一个GeoJSON Point几何对象之间可以互相映射。一个GeoJSON点总是被转化成一个带有不确定参数的’geo‘ URI。
’geo’ URI:
geo:lat,lon
GeoJSON:
{"type": "Point", "coordinates": [lon, lat]}
指定了海拔高度的 ’geo’ URIs 和GeoJSON Points 之间的映射如下:
’geo’ URI:
geo:lat,lon,alt
GeoJSON:
{"type": "Point", "coordinates": [lon, lat, alt]}
GeoJSON中没有不确定的概念,不精确或不确定的’geo‘ URIs不能被映射成GeoJSON geometries。
GeoJSON和所有的JSON内容类型有同样的安全问题。参考[ rfc7159.pdf#section-12 ] 获取更多信息。 GeoJSON没有提供可执行的内容。
GeoJSON不提供隐蔽的或完整的服务。如果敏感的数据要求隐秘或完整的保护,这就必须通过传输层提供,比如Transport Layer Security (TLS) 或者HTTPS。 当然也会存在存储数据须要被保护的情况,这些内容不在本规范的范围内。
与其他地理数据格式一样,例如KMLv2.2,提供有关敏感人员,动物,栖息地和设施位置的详细信息,可能会使其遭受未经授权的追踪或伤害。
KMLv2.2 Wilson, T., "OGC KML", OGC 07-147r2, Version 2.2.0, April 2008.
数据的提供者应该意识到这种无意识的标识一个个体风险当匿名数据集中的位置信息没有被偏斜或没有被充分的模糊处理的话,并且应该认识到位置遮蔽的有效性受到许多因素的限制,不可能完全有效的抵御那些坚决的攻击。[ RFC6772 ]。
为了最大限度的互操作性,GeoJSON文本应该符合Internet JSON (I-JSON) 的约束。
GeoJSON文本大小字节数是一个重要的互操作性的考量,其中经纬度值的精度对文本的大小有比较大的影响。一个GeoJSON文本包含许多的多边形,当坐标精度从6个小数位到15个小数位,会导致将近两倍的数据膨胀。地理坐标以度为单位,6个小数位(在例如sprintf中通用的默认值)约为10厘米,在当前的GPS系统的精度之内。 实现应该考虑使用一个超过须要的经度带来的开销。
此外,WGS 84 WGS84数据是大地水准面的相对粗略的近似值, 相对于一个平行于地球平均海平面的平面,其高度或高或低于5米(但一般在2至3米之间)变化。
IANA: http://www.iana.org
GeoJSON文本的media type 是 “application/geo+json” 并且被注册在[RFC6838]的"Media Types"注册描述中。在同一个注册表中,“application / vnd.geo + json”的条目应该将其状态改为“OBSOLETED”(“废弃”),指向媒体类型“application / geo + json”的指针以及添加到此RFC的引用。
略
下面每个示例代表一个合法的完整的GeoJSON对象
点坐标是x, y 的顺序(东距,北距用于投影坐标, 经度,纬度用于地理坐标):
{
"type": "Point",
"coordinates": [100.0, 0.0]
}
LineStrings坐标是一个position数组(见3.1.1 节)
{
"type": "LineString",
"coordinates": [
[100.0, 0.0],
[101.0, 1.0]
]
}
一个Polygon的坐标是一个线性环坐标数组的数组(见 3.1.6节)。第一个数组元素代表外圈环。任何后续的元素代表内圈环(或者说孔)。
无孔:
{
"type": "Polygon",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
]
]
}
有孔:
{
"type": "Polygon",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.8, 0.8],
[100.8, 0.2],
[100.2, 0.2],
[100.2, 0.8],
[100.8, 0.8]
]
]
}
MultiPoint的坐标是一个position数组
{
"type": "MultiPoint",
"coordinates": [
[100.0, 0.0],
[101.0, 1.0]
]
}
MultiLineString的坐标是一个LineString坐标数组的数组:
{
"type": "MultiLineString",
"coordinates": [
[
[100.0, 0.0],
[101.0, 1.0]
],
[
[102.0, 2.0],
[103.0, 3.0]
]
]
}
MultiPolygon的坐标是一个Polygon坐标数组的数组:
{
"type": "MultiPolygon",
"coordinates": [
[
[
[102.0, 2.0],
[103.0, 2.0],
[103.0, 3.0],
[102.0, 3.0],
[102.0, 2.0]
]
],
[
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.2, 0.2],
[100.2, 0.8],
[100.8, 0.8],
[100.8, 0.2],
[100.2, 0.2]
]
]
]
}
GeometryCollection的"geometries"数组中的每个元素都是一个Geometry对象,描述如下:
{
"type": "GeometryCollection",
"geometries": [{
"type": "Point",
"coordinates": [100.0, 0.0]
}, {
"type": "LineString",
"coordinates": [
[101.0, 0.0],
[102.0, 1.0]
]
}
]
}
来自Pre-IETF GeoJSON格式规范的更改
略
多有在本规范中定义的GeoJSON对象:FeatureCollection, Feature, and Geometry,都恰好由一个JSON对象构成。 然而,某些情况下,应用须要表示一个这些对象的集合或是序列,以有效地“流动”大量的Feature对象。这种集合和序列的定义超出了本规范的范围。
如果确实须要这样一种表达,那就须要一种新的media type去对这些集合和序列进行表达。当定义一个新的meida type时,可能基于"JavaScript Object Notation (JSON) Text Sequences" RFC7464 是有用的,留下如何将多个JSON对象表示为该分类的基础,并且只定义它如何应用于GeoJSON对象。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。