当前位置: 首页 > 工具软件 > TopoJSON > 使用案例 >

TopoJSON格式规范说明

邓元白
2023-12-01

TopoJSON 是 GeoJSON 的扩展, 增加了拓扑逻辑的编码。

武汉市TopoJSON数据

1.简介

TopoJSON 是一种 JSON 格式,用于将地理数据结构编码为共享拓扑。 TopoJSON 拓扑表示共享一个称为弧的位置序列的一个或多个几何。 TopoJSON 作为 GeoJSON 的扩展,支持多种几何类型:Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon 和 GeometryCollection。 TopoJSON 中的几何可能包含其他属性,以对非几何数据进行编码。

1.1.举例

TopoJSON 特征集合:

1.1.1 example 1

一个 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]]
  ]
}

1.1.2 example 2

带 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]]
  ]
}

1.2.定义

  • JavaScript 对象表示和术语对象、名字、值、数组和数字在 IETF RFC 4627 即http://www.ietf.org/rfc/rfc4627.txt里定义。
  • 这篇文档里的关键字"必须",“不允许”,“需要”,“应当”,“应当不”,“应该”,“不应该”,“推荐的”,"也许"和"可选的"在 IETF RFC 2119, 即http://www.ietf.org/rfc/rfc2119.txt里解释。
  • 所有浮点数都必须视为双精度浮点数,并且所有整数都必须是 32 位有符号整数。

2.TopoJSON 对象

TopoJSON 总是由一个单独的拓扑(topology)对象组成。一个拓扑对象可以包含任意个已命名的几何(geometry)对象。 术语" TopoJSON 对象"可以指其包含的拓扑或几何对象。

  • TopoJSON 对象可能有任何数目成员(名/值对)。
  • TopoJSON 对象必须由一个名字为"type"的成员。这个成员的值是由 TopoJSON 对象的类型所确定的字符串。
  • type 成员的值必须是下面之一:“Topology”, “Point”, “MultiPoint”, “LineString”, “MultiLineString”, “Polygon”, “MultiPolygon” 或者 “GeometryCollection”。这儿 type 成员值必须如这儿所示。
  • TopoJSON 对象可能有一个"bbox"成员,它的值必须是边界框数组(见4.边界框) 。

2.1 拓扑对象 (Topology)

拓扑是一种 TopoJSON 对象,这时 type 成员的值是下面字符串之一:“Topology”。

  • 拓扑必须具有名称为"objects"的成员,其值是另一个对象。 该对象的每个成员的值是一个几何对象。
  • 拓扑必须具有名称为"arcs"的成员,其值是弧的数组。
  • 拓扑可能具有"transform"成员,其值必须是转换。
  • 拓扑可能具有"bbox"成员,其值必须是边界框数组。

2.1.1.位置(Positions)

位置由数字数组表示。必须至少两个元素,可以有更多元素。元素的顺序必须遵从 x,y,z 顺序(投影坐标参考系统中坐标的东向、北向、高度或者地理坐标参考系统中的坐标长度、纬度、高度)。任何数目的其他元素是允许的—其他元素的说明和意义超出了这篇规格说明的范围。

2.1.2 转换(Transforms)

拓扑可以具有其值是变换对象的"变换"成员。 转换的目的是通过将位置表示为整数而不是浮点数来量化(quantized)位置,以实现更有效的序列化。

  • 转换必须具有一个名称为"scale"的成员,其值是一个由两个元素组成的数字数组。
  • 转换必须具有一个名称为"translate"的成员,其值是一个由两个元素组成的数字数组。

"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 其余参数无需对其进行转换,将保留不变。

2.1.3 弧(Arcs)

拓扑必须具有"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;
  });
}

2.1.4 弧索引(Arc Indexes)

由 LineStrings(LineString 或 MultiLineString)或 LinearRings(Polygon 或 MultiPolygon)组成的几何对象必须由弧构造。 每个弧都必须由从零开始的数字索引引用到包含的拓扑的 arcs 数组中。 例如,0 表示第一个弧,1 表示第二个弧,依此类推。

负弧索引表示必须颠倒索引补码处的弧才能重建几何形状:-1 表示反向的第一弧,-2 表示反向的第二弧,依此类推。 在 JavaScript 中,您可以使用按位 NOT 运算符〜i 来否定负弧索引 i。

如果引用多个弧以构造 LineString 或 LinearRing,则后一个弧的第一个位置必须等于前一个弧的最后一个位置。 然后,当重建几何形状时,除第一弧以外的每个弧的第一位置可以被丢弃; 等效地,每个弧的最后一个位置(最后一个除外)都可以删除。

2.1.5 对象(Objects)

拓扑必须具有"对象"成员,其值是一个对象。 该对象可以具有任意数量的成员,其值必须是几何对象。

2.2 几何对象(Geometry Objects)

几何是一种 TopoJSON 对象,这时 type 成员的值是下面字符串之一:“Point”,“MultiPoint”,“LineString”,“MultiLineString”,“Polygon”,“MultiPolygon"或"GeometryCollection”。

类型为"Point"或"MultiPoint"的 TopoJSON 几何对象必须具有名称为"coordinates"的成员。 类型为"LineString",“MultiLineString”,"Polygon"或"MultiPolygon"的 TopoJSON 几何对象必须具有名称为"arcs"的成员。 弧和坐标成员的值始终是一个数组。 此数组中元素的结构由几何类型决定。

如果几何图形具有常用的标识符,则该标识符应作为几何对象的成员包含,名称为"id"。 几何对象可能具有名称为"properties"的成员。 属性成员的值是一个对象(任何 JSON 对象或 JSON 空值)。

2.2.1 点(Point)

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

2.2.2 多点(MultiPoint)

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

2.2.3 线(LineString)

对类型"LineString"来说,“arcs"成员必须是弧索引的数组。

2.2.4 多线(MultiLineString)

对类型“MultiLineString"来说,"arcs"成员必须是一个线弧索引数组的数组。

2.2.5 面(Polygon)

对类型"Polygon"来说,"arcs"成员必须是一个线性环弧索引数组的数组。对拥有多个环的的面来说,第一个环必须是外部环,其他的必须是内部环或者孔。

线性环市具有 4 个或者更多位置的封闭的线。第一个和最后一个位置是相等的(它们表示相同的的点)。

2.2.6 多面(MultiPolygon)

对类型"MultiPlygon"来说,"arcs"成员必须是面弧索引数组的数组。

2.2.7 几何集合(Geometry Collection)

类型为"GeometryCollection"的 TopoJSON 对象是一个集合对象,它表示几何对象的集合。

几何集合必须有一个名字为"geometries"的成员。与"geometries"相对应的值是一个数组。这个数组中的每个元素都是一个 TopoJSON 几何对象。

3.坐标参考系统对象

TopoJSON 对象的坐标参考系统(CRS)是由它的"crs"成员(指的是下面的 CRS 对象)来确定的。如果对象没有 crs 成员,那么它的父对象或者祖父对象的 crs 成员可能被获取作为它的 crs。如果这样还没有获得 crs 成员,那么默认的 CRS 将应用到 TopoJSON 对象。

  • 默认的 CRS 是地理坐标参考系统,使用的是 WGS84 数据,长度和高度的单位是十进制标示。
  • 名字为"crs"成员的值必须是 JSON 对象(指的是下面的 CRS 对象)或者 JSON 的 null。如果 CRS 的值为 null,那么就假设没有 CRS 了。
  • crs 成员应当位于(拓扑、对象顺序的)层级结构里 TopoJSON 对象的最顶级,而且在自对象或者孙子对象里不应该重复或者覆盖。
  • 非空的 CRS 对象有两个强制拥有的对象:“type"和"properties”。
  • type 成员的值必须是字符串,这个字符串说明了 CRS 对象的类型。
  • 属性成员的值必须是对象。
  • CRS 应不能更改坐标顺序。

3.1. 名字 CRS

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"
    }
  }

3.2. 连接 CRS

CRS 对象也可以连接到互联网上的 CRS 参数。在这种情况下,它的"type"成员的值必须是字符串"link",它的"properties"成员的值必须是一个连接对象(见 3.2.1.连接对象) 。

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"
    }
  }

4.边界框

包含有关拓扑或几何的坐标范围的信息,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]
}

附录 A.集合例子

下面例子中的每一个都表示一个完整的 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

 类似资料: