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