osm2geojson-ultra
Version:
a faster & more complete OSM & Overpass (either in xml or in json formats) to geojson convertor - 4x faster than xmldom + osmtogeojson in most situations - implemented in TypeScript with txml for XML parsing
115 lines (114 loc) • 3.65 kB
JavaScript
import { OsmObject } from "./osm-object.js";
import { LateBinder } from "./late-binder.js";
import { isRing, ringDirection, strArrayToFloat, strArrayArrayToFloat, } from "./utils.js";
import polygonTags from "./polytags.json" with { type: "json" };
export class Way extends OsmObject {
constructor(id, refElems) {
super("way", id, refElems);
this.tainted = false;
this.latLngArray = [];
this.center = null;
}
addLatLng(latLng) {
this.latLngArray.push(latLng);
}
setCenter(center) {
this.center = center;
}
setLatLngArray(latLngArray) {
this.latLngArray = latLngArray;
}
addNodeRef(ref) {
const binder = new LateBinder(this.latLngArray, (id) => {
const node = this.refElems.get(`node/${id}`);
if (node) {
node.refCount++;
return node.getLatLng();
}
else {
this.tainted = true;
}
}, this, [ref]);
this.latLngArray.push(binder);
this.refElems.addBinder(binder);
}
addTags(tags) {
super.addTags(tags);
}
addTag(k, v) {
super.addTag(k, v);
}
toCoordsArray() {
return this.latLngArray.map((latLng) => [
latLng.lon,
latLng.lat,
]);
}
toFeature() {
let coordsArrayString = this.toCoordsArray();
if (coordsArrayString.length > 1) {
const coordsArray = strArrayArrayToFloat(coordsArrayString);
const feature = {
type: "Feature",
id: this.getCompositeId(),
properties: this.getProps(),
geometry: {
type: "LineString",
coordinates: coordsArray,
},
};
if (this.tainted) {
feature.properties["@tainted"] = this.tainted;
}
if (this.isPolygon && isRing(coordsArray)) {
if (ringDirection(coordsArray) !== "counterclockwise") {
coordsArray.reverse();
}
feature.geometry = {
type: "Polygon",
coordinates: [coordsArray],
};
if (this.tainted) {
feature.properties["@tainted"] = this.tainted;
}
return feature;
}
return feature;
}
else if (this.center !== null) {
const feature = {
type: "Feature",
id: this.getCompositeId(),
properties: this.getProps(),
geometry: {
type: "Point",
coordinates: strArrayToFloat([this.center.lon, this.center.lat]),
},
};
if (this.tainted) {
feature.properties["@tainted"] = this.tainted;
}
return feature;
}
}
get isPolygon() {
var _a;
let isPolygon = false;
for (const [key, o] of Object.entries(polygonTags)) {
const v = this.tags[key];
if (v && o) {
if ((_a = o.ignore) === null || _a === void 0 ? void 0 : _a.includes(v)) {
continue;
}
isPolygon = true;
if (o.include) {
isPolygon = o.include.includes(v);
}
else if (o.exclude) {
isPolygon = !o.exclude.includes(v);
}
}
}
return isPolygon;
}
}