このビューアーでできること
TopoJSONはGeoJSONのコンパクトな親戚です。共有する境界を1回だけ保存し、座標をふつう小さな整数で書きます。そのためファイルがとても小さくなり、D3.jsの地図、選挙地図、多くのデータジャーナリズムのプロジェクトで使われています。欠点は、TopoJSONファイルを目で見ても内容が読めないことと、多くのGISツールやWeb地図が変換なしでは開けないことです。
このビューアーはファイルを直接開きます。.topojsonまたは.jsonファイルを地図にドロップすると、本当にトポロジーかどうかを確かめ、アークから各図形を組み立て直し、名前の付いたオブジェクトごとに色を変えて別々のレイヤーとして描きます。サイドバーには、オブジェクト数、フィーチャ数、アーク数、量子化されているかとグリッドの細かさ、同じデータを普通のGeoJSONにした場合にどれだけ大きくなるかが表示されます。フィーチャをクリックすると、TopoJSONのidを含む属性が読めます。
普通のGeoJSONビューアーにはない機能を1つ加えました。「Highlight shared borders」です。2つの異なるフィーチャが共有するアークだけを、トポロジーから直接描きます。国、都道府県、選挙区の地図に、隙間や重なりのないきれいな共有境界が本当にあるかを確認する最も速い方法です。別のツールでデータが必要なときは、1つのオブジェクトまたはすべてをGeoJSONでダウンロードしてください。何もアップロードされず、ファイルがコンピューターから出ることはありません。
TopoJSONとGeoJSONの違い
どちらの形式もJSONで、どちらも属性付きのポイント、ライン、ポリゴンを表します。違いは座標の保存方法です。
| 項目 | TopoJSON | GeoJSON |
|---|---|---|
| 共有する境界 | アークとして1回だけ保存し、それを使う各図形が参照する | 接する各ポリゴンに毎回保存する |
| 座標 | ふつうは量子化した整数を、小さな差分(デルタ)で書く | 各頂点に完全な小数の経度・緯度 |
| ファイルサイズ | 接し合うポリゴンではたいていずっと小さい | 大きいが読みやすい |
| レイヤー | 1つのファイルに名前付きのオブジェクトを複数 | 1ファイルに1つのFeatureCollection |
| トポロジー | どの図形が隣同士かを知っているので、境界をまとめて単純化できる | 図形どうしのつながりはない |
| 対応ツール | D3.js、mapshaper、GDAL/QGIS(読み込みのみ)、このビューアー | ほぼすべてのGISとWeb地図ライブラリ |
| 規格 | TopoJSON Format Specification 1.0(コミュニティ) | IETF RFC 7946 |
私の目安です。国、州、選挙区のように接し合うポリゴンを大量にブラウザへ送り、サイズが重要な場合はTopoJSONを使います。それ以外、特に他の人やツールがデータを編集する場合はGeoJSONを使います。
TopoJSONファイルの中身
TopoJSONファイルは、typeが"Topology"の1つのJSONオブジェクトです。主なメンバーは次のとおりです。
- type
- 常に
"Topology"。"FeatureCollection"と書かれたファイルはTopoJSONではなくGeoJSONです。 - objects
- 名前付きオブジェクトの辞書で、たとえば
countriesやcapitals。それぞれがジオメトリまたはGeometryCollectionで、このビューアーでは1つずつレイヤーになります。 - arcs
- 共有のライン一覧です。ポリゴンやライン自体は座標を持たず、自分を作るアークの番号を並べます。
- transform
- 省略可能。あるとファイルは量子化されています。アークの位置は整数で、
scaleとtranslateで経度・緯度に戻します。 - bbox
- 省略可能。全データの外接矩形で、[最小 x, 最小 y, 最大 x, 最大 y] の形です。
- properties, id
- 各ジオメトリは、GeoJSONのフィーチャと同じく
properties(属性)とidを持てます。
これは、接し合う2つの正方形の畑を含む、ごく小さな完全なトポロジーです。下の数学のセクションで計算するのと同じ例です。
{
"type": "Topology",
"transform": { "scale": [0.001, 0.001], "translate": [-10, 40] },
"objects": {
"fields": {
"type": "GeometryCollection",
"geometries": [
{ "type": "Polygon", "arcs": [[0, 1]], "properties": { "name": "A" } },
{ "type": "Polygon", "arcs": [[2, -1]], "properties": { "name": "B" } }
]
}
},
"arcs": [
[[4000, 7000], [0, 1000]],
[[4000, 8000], [-1000, 0], [0, -1000], [1000, 0]],
[[4000, 7000], [1000, 0], [0, 1000], [-1000, 0]]
]
}畑Aはアーク 0 と 1 を使います。畑Bはアーク 2 と、続けて -1 を使います。負のインデックスは「このアークを逆向きに使う」という意味です。-1 は1の補数 ~0 なので、アーク0を逆にしたものです。畑どうしの境界(アーク0)は1回しか書かれていません。
技術的な詳細
ビューアーが読み込んで表示する内容を正確に説明します。
- 対応ファイル
"type": "Topology"を持つ.topojsonと.jsonファイル、100 MBまで。GeoJSONファイルの場合は、GeoJSONビューアーを案内するわかりやすいメッセージが出ます。- ジオメトリタイプ
- Point、MultiPoint、LineString、MultiLineString、Polygon、MultiPolygon、GeometryCollection。nullのジオメトリにも対応します(スキップされます)。
- オブジェクト
- 名前付きのオブジェクトはそれぞれ1つのレイヤーになり、チェックボックス、色、ジオメトリタイプ、フィーチャ数、フィールド数、GeoJSONのダウンロードが付きます。
- 量子化されたファイル
- 完全に対応しています。
transformを読み、デルタ符号化された整数を復号し、グリッド1ステップの地上での大きさをメートルで表示します。 - 共有境界
- ポリゴンを含むオブジェクトでは、2つの異なるフィーチャが使うアークのメッシュ(
a !== bを指定したtopojson.mesh)を作り、上に重ねて描けます。 - 属性
- すべての
propertiesがポップアップに表示されます。TopoJSONのidは属性idとして加えるので、画面で見られ、書き出しにも残ります。 - 座標系
- Web地図用のTopoJSONはふつうWGS84の経度・緯度です。変換前に投影されたファイル(たとえばD3地図用のUS Albers)は度単位ではないので、世界地図の上には置けません。
- 書き出し
- 各オブジェクトを別々のGeoJSONファイルに、またはすべてのオブジェクトを1つのGeoJSONに。後者では、各フィーチャの出どころを示す属性
topojson_objectが付きます。 - ベースマップ
- 標準は道路地図で、衛星画像も選べます。塗りの不透明度を0にすると輪郭だけが見えます。
- プライバシー
- ファイルはブラウザ内で読み込まれ、復号されます。サーバーには何も送られません。
TopoJSONファイルを表示する手順
組み込みのサンプルで全体の流れを示します。Natural Earthのヨーロッパ50か国と22の首都を、2つのオブジェクトを持つ1つの量子化トポロジーとして保存したものです。

地図は道路のベースマップ付きで開きます。Uploadを使うか、ファイルを地図にドラッグするか、Sample Dataをクリックします。

ファイルはブラウザ内で復号され、各オブジェクトがそれぞれの色で描かれます。File Infoには、オブジェクト数、フィーチャ数、アーク数、量子化のステップ、同じデータをGeoJSONにした場合の大きさが表示されます。

Objectsパネルには、トポロジー内の各オブジェクトがジオメトリタイプとフィーチャ数とともに並びます。チェックを外すと非表示になり、色の四角をクリックすると色を変えられます。

「Highlight shared borders」にチェックを入れると、2つの異なるフィーチャが共有するアークを、トポロジーそのものから描きます。海岸線は共有されていないので、そのままです。

フィーチャをクリックすると属性が開きます。ポップアップには、そのフィーチャが属するオブジェクト名とTopoJSONのidも表示されます。

オブジェクトの横にあるGeoJSONリンクでそのオブジェクトだけを、Download All as GeoJSONですべてを1つのファイルでダウンロードします。
TopoJSONを開いて変換するほかの方法
このビューアーはファイルをすばやく確認するためのものです。TopoJSONファイルで本格的な作業が必要なときは、次のツールを使います。
mapshaper
mapshaper(Webサイトのmapshaper.org、またはコマンドラインツール)は、TopoJSON、Shapefile、GeoJSON、CSVを読み書きできます。境界を共有したまま単純化したり、TopoJSONと他の形式を相互に変換したりするのに最適なツールです。
QGISとGDAL
GDALには読み込み専用のTopoJSONドライバーがあるので、QGISはTopoJSONファイルをドラッグ&ドロップで開けます。各オブジェクトは別々のレイヤーとして表示されます。保存するにはレイヤーをGeoJSONまたはGeoPackageに書き出します。コマンドラインでは ogr2ogr で変換します。
topojsonのコマンドラインツール
geo2topo(topojson-server)はGeoJSONファイルからトポロジーを作り、toposimplify(topojson-simplify)と topoquantize(topojson-client)はそれを小さくし、topo2geo(これもtopojson-client)はオブジェクトをGeoJSONに戻します。
D3.jsとPython
ブラウザでは、topojson.feature がオブジェクトをD3や任意の地図ライブラリ用のGeoJSONに変え、topojson.mesh が共有境界を返します。Pythonでは、GeoPandasがGDAL経由でTopoJSONを1つのオブジェクト(レイヤー)ずつ読み込みます。
同じ作業をコードで
次のコマンドは国のファイルを双方向に変換し、JavaScriptとPythonで読み込みます。
# mapshaper (npm install -g mapshaper) mapshaper countries.shp -o format=topojson quantization=1e5 countries.topojson mapshaper countries.topojson -o format=geojson countries.geojson # topojson-server / topojson-client command line tools geo2topo countries=countries.geojson > countries.topojson topo2geo countries=countries.geojson < countries.topojson # GDAL / OGR: each TopoJSON object becomes its own layer ogrinfo countries.topojson ogr2ogr -f GeoJSON countries.geojson countries.topojson countries
// D3.js + topojson-client in the browser
const topo = await d3.json("countries.topojson");
const countries = topojson.feature(topo, topo.objects.countries);
const borders = topojson.mesh(topo, topo.objects.countries, (a, b) => a !== b);
# Python: GeoPandas reads TopoJSON through GDAL, one object at a time
import geopandas as gpd
countries = gpd.read_file("countries.topojson", layer="countries")私の考えでは、元データはGeoJSON、GeoPackage、Shapefileで管理し、TopoJSONはWeb向けの最後のステップで作るのがよいです。作り直すのは簡単ですが、手で編集するのは大変だからです。
ビューアーの仕組み
ファイルをドロップしてから地図に表示されるまでの流れです。すべてのステップはブラウザ内で動きます。
- JSONを読み込んで確認する. ファイルをテキストとして読み込み、解析します。最上位の
typeが"Topology"でない場合や、objectsやarcsがない場合は、空の地図ではなくわかりやすいエラーを表示します。 - アークを復号する. ファイルに
transformがあれば、各アークをデルタ符号化された整数から経度・緯度に戻します。transformがなければ、アークの位置をそのまま使います。 - 各オブジェクトを組み立て直す. 名前付きのオブジェクトごとに、
topojson.featureが参照されたアークをつないでリングやラインにし、負のインデックスのアークを逆向きにし、元のpropertiesとidを持つGeoJSONのFeatureCollectionを返します。 - 共有境界のメッシュを作る. ポリゴンを含むオブジェクトでは、フィルター
a !== bを指定したtopojson.meshが、2つの異なるフィーチャに属するアークをすべて集めます。海岸線のように1つのフィーチャしか使わないアークは除かれます。 - ファイルを測る. オブジェクト、フィーチャ、アークの数を数え、量子化1ステップの大きさをメートルで求め、復号したGeoJSONがどれだけの大きさになるかを測ります。
- 描いて表示範囲を合わせる. 各オブジェクトはそれぞれの色のLeafletレイヤーになります。ポイントは円で描きます。地図は表示中のすべてのデータにズームします。
復号そのものは、形式の考案者が書いたリファレンスライブラリのtopojson-clientが行います。そのため、このビューアーはD3の地図とまったく同じようにファイルを読み込みます。
TopoJSONがファイルを小さくする仕組み
TopoJSONは、アークの共有、量子化、デルタ符号化という3つの方法で容量を節約します。上のサンプルのトポロジーを使って、それぞれの計算を説明します。
1. アークの共有
GeoJSONでは、2つのポリゴンの間の境界は、それぞれのポリゴンに1回ずつ、合計2回書かれます。TopoJSONは、3つ以上の図形が出会う点で各境界をアークに切り分け、各アークを1回だけ保存し、各ポリゴンには使うアークの番号を並べさせます。負のインデックスはアークを逆向きに使います。
インデックス i ≥ 0 → アーク i、最初の点から最後の点へ インデックス i < 0 → アーク ~i = −i − 1、最後の点から最初の点へ 畑Aのリング: [0, 1] = アーク0、続いてアーク1 畑Bのリング: [2, −1] = アーク2、続いて逆向きのアーク0
国の地図では、各国境の長さのほとんどがちょうど2か国で共有されています。そのため、このステップだけで国境の座標のほぼ半分が減ります。
2. 量子化
量子化は、各座標を規則正しいグリッドに合わせ、そのマス目を整数で書きます。量子化の値を q とすると、外接矩形は各軸で q − 1 ステップに分けられます。transformには、グリッドの大きさ(scale)とグリッドの角(translate)が保存されます。
scale_x = (x_max − x_min) / (q − 1) scale_y = (y_max − y_min) / (q − 1) 経度 = x_整数 · scale_x + translate_x 緯度 = y_整数 · scale_y + translate_y
サンプルファイルは、ヨーロッパとロシア西部、経度で約69°、緯度で約36°の範囲に q = 100 000 を使っています。1ステップは東西方向に約0.0007°で、北緯55°では約44 m、南北方向では約40 mです。元の1:50mのデータよりはるかに細かいので、目に見える詳細は失われません。File Infoパネルには、ご自分のファイルのこのステップが表示されます。
3. デルタ符号化
各アークの中で、完全な整数で書かれるのは最初の位置だけです。それ以降の位置は、1つ前の位置との差で書かれます。隣り合う点は近くにあるので、差は桁数の少ない小さな数になります。
保存されたアーク: [[4000, 7000], [0, 1000]] 点1: x = 4000 y = 7000 点2: x = 4000 + 0 = 4000 y = 7000 + 1000 = 8000 scale [0.001, 0.001] と translate [−10, 40] を使うと: 点1: (4000 · 0.001 − 10, 7000 · 0.001 + 40) = (−6, 47) 点2: (4000 · 0.001 − 10, 8000 · 0.001 + 40) = (−6, 48)
つまり例のアーク0は (−6, 47) から (−6, 48) への線で、畑Aと畑Bの境界です。3つのアークをすべて復号すると、A = (−7…−6, 47…48) と B = (−6…−5, 47…48) の2つの正方形になります。これはビューアー自身のテストが確認しているケースそのもので、共有境界のメッシュがこの1本の境界線だけを返すことも確認しています。
4. 結果として
このビューアーのサンプルでは、小数4桁の元のGeoJSONが約211 KB、TopoJSONが約114 KBで、ほぼ半分です。ビューアーがTopoJSONを完全な小数のGeoJSONに復号すると約500 KBになり、これがFile Infoパネルに表示される数値です。どのWebサーバーも使うgzip圧縮の後では差はふつう小さくなりますが、共有境界の多い地図でははっきり残ります。
TopoJSONビューアーが役立つ場面
私が手早くTopoJSONビューアーを使うのは、次のような場面です。
- D3の地図を作る前にファイルを確認する. ダウンロードしたTopoJSONファイルにどんなオブジェクトがあり、どんな名前で、どんな属性を持つかを確認できます。コードを書き始める前に、`topo.objects` に何を書けばよいかがわかります。
- 単純化した後の境界を確認する. mapshaperやtoposimplifyで地図を単純化した後、「Highlight shared borders」をオンにして、隣同士が隙間や細い破片のないきれいな境界を今も共有しているかを確認します。
- TopoJSONファイルからGeoJSONを取り出す. 多くのWeb地図やGISツールはGeoJSONしか受け付けません。何もインストールせずに、1つのオブジェクトまたはファイル全体をGeoJSONでダウンロードできます。
- 選挙や国勢調査の地図を確認する. 報道機関は選挙区や市区町村の境界をTopoJSONで公開することがよくあります。結果を結合する前に、ファイルを開いて名前、id、範囲を確認できます。
- 量子化レベルを比べる. 量子化の設定を変えて作った同じ地図を開き、メートル単位のステップとファイルサイズを比べて、見た目を保てる最小のファイルを選べます。
- トポロジーの仕組みを教える. オブジェクトの一覧、アークの数、共有境界の表示を使うと、トポロジーが普通のGeoJSONより小さい理由を学生に簡単に示せます。
- world-atlasとus-atlasのファイルを開く. これらの人気のnpmパッケージには、国、米国の州、郡のTopoJSONが入っています。ここで開くと中身が正確にわかります。
- ファイルが読み込めない理由を調べる. 地図ライブラリがファイルの読み込みに失敗したとき、本当にTopoJSONなのか、拡張子が違うだけのGeoJSONなのか、アークの参照が壊れたファイルなのかをビューアーが教えてくれます。
よくある質問
1. TopoJSONとは何ですか?
TopoJSONは、ジオメトリをトポロジーとして保存するGeoJSONの拡張です。共有する境界はアークとして1回だけ保存され、座標はふつう整数に量子化されます。Web用の地図ファイルを小さくするために、D3.jsの作者であるMike Bostockが考案しました。
2. TopoJSONファイルはどうやって開きますか?
このビューアーの地図にドロップするか、Uploadをクリックしてください。QGISでは、GDALがTopoJSONを読めるので、地図ウィンドウにドラッグすれば開けます。コードでは、topojson-clientの topojson.feature で各オブジェクトをGeoJSONに変換します。
3. TopoJSONとGeoJSONの違いは何ですか?
GeoJSONは各図形の完全な座標を書くので、共有する境界は2回現れます。TopoJSONは各境界をアークとして1回だけ書き、図形はそれを参照します。座標はふつう小さな整数で保存します。TopoJSONファイルは小さく、GeoJSONファイルは単純でほぼどこでも使えます。
4. TopoJSONをGeoJSONに変換するには?
ここでファイルを読み込み、Download All as GeoJSONをクリックするか、オブジェクトの横のGeoJSONリンクを使います。コマンドラインでは topo2geo や mapshaper -o format=geojson で同じことができます。
5. ファイルに複数のオブジェクトがあります。どうなりますか?
各オブジェクトが、それぞれの色とチェックボックスを持つ別々のレイヤーになります。オブジェクトごとに別のGeoJSONファイルとしてダウンロードすることも、まとめてダウンロードすることもできます。まとめたファイルでは、各フィーチャに属性 topojson_object が加わります。
6. 「Highlight shared borders」は何を表示しますか?
同じオブジェクト内の2つの異なるフィーチャが使うアーク、たとえば2つの国の国境を描きます。海岸線のように1つのフィーチャしか使わないアークは描きません。D3の topojson.mesh(topology, object, (a, b) => a !== b) と同じです。
7. File Infoパネルの「量子化」とはどういう意味ですか?
ファイルに transform があり、座標がグリッド上の整数になっているという意味です。パネルには、グリッド1ステップの地上での大きさが表示されます。数メートルのステップなら都市の地図に、数百メートルのステップなら世界地図に十分です。
8. 地図が違う場所に出たり、とても小さく表示されたりするのはなぜですか?
一部のTopoJSONファイル、特に米国のD3地図用に作られたものは、変換前に投影されているため、座標が経度・緯度ではなく画面のピクセルになっています。そのようなファイルは世界地図の上に置けません。投影されていない版のデータを使ってください。
9. ファイルがGeoJSONだというメッセージが出るのはなぜですか?
TopoJSONファイルの多くは.jsonの拡張子を使い、GeoJSONファイルも同じです。ビューアーは名前ではなく中身を確認します。ファイルが "type": "FeatureCollection" で始まっていればGeoJSONです。このサイトのGeoJSONビューアーで開いてください。
10. ファイルはアップロードされますか?
いいえ。ファイルはtopojson-clientを使ってブラウザ内で読み込まれ、復号されます。インターネットから読み込むのはベースマップのタイルだけです。
ライブラリとデータ
このビューアーはオープンソースソフトウェアとオープンデータの上に作られています。これらのプロジェクトに関わる皆さんに感謝します。
- topojson-client 3.1 · ISC · Mike Bostockトポロジーを復号します。アークを座標に戻し、各オブジェクトをGeoJSONとして組み立て直し、共有境界のメッシュを作ります。
- Leaflet 1.9 · BSD-2-Clause · Volodymyr Agafonkin and contributorsインタラクティブな地図、レイヤー、ポップアップを描きます。
- Natural Earth (1:50m Admin 0 countries) · パブリックドメイン · Natural Earth contributorsサンプルファイルで使っている国境データ。
- OpenStreetMap, Protomaps (hosted by KONAKTIVE), CARTO, Esri World Imagery · ODbLと提供元の利用規約 · OpenStreetMap contributors, Protomaps, KONAKTIVE, CARTO, Esriベースマップのタイルと画像。
関連するGISファイルビューアー
TopoJSONファイルはブラウザ内で読み込まれ、復号されます。ファイルがサーバーにアップロードされることはありません。サンプルはNatural Earthのデータ(パブリックドメイン)を使っています。 地図タイル © OpenStreetMap の貢献者、Protomapsで描画(ホスティング:KONAKTIVE)、予備としてCARTO。 衛星画像:Esri。
