UNPKG

maplair

Version:

JavaScript library for mobile-friendly interactive maps

192 lines (191 loc) • 7.03 kB
import { formatNum } from "../core/Util.js"; import { LatLng } from "../geo/LatLng.js"; import { isFlat } from "../geometry/LineUtil.js"; import { LayerGroup } from "./LayerGroup.js"; import { FeatureGroup } from "./FeatureGroup.js"; import { Marker } from "./marker/Marker.js"; import { CircleMarker } from "./vector/CircleMarker.js"; import { Circle } from "./vector/Circle.js"; import { Polyline } from "./vector/Polyline.js"; import { Polygon } from "./vector/Polygon.js"; //#region src/layer/GeoJSON.js var GeoJSON = class GeoJSON extends FeatureGroup { constructor(geojson, options) { super(void 0, options); if (geojson) this.addData(geojson); this.callInitHooks(GeoJSON); } addData(geojson) { const features = Array.isArray(geojson) ? geojson : geojson.features; if (features) { for (const feature of features) if (feature.geometries || feature.geometry || feature.features || feature.coordinates) this.addData(feature); return this; } const options = this.options; if (options.filter && !options.filter(geojson)) return this; const layer = GeoJSON.geometryToLayer(geojson, options); if (!layer) return this; layer.feature = GeoJSON.asFeature(geojson); layer.defaultOptions = layer.options; this.resetStyle(layer); if (options.onEachFeature) options.onEachFeature(geojson, layer); return this.addLayer(layer); } resetStyle(layer) { if (layer === void 0) return this.eachLayer(this.resetStyle, this); layer.options = Object.create(layer.defaultOptions); this._setLayerStyle(layer, this.options.style); return this; } setStyle(style) { return this.eachLayer((layer) => this._setLayerStyle(layer, style)); } _setLayerStyle(layer, style) { if (layer.setStyle) { if (typeof style === "function") style = style(layer.feature); layer.setStyle(style); } } static geometryToLayer(geojson, options) { const geometry = geojson.type === "Feature" ? geojson.geometry : geojson, coords = geometry?.coordinates, layers = [], pointToLayer = options?.pointToLayer, _coordsToLatLng = options?.coordsToLatLng ?? GeoJSON.coordsToLatLng; let latlng, latlngs; if (!coords && !geometry) return null; switch (geometry.type) { case "Point": latlng = _coordsToLatLng(coords); return GeoJSON._pointToLayer(pointToLayer, geojson, latlng, options); case "MultiPoint": for (const coord of coords) { latlng = _coordsToLatLng(coord); layers.push(GeoJSON._pointToLayer(pointToLayer, geojson, latlng, options)); } return new FeatureGroup(layers); case "LineString": case "MultiLineString": latlngs = GeoJSON.coordsToLatLngs(coords, geometry.type === "LineString" ? 0 : 1, _coordsToLatLng); return new Polyline(latlngs, options); case "Polygon": case "MultiPolygon": latlngs = GeoJSON.coordsToLatLngs(coords, geometry.type === "Polygon" ? 1 : 2, _coordsToLatLng); return new Polygon(latlngs, options); case "GeometryCollection": for (const g of geometry.geometries) { const geoLayer = GeoJSON.geometryToLayer({ geometry: g, type: "Feature", properties: geojson.properties }, options); if (geoLayer) layers.push(geoLayer); } return new FeatureGroup(layers); case "FeatureCollection": for (const f of geometry.features) { const featureLayer = GeoJSON.geometryToLayer(f, options); if (featureLayer) layers.push(featureLayer); } return new FeatureGroup(layers); default: throw new Error("Invalid GeoJSON object."); } } static _pointToLayer(pointToLayerFn, geojson, latlng, options) { return pointToLayerFn ? pointToLayerFn(geojson, latlng) : new Marker(latlng, options?.markersInheritOptions && options); } static coordsToLatLng(coords) { return new LatLng(coords[1], coords[0], coords[2]); } static coordsToLatLngs(coords, levelsDeep, _coordsToLatLng) { return coords.map((coord) => levelsDeep ? GeoJSON.coordsToLatLngs(coord, levelsDeep - 1, _coordsToLatLng) : (_coordsToLatLng || GeoJSON.coordsToLatLng)(coord)); } static latLngToCoords(latlng, precision) { latlng = new LatLng(latlng); return latlng.alt !== void 0 ? [ formatNum(latlng.lng, precision), formatNum(latlng.lat, precision), formatNum(latlng.alt, precision) ] : [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision)]; } static latLngsToCoords(latlngs, levelsDeep, close, precision) { const coords = latlngs.map((latlng) => levelsDeep ? GeoJSON.latLngsToCoords(latlng, isFlat(latlng) ? 0 : levelsDeep - 1, close, precision) : GeoJSON.latLngToCoords(latlng, precision)); if (!levelsDeep && close && coords.length > 0) coords.push(coords[0].slice()); return coords; } static getFeature(layer, newGeometry) { return layer.feature ? { ...layer.feature, geometry: newGeometry } : GeoJSON.asFeature(newGeometry); } static asFeature(geojson) { if (geojson.type === "Feature" || geojson.type === "FeatureCollection") return geojson; return { type: "Feature", properties: {}, geometry: geojson }; } }; const PointToGeoJSON = { toGeoJSON(precision) { return GeoJSON.getFeature(this, { type: "Point", coordinates: GeoJSON.latLngToCoords(this.getLatLng(), precision) }); } }; Marker.include(PointToGeoJSON); Circle.include(PointToGeoJSON); CircleMarker.include(PointToGeoJSON); Polyline.include({ toGeoJSON(precision) { const multi = !isFlat(this._latlngs); const coords = GeoJSON.latLngsToCoords(this._latlngs, multi ? 1 : 0, false, precision); return GeoJSON.getFeature(this, { type: `${multi ? "Multi" : ""}LineString`, coordinates: coords }); } }); Polygon.include({ toGeoJSON(precision) { const holes = !isFlat(this._latlngs), multi = holes && !isFlat(this._latlngs[0]); let coords = GeoJSON.latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true, precision); if (!holes) coords = [coords]; return GeoJSON.getFeature(this, { type: `${multi ? "Multi" : ""}Polygon`, coordinates: coords }); } }); LayerGroup.include({ toMultiPoint(precision) { const coords = []; this.eachLayer((layer) => { coords.push(layer.toGeoJSON(precision).geometry.coordinates); }); return GeoJSON.getFeature(this, { type: "MultiPoint", coordinates: coords }); }, toGeoJSON(precision) { const type = this.feature?.geometry?.type; if (type === "MultiPoint") return this.toMultiPoint(precision); const isGeometryCollection = type === "GeometryCollection", jsons = []; this.eachLayer((layer) => { if (layer.toGeoJSON) { const json = layer.toGeoJSON(precision); if (isGeometryCollection) jsons.push(json.geometry); else { const feature = GeoJSON.asFeature(json); if (feature.type === "FeatureCollection") jsons.push(...feature.features); else jsons.push(feature); } } }); if (isGeometryCollection) return GeoJSON.getFeature(this, { geometries: jsons, type: "GeometryCollection" }); return { type: "FeatureCollection", features: jsons }; } }); //#endregion export { GeoJSON }; //# sourceMappingURL=GeoJSON.js.map