Skip to content

Instantly share code, notes, and snippets.

@naogify
Created August 28, 2025 21:32
Show Gist options
  • Select an option

  • Save naogify/7812781d4452a9aa35696ffc50361bd7 to your computer and use it in GitHub Desktop.

Select an option

Save naogify/7812781d4452a9aa35696ffc50361bd7 to your computer and use it in GitHub Desktop.
PBFからGeoJSONに変換するスクリプト
#!/usr/bin/env node
/**
* PBF(MVT) -> GeoJSON
* Usage: node pbf2geojson.js /path/to/{z}/{x}/{y}.pbf > out.geojson
*/
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
const { VectorTile } = require('@mapbox/vector-tile');
const Pbf = require('pbf');
if (process.argv.length < 3) {
console.error('Usage: node pbf2geojson.js /path/to/{z}/{x}/{y}.pbf');
process.exit(1);
}
const filePath = process.argv[2];
// z/x/y をパスから推定
const m = filePath.replace(/\\/g, '/').match(/\/(\d+)\/(\d+)\/(\d+)\.pbf$/);
if (!m) {
console.error('Error: path must end with /{z}/{x}/{y}.pbf');
process.exit(1);
}
const z = Number(m[1]);
const x = Number(m[2]);
const y = Number(m[3]);
// buffer を読み込み & gzip 判定
let buf = fs.readFileSync(filePath);
const isGzip = buf[0] === 0x1f && buf[1] === 0x8b;
if (isGzip) buf = zlib.gunzipSync(buf);
// VectorTile をパース
const vt = new VectorTile(new Pbf(buf));
// 全レイヤーを GeoJSON に
const features = [];
for (const layerName of Object.keys(vt.layers)) {
const layer = vt.layers[layerName];
for (let i = 0; i < layer.length; i++) {
const f = layer.feature(i).toGeoJSON(x, y, z);
// layer 名を properties に付与(後でフィルタしやすい)
f.properties = { _layer: layerName, ...f.properties };
features.push(f);
}
}
const fc = { type: 'FeatureCollection', features };
process.stdout.write(JSON.stringify(fc));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment