UNPKG

sg-heatmap

Version:

Open-source all-in-one Swiss Army knife tool for creating Choropleth maps

88 lines (80 loc) 3.01 kB
// // Deprecated // Switched to using GeoJSON // import fs from 'fs'; import xml2js from 'xml2js'; import { html2json as htmlParser } from 'html2json'; import { maxBy, minBy } from 'lodash'; import { encodePolyline, fromSVY21 } from './helpers/geometry'; var kmlParser = new xml2js.Parser({ explicitArray: false }); var kmls = { region: 'MP14_REGION_NO_SEA_PL.kml', planning_area: 'MP14_PLNG_AREA_NO_SEA_PL.kml', subzone: 'MP14_SUBZONE_NO_SEA_PL.kml' }; Object.keys(kmls).forEach(function (layer) { var data = fs.readFileSync('data/raw/' + kmls[layer]); kmlParser.parseString(data, function (err, result) { if (err) console.error(err); var parsed = result.kml.Document.Folder.Placemark; fs.writeFileSync('data/semi/' + layer + '_raw.json', JSON.stringify(parsed)); var cleaned = parsed.map(function (area) { var meta = area.description.replace(/\r?\n|\r/g, ''); meta = htmlParser(meta).child[0].child.find(function (_ref) { var node = _ref.node, tag = _ref.tag; return node === 'element' && tag === 'body'; }).child.find(function (_ref2) { var node = _ref2.node, tag = _ref2.tag; return node === 'element' && tag === 'table'; }).child[1].child[0].child[0].child.reduce(function (tb, tr) { var key = tr.child[0].child[0].text.replace(/ /g, '_'); var value = tr.child[1].child[0].text; tb[key] = value; return tb; }, {}); var center = fromSVY21([meta.X_ADDR, meta.Y_ADDR]); var polygons = area.MultiGeometry.Polygon; var boundary = polygons instanceof Array ? polygons.map(formatPolygon) : [formatPolygon(polygons)]; var key = meta.Subzone_Code || meta.Planning_Area_Code || meta.Region_Code; return { key: key, meta: meta, center: center, boundary: boundary }; }); fs.writeFileSync('data/' + layer + '.json', JSON.stringify(cleaned)); }); }); function formatPolygon(polygon) { var outerBoundaryIs = polygon.outerBoundaryIs, innerBoundaryIs = polygon.innerBoundaryIs; var result = {}; result.outer = formatLatLng(outerBoundaryIs.LinearRing.coordinates); result.bounds = { sw: [minBy(result.outer, function (v) { return v[0]; })[0], minBy(result.outer, function (v) { return v[1]; })[1]], ne: [maxBy(result.outer, function (v) { return v[0]; })[0], maxBy(result.outer, function (v) { return v[1]; })[1]] }; result.outer = encodePolyline(result.outer); if (innerBoundaryIs) { result.inners = innerBoundaryIs instanceof Array ? innerBoundaryIs.map(function (b) { return formatLatLng(b.LinearRing.coordinates); }) : [formatLatLng(innerBoundaryIs.LinearRing.coordinates)]; result.inners = result.inners.map(function (v) { return encodePolyline(v); }); } return result; } function formatLatLng(str) { return str.trim().split(' ').map(function (substr) { var xyz = substr.split(','); return [+xyz[1], +xyz[0]]; }); }