UNPKG

kmap-ui

Version:

A components of zmap base on vue2.X

286 lines (262 loc) 9.3 kB
/* Copyright (c) 2016 Jean-Marc VIGLINO, released under the CeCILL-B license (French BSD license) (http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt). */ import ol_ext_inherits from '../util/ext' import {unByKey as ol_Observable_unByKey} from 'ol/Observable' import ol_control_Control from 'ol/control/Control' import ol_geom_Polygon from 'ol/geom/Polygon' import ol_geom_Point from 'ol/geom/Point' import ol_interaction_Pointer from 'ol/interaction/Pointer' import ol_Map from 'ol/Map' import ol_Collection from 'ol/Collection' import ol_View from 'ol/View' import ol_source_Vector from 'ol/source/Vector' import ol_style_Style from 'ol/style/Style' import ol_style_Circle from 'ol/style/Circle' import ol_style_Fill from 'ol/style/Fill' import ol_style_Stroke from 'ol/style/Stroke' import ol_layer_Vector from 'ol/layer/Vector' import ol_Feature from 'ol/Feature' /** * OpenLayers 3 Layer Overview Control. * The overview can rotate with map. * Zoom levels are configurable. * Click on the overview will center the map. * Change width/height of the overview trough css. * * @constructor * @extends {ol_control_Control} * @param {Object=} options Control options. * @param {ol.ProjectionLike} options.projection The projection. Default is EPSG:3857 (Spherical Mercator). * @param {Number} options.minZoom default 0 * @param {Number} options.maxZoom default 18 * @param {boolean} options.rotation enable rotation, default false * @param {top|bottom-left|right} options.align position * @param {Array<ol.layer>} options.layers list of layers * @param {ol.style.Style | Array.<ol.style.Style> | undefined} options.style style to draw the map extent on the overveiw * @param {bool|elastic} options.panAnimation use animation to center map on click, default true */ var ol_control_Overview = function(options) { options = options || {}; var self = this; // API this.minZoom = options.minZoom || 0; this.maxZoom = options.maxZoom || 18; this.rotation = options.rotation; var element; if (options.target) { element = document.createElement("div"); this.panel_ = options.target; } else { element = document.createElement("div"); element.classList.add('ol-overview', 'ol-unselectable', 'ol-control', 'ol-collapsed'); if (/top/.test(options.align)) element.classList.add('ol-control-top'); if (/right/.test(options.align)) element.classList.add('ol-control-right'); var button = document.createElement("button"); button.setAttribute('type','button'); button.addEventListener("touchstart", function(e){ self.toggleMap(); e.preventDefault(); }); button.addEventListener("click", function(){self.toggleMap()}); element.appendChild(button); this.panel_ = document.createElement("div"); this.panel_.classList.add("panel"); element.appendChild(this.panel_); } ol_control_Control.call(this, { element: element, target: options.target }); // Create a overview map this.ovmap_ = new ol_Map({ controls: new ol_Collection(), interactions: new ol_Collection(), target: this.panel_, view: new ol_View ({ zoom: 2, center: [0,0], projection: options.projection }), layers: options.layers }); this.oview_ = this.ovmap_.getView(); // Cache extent this.extentLayer = new ol_layer_Vector({ name: 'Cache extent', source: new ol_source_Vector(), style: options.style || [new ol_style_Style({ image: new ol_style_Circle({ fill: new ol_style_Fill({ color: 'rgba(255,0,0, 1)' }), stroke: new ol_style_Stroke({ width: 7, color: 'rgba(255,0,0, 0.8)' }), radius: 5 }), stroke: new ol_style_Stroke({ width: 5, color: "rgba(255,0,0,0.8)" }) } )] }) this.ovmap_.addLayer(this.extentLayer); /** Elastic bounce * @param {Int} bounce number of bounce * @param {Number} amplitude amplitude of the bounce [0,1] * @return {Number} * / var bounceFn = function (bounce, amplitude){ var a = (2*bounce+1) * Math.PI/2; var b = amplitude>0 ? -1/amplitude : -100; var c = - Math.cos(a) * Math.pow(2, b); return function(t) { t = 1-Math.cos(t*Math.PI/2); return 1 + Math.abs( Math.cos(a*t) ) * Math.pow(2, b*t) + c*t; } } /** Elastic bounce * @param {Int} bounce number of bounce * @param {Number} amplitude amplitude of the bounce [0,1] * @return {Number} */ var elasticFn = function (bounce, amplitude) { var a = 3*bounce * Math.PI/2; var b = amplitude>0 ? -1/amplitude : -100; var c = Math.cos(a) * Math.pow(2, b); return function(t){ t = 1-Math.cos(t*Math.PI/2); return 1 - Math.cos(a*t) * Math.pow(2, b*t) + c*t; } } // Click on the preview center the map this.ovmap_.addInteraction (new ol_interaction_Pointer({ handleDownEvent: function(evt) { if (options.panAnimation !==false) { if (options.panAnimation=="elastic" || options.elasticPan) { self.getMap().getView().animate({ center: evt.coordinate, easing: elasticFn(2,0.3), duration: 1000 }); } else { self.getMap().getView().animate({ center: evt.coordinate, duration: 300 }); } } else self.getMap().getView().setCenter(evt.coordinate); return false; } })); }; ol_ext_inherits(ol_control_Overview, ol_control_Control); /** Get overview map * @return {ol.Map} */ ol_control_Overview.prototype.getOverviewMap = function(){ return this.ovmap_; }; /** Toggle overview map */ ol_control_Overview.prototype.toggleMap = function(){ this.element.classList.toggle("ol-collapsed"); this.ovmap_.updateSize(); this.setView(); }; /** Set overview map position * @param {top|bottom-left|right} */ ol_control_Overview.prototype.setPosition = function(align){ if (/top/.test(align)) this.element.classList.add("ol-control-top"); else this.element.classList.remove("ol-control-top"); if (/right/.test(align)) this.element.classList.add("ol-control-right"); else this.element.classList.remove("ol-control-right"); }; /** * Set the map instance the control associated with. * @param {ol.Map} map The map instance. */ ol_control_Overview.prototype.setMap = function(map) { if (this._listener) ol_Observable_unByKey(this._listener); this._listener = null; ol_control_Control.prototype.setMap.call(this, map); if (map) { this._listener = map.getView().on('propertychange', this.setView.bind(this)); this.setView(); } }; /** Calculate the extent of the map and draw it on the overview */ ol_control_Overview.prototype.calcExtent_ = function(extent){ var map = this.getMap(); if (!map) return; var source = this.extentLayer.getSource(); source.clear(); var f = new ol_Feature(); var size = map.getSize(); var resolution = map.getView().getResolution(); var rotation = map.getView().getRotation(); var center = map.getView().getCenter(); if (!resolution) return; var dx = resolution * size[0] / 2; var dy = resolution * size[1] / 2; var res2 = this.oview_.getResolution(); if (dx/res2>5 || dy/res2>5) { var cos = Math.cos(rotation); var sin = Math.sin(rotation); var i, x, y; extent=[[-dx,-dy],[-dx,dy],[dx,dy],[dx,-dy]]; for (i = 0; i < 4; ++i) { x = extent[i][0]; y = extent[i][1]; extent[i][0] = center[0] + x * cos - y * sin; extent[i][1] = center[1] + x * sin + y * cos; } f.setGeometry (new ol_geom_Polygon( [ extent ])); } else { f.setGeometry (new ol_geom_Point( center )); } source.addFeature(f); }; /** * @private */ ol_control_Overview.prototype.setView = function(e){ if (!e) { // refresh all this.setView({key:'rotation'}); this.setView({key:'resolution'}); this.setView({key:'center'}); return; } // Set the view params switch (e.key){ case 'rotation': { if (this.rotation) this.oview_.setRotation(this.getMap().getView().getRotation()); else if (this.oview_.getRotation()) this.oview_.setRotation(0); break; } case 'center': { var mapExtent = this.getMap().getView().calculateExtent(this.getMap().getSize()); var extent = this.oview_.calculateExtent(this.ovmap_.getSize()); if (mapExtent[0]<extent[0] || mapExtent[1]<extent[1] || mapExtent[2]>extent[2] || mapExtent[3]>extent[3]){ this.oview_.setCenter(this.getMap().getView().getCenter()); } break; } case 'resolution': { //var z = Math.round(this.getMap().getView().getZoom()/2)*2-4; var z = Math.round(this.oview_.getZoomForResolution(this.getMap().getView().getResolution())/2)*2-4; z = Math.min ( this.maxZoom, Math.max(this.minZoom, z) ); this.oview_.setZoom(z); break; } default: break; } this.calcExtent_(); }; export default ol_control_Overview