UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

315 lines (261 loc) 11.1 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _Coordinates = _interopRequireDefault(require("../Core/Geographic/Coordinates")); var _Feature = _interopRequireWildcard(require("../Core/Feature")); var _Style = _interopRequireDefault(require("../Core/Style")); function readCRS(json) { if (json.crs) { if (json.crs.type.toLowerCase() == 'epsg') { return "EPSG:".concat(json.crs.properties.code); } else if (json.crs.type.toLowerCase() == 'name') { var epsgIdx = json.crs.properties.name.toLowerCase().indexOf('epsg:'); if (epsgIdx >= 0) { // authority:version:code => EPSG:[...]:code var codeStart = json.crs.properties.name.indexOf(':', epsgIdx + 5); if (codeStart > 0) { return "EPSG:".concat(json.crs.properties.name.substr(codeStart + 1)); } } } throw new Error("Unsupported CRS type '".concat(json.crs, "'")); } // assume default crs return 'EPSG:4326'; } var coord = new _Coordinates["default"]('EPSG:4978', 0, 0, 0); // filter with the first point var firstPtIsOut = function (extent, aCoords, crs) { coord.crs = crs; coord.setFromArray(aCoords[0]); return !extent.isPointInside(coord); }; var toFeature = { populateGeometry: function populateGeometry(crsIn, coordinates, geometry) { var setAltitude = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; geometry.startSubGeometry(coordinates.length); var useAlti = setAltitude && typeof coordinates[0][2] == 'number'; // coordinates is a list of pair [[x1, y1], [x2, y2], ..., [xn, yn]] var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = coordinates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var pair = _step.value; coord.crs = crsIn; coord.setFromValues(pair[0], pair[1], useAlti ? pair[2] : 0); geometry.pushCoordinates(coord); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator["return"] != null) { _iterator["return"](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } geometry.updateExtent(); }, "default": function _default(feature, crsIn, coordsIn, filteringExtent, setAltitude, properties) { if (filteringExtent && firstPtIsOut(filteringExtent, coordsIn, crsIn)) { return; } var geometry = feature.bindNewGeometry(); geometry.properties = properties; geometry.properties.style = new _Style["default"]().setFromGeojsonProperties(properties, feature.type); this.populateGeometry(crsIn, coordsIn, geometry, setAltitude); feature.updateExtent(geometry); }, polygon: function polygon(feature, crsIn, coordsIn, filteringExtent, setAltitude, properties) { // filtering if (filteringExtent && firstPtIsOut(filteringExtent, coordsIn[0], crsIn)) { return; } var geometry = feature.bindNewGeometry(); geometry.properties = properties; geometry.properties.style = new _Style["default"]().setFromGeojsonProperties(properties, feature.type); // Then read contour and holes for (var i = 0; i < coordsIn.length; i++) { this.populateGeometry(crsIn, coordsIn[i], geometry, setAltitude); } feature.updateExtent(geometry); }, multi: function multi(type, feature, crsIn, coordsIn, filteringExtent, setAltitude, properties) { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = coordsIn[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var coords = _step2.value; this[type](feature, crsIn, coords, filteringExtent, setAltitude, properties); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2["return"] != null) { _iterator2["return"](); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } }; function coordinatesToFeature(type, feature, crsIn, coordinates, filteringExtent, setAltitude, properties) { if (coordinates.length == 0) { return; } switch (type) { case 'point': case 'linestring': return toFeature["default"](feature, crsIn, coordinates, filteringExtent, setAltitude, properties); case 'multipoint': case 'multilinestring': return toFeature.multi('default', feature, crsIn, coordinates, filteringExtent, setAltitude, properties); case 'polygon': return toFeature.polygon(feature, crsIn, coordinates, filteringExtent, setAltitude, properties); case 'multipolygon': return toFeature.multi('polygon', feature, crsIn, coordinates, filteringExtent, setAltitude, properties); case 'geometrycollection': default: throw new Error("Unhandled geojson type ".concat(feature.type)); } } function toFeatureType(jsonType) { switch (jsonType) { case 'point': case 'multipoint': return _Feature.FEATURE_TYPES.POINT; case 'linestring': case 'multilinestring': return _Feature.FEATURE_TYPES.LINE; case 'polygon': case 'multipolygon': return _Feature.FEATURE_TYPES.POLYGON; case 'geometrycollection': default: throw new Error("Unhandled geometry type ".concat(jsonType)); } } var keyProperties = ['type', 'geometry', 'properties']; function jsonFeatureToFeature(crsIn, crsOut, json, filteringExtent, options, featureCollection) { if (options.filter && !options.filter(json.properties, json.geometry)) { return; } var jsonType = json.geometry.type.toLowerCase(); var featureType = toFeatureType(jsonType); var feature = options.mergeFeatures ? featureCollection.requestFeatureByType(featureType) : new _Feature["default"](featureType, crsOut, options); var geometryCount = feature.geometryCount; var coordinates = jsonType != 'point' ? json.geometry.coordinates : [json.geometry.coordinates]; var setAltitude = !options.overrideAltitudeInToZero && options.withAltitude; var properties = json.properties || {}; // copy other properties for (var _i = 0, _Object$keys = Object.keys(json); _i < _Object$keys.length; _i++) { var key = _Object$keys[_i]; if (!keyProperties.includes(key.toLowerCase())) { properties[key] = json[key]; } } coordinatesToFeature(jsonType, feature, crsIn, coordinates, filteringExtent, setAltitude, properties); if (feature.geometryCount == geometryCount) { return; } return feature; } function jsonFeaturesToFeatures(crsIn, crsOut, jsonFeatures, filteringExtent, options) { var features = new _Feature.FeatureCollection(crsOut, options); var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = jsonFeatures[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var jsonFeature = _step3.value; var feature = jsonFeatureToFeature(crsIn, crsOut, jsonFeature, filteringExtent, options, features); if (feature && !options.mergeFeatures) { features.pushFeature(feature); } } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3["return"] != null) { _iterator3["return"](); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } if (options.mergeFeatures) { features.removeEmptyFeature(); features.updateExtent(); } return features; } /** * The GeoJsonParser module provide a [parse]{@link module:GeoJsonParser.parse} * method that takes a GeoJSON in and gives an object formatted for iTowns * containing all necessary informations to display this GeoJSON. * * @module GeoJsonParser */ var _default = { /** * @typedef {Object} GeoJsonParserOptions * @property {string} crsOut - The CRS to convert the input coordinates * to. * @property {string} crsIn - Override the data CRS. * @property {Extent} [filteringExtent] - Optional filter to reject * features outside of this extent. * @property {boolean} [buildExtent=false] - If true the geometry will * have an extent property containing the area covered by the geom * @property {function} [filter] - Filter function to remove features * @property {boolean} [mergeFeatures=true] - If true all geometries are merged by type and multi-type * @property {boolean} [withNormal=true] - If true each coordinate normal is computed * @property {boolean} [withAltitude=true] - If true each coordinate altitude is kept * @property {boolean} [overrideAltitudeInToZero=false] - If true, the altitude of the source data isn't taken into account for 3D geometry convertions. * the altitude will be override to 0. This can be useful if you don't have a DEM or provide a new one when converting (with Layer.convert). */ /** * Parse a GeoJSON file content and return a [FeatureCollection]{@link FeatureCollection}. * * @param {string} json - The GeoJSON file content to parse. * @param {GeoJsonParser~GeoJsonParserOptions} options - Options controlling * the parsing. * * @return {Promise} A promise resolving with a [FeatureCollection]{@link FeatureCollection}. */ parse: function parse(json) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var crsOut = options.crsOut; var filteringExtent = options.filteringExtent; if (typeof json === 'string') { json = JSON.parse(json); } options.crsIn = options.crsIn || readCRS(json); options.mergeFeatures = options.mergeFeatures == undefined ? true : options.mergeFeatures; options.withNormal = options.withNormal == undefined ? true : options.withNormal; options.withAltitude = options.withAltitude == undefined ? true : options.withAltitude; switch (json.type.toLowerCase()) { case 'featurecollection': return Promise.resolve(jsonFeaturesToFeatures(options.crsIn, crsOut, json.features, filteringExtent, options)); case 'feature': return Promise.resolve(jsonFeaturesToFeatures(options.crsIn, crsOut, [json], filteringExtent, options)); default: throw new Error("Unsupported GeoJSON type: '".concat(json.type)); } } }; exports["default"] = _default;