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); });