UNPKG

osm2geojson-lite

Version:

a lightweight yet faster osm (either in xml or in json formats) to geojson convertor - 4x faster than xmldom + osmtogeojson in most situations - implemented in pure JavaScript without any 3rd party dependency

98 lines (97 loc) 3.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.purgeProps = purgeProps; exports.first = first; exports.last = last; exports.coordsToKey = coordsToKey; exports.addToMap = addToMap; exports.removeFromMap = removeFromMap; exports.getFirstFromMap = getFirstFromMap; exports.isRing = isRing; exports.ringDirection = ringDirection; exports.pointInsidePolygon = pointInsidePolygon; exports.strArrayArrayToFloat = strArrayArrayToFloat; exports.strArrayToFloat = strArrayToFloat; function purgeProps(obj, blacklist) { if (obj) { const rs = Object.assign({}, obj); if (blacklist) { for (const prop of blacklist) { delete rs[prop]; } } return rs; } return {}; } function first(a) { return a[0]; } function last(a) { return a[a.length - 1]; } function coordsToKey(a) { return a.join(','); } function addToMap(m, k, v) { const a = m[k]; if (a) { a.push(v); } else { m[k] = [v]; } } function removeFromMap(m, k, v) { const a = m[k]; let idx = -1; if (a) { idx = a.indexOf(v); } if (idx >= 0) { a.splice(idx, 1); } } function getFirstFromMap(m, k) { const a = m[k]; if (a && a.length > 0) { return a[0]; } return null; } // need 3+ different points to form a ring, here using > 3 is 'coz a the first and the last points are actually the same function isRing(a) { return a.length > 3 && coordsToKey(first(a)) === coordsToKey(last(a)); } function ringDirection(a, xIdx, yIdx) { xIdx = xIdx || 0, yIdx = yIdx || 1; // get the index of the point which has the maximum x value const m = a.reduce((maxxIdx, v, idx) => a[maxxIdx][xIdx || 0] > v[xIdx || 0] ? maxxIdx : idx, 0); // 'coz the first point is virtually the same one as the last point, // we need to skip a.length - 1 for left when m = 0, // and skip 0 for right when m = a.length - 1; const l = m <= 0 ? a.length - 2 : m - 1; const r = m >= a.length - 1 ? 1 : m + 1; const xa = a[l][xIdx]; const xb = a[m][xIdx]; const xc = a[r][xIdx]; const ya = a[l][yIdx]; const yb = a[m][yIdx]; const yc = a[r][yIdx]; const det = (xb - xa) * (yc - ya) - (xc - xa) * (yb - ya); return det < 0 ? 'clockwise' : 'counterclockwise'; } ; function pointInsidePolygon(pt, polygon, xIdx, yIdx) { xIdx = xIdx || 0, yIdx = yIdx || 1; let result = false; for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { if ((polygon[i][xIdx] <= pt[xIdx] && pt[xIdx] < polygon[j][xIdx] || polygon[j][xIdx] <= pt[xIdx] && pt[xIdx] < polygon[i][xIdx]) && pt[yIdx] < (polygon[j][yIdx] - polygon[i][yIdx]) * (pt[xIdx] - polygon[i][xIdx]) / (polygon[j][xIdx] - polygon[i][xIdx]) + polygon[i][yIdx]) { result = !result; } } return result; } ; function strArrayArrayToFloat(el) { return el.map(strArrayToFloat); } function strArrayToFloat(el) { return el.map(parseFloat); }