Spaces:
Sleeping
Sleeping
| // Dissolve the 101 datameet pincode polygons into ONE outer Bengaluru boundary, | |
| // keep only the largest ring (discard small detached pieces), and write it to | |
| // public/ so it can be fetched at runtime by the map and the hex generator. | |
| // | |
| // Run: node scripts/build-boundary.mjs | |
| import { readFileSync, writeFileSync, mkdirSync } from 'fs' | |
| import * as turf from '@turf/turf' | |
| const raw = JSON.parse( | |
| readFileSync('src/data/bangalore-boundary.geojson', 'utf8'), | |
| ) | |
| const polys = raw.features.filter( | |
| (f) => | |
| f.geometry && | |
| (f.geometry.type === 'Polygon' || f.geometry.type === 'MultiPolygon'), | |
| ) | |
| console.log(`Union of ${polys.length} pincode polygons...`) | |
| // @turf/turf v7's union takes a FeatureCollection of polygons. | |
| let merged = polys[0] | |
| for (let i = 1; i < polys.length; i++) { | |
| merged = turf.union(turf.featureCollection([merged, polys[i]])) | |
| } | |
| // Keep only the largest polygon ring (discard small detached pieces). | |
| if (merged.geometry.type === 'MultiPolygon') { | |
| const largest = merged.geometry.coordinates | |
| .slice() | |
| .sort((a, b) => turf.area(turf.polygon(b)) - turf.area(turf.polygon(a)))[0] | |
| merged.geometry = { | |
| type: 'Polygon', | |
| coordinates: largest, | |
| } | |
| } | |
| // Drop holes — keep only the outer ring for a clean single silhouette. | |
| merged.geometry.coordinates = [merged.geometry.coordinates[0]] | |
| merged.properties = { name: 'bangalore-outer-boundary' } | |
| // Smooth out small jagged seams left where the pincode polygons met, without | |
| // distorting the overall city shape. Light tolerance, high quality. | |
| try { | |
| const simplified = turf.simplify(merged, { | |
| tolerance: 0.0005, | |
| highQuality: true, | |
| mutate: false, | |
| }) | |
| if (simplified?.geometry?.coordinates?.[0]?.length >= 4) { | |
| merged = simplified | |
| merged.properties = { name: 'bangalore-outer-boundary' } | |
| console.log('Boundary simplified (tolerance 0.0005).') | |
| } | |
| } catch (err) { | |
| console.warn('turf.simplify failed, using un-simplified boundary:', err) | |
| } | |
| mkdirSync('public', { recursive: true }) | |
| writeFileSync( | |
| 'public/bangalore-outer-boundary.geojson', | |
| JSON.stringify(merged), | |
| ) | |
| // Also write into src/data so it can be statically imported (bundled) by the | |
| // hex generator without a runtime fetch. | |
| writeFileSync( | |
| 'src/data/bangalore-outer-boundary.geojson', | |
| JSON.stringify(merged), | |
| ) | |
| console.log( | |
| `Outer boundary written (${merged.geometry.coordinates[0].length} vertices).`, | |
| ) | |