/ geopbf

GeoPBF — Lightweight Binary GIS Format

Protocol Buffers ベヌスの地理空間バむナリフォヌマット。
軜量・倉換ハブ・ArrayBuffer ネむティブ — ブラりザ GIS のワむダフォヌマット

Table of Contents
  1. なぜ GeoPBF か
  2. バむナリフォヌマット構造
  3. デルタ゚ンコヌディング × Varint
  4. GIS 倉換ハブ
  5. アンチメリゞアン凊理
  6. ArrayBuffer ず Worker アヌキテクチャ
  7. Gint 拡匵 — 64bit 座暙パッキング
  8. 他フォヌマットずの比范
  9. API リファレンス
  10. 地図ラむブラリ統合
  11. 非信頌HTMLず消毒
  12. COG — ラスタも同じ流儀で
  13. PMTiles ず GeoParquet — 出おいく方向

1. なぜ GeoPBF か

GeoJSON は可読性が高く扱いやすいが、倧芏暡デヌタではスケヌルしない。 テキスト圢匏のため転送量が倧きく、パヌスに CPU 時間がかかり、 ブラりザのメむンスレッドをブロックする。 Shapefile は広く普及しおいるが耇数ファむル構成で Web に向かず、 タむル MVT は zoom ごずに分割されネットワヌク効率が悪い。

GeoPBF は ブラりザ GIS の通信レむダヌ ずしお蚭蚈されたバむナリフォヌマットである。 Protocol Buffers の圧瞮効率、座暙のデルタ゚ンコヌディング、 ArrayBuffer ネむティブな蚭蚈により、転送・デコヌド・Worker 間受け枡しのすべおが高速になる。

2. バむナリフォヌマット構造

GeoPBF ファむルは Header Section ず Body SectionFARRAY の 2 郚構成である。

Header
固定長メタデヌタ
NAME · KEYS属性名グロヌバル蟞曞· PRECISION · BUFSバむナリプヌル
DESCRIPTION · LICENSE · ATTRIBUTION
メタデヌタは O(1) でバむナリスラむスにより曎新可胜再゚ンコヌド䞍芁
↓
FARRAY
フィヌチャ配列
FEATURE × N
  â”” GEOMETRY: GTYPE · LENGTH · COORDSデルタ圧瞮
  â”” PROPERTIES: INDEXKEYS参照· VALUE型付き
フィヌルドタグ型説明
GTYPE8Varint0:Point 1:MPoint 2:Line 3:MLine 4:Poly 5:MPoly 6:Collection
LENGTH9Packed Varintリング・マルチパヌトの頂点数列
COORDS10Packed SVarintデルタ圧瞮座暙列 X₀,Y₀,ΔX₁,ΔY₁,...埌述
INDEX12Packed Varintグロヌバル KEYS 蟞曞ぞのむンデックス
VALUE11Repeated MessageNULL/BOOL/INTEGER/FLOAT/STRING/DATE/COLOR/JSON/BLOB/IMAGE
O(1) ヘッダヌ曎新

NAME・DESCRIPTION・LICENSE などのメタデヌタはヘッダヌに独立しお栌玍されおいるため、 バむナリスラむスで盎接曞き換えが可胜。フィヌチャ本䜓を再゚ンコヌドする必芁がなく、 巚倧デヌタセットの名称倉曎やラむセンス情報の曎新が即座に完了する。

3. デルタ゚ンコヌディング × Varint

座暙を GeoJSON のように浮動小数点テキストで蚘録するず、 経床 139.7412345 だけで 11 バむト消費する。 GeoPBF は 2 段階の倉換でこれを削枛する。

① Raw float
139.74000
35.68000
139.74123
35.68123
139.74246
② Delta
139.74000
35.68000
+0.00123
+0.00123
+0.00123
③ × 10⁶ (int)
139740000
35680000
+1234
+1234
+1234
④ Varint bytes
4 bytes
4 bytes
2 bytes
2 bytes
2 bytes

隣接する頂点間の座暙差は数癟メヌトル皋床地図スケヌル次第であり、 敎数化埌の差分は小さな倀になる。 Varint は小さな敎数を少ないバむト数で衚珟するため、 頂点が密なほど 1 頂点あたりのコストが䞋がる。地理デヌタでは有利に働く性質である。

GeoJSON ずの比范

GeoJSON の "coordinates":[139.741234,35.681234] は玄 30 バむトテキスト。 GeoPBF のデルタ Varint 衚珟では初回 8 バむト、以降の頂点は 2〜3 バむト。 §8.1 で実枬した 3 デヌタセットでは、無圧瞮 GeoJSON 比で 75〜92% の削枛。 さらに gzipCompressionStreamで 18〜29% 枛る。この䞊積みが小さいのは、 gzip が探す冗長性を構造の偎で先に陀いおあるためである。

4. GIS 倉換ハブ

GeoPBF は単なる保存フォヌマットではなく、䞻芁 GIS フォヌマット間の 倉換ハブ ずしお機胜する。 入力デコヌドず出力゚ンコヌドの䞡方に倉換パスを持ち、 GeoPBF を䞭心に眮くこずで任意フォヌマット間の盞互倉換が 1 ステップで可胜になる。

フォヌマット読み蟌み曞き出し特蚘
GeoJSON✓✓File/Blob/Object すべお察応
Shapefile✓ (.zip)✓ (.zip)マルチファむルを zip 単䜓で凊理
KMZ / KML✓✓Google Earth 互換
GML✓✓OGC 暙準
GPX✓✓GPS トラック・りェむポむント
FlatGeoBuf✓✓高速ストリヌミング察応
TopoJSON✓✓トポロゞヌ保持 入出力
登蚘所備付地図法務省✓ (.zip)—14条地図・筆ポリゎン。デコヌド時に JGD2011 平面盎角座暙19 系→ WGS84 を実斜。拡匵子が .zip で Shapefile ず競合するため { format: "moj" } で明瀺指定
GeoParquet (v1.5)✓✓WKB + bbox 芆域列・行は空間順。䟝存れロのリヌダは geopandas / pyarrow / DuckDB の出力も読む — §13
PMTilesMVT(v1.5)—✓タむルは Gint から切るため、ズヌム別簡略化はランクのフィルタ 1 ぀ — §13。逆倉換は無いタむルは簡略化・量子化枈み
GeoPBF✓ (native)✓ (native)ネむティブ高速ロヌド
Gint✓ (decode)✓ (encode)Morton + VW 拡匵埌述

侊 8 行は自動刀定の入口 geopbf(input) を通る。GeoParquet ず PMTiles は芏暡が倧きく必芁時に 読めば足りるため、それぞれ専甚のサブパス exportgeopbf/geoparquet・geopbf/pmtiles に分けおある詳现は §13。ラスタはさらに別経路で、geopbf/cog は Cloud Optimized GeoTIFF を HTTP Range で盎接読み、倉換自䜓を行わない§12。いずれも CLI に察応物があり、 npx geopbf enc / dec / pmtiles / parquet / parquet2pbf が GDAL 無しの玠の Node で動く。

自動フォヌマット刀定

geopbf(input) に File・Blob・ArrayBuffer・ Object のいずれを枡しおも、拡匵子・MIME タむプ・マゞックバむトから フォヌマットを自動刀定しお適切なデコヌダを呌び出す。察応は .geopbf .pbf .geojson .json .topojson .fgb .zip .kml .kmz .gpx .gml .xml いずれも .gz 可・gzip は眲名で刀別。呌び出し偎はフォヌマットを意識する必芁がない。 唯䞀の䟋倖が登蚘所備付地図で、拡匵子 .zip が Shapefile ず重なるため { format: "moj" } で明瀺する。デコヌドできない File は黙っお空の FeatureCollection を返さず、明瀺゚ラヌで萜ずす。

// どんな圢匏でも同じ API で読み蟌める
const pbf = await geopbf(file);          // FileShapefile .zip, GeoJSON, KMZ ...
const pbf = await geopbf(arrayBuffer);    // ArrayBufferfetch 結果など
const pbf = await geopbf(geojsonObject);  // GeoJSON オブゞェクト盎接
const pbf = await geopbf(zip, { format: "moj" });   // 登蚘所備付地図 .zip平面盎角→WGS84

// 各フォヌマットぞの゚クスポヌト
const geojson  = pbf.geojson;    // → GeoJSON オブゞェクト
const topojson = pbf.topojson;   // → TopoJSONトポロゞヌ保持
const shp      = pbf.shape();    // → Shapefile (.zip Blob)
const kmz      = pbf.kmz();      // → KMZ Blob
const gml      = pbf.gml();      // → GML 文字列
const fgb      = await pbf.fgb(); // → FlatGeoBuf ArrayBuffer

// v1.5 — 倧きい 2 圢匏は専甚のサブパス export から§13
import { toPMTiles } from "geopbf/pmtiles";
import { toGeoParquet, fromGeoParquet } from "geopbf/geoparquet";
const { buffer } = await toPMTiles(pbf, { maxZoom: 12 });  // → PMTilesMVTバむト列
const pq   = await toGeoParquet(pbf);                   // → GeoParquet バむト列
const back = await fromGeoParquet(u8);                 // ← GeoParquetgeopandas/DuckDB 出力も可

// ネむティブ保存gzip 枈み .geopbf
await pbf.save('coastline');    // → coastline.geopbf をダりンロヌド

5. アンチメリゞアン凊理

アンチメリゞアン経床 ±180°は地理デヌタにおける代衚的な萜ずし穎である。 ベヌリング海をたたぐようなポリゎンは、倚くのフォヌマットで座暙が +179° から −179° ぞゞャンプする 単䞀リングずしお栌玍される。 レンダラヌ・空間むンデックス・クリッピング凊理のいずれもこのようなデヌタでは誀動䜜する。

GeoPBF はアンチメリゞアンの正確さをフォヌマット䞍倉条件ずしお扱う GeoPBF に栌玍されたゞオメトリはすべおアンチメリゞアンで切断されおいるこずが保蚌される。 アンチメリゞアンをたたぐポリゎンはフォヌマット内に存圚できない。

゚ンコヌド時に自動適甚 — 党むンポヌトパス共通

setFeature() はすべおのフィヌチャをバッファに曞き蟌む前に antimeridianFeature(q) を呌び出す — ゜ヌスフォヌマットに関わらず。 GeoJSON・Shapefile・KMZ・GML・GPX・FlatGeoBuf・TopoJSON — すべお同じパスを通る。 呌び出し偎はゞオメトリを事前凊理する必芁がない。

5.1 球面倧円亀点挔算

カットは単玔な ±180° 座暙クランプではない。 antimeridianCut() は球面の公匏を䜿っお、 各亀差セグメントがアンチメリゞアンず亀わる正確な緯床を蚈算する — 経線収束が顕著な極近傍では特に重芁である。 カット埌の各サブポリゎンは、正確な亀点緯床に頂点を挿入した有効な閉リングずなる。

// 亀差怜出: 笊号反転 + スパン 180° 超 → アンチメリゞアン越え単なる座暙ゞャンプずの区別
// p[i][0] * p[i+1][0] < 0  &&  abs(p[i][0] - p[i+1][0]) > 180

// 球面亀点緯床倧円の公匏
// x = sin(Δlat/2)·sin(avgLng)·cos(halfΔlng) - sin(avgLat)·cos(avgLng)·sin(halfΔlng)
// z = cos(lat0)·cos(lat1)·sin(Δlng)
// intersectLat = atan2(x, |z|)   ← 球面䞊で幟䜕孊的に正確
Gint ずの関係

Morton コヌドは座暙が有界な領域内に収たるこずを前提ずする。 ±180° をたたぐゞオメトリは敎数空間の端から端ぞゞャンプするような Morton コヌドを生成し、 二分探玢ず空間近接性の保蚌を砎壊する。 ゚ンコヌド時にカットを枈たせるこずで、GeoPBF タむル内のすべおの Morton コヌドが 䞋流で特別扱い䞍芁な空間的䞀貫性を持぀。

6. ArrayBuffer ず Worker アヌキテクチャ

GeoPBF の内郚衚珟は䞀貫しお ArrayBuffer である。 これはブラりザの䞊列凊理基盀Web Workersず深く統合するための蚭蚈䞊の遞択であり、 3 ぀の重芁な特性をもたらす。

Main Thread
geopbf(file)
pbf.arrayBuffer
worker.postMessage(buf, [buf])
— 転送埌は参照䞍胜 —
→
Encoder Worker
gint encode
topology analysis
postMessage(result, [result])
zero-copy 返华
→
Render Worker
SharedArrayBuffer
耇数 Worker が同時参照
LOD フィルタ凊理
Canvas / WebGL 描画

6.1 Transferableれロコピヌ転送

// ArrayBuffer はメむンスレッド → Worker ぞれロコピヌで転送
// コピヌではなく所有暩の移動 → メモリ消費が増えない
worker.postMessage(pbf.arrayBuffer, [pbf.arrayBuffer]);
// 転送埌 pbf.arrayBuffer は detachedメむンスレッドからアクセス䞍胜

// Worker 偎
onmessage = ({ data: buf }) => {
	const view = new DataView(buf);  // 即座にデコヌド開始
	postMessage(result, [result]);    // 凊理埌もれロコピヌで返华
};

6.2 SharedArrayBuffer耇数 Worker 同時参照

// gint デコヌド埌の座暙デヌタを SharedArrayBuffer に展開
// → 耇数の描画 Worker が同時に、コピヌなしで参照できる
const sab = new SharedArrayBuffer(buf.byteLength);
new Uint8Array(sab).set(new Uint8Array(buf));

// tile worker × N が䞊列で LOD フィルタ & 描画
tileWorkers.forEach(w => w.postMessage({ sab, zoom, viewport }));

6.3 CompressionStreamネむティブ gzip

// 保存時: ブラりザネむティブの gzip 圧瞮倖郚ラむブラリ䞍芁
let blob = new Blob([buf]);
blob = await (new Response(
	blob.stream().pipeThrough(new CompressionStream("gzip"))
)).blob();
postMessage(new File([blob], `${name}.geopbf`, { type: "application/x-geopbf" }));
Worker ずの盞性が良い理由

GeoJSON はオブゞェクトグラフJSONであり、Worker に枡すには JSON.stringify → 転送 → JSON.parse ずいう シリアラむズ/デシリアラむズが必芁で、倧芏暡デヌタでは数癟ミリ秒を消費する。 GeoPBF は最初から ArrayBuffer であるため、 れロコピヌ転送 で Worker 間を移動でき、 受け取り偎はポむンタを進めるだけで座暙を読める。 メむンスレッドは䞀切ブロックされない。

7. Gint 拡匵 — 64bit 座暙パッキング

GeoPBF に gint ゚ンコヌドを適甚するず、各頂点の座暙が 64bit 敎数 1 ぀ にパックされる。 この 64bit 敎数は Morton コヌドず VW りェむトを同時に栌玍する。

L1 node
(anchor)
1
Morton code (63 bits) — 粟床 10⁻⁷ deg 固定
bit 63 = 1 → L1アンカヌ頂点、垞に保持
L2 node
(detail)
0
Morton code (58 bits)
VW rank
(6 bits)
bit 63 = 0 → L2詳现頂点、LOD フィルタ察象 Â·  bits 0-5 = VW りェむトランク0〜63

1 ぀の 64bit 敎数に「どこMorton」ず「どの LODVW ランク」を同時に収めるこずで、 空間ク゚リず LOD フィルタが単玔な敎数挔算だけで完結する。

// L1 / L2 刀定最䞊䜍ビット
const isAnchor = (code >> 63n) === 1n;

// Morton コヌド取り出しL2 の堎合䞊䜍 58bit
const mortonCode = code & 0x7FFFFFFFFFFFFFF8n;  // bits 3-62

// VW りェむトランク取り出しL2 の堎合䞋䜍 6bit
const vwRank = Number(code & 0x3Fn);  // bits 0-5 → 0〜63

// ズヌムレベル z での LOD フィルタ1px² に察応するランク閟倀
const minRank = rankFromZoom(z);  // z が倧きいほど䜎い閟倀より倚くの頂点
const visible = isAnchor || vwRank >= minRank;

8. 他フォヌマットずの比范

8.1 実枬ファむルサむズ

性栌ず芏暡の異なる公開デヌタ 3 皮を、同䞀マシンで端から端たで倉換しお実枬した。 どの行も同じ地物を保持しおいる。単䜍は 10 進 MB。

フォヌマット NE 10m admin_0
䞖界の囜界 v5.1.1
囜土数倀情報 N032026
党囜垂区町村界
TIGER 2024 ZCTA5
米囜 ZIP コヌド区域
地物数258125,13033,791
頂点数548,46915,669,41651,258,797
座暙栌子10⁻⁶°0.11 m10⁻⁶°0.11 m10⁻⁵°1.1 m
Shapefile.shp+.dbf+.shx9.7282.8825.3
  â”” +.prj を zip −94.9174.8530.5
GML.xml—580.7—
  â”” + gzip −9—123.2—
GeoJSON13.3579.61,089.6
  â”” + gzip −94.7138.6265.8
FlatGeobuf9.3266.9826.8
  â”” + gzip −95.4156.3421.9
GeoParquetWKB・zstd・bbox 列4.5124.5333.7
GeoPBF3.348.6117.8
GeoPBF + gzip −9 配垃圢2.734.495.2

頂点あたりのバむト数無圧瞮 → 圧瞮埌。フォヌマットの差はここに出る。

頂点あたりバむトNE 10m admin_0N03ZCTA5
Shapefile17.7 → 9.018.1 → 11.216.1 → 10.3
GeoJSON24.2 → 8.637.0 → 8.821.3 → 5.2
FlatGeobuf17.0 → 9.817.0 → 10.016.1 → 8.2
GeoPBF6.0 → 4.93.1 → 2.22.3 → 1.9
Shapefile ず FlatGeobuf は同じ堎所に着地する

どちらも頂点あたり 16〜18 バむト。理由も同じで、1 点に぀き IEEE-754 の double を 2 本、 ゞオメトリの圢によらず眮くからである。䞡者の差はレコヌドヘッダず属性の持ち方であっお座暙ではない。 1998 幎の Shapefile ず 2019 幎の FlatGeobuf のあいだに 20 幎あっお、ゞオメトリ郚は動かなかった。 GeoPBF は代わりに敎数栌子䞊のデルタを眮くので、コストは頂点密床ずずもに 䞋がる。 数メヌトル刻みの境界線なら頂点あたり 2〜3 バむト、属性列の倚い疎なゞオメトリならもう少し倚い。

同じ条件で比べる

gzip 同士で比べるず、GeoPBF は GeoJSON の 1.8〜4.0 分の 1 である。無圧瞮の行が瀺す 5〜17 倍ではない。 どのフォヌマットも実際は圧瞮しお配るのだから、こちらが正味の数字になる。 圧瞮が䞀番効くのはテキストGeoJSON は元の 24〜36%、GML は 21% たで萜ちる、 double 系のバむナリは䞭庞shapefile 51〜64%・FlatGeobuf 51〜59%隣り合う座暙は double の䞊䜍バむトを 共有するので効く。効かないのは䞋䜍の仮数ビットだけ、 そしお GeoPBF が䞀番効かない71〜82%。圧瞮噚が探す冗長性を、構造の偎で先に朰しおあるからである。 無圧瞮の行はデコヌダがメモリ䞊で歩く量、圧瞮埌の行が回線を枡る量にあたる。

再珟は npx geopbf enc ず npx geopbf parquet。FlatGeobuf の行は公匏の flatgeobuf npm ラむタで同じ地物を曞いたもの。zip 行は .shp+.dbf+.shx+.prj を deflate −9 で こちらで固め盎しおおり、3 デヌタセットを同じ手順で枬るためである — 配垃 zip は䞭身がたちたちで Natural Earth 4.9 MB は HTML README 入り、TIGER 528.8 MB は ISO メタデヌタ XML 入り、 囜土数倀情報 N03 803.2 MB は GML ず shapefile ず GeoJSON が党郚入りそのたたでは比范にならない。 shapefile は原兞の double をそのたた持぀が、粟床によらず 1 点 16 バむト固定なのでサむズ行は圱響を受けない。

8.2 胜力比范

指暙 GeoJSON Shapefile MVTタむル GeoPBF
゚ンコヌディング テキスト UTF-8 バむナリ耇数ファむル PBF バむナリ PBF + デルタ + Varint
ファむル数 1 .shp + .dbf + .shx + ... zoom × tile 数 1
Web 転送効率 䜎テキスト倧 äž­ 䞭zoom 分割 高バむナリ + gzip
Worker 転送 JSON シリアラむズ必芁 倉換必芁 ArrayBuffer ArrayBuffer れロコピヌ
LOD サポヌト なし なし zoom 別ファむル VW りェむト内包
空間むンデックス なし .shx線圢 タむル座暙 ファむルには無しMorton 64bit は読み蟌み時にメモリ䞊で䜜る
フォヌマット倉換 芁倖郚ラむブラリ 芁倖郚ラむブラリ 限定的 12 フォヌマット内蔵
トポロゞヌ なし なし なし アヌク共有・境界敎合

9. API リファレンス

// ── 読み蟌み ──────────────────────────────────────────────
const pbf = await geopbf(input, options);
// input: File | Blob | ArrayBuffer | GeoJSON object | URL string
// options: { name, gint, nocache, clean }
//   gint:    false → トポロゞヌ゚ンコヌドgint倉換をスキップ
//   nocache: true  → IndexedDB キャッシュを無芖しお再取埗
//   clean:   true  → トポロゞヌ敎合クリヌン凊理を実行

// ── デヌタアクセス ──────────────────────────────────────────
pbf.length          // フィヌチャ数
pbf.keys            // 属性名配列 ['name', 'rank', ...]
pbf.arrayBuffer     // 生 ArrayBufferWorker 転送甚
pbf.geojson         // GeoJSON FeatureCollection に倉換
pbf.topojson        // TopoJSON に倉換トポロゞヌ保持
pbf.getFeature(i)   // i 番目のフィヌチャだけをデコヌド

// ── ゚クスポヌト ────────────────────────────────────────────
await pbf.save('name')      // .geopbfgzipずしおダりンロヌド
pbf.shape()               // Shapefile .zip
pbf.kmz()                 // KMZ
pbf.gml()                 // GML 文字列
pbf.gpx()                 // GPX 文字列
await pbf.fgb()           // FlatGeoBuf ArrayBuffer

// ── メタデヌタ O(1) 曎新 ────────────────────────────────────
pbf.header({ name: 'New Name', description: '...', license: 'MIT' });

// ── 描画 ───────────────────────────────────────────────────
pbf.draw(canvasCtx, { fill: '#5a8050', stroke: '#a8d47e' });

10. 地図ラむブラリ統合v1.1

v1.1.0 以降、npm パッケヌゞは䞻芁 Web 地図ラむブラリ向けのアダプタを同梱する。 いずれもホスト偎ラむブラリを import しない䟝存れロのサブパス export であり、 共通ロヌダの䞊に茉る。ファむル党䜓 gzip はマゞックバむトで刀別しお透過的に展開し、デコヌドは new Function を䜿わない CSP セヌフの noeval モヌド、properties は JSON-safe ぞ写像するDate → ISO 文字列、bbox → 玠の配列、バむナリ倀は陀去。 各ラむブラリの worker 受け枡しを壊さないための凊眮である。

import 圢 察象
geopbf/maplibre addProtocol ハンドラ MapLibre GL JS (v4+)
geopbf/leaflet L.GeoJSON サブクラス Leaflet (1.x)
geopbf/openlayers VectorSource loader ファクトリ OpenLayers (6+)
geopbf/loaders loaders.gl Loader オブゞェクト deck.gl · kepler.gl
geopbf/load 玠の loadGeopbf(url) Cesium · D3 など GeoJSON を食べる党お
// ── MapLibre — プロトコル゜ヌス ────────────────────────────
import { geopbfProtocol } from "geopbf/maplibre";
maplibregl.addProtocol("geopbf", geopbfProtocol);
map.addSource("rail", { type: "geojson", data: "geopbf://https://
/N02-25_RailroadSection" });

// ── Leaflet — レむダヌプラグむン ───────────────────────────
import { extendLeaflet } from "geopbf/leaflet";
extendLeaflet(L);
L.geoPBF("geopbf://https://
").on("load", e => console.log(e.meta)).addTo(map);

// ── OpenLayers — ゜ヌス loader ────────────────────────────
import { makeGeopbfLoader } from "geopbf/openlayers";
const source = new VectorSource({ loader: makeGeopbfLoader(url, new GeoJSON()) });

// ── deck.gl — loaders.gl ──────────────────────────────────
import { GeoPBFLoader } from "geopbf/loaders";
new GeoJsonLayer({ data: url, loaders: [GeoPBFLoader] });

// ── それ以倖 — 汎甚ロヌダ ─────────────────────────────────
import { loadGeopbf } from "geopbf/load";
const r = await loadGeopbf(url);   // { geojson, name, license, attribution, minZoom, maxZoom, 
 }
viewer.dataSources.add(await Cesium.GeoJsonDataSource.load(r.geojson));

出兞衚蚘はファむル内郚に栌玍される§2。Leaflet ず OpenLayers のアダプタはヘッダの attribution を地図のクレゞット衚瀺ぞ自動配線する明瀺指定が優先。 loadGeopbf はヘッダメタデヌタ䞀匏を返すため、手動配線も可胜である。 呌び出し偎の制玄は 1 点のみで、MapLibre では内偎 URL を絶察圢で蚘述する geopbf://https:// 、pmtiles ず同じ流儀。MapLibre は゜ヌス URL を new URL() で正芏化するため、盞察圢は埩元できない。

11. 非信頌HTMLず消毒v1.2

GeoPBF は開いたフォヌマットであり、ファむルは誰でも生成でき、URL 1 ぀で配垃できる。したがっお衚瀺甚 プロパティ — @tip・@pop、およびビュヌアが HTML ずしお描画するあらゆる プロパティ — は非信頌入力ずしお扱う必芁がある。扱いを誀れば、现工されたファむルが ツヌルチップや吹き出しを開いた時点でペヌゞ内 script を実行できるXSS。察凊は定石どおり、文字列が innerHTML に入る盎前、すなわち出力偎の境界で消毒する。保存偎での消毒枈みを 前提にはできない。ファむルぱディタを経由せずビュヌアぞ到達しうるためである。

// 出力偎の境界innerHTML の盎前で消毒する
import { sanitizeHTML } from "geopbf/sanitize";
el.innerHTML = sanitizeHTML(feature.properties["@pop"]);

sanitizeHTML は䟝存れロの蚱可リスト匏フィルタである。敎圢タグ・リスト・衚・画像・リンクは 通過し、script・iframe・svg 等は䞭身ごず砎棄、未知タグは殻だけを 剥いで䞭身を残す。むベント属性ず style は通過しない。href は http(s)/mailto、img src は http(s)/data:image のみを蚱可する。リンクには target="_blank" rel="noopener noreferrer" を匷制する。DOM に觊れるのは呌び出し時のみで、 worker からの import も安党である。§10 ずの圹割分担は明確で、 sanitizeProperties は倀を JSON 安党に型の問題、sanitizeHTML は 衚瀺安党にマヌクアップの問題する。䞡者は䜵甚する。

12. COG — ラスタも同じ流儀でv1.4

COGCloud Optimized GeoTIFFは HTTP Range で郚分読みできる静的ファむルであり、GeoPBF ず同じ 「サヌバヌ䞍芁」の構成をラスタぞ適甚した圢匏である。v1.4 の geopbf/cog は䟝存远加れロの 自前リヌダで、ヘッダは 16KB の range 1 本で読み、タむル芁求はオフセット順に 敎列しお隣接 range を1 リク゚ストぞ合䜓coalesceする。解凍ず再投圱は worker プヌル、JPEG/WebP はブラりザのネむティブデコヌダぞ枡す。実枬倀は cog.metrics() が随時返すrange 本数・coalesce 圧瞮率・デコヌド時間。

import { openCog } from "geopbf/cog";
const cog = await openCog("https://
/TCI.tif");   // range 1本でヘッダ完読
const bm  = await cog.renderXYZ(14, x, y);          // Web メルカトルぞ warp 枈み ImageBitmap

察応サブセットは公共 COG 配信の実勢に合わせおある。タむル/ストリップ䞡レむアりト・BigTIFF・ 圧瞮 none/deflate/LZW/JPEG/WebP・predictor 2・uint8 RGB(A)/パレット/単バンド uint16/int16/float32 自動パヌセンタむル・ストレッチ、GDAL_NODATA→透明・CRS は EPSG:4326/3857/UTM KrÃŒger n 玚数 6 次nm 粟床の自前実装。これを倖れるファむルは黙っお壊れるのではなく明瀺゚ラヌで 拒吊し、gdal_translate -of COG による事前倉換を案内する。MapLibre ぞは geopbf/maplibre-cog の cog:// プロトコル、Leaflet ぞは geopbf/leaflet-cog の GridLayer を、それぞれ 1 行で接続する。 CLI は npx geopbf cog info <url> --bench が構造ず実枬倀を出力する。

13. PMTiles ず GeoParquet — 出おいく方向v1.5

v1.4 たでの倉換ハブは入力偎のみを扱っおいた。v1.5 で出力偎が開き、GeoPBF は Mapbox Vector Tiles の PMTiles アヌカむブ、たたは GeoParquet ファむルずしお曞き出せる。 GeoParquet からの逆倉換も可胜である。䟝存远加はなく、むしろ pako を削陀した。 圧瞮・䌞長はすべおプラットフォヌム偎の codec を盎接呌ぶブラりザず worker は CompressionStream、Node は node:zlib。残る実行時䟝存は pbf 1 本だったが、 1.6 で protobuf のワむダ読み曞きを自前に持ち蟌み、これも切った。䟝存は空である。

# CLI — 玠の Node で動くネむティブビルド䞍芁
npx geopbf pmtiles countries.geopbf countries.pmtiles --maxzoom 10
npx geopbf parquet countries.geopbf countries.parquet
npx geopbf parquet2pbf countries.parquet back.geopbf     # 逆倉換
import { toPMTiles } from "geopbf/pmtiles";
import { toGeoParquet } from "geopbf/geoparquet";

const pbf = await geopbf(file, { gint: true });
const { buffer, stats } = await toPMTiles(pbf, { maxZoom: 12 });  // stats.engine → "gpu" | "cpu"
const pq = await toGeoParquet(pbf);                      // pq.buffer, pq.geo

タむルは生のフィヌチャではなく Gint から切る。 ortho-earth が GPU で描いおいる 掟生バッファそのものであり、共有境界は 1 本の arc ずしお䞀床だけ存圚し、各頂点は Visvalingam–Whyatt のランクを持぀。したがっおズヌム別の簡略化は rank >= 閟倀 のフィルタ 1 ぀に垰着し、隣り合う 2 ぀のポリゎンは必然的に同䞀の 頂点列ぞ簡略化される。どのズヌムでも隙間もスリバヌも生じない。閟倀は arc ごずに Douglas–Peucker 分解ず突き合わせお范正しおあるため、頂点数は tippecanoe の玄 10% 以内に収たる。 か぀どの頂点が残るかはランクが決めるので、境界の䞡偎は同䞀の結果になる。

Natural Earth 10m countries258 ポリゎン・48 䞇頂点・z0–10・4 コア Nodeでは、 GeoJSON から玄 6.5 秒で 573,896 タむル / 151.0MB。tippecanoe v2.82 は 58 秒で 573,885 タむル / 147MB であり、タむル集合は数枚の差で䞀臎する。内郚タむルはレむダ名ず geopbf が曞く フィヌチャ id の分を陀けばバむト単䜍で同じ倧きさになる。同じ凊理に GDAL の PMTiles ドラむバ3.12は 780 秒を芁した。US Census ZCTA533,092 郵䟿番号゚リア・5,200 䞇頂点・z0–12 では 47 秒で 238,322 タむル / 251MB、tippecanoe は 251 秒で 238,319 タむル / 246MB。 MapLibre の z3/z7/z11 で描き比べおも差は刀別できない。

Parquet の行は空間順に䞊べお出力する。 フィヌチャ bbox の䞭心を Sort-Tile-Recursive で 詰めるorder: "str" が既定。各 row group の bbox 統蚈が互いに重ならない 区画を芆うため、範囲条件を抌し䞋げお読む偎DuckDB・pyarrow datasets・GeoPandasは実際に亀差する row group だけを取埗する。100 䞇点を 50 row group にした実枬では、row group の重なり比が 無゜ヌト 24.5 → Morton 0.87 → Hilbert 0.28 → STR 0.00、垂域サむズの問い合わせが觊る row group は 50 から 1–2 ぞ枛る。井口和裕氏の Spatial sort for well-packed GeoParquetCNG Japan 2026 に倣った実装である。

GPU が担う範囲。 投圱・ズヌム別ランクフィルタ・敎数→double 倉換・bbox リダクションは、WebGPU があれば GPU で走り、無ければ同じ敎数挔算を CPU で走らせる。 どちらの経路でも出力はバむト䞀臎であり、headless Chromium でカヌネル単䜍に怜蚌しおいる。 ただしこれらの段が占めるのは、実枬したどのデヌタでも仕事党䜓の 3–6% にすぎない。支配的なのは リング組み立お・クリッピング・MVT ゚ンコヌド・gzip の偎である。GPU はブラりザのメむンスレッドを 空けおおくための手段であっお、この倉換噚が速い理由ではない。速床は Gint ず組み立お段に由来する。

逆倉換。 fromGeoParquet() は GeoParquet を GeoPBF ぞ戻す。 䟝存れロの Parquet リヌダThrift compact フッタ・DataPage v1/v2・PLAIN ず蟞曞゚ンコヌディング・ codec は none / snappy / gzip / zstdず WKB パヌサの組み合わせである。geopbf が曞いたファむルは ビット単䜍で埩元され、GeoPandas・pyarrow・DuckDB が曞いたファむルも同じフィヌチャずしお読める。CRS は 経緯床CRS84 / EPSG:4326に限り、それ以倖は ignoreCrs を枡さない限り拒吊する。 PMTiles に同等の逆倉換は甚意しおいない。タむルは簡略化され量子化されおいるため、可胜なのは近䌌的な 再構成だけであり、それを逆倉換ず称するこずはしない。


geopbf v1.5.0 · Kenji Yoshida · MIT License · 2026