gc-wing/scripts/prepare-zones.mjs
2026-02-15 11:22:38 +09:00

97 lines
2.7 KiB
JavaScript
Raw Blame 히스토리

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import fs from "node:fs/promises";
import path from "node:path";
const ROOT = process.cwd();
const ZONES = [
{ zoneId: "1", file: "특정어업수역Ⅰ.json", label: "", name: "수역I(동해)" },
{ zoneId: "2", file: "특정어업수역Ⅱ.json", label: "Ⅱ", name: "수역II(제주남방)" },
{ zoneId: "3", file: "특정어업수역Ⅲ.json", label: "Ⅲ", name: "수역III(서해남부)" },
{ zoneId: "4", file: "특정어업수역Ⅳ.json", label: "Ⅳ", name: "수역IV(서해중간)" },
];
// Inverse Web Mercator (EPSG:3857) -> WGS84 lon/lat
function mercatorToLonLat(x, y) {
const R = 6378137;
const lon = (x / R) * (180 / Math.PI);
const lat = (2 * Math.atan(Math.exp(y / R)) - Math.PI / 2) * (180 / Math.PI);
return [lon, lat];
}
function looksLikeLonLat(x, y) {
return Math.abs(x) <= 180 && Math.abs(y) <= 90;
}
function convertPoint(pt) {
if (!Array.isArray(pt) || pt.length < 2) return pt;
const x = pt[0];
const y = pt[1];
if (typeof x !== "number" || typeof y !== "number") return pt;
if (looksLikeLonLat(x, y)) return [x, y];
return mercatorToLonLat(x, y);
}
function convertCoords(coords) {
if (!Array.isArray(coords)) return coords;
if (coords.length === 0) return coords;
// Point: [x, y]
if (typeof coords[0] === "number") return convertPoint(coords);
// Nested arrays
return coords.map(convertCoords);
}
async function main() {
const rawDir = path.join(ROOT, "data", "raw", "zones");
const outDir = path.join(ROOT, "apps", "web", "public", "data", "zones");
await fs.mkdir(outDir, { recursive: true });
const features = [];
for (const z of ZONES) {
const rawPath = path.join(rawDir, z.file);
const txt = await fs.readFile(rawPath, "utf-8");
const fc = JSON.parse(txt);
if (!fc || fc.type !== "FeatureCollection" || !Array.isArray(fc.features)) {
throw new Error(`Unexpected GeoJSON in ${rawPath}`);
}
for (const f of fc.features) {
if (!f?.geometry?.coordinates) continue;
const geometry = {
...f.geometry,
coordinates: convertCoords(f.geometry.coordinates),
};
features.push({
...f,
properties: {
...(f.properties || {}),
zoneId: z.zoneId,
zoneLabel: z.label,
zoneName: z.name,
},
geometry,
});
}
}
const out = {
type: "FeatureCollection",
name: "zones.wgs84",
features,
};
const outPath = path.join(outDir, "zones.wgs84.geojson");
await fs.writeFile(outPath, JSON.stringify(out), "utf-8");
// eslint-disable-next-line no-console
console.log(`Wrote ${features.length} features -> ${path.relative(ROOT, outPath)}`);
}
main().catch((err) => {
// eslint-disable-next-line no-console
console.error(err);
process.exit(1);
});