UNPKG

kmap-ui

Version:

A components of zmap base on vue2.X

281 lines (256 loc) 8.57 kB
/* Copyright (c) 2015 Jean-Marc VIGLINO, released under the CeCILL-B license (French BSD license) (http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt). ol_source_GeoImage is a layer source with georeferencement to place it on a map. olx.source.GeoImageOptions: { url: {string} url of the static image image: {image} the static image, if not provided, use url to load an image imageCenter: {ol.Coordinate} of the center of the image imageScale: {ol.Size|Number} [scalex, scaley] of the image imageRotate: {number} angle of the image in radian, default 0 imageCrop: {ol.Extent} of the image to be show (in the image) default: [0,0,imageWidth,imageHeight] imageMask: {Array.<ol.Coordinate>} - linestring to mask the image on the map } */ import ol_ext_inherits from '../util/ext' import ol_source_ImageCanvas from 'ol/source/ImageCanvas' import ol_geom_Polygon from 'ol/geom/Polygon' import {boundingExtent as ol_extent_boundingExtent} from 'ol/extent' import {fromExtent as ol_geom_Polygon_fromExtent} from 'ol/geom/Polygon' /** Layer source with georeferencement to place it on a map * @constructor * @extends {ol_source_ImageCanvas} * @param {olx.source.GeoImageOptions=} options */ var ol_source_GeoImage = function(opt_options) { var options = { attributions: opt_options.attributions, logo: opt_options.logo, projection: opt_options.projection }; // options.projection = opt_options.projection; // Coordinate of the image center this.center = opt_options.imageCenter; // Scale of the image this.scale = opt_options.imageScale; // Rotation of the image this.rotate = opt_options.imageRotate ? opt_options.imageRotate : 0; // Crop of the image this.crop = opt_options.imageCrop; // Mask of the image this.mask = opt_options.imageMask; // Load Image this._image = (opt_options.image ? opt_options.image : new Image ); this._image.crossOrigin = opt_options.crossOrigin; // 'anonymous'; // Show image on load var self = this; this._image.onload = function() { self.setCrop (self.crop); self.changed(); } if (!opt_options.image) this._image.src = opt_options.url; // Draw image on canvas options.canvasFunction = function(extent, resolution, pixelRatio, size /*, projection*/ ) { var canvas = document.createElement('canvas'); canvas.width = size[0]; canvas.height = size[1]; var ctx = canvas.getContext('2d'); if (!this._imageSize) return canvas; // transform coords to pixel function tr(xy) { return [ (xy[0]-extent[0])/(extent[2]-extent[0]) * size[0], (xy[1]-extent[3])/(extent[1]-extent[3]) * size[1] ]; } // Clipping mask if (this.mask) { ctx.beginPath(); var p = tr(this.mask[0]); ctx.moveTo(p[0],p[1]); for (var i=1; i<this.mask.length; i++) { p = tr(this.mask[i]); ctx.lineTo(p[0],p[1]); } ctx.clip(); } // Draw var pixel = tr(this.center); var dx = (this._image.naturalWidth/2 - this.crop[0]) *this.scale[0] /resolution *pixelRatio; var dy = (this._image.naturalHeight/2 - this.crop[1]) *this.scale[1] /resolution *pixelRatio; var sx = this._imageSize[0]*this.scale[0]/resolution *pixelRatio; var sy = this._imageSize[1]*this.scale[1]/resolution *pixelRatio; ctx.translate(pixel[0],pixel[1]); if (this.rotate) ctx.rotate(this.rotate); ctx.drawImage(this._image, this.crop[0], this.crop[1], this._imageSize[0], this._imageSize[1], -dx, -dy, sx,sy); return canvas; } ol_source_ImageCanvas.call (this, options); this.setCrop (this.crop); // Calculate extent on change this.on('change', function() { this.set('extent', this.calculateExtent()); }.bind(this)); }; ol_ext_inherits(ol_source_GeoImage, ol_source_ImageCanvas); /** * Get coordinate of the image center. * @return {ol.Coordinate} coordinate of the image center. * @api stable */ ol_source_GeoImage.prototype.getCenter = function() { return this.center; } /** * Set coordinate of the image center. * @param {ol.Coordinate} coordinate of the image center. * @api stable */ ol_source_GeoImage.prototype.setCenter = function(center) { this.center = center; this.changed(); } /** * Get image scale. * @return {ol.size} image scale (along x and y axis). * @api stable */ ol_source_GeoImage.prototype.getScale = function() { return this.scale; } /** * Set image scale. * @param {ol.size|Number} image scale (along x and y axis or both). * @api stable */ ol_source_GeoImage.prototype.setScale = function(scale) { switch (typeof(scale)) { case 'number': scale = [scale,scale]; break; case 'object': if (scale.length != 2) return; break; default: return; } this.scale = scale; this.changed(); }; /** * Get image rotation. * @return {Number} rotation in degre. * @api stable */ ol_source_GeoImage.prototype.getRotation = function() { return this.rotate; }; /** * Set image rotation. * @param {Number} rotation in radian. * @api stable */ ol_source_GeoImage.prototype.setRotation = function(angle) { this.rotate = angle; this.changed(); }; /** * Get the image. * @api stable */ ol_source_GeoImage.prototype.getGeoImage = function() { return this._image; }; /** * Get image crop extent. * @return {ol.extent} image crop extent. * @api stable */ ol_source_GeoImage.prototype.getCrop = function() { return this.crop; }; /** * Set image mask. * @param {ol.geom.LineString} coords of the mask * @api stable */ ol_source_GeoImage.prototype.setMask = function(mask) { this.mask = mask; this.changed(); }; /** * Get image mask. * @return {ol.geom.LineString} coords of the mask * @api stable */ ol_source_GeoImage.prototype.getMask = function() { return this.mask; }; /** * Set image crop extent. * @param {ol.extent|Number} image crop extent or a number to crop from original size. * @api stable */ ol_source_GeoImage.prototype.setCrop = function(crop) { // Image not loaded => get it latter if (!this._image.naturalWidth) { this.crop = crop; return; } if (crop) { switch (typeof(crop)) { case 'number': crop = [crop,crop,this._image.naturalWidth-crop,this._image.naturalHeight-crop]; break; case 'object': if (crop.length != 4) return; break; default: return; } crop = ol_extent_boundingExtent([ [crop[0],crop[1]], [crop[2],crop[3]] ]); this.crop = [ Math.max(0,crop[0]), Math.max(0,crop[1]), Math.min(this._image.naturalWidth,crop[2]), Math.min(this._image.naturalHeight,crop[3]) ]; } else this.crop = [0,0, this._image.naturalWidth,this._image.naturalHeight]; if (this.crop[2]<=this.crop[0]) this.crop[2] = this.crop[0]+1; if (this.crop[3]<=this.crop[1]) this.crop[3] = this.crop[1]+1; this._imageSize = [ this.crop[2]-this.crop[0], this.crop[3]-this.crop[1] ]; this.changed(); }; /** Get the extent of the source. * @param {module:ol/extent~Extent} extent If provided, no new extent will be created. Instead, that extent's coordinates will be overwritten. * @return {ol.extent} */ ol_source_GeoImage.prototype.getExtent = function(opt_extent) { if (opt_extent) { var ext = this.get('extent'); for (var i=0; i<opt_extent.length; i++) { opt_extent[i] = ext[i]; } return ext; } else { return this.get('extent'); } }; /** Calculate the extent of the source image. * @param {boolean} usemask return the mask extent, default return the image extent * @return {ol.extent} */ ol_source_GeoImage.prototype.calculateExtent = function(usemask) { var polygon; if (usemask!==false && this.getMask()) { polygon = new ol_geom_Polygon([this.getMask()]) } else { var center = this.getCenter(); var scale = this.getScale(); var width = this.getGeoImage().width * scale[0]; var height = this.getGeoImage().height * scale[1]; var extent = ol_extent_boundingExtent([ [ center[0]-width/2, center[1]-height/2 ], [ center[0]+width/2, center[1]+height/2 ] ]); polygon = ol_geom_Polygon_fromExtent(extent); polygon.rotate(-this.getRotation(), center); } var ext = polygon.getExtent(); return ext; }; export default ol_source_GeoImage