TopoJSON 是 GeoJSON 的扩展, 增加了拓扑逻辑的编码。
TopoJSON 是一种 JSON 格式,用于将地理数据结构编码为共享拓扑。 TopoJSON 拓扑表示共享一个称为弧的位置序列的一个或多个几何。 TopoJSON 作为 GeoJSON 的扩展,支持多种几何类型:Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon 和 GeometryCollection。 TopoJSON 中的几何可能包含其他属性,以对非几何数据进行编码。
TopoJSON 特征集合:
一个 TopoJSON 拓扑,其中包含一个名为"example"的对象,其本身是一个几何集合:
{
"type": "Topology",
"objects": {
"example": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"properties": {
"prop0": "value0"
},
"coordinates": [102, 0.5]
},
{
"type": "LineString",
"properties": {
"prop0": "value0",
"prop1": 0
},
"arcs": [0]
},
{
"type": "Polygon",
"properties": {
"prop0": "value0",
"prop1": {
"this": "that"
}
},
"arcs": [[-2]]
}
]
}
},
"arcs": [
[[102, 0], [103, 1], [104, 0], [105, 1]],
[[100, 0], [101, 0], [101, 1], [100, 1], [100, 0]]
]
}
相同的拓扑(quantized)
{
"type": "Topology",
"transform": {
"scale": [0.0005000500050005, 0.00010001000100010001],
"translate": [100, 0]
},
"objects": {
"example": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"properties": {
"prop0": "value0"
},
"coordinates": [4000, 5000]
},
{
"type": "LineString",
"properties": {
"prop0": "value0",
"prop1": 0
},
"arcs": [0]
},
{
"type": "Polygon",
"properties": {
"prop0": "value0",
"prop1": {
"this": "that"
}
},
"arcs": [[1]]
}
]
}
},
"arcs": [
[[4000, 0], [1999, 9999], [2000, -9999], [2000, 9999]],
[[0, 0], [0, 9999], [2000, 0], [0, -9999], [-2000, 0]]
]
}
带 id 、bbox 的拓扑
{
"type": "Topology",
"bbox": [0, 0, 10, 10],
"objects": {
"point": {
"id": "pointy",
"bbox": [1, 2, 1, 2],
"properties": {
"name": "Point E. Daht"
},
"type": "Point",
"coordinates": [1, 2]
},
"points": {
"id": "pointies",
"bbox": [1, 2, 3, 4],
"properties": {
"name": "Sir Points-a-Lot"
},
"type": "MultiPoint",
"coordinates": [[1, 2], [3, 4]]
},
"collection": {
"id": "collection",
"bbox": [1, 2, 1, 2],
"properties": {
"name": "Collection"
},
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"id": "collection-point",
"coordinates": [1, 2]
}
]
},
"polygon": {
"id": "polly",
"bbox": [0, 0, 10, 10],
"properties": {
"name": "Polly Gan"
},
"type": "Polygon",
"arcs": [
[0]
]
}
},
"arcs": [
[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]
]
}
TopoJSON 总是由一个单独的拓扑(topology)对象组成。一个拓扑对象可以包含任意个已命名的几何(geometry)对象。 术语" TopoJSON 对象"可以指其包含的拓扑或几何对象。
拓扑是一种 TopoJSON 对象,这时 type 成员的值是下面字符串之一:“Topology”。
位置由数字数组表示。必须至少两个元素,可以有更多元素。元素的顺序必须遵从 x,y,z 顺序(投影坐标参考系统中坐标的东向、北向、高度或者地理坐标参考系统中的坐标长度、纬度、高度)。任何数目的其他元素是允许的—其他元素的说明和意义超出了这篇规格说明的范围。
拓扑可以具有其值是变换对象的"变换"成员。 转换的目的是通过将位置表示为整数而不是浮点数来量化(quantized)位置,以实现更有效的序列化。
"scale"和"translate"成员的长度都必须为二。 拓扑中的每个位置都必须量化,每个位置中的第一和第二个元素都是整数。
要将量化位置转换为绝对位置,请执行以下操作:
实现将单个位置从给定的量化拓扑转换为绝对坐标:
function transformPoint(topology, position) {
position = position.slice();
position[0] =
position[0] * topology.transform.scale[0] + topology.transform.translate[0];
position[1] =
position[1] * topology.transform.scale[1] + topology.transform.translate[1];
return position;
}
注意,position 其余参数无需对其进行转换,将保留不变。
拓扑必须具有"arcs"成员,其值是位置数组。 每个弧必须是两个或更多位置的数组。
如果对拓扑进行了量化,则必须对经过量化的拓扑中每个弧的位置进行增量编码。 弧的第一个位置是正常位置[x1,y2]。 第二位置[x2,y2]被编码为[Δx2,Δy2],其中 x2 = x1 +Δx2 和 y2 = y1 +Δy2。 第三位置[x3,y3]编码为[Δx3,Δy3],其中 x3 = x2 +Δx3 = x1 +Δx2 +Δx3 和 y3 = y2 +Δy3 = y1 +Δy2 +Δy3 等。
实现从给定的量化拓扑中解码单个增量编码的量化弧:
function decodeArc(topology, arc) {
var x = 0,
y = 0;
return arc.map(function (position) {
position = position.slice();
position[0] =
(x += position[0]) * topology.transform.scale[0] +
topology.transform.translate[0];
position[1] =
(y += position[1]) * topology.transform.scale[1] +
topology.transform.translate[1];
return position;
});
}
由 LineStrings(LineString 或 MultiLineString)或 LinearRings(Polygon 或 MultiPolygon)组成的几何对象必须由弧构造。 每个弧都必须由从零开始的数字索引引用到包含的拓扑的 arcs 数组中。 例如,0 表示第一个弧,1 表示第二个弧,依此类推。
负弧索引表示必须颠倒索引补码处的弧才能重建几何形状:-1 表示反向的第一弧,-2 表示反向的第二弧,依此类推。 在 JavaScript 中,您可以使用按位 NOT 运算符〜i 来否定负弧索引 i。
如果引用多个弧以构造 LineString 或 LinearRing,则后一个弧的第一个位置必须等于前一个弧的最后一个位置。 然后,当重建几何形状时,除第一弧以外的每个弧的第一位置可以被丢弃; 等效地,每个弧的最后一个位置(最后一个除外)都可以删除。
拓扑必须具有"对象"成员,其值是一个对象。 该对象可以具有任意数量的成员,其值必须是几何对象。
几何是一种 TopoJSON 对象,这时 type 成员的值是下面字符串之一:“Point”,“MultiPoint”,“LineString”,“MultiLineString”,“Polygon”,“MultiPolygon"或"GeometryCollection”。
类型为"Point"或"MultiPoint"的 TopoJSON 几何对象必须具有名称为"coordinates"的成员。 类型为"LineString",“MultiLineString”,"Polygon"或"MultiPolygon"的 TopoJSON 几何对象必须具有名称为"arcs"的成员。 弧和坐标成员的值始终是一个数组。 此数组中元素的结构由几何类型决定。
如果几何图形具有常用的标识符,则该标识符应作为几何对象的成员包含,名称为"id"。 几何对象可能具有名称为"properties"的成员。 属性成员的值是一个对象(任何 JSON 对象或 JSON 空值)。
对类型"Point"来说,“coordinates"成员必须是一个单独的位置。
对类型"MultiPoint"来说,"coordinates"成员必须是位置数组。
对类型"LineString"来说,“arcs"成员必须是弧索引的数组。
对类型“MultiLineString"来说,"arcs"成员必须是一个线弧索引数组的数组。
对类型"Polygon"来说,"arcs"成员必须是一个线性环弧索引数组的数组。对拥有多个环的的面来说,第一个环必须是外部环,其他的必须是内部环或者孔。
线性环市具有 4 个或者更多位置的封闭的线。第一个和最后一个位置是相等的(它们表示相同的的点)。
对类型"MultiPlygon"来说,"arcs"成员必须是面弧索引数组的数组。
类型为"GeometryCollection"的 TopoJSON 对象是一个集合对象,它表示几何对象的集合。
几何集合必须有一个名字为"geometries"的成员。与"geometries"相对应的值是一个数组。这个数组中的每个元素都是一个 TopoJSON 几何对象。
TopoJSON 对象的坐标参考系统(CRS)是由它的"crs"成员(指的是下面的 CRS 对象)来确定的。如果对象没有 crs 成员,那么它的父对象或者祖父对象的 crs 成员可能被获取作为它的 crs。如果这样还没有获得 crs 成员,那么默认的 CRS 将应用到 TopoJSON 对象。
CRS 对象可以通过名字来表明坐标参考系统。在这种情况下,它的"type"成员的值必须是字符串"name"。它的"properties"成员的值必须是包含"name"成员的对象。这个"name"成员的值必须是标识坐标参考系统的字符串。比如“urn:ogc:def:crs:OGC:1.3:CRS84"的 OGC CRS 的 URN 应当优先于旧的标识符如"EPSG:4326"得到选用:
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
}
CRS 对象也可以连接到互联网上的 CRS 参数。在这种情况下,它的"type"成员的值必须是字符串"link",它的"properties"成员的值必须是一个连接对象(见 3.2.1.连接对象) 。
连接对象由一个必需的成员:“href”,和一个可选的成员:“type”。
必需的"href"成员的值必须是解引用的 URI(统一资源标识)。
可选的"type"成员的值必须是字符串,而且这个字符串暗示了所提供的 URI 里用来表示 CRS 参数的格式。建议值是:“proj4”,“ogcwkt”,esriwkt",不过可以使用其他值:
"crs": {
"type": "link",
"properties": {
"href": "http://example.com/crs/42",
"type": "proj4"
}
}
相对连接常常可以作为辅助文件里的 CRS 的直接处理器:
"crs": {
"type": "link",
"properties": {
"href": "data.crs",
"type": "ogcwkt"
}
}
包含有关拓扑或几何的坐标范围的信息,TopoJSON 对象可能有一个名字为"bbox" 的成员。bbox 成员的值必须是 2*n 数组,这儿 n 是所包含几何对象的维数,并且所有坐标轴的最低值后面跟着最高者值。bbox 的坐标轴的顺序遵循几何坐标轴的顺序。边界框不应使用拓扑的变换进行变换(如果有的话)。
拓扑
{
"type": "Topology",
"bbox": [-180.0, -90.0, 180.0, 90.0],
"objects": {
}
...
}
几何对象
{
"type": "Point",
"bbox": [-180.0, -90.0, 180.0, 90.0],
"coordinates": [102, 0.5]
}
下面例子中的每一个都表示一个完整的 GeoJSON 对象。注意 JSON 对象里的结尾的空白字符没有意义。例子里所用的空白符有助于说明这个数据结构,不过不是必需的。
点坐标是按照 x,y 顺序的(投影坐标的东向、北向,地理坐标的长度、高度):
{
"type": "Point",
"coordinates": [100.0, 0.0]
}
a single arc
{
"type": "LineString",
"arcs": [42]
}
multiple arcs
{
"type": "LineString",
"arcs": [42,43]
}
将弧拼接在一起以形成几何形状时,弧的最后一个坐标必须与后续弧的第一个坐标(如果有)相同。 例如,如果弧 42 代表点序列 A→B→C,而弧 43 代表点序列 C→D→E,则线串[42,43]代表点序列 A→B→C→D→E。
没有孔的:
{
"type": "Topology",
"bbox": [0, 0, 10, 10],
"objects": {
"polygon": {
"type": "Polygon",
"arcs": [
[0]
]
}
},
"arcs": [
[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]
]
}
有孔的:
{
"type": "Topology",
"bbox": [0, 0, 10, 10],
"objects": {
"polygon": {
"type": "Polygon",
"arcs": [
[0],
[1]
]
}
},
"arcs": [
[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]],
[[4, 4], [4, 6], [6, 6], [6, 4], [4, 4]]
]
}
多点的坐标是位置数组:
{
"type": "MultiPoint",
"coordinates": [
[100.0, 0.0],
[101.0, 1.0]
]
}
多线的坐标是线坐标数组的数组:
{
"type": "MultiLineString",
"arcs": [
[0],
[42,43]
]
}
多面的坐标是面坐标数组的数组:
{
"type": "MultiPolygon",
"coordinates": [
[
[0]
],
[
[42]
]
]
}
几何集合的几何数组里的每个元素都是上面所描述的几何对象之一:
{
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"properties": {},
"coordinates": [4000, 5000]
},
{
"type": "LineString",
"properties": {},
"arcs": [0]
},
{
"type": "Polygon",
"properties": {},
"arcs": [[1]]
}
]
}
1、参考topojson-specification
2、https://github.com/topojson/topojson