UNPKG

@deck.gl/geo-layers

Version:

deck.gl layers supporting geospatial use cases and GIS formats

522 lines (428 loc) 19.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _core = require("@deck.gl/core"); var _core2 = require("@math.gl/core"); var _mvt = require("@loaders.gl/mvt"); var _gis = require("@loaders.gl/gis"); var _extensions = require("@deck.gl/extensions"); var _tileLayer = _interopRequireDefault(require("../tile-layer/tile-layer")); var _utils = require("../tile-layer/utils"); var _coordinateTransform = require("./coordinate-transform"); var _findIndexBinary = _interopRequireDefault(require("./find-index-binary")); var _layers = require("@deck.gl/layers"); function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var WORLD_SIZE = 512; var defaultProps = _objectSpread(_objectSpread({}, _layers.GeoJsonLayer.defaultProps), {}, { uniqueIdProperty: { type: 'string', value: '' }, highlightedFeatureId: null, loaders: [_mvt.MVTWorkerLoader], binary: true }); var MVTLayer = function (_TileLayer) { (0, _inherits2.default)(MVTLayer, _TileLayer); var _super = _createSuper(MVTLayer); function MVTLayer() { (0, _classCallCheck2.default)(this, MVTLayer); return _super.apply(this, arguments); } (0, _createClass2.default)(MVTLayer, [{ key: "initializeState", value: function initializeState() { (0, _get2.default)((0, _getPrototypeOf2.default)(MVTLayer.prototype), "initializeState", this).call(this); var binary = this.context.viewport.resolution !== undefined ? false : this.props.binary; this.setState({ binary: binary, data: null, tileJSON: null }); } }, { key: "isLoaded", get: function get() { return this.state.data && this.state.tileset && (0, _get2.default)((0, _getPrototypeOf2.default)(MVTLayer.prototype), "isLoaded", this); } }, { key: "updateState", value: function updateState(_ref) { var props = _ref.props, oldProps = _ref.oldProps, context = _ref.context, changeFlags = _ref.changeFlags; if (changeFlags.dataChanged) { this._updateTileData(); } if (this.state.data) { (0, _get2.default)((0, _getPrototypeOf2.default)(MVTLayer.prototype), "updateState", this).call(this, { props: props, oldProps: oldProps, context: context, changeFlags: changeFlags }); this._setWGS84PropertyForTiles(); } var highlightColor = props.highlightColor; if (highlightColor !== oldProps.highlightColor && Array.isArray(highlightColor)) { this.setState({ highlightColor: highlightColor }); } } }, { key: "_updateTileData", value: function () { var _updateTileData2 = (0, _asyncToGenerator2.default)(_regenerator.default.mark(function _callee() { var data, tileJSON, _this$props, onDataLoad, fetch; return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: data = this.props.data; tileJSON = null; if (!(typeof data === 'string' && !(0, _utils.isURLTemplate)(data))) { _context.next = 18; break; } _this$props = this.props, onDataLoad = _this$props.onDataLoad, fetch = _this$props.fetch; this.setState({ data: null, tileJSON: null }); _context.prev = 5; _context.next = 8; return fetch(data, { propName: 'data', layer: this, loaders: [] }); case 8: tileJSON = _context.sent; _context.next = 15; break; case 11: _context.prev = 11; _context.t0 = _context["catch"](5); this.raiseError(_context.t0, 'loading TileJSON'); data = null; case 15: if (onDataLoad) { onDataLoad(tileJSON); } _context.next = 19; break; case 18: if (data.tilejson) { tileJSON = data; } case 19: if (tileJSON) { data = tileJSON.tiles; } this.setState({ data: data, tileJSON: tileJSON }); case 21: case "end": return _context.stop(); } } }, _callee, this, [[5, 11]]); })); function _updateTileData() { return _updateTileData2.apply(this, arguments); } return _updateTileData; }() }, { key: "_getTilesetOptions", value: function _getTilesetOptions(props) { var opts = (0, _get2.default)((0, _getPrototypeOf2.default)(MVTLayer.prototype), "_getTilesetOptions", this).call(this, props); var tileJSON = this.state.tileJSON; if (tileJSON) { if (Number.isFinite(tileJSON.minzoom) && tileJSON.minzoom > props.minZoom) { opts.minZoom = tileJSON.minzoom; } if (Number.isFinite(tileJSON.maxzoom) && (!Number.isFinite(props.maxZoom) || tileJSON.maxzoom < props.maxZoom)) { opts.maxZoom = tileJSON.maxzoom; } } return opts; } }, { key: "renderLayers", value: function renderLayers() { if (!this.state.data) return null; return (0, _get2.default)((0, _getPrototypeOf2.default)(MVTLayer.prototype), "renderLayers", this).call(this); } }, { key: "getTileData", value: function getTileData(tile) { var _loadOptions; var url = (0, _utils.getURLFromTemplate)(this.state.data, tile); if (!url) { return Promise.reject('Invalid URL'); } var loadOptions = this.getLoadOptions(); var binary = this.state.binary; var fetch = this.props.fetch; var signal = tile.signal, x = tile.x, y = tile.y, z = tile.z; loadOptions = _objectSpread(_objectSpread({}, loadOptions), {}, { mimeType: 'application/x-protobuf', mvt: _objectSpread(_objectSpread({}, (_loadOptions = loadOptions) === null || _loadOptions === void 0 ? void 0 : _loadOptions.mvt), {}, { coordinates: this.context.viewport.resolution ? 'wgs84' : 'local', tileIndex: { x: x, y: y, z: z } }), gis: binary ? { format: 'binary' } : {} }); return fetch(url, { propName: 'data', layer: this, loadOptions: loadOptions, signal: signal }); } }, { key: "renderSubLayers", value: function renderSubLayers(props) { var tile = props.tile; var worldScale = Math.pow(2, tile.z); var xScale = WORLD_SIZE / worldScale; var yScale = -xScale; var xOffset = WORLD_SIZE * tile.x / worldScale; var yOffset = WORLD_SIZE * (1 - tile.y / worldScale); var modelMatrix = new _core2.Matrix4().scale([xScale, yScale, 1]); props.autoHighlight = false; if (!this.context.viewport.resolution) { props.modelMatrix = modelMatrix; props.coordinateOrigin = [xOffset, yOffset, 0]; props.coordinateSystem = _core.COORDINATE_SYSTEM.CARTESIAN; props.extensions = [].concat((0, _toConsumableArray2.default)(props.extensions || []), [new _extensions.ClipExtension()]); } var subLayers = (0, _get2.default)((0, _getPrototypeOf2.default)(MVTLayer.prototype), "renderSubLayers", this).call(this, props); if (this.state.binary && !(subLayers instanceof _layers.GeoJsonLayer)) { _core.log.warn('renderSubLayers() must return GeoJsonLayer when using binary:true')(); } return subLayers; } }, { key: "_updateAutoHighlight", value: function _updateAutoHighlight(info) { var uniqueIdProperty = this.props.uniqueIdProperty; var _this$state = this.state, hoveredFeatureId = _this$state.hoveredFeatureId, hoveredFeatureLayerName = _this$state.hoveredFeatureLayerName; var hoveredFeature = info.object; var newHoveredFeatureId; var newHoveredFeatureLayerName; if (hoveredFeature) { newHoveredFeatureId = getFeatureUniqueId(hoveredFeature, uniqueIdProperty); newHoveredFeatureLayerName = getFeatureLayerName(hoveredFeature); } var highlightColor = this.props.highlightColor; if (typeof highlightColor === 'function') { highlightColor = highlightColor(info); } if (hoveredFeatureId !== newHoveredFeatureId || hoveredFeatureLayerName !== newHoveredFeatureLayerName) { this.setState({ highlightColor: highlightColor, hoveredFeatureId: newHoveredFeatureId, hoveredFeatureLayerName: newHoveredFeatureLayerName }); } } }, { key: "getPickingInfo", value: function getPickingInfo(params) { var info = (0, _get2.default)((0, _getPrototypeOf2.default)(MVTLayer.prototype), "getPickingInfo", this).call(this, params); var isWGS84 = this.context.viewport.resolution; if (this.state.binary && info.index !== -1) { var data = params.sourceLayer.props.data; info.object = (0, _gis.binaryToGeojson)(data, { globalFeatureId: info.index }); } if (info.object && !isWGS84) { info.object = transformTileCoordsToWGS84(info.object, info.tile.bbox, this.context.viewport); } return info; } }, { key: "getSubLayerPropsByTile", value: function getSubLayerPropsByTile(tile) { return { highlightedObjectIndex: this.getHighlightedObjectIndex(tile), highlightColor: this.state.highlightColor }; } }, { key: "getHighlightedObjectIndex", value: function getHighlightedObjectIndex(tile) { var _this$state2 = this.state, hoveredFeatureId = _this$state2.hoveredFeatureId, hoveredFeatureLayerName = _this$state2.hoveredFeatureLayerName, binary = _this$state2.binary; var _this$props2 = this.props, uniqueIdProperty = _this$props2.uniqueIdProperty, highlightedFeatureId = _this$props2.highlightedFeatureId; var data = tile.content; var isHighlighted = isFeatureIdDefined(highlightedFeatureId); var isFeatureIdPresent = isFeatureIdDefined(hoveredFeatureId) || isHighlighted; if (!isFeatureIdPresent) { return -1; } var featureIdToHighlight = isHighlighted ? highlightedFeatureId : hoveredFeatureId; if (Array.isArray(data)) { return data.findIndex(function (feature) { var isMatchingId = getFeatureUniqueId(feature, uniqueIdProperty) === featureIdToHighlight; var isMatchingLayer = isHighlighted || getFeatureLayerName(feature) === hoveredFeatureLayerName; return isMatchingId && isMatchingLayer; }); } else if (data && binary) { return (0, _findIndexBinary.default)(data, uniqueIdProperty, featureIdToHighlight, isHighlighted ? '' : hoveredFeatureLayerName); } return -1; } }, { key: "_pickObjects", value: function _pickObjects(maxObjects) { var _this$context = this.context, deck = _this$context.deck, viewport = _this$context.viewport; var width = viewport.width; var height = viewport.height; var x = viewport.x; var y = viewport.y; var layerIds = [this.id]; return deck.pickObjects({ x: x, y: y, width: width, height: height, layerIds: layerIds, maxObjects: maxObjects }); } }, { key: "getRenderedFeatures", value: function getRenderedFeatures() { var maxFeatures = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; var features = this._pickObjects(maxFeatures); var featureCache = new Set(); var renderedFeatures = []; var _iterator = _createForOfIteratorHelper(features), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var f = _step.value; var featureId = getFeatureUniqueId(f.object, this.props.uniqueIdProperty); if (featureId === undefined) { renderedFeatures.push(f.object); } else if (!featureCache.has(featureId)) { featureCache.add(featureId); renderedFeatures.push(f.object); } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return renderedFeatures; } }, { key: "_setWGS84PropertyForTiles", value: function _setWGS84PropertyForTiles() { var _this = this; var propName = 'dataInWGS84'; var tileset = this.state.tileset; tileset.selectedTiles.forEach(function (tile) { if (!tile.hasOwnProperty(propName)) { Object.defineProperty(tile, propName, { get: function get() { if (!tile.content) { return null; } if (_this.state.binary && Array.isArray(tile.content) && !tile.content.length) { return []; } if (tile._contentWGS84 === undefined) { var content = _this.state.binary ? (0, _gis.binaryToGeojson)(tile.content) : tile.content; tile._contentWGS84 = content.map(function (feature) { return transformTileCoordsToWGS84(feature, tile.bbox, _this.context.viewport); }); } return tile._contentWGS84; } }); } }); } }]); return MVTLayer; }(_tileLayer.default); exports.default = MVTLayer; function getFeatureUniqueId(feature, uniqueIdProperty) { if (uniqueIdProperty) { return feature.properties[uniqueIdProperty]; } if ('id' in feature) { return feature.id; } return undefined; } function getFeatureLayerName(feature) { var _feature$properties; return ((_feature$properties = feature.properties) === null || _feature$properties === void 0 ? void 0 : _feature$properties.layerName) || null; } function isFeatureIdDefined(value) { return value !== undefined && value !== null && value !== ''; } function transformTileCoordsToWGS84(object, bbox, viewport) { var feature = _objectSpread(_objectSpread({}, object), {}, { geometry: { type: object.geometry.type } }); Object.defineProperty(feature.geometry, 'coordinates', { get: function get() { var wgs84Geom = (0, _coordinateTransform.transform)(object.geometry, bbox, viewport); return wgs84Geom.coordinates; } }); return feature; } MVTLayer.layerName = 'MVTLayer'; MVTLayer.defaultProps = defaultProps; //# sourceMappingURL=mvt-layer.js.map