tchen-vuelayers
Version:
Web map Vue components with the power of OpenLayers
334 lines (302 loc) • 7.65 kB
JavaScript
/**
* 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;