UNPKG

tchen-vuelayers

Version:

Web map Vue components with the power of OpenLayers

334 lines (302 loc) 7.65 kB
/** * VueLayers * Web map Vue components with the power of OpenLayers * * @package vuelayers * @author Vladimir Vershinin <ghettovoice@gmail.com> * @version 0.11.1 * @license MIT * @copyright (c) 2017-2019, Vladimir Vershinin <ghettovoice@gmail.com> */ import _Object$defineProperties from '@babel/runtime-corejs2/core-js/object/define-properties'; import { distinctUntilChanged } from 'rxjs/_esm5/internal/operators/distinctUntilChanged'; import { map } from 'rxjs/_esm5/internal/operators/map'; import { throttleTime } from 'rxjs/_esm5/internal/operators/throttleTime'; import { boundingExtent } from '../ol-ext/extent'; import { findPointOnSurface } from '../ol-ext/geom'; import { transforms } from '../ol-ext/proj'; import observableFromOlEvent from '../rx-ext/from-ol-event'; import { hasGeometry } from '../util/assert'; import { isEqual } from '../util/minilo'; import mergeDescriptors from '../util/multi-merge-descriptors'; import cmp from './ol-virt-cmp'; import projTransforms from './proj-transforms'; import useMapCmp from './use-map-cmp'; var props = { /** * Coordinates in the map view projection. * @type {number[]|Coordinate} */ coordinates: { type: Array, required: true, validator: function validator(val) { return val.length; } } }; var computed = { /** * @type {string} * @abstract * @readonly */ type: function type() { throw new Error('Not implemented computed property'); }, /** * @type {number[]|Extent|undefined} */ extent: function extent() { if (this.extentViewProj && this.resolvedDataProjection) { return this.extentToDataProj(this.extentViewProj); } }, /** * @type {number[]|Extent|undefined} */ extentViewProj: function extentViewProj() { if (this.rev && this.$geometry) { return this.$geometry.getExtent(); } }, /** * @type {number[]|Coordinate|undefined} */ point: function point() { if (this.pointViewProj && this.resolvedDataProjection) { return this.pointToDataProj(this.pointViewProj); } }, /** * @type {Array<number>} */ pointViewProj: function pointViewProj() { if (this.rev && this.$geometry) { return findPointOnSurface(this.$geometry); } }, /** * @type {Array|undefined} */ coordinatesViewProj: function coordinatesViewProj() { if (this.rev && this.$geometry) { return this.$geometry.getCoordinates(); } } }; var methods = { /** * @return {Geometry|Promise<Geometry>} * @protected */ createOlObject: function createOlObject() { return this.createGeometry(); }, /** * @return {Geometry|Promise<Geometry>} * @protected * @abstract */ createGeometry: function createGeometry() { throw new Error('Not implemented method'); }, /** * @return {Coordinate} */ getCoordinates: function getCoordinates() { hasGeometry(this); return this.toDataProj(this.$geometry.getCoordinates()); }, /** * @param {Coordinate} coordinates */ setCoordinates: function setCoordinates(coordinates) { hasGeometry(this); this.$geometry.setCoordinates(this.toViewProj(coordinates)); }, /** * @return {Promise} * @throws {AssertionError} * @protected */ init: function init() { this.setupTransformFunctions(); return cmp.methods.init.call(this); }, /** * @protected */ setupTransformFunctions: function setupTransformFunctions() { var _this = this; // define helper methods based on geometry type var transform = transforms[this.type].transform; /** * @method * @param {Array} coordinates * @return {number[]} * @protected */ this.toDataProj = function (coordinates) { return transform(coordinates, _this.viewProjection, _this.resolvedDataProjection); }; /** * @method * @param {Array} coordinates * @return {number[]} * @protected */ this.toViewProj = function (coordinates) { return transform(coordinates, _this.resolvedDataProjection, _this.viewProjection); }; }, /** * @return {void|Promise<void>} * @protected */ deinit: function deinit() { return cmp.methods.deinit.call(this); }, /** * @return {Promise} */ refresh: function refresh() { return cmp.methods.refresh.call(this); }, /** * @return {Object} * @protected */ getServices: function getServices() { var vm = this; return mergeDescriptors(cmp.methods.getServices.call(this), { get geometry() { return vm.$geometry; } }); }, /** * @return {void} * @protected */ mount: function mount() { this.$geometryContainer && this.$geometryContainer.setGeometry(this); this.subscribeAll(); }, /** * @return {void} * @protected */ unmount: function unmount() { this.unsubscribeAll(); this.$geometryContainer && this.$geometryContainer.setGeometry(undefined); }, /** * @return {void} * @protected */ subscribeAll: function subscribeAll() { subscribeToGeomChanges.call(this); } }; var watch = { coordinates: function coordinates(value) { if (!this.$geometry || !this.$view) return; // compares in data projection var isEq = isEqualGeom({ coordinates: value, extent: boundingExtent(value) }, { coordinates: this.getCoordinates(), extent: this.extent }); if (!isEq) { this.setCoordinates(value); } }, resolvedDataProjection: function resolvedDataProjection() { if (this.$geometry) { this.setupTransformFunctions(); this.setCoordinates(this.coordinates); } } }; var geometry = { mixins: [cmp, useMapCmp, projTransforms], props: props, computed: computed, watch: watch, methods: methods, stubVNode: { empty: function empty() { return this.$options.name; } }, created: function created() { var _this2 = this; _Object$defineProperties(this, { /** * @type {Geometry|undefined} */ $geometry: { enumerable: true, get: function get() { return _this2.$olObject; } }, $map: { enumerable: true, get: function get() { return _this2.$services && _this2.$services.map; } }, $view: { enumerable: true, get: function get() { return _this2.$services && _this2.$services.view; } }, $geometryContainer: { enumerable: true, get: function get() { return _this2.$services && _this2.$services.geometryContainer; } } }); } }; /** * @return {void} * @private */ function subscribeToGeomChanges() { var _this3 = this; hasGeometry(this); var ft = 100; var changes = observableFromOlEvent(this.$geometry, 'change', function () { return { coordinates: _this3.getCoordinates(), extent: _this3.extent }; }).pipe(throttleTime(ft), distinctUntilChanged(isEqualGeom), map(function (_ref) { var coordinates = _ref.coordinates; return { prop: 'coordinates', value: coordinates }; })); this.subscribeTo(changes, function (_ref2) { var prop = _ref2.prop, value = _ref2.value; ++_this3.rev; _this3.$emit("update:".concat(prop), value); }); } /** * @param {{coordinates: number[], extent: number[]}} a * @param {{coordinates: number[], extent: number[]}} b * @returns {boolean} */ function isEqualGeom(a, b) { return isEqual(a.extent, b.extent) ? isEqual(a.coordinates, b.coordinates) : false; } export default geometry;