New file |
| | |
| | | /* eslint-disable */ |
| | | let L = window.L |
| | | (function (factory) { |
| | | var L, proj4; |
| | | if (typeof define === 'function' && define.amd) { |
| | | // AMD |
| | | define(['leaflet', 'proj4'], factory); |
| | | } else if (typeof module === 'object' && typeof module.exports === "object") { |
| | | // Node/CommonJS |
| | | L = require('leaflet'); |
| | | proj4 = require('proj4'); |
| | | module.exports = factory(L, proj4); |
| | | } else { |
| | | // Browser globals |
| | | if (typeof window.L === 'undefined' || typeof window.proj4 === 'undefined') |
| | | throw 'Leaflet and proj4 must be loaded first'; |
| | | factory(window.L, window.proj4); |
| | | } |
| | | }(function (L, proj4) { |
| | | if (proj4.__esModule && proj4.default) { |
| | | // If proj4 was bundled as an ES6 module, unwrap it to get |
| | | // to the actual main proj4 object. |
| | | // See discussion in https://github.com/kartena/Proj4Leaflet/pull/147 |
| | | proj4 = proj4.default; |
| | | } |
| | | |
| | | L.Proj = {}; |
| | | |
| | | L.Proj._isProj4Obj = function(a) { |
| | | return (typeof a.inverse !== 'undefined' && |
| | | typeof a.forward !== 'undefined'); |
| | | }; |
| | | |
| | | L.Proj.Projection = L.Class.extend({ |
| | | initialize: function(code, def, bounds) { |
| | | var isP4 = L.Proj._isProj4Obj(code); |
| | | this._proj = isP4 ? code : this._projFromCodeDef(code, def); |
| | | this.bounds = isP4 ? def : bounds; |
| | | }, |
| | | |
| | | project: function (latlng) { |
| | | var point = this._proj.forward([latlng.lng, latlng.lat]); |
| | | return new L.Point(point[0], point[1]); |
| | | }, |
| | | |
| | | unproject: function (point, unbounded) { |
| | | var point2 = this._proj.inverse([point.x, point.y]); |
| | | return new L.LatLng(point2[1], point2[0], unbounded); |
| | | }, |
| | | |
| | | _projFromCodeDef: function(code, def) { |
| | | if (def) { |
| | | proj4.defs(code, def); |
| | | } else if (proj4.defs[code] === undefined) { |
| | | var urn = code.split(':'); |
| | | if (urn.length > 3) { |
| | | code = urn[urn.length - 3] + ':' + urn[urn.length - 1]; |
| | | } |
| | | if (proj4.defs[code] === undefined) { |
| | | throw 'No projection definition for code ' + code; |
| | | } |
| | | } |
| | | |
| | | return proj4(code); |
| | | } |
| | | }); |
| | | |
| | | L.Proj.CRS = L.Class.extend({ |
| | | includes: L.CRS, |
| | | |
| | | options: { |
| | | transformation: new L.Transformation(1, 0, -1, 0) |
| | | }, |
| | | |
| | | initialize: function(a, b, c) { |
| | | var code, |
| | | proj, |
| | | def, |
| | | options; |
| | | |
| | | if (L.Proj._isProj4Obj(a)) { |
| | | proj = a; |
| | | code = proj.srsCode; |
| | | options = b || {}; |
| | | |
| | | this.projection = new L.Proj.Projection(proj, options.bounds); |
| | | } else { |
| | | code = a; |
| | | def = b; |
| | | options = c || {}; |
| | | this.projection = new L.Proj.Projection(code, def, options.bounds); |
| | | } |
| | | |
| | | L.Util.setOptions(this, options); |
| | | this.code = code; |
| | | this.transformation = this.options.transformation; |
| | | |
| | | if (this.options.origin) { |
| | | this.transformation = |
| | | new L.Transformation(1, -this.options.origin[0], |
| | | -1, this.options.origin[1]); |
| | | } |
| | | |
| | | if (this.options.scales) { |
| | | this._scales = this.options.scales; |
| | | } else if (this.options.resolutions) { |
| | | this._scales = []; |
| | | for (var i = this.options.resolutions.length - 1; i >= 0; i--) { |
| | | if (this.options.resolutions[i]) { |
| | | this._scales[i] = 1 / this.options.resolutions[i]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | this.infinite = !this.options.bounds; |
| | | |
| | | }, |
| | | |
| | | scale: function(zoom) { |
| | | var iZoom = Math.floor(zoom), |
| | | baseScale, |
| | | nextScale, |
| | | scaleDiff, |
| | | zDiff; |
| | | if (zoom === iZoom) { |
| | | return this._scales[zoom]; |
| | | } else { |
| | | // Non-integer zoom, interpolate |
| | | baseScale = this._scales[iZoom]; |
| | | nextScale = this._scales[iZoom + 1]; |
| | | scaleDiff = nextScale - baseScale; |
| | | zDiff = (zoom - iZoom); |
| | | return baseScale + scaleDiff * zDiff; |
| | | } |
| | | }, |
| | | |
| | | zoom: function(scale) { |
| | | // Find closest number in this._scales, down |
| | | var downScale = this._closestElement(this._scales, scale), |
| | | downZoom = this._scales.indexOf(downScale), |
| | | nextScale, |
| | | nextZoom, |
| | | scaleDiff; |
| | | // Check if scale is downScale => return array index |
| | | if (scale === downScale) { |
| | | return downZoom; |
| | | } |
| | | if (downScale === undefined) { |
| | | return -Infinity; |
| | | } |
| | | // Interpolate |
| | | nextZoom = downZoom + 1; |
| | | nextScale = this._scales[nextZoom]; |
| | | if (nextScale === undefined) { |
| | | return Infinity; |
| | | } |
| | | scaleDiff = nextScale - downScale; |
| | | return (scale - downScale) / scaleDiff + downZoom; |
| | | }, |
| | | |
| | | distance: L.CRS.Earth.distance, |
| | | |
| | | R: L.CRS.Earth.R, |
| | | |
| | | /* Get the closest lowest element in an array */ |
| | | _closestElement: function(array, element) { |
| | | var low; |
| | | for (var i = array.length; i--;) { |
| | | if (array[i] <= element && (low === undefined || low < array[i])) { |
| | | low = array[i]; |
| | | } |
| | | } |
| | | return low; |
| | | } |
| | | }); |
| | | |
| | | L.Proj.GeoJSON = L.GeoJSON.extend({ |
| | | initialize: function(geojson, options) { |
| | | this._callLevel = 0; |
| | | L.GeoJSON.prototype.initialize.call(this, geojson, options); |
| | | }, |
| | | |
| | | addData: function(geojson) { |
| | | var crs; |
| | | |
| | | if (geojson) { |
| | | if (geojson.crs && geojson.crs.type === 'name') { |
| | | crs = new L.Proj.CRS(geojson.crs.properties.name); |
| | | } else if (geojson.crs && geojson.crs.type) { |
| | | crs = new L.Proj.CRS(geojson.crs.type + ':' + geojson.crs.properties.code); |
| | | } |
| | | |
| | | if (crs !== undefined) { |
| | | this.options.coordsToLatLng = function(coords) { |
| | | var point = L.point(coords[0], coords[1]); |
| | | return crs.projection.unproject(point); |
| | | }; |
| | | } |
| | | } |
| | | |
| | | // Base class' addData might call us recursively, but |
| | | // CRS shouldn't be cleared in that case, since CRS applies |
| | | // to the whole GeoJSON, inluding sub-features. |
| | | this._callLevel++; |
| | | try { |
| | | L.GeoJSON.prototype.addData.call(this, geojson); |
| | | } finally { |
| | | this._callLevel--; |
| | | if (this._callLevel === 0) { |
| | | delete this.options.coordsToLatLng; |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | |
| | | L.Proj.geoJson = function(geojson, options) { |
| | | return new L.Proj.GeoJSON(geojson, options); |
| | | }; |
| | | |
| | | L.Proj.ImageOverlay = L.ImageOverlay.extend({ |
| | | initialize: function (url, bounds, options) { |
| | | L.ImageOverlay.prototype.initialize.call(this, url, null, options); |
| | | this._projectedBounds = bounds; |
| | | }, |
| | | |
| | | // Danger ahead: Overriding internal methods in Leaflet. |
| | | // Decided to do this rather than making a copy of L.ImageOverlay |
| | | // and doing very tiny modifications to it. |
| | | // Future will tell if this was wise or not. |
| | | _animateZoom: function (event) { |
| | | var scale = this._map.getZoomScale(event.zoom); |
| | | var northWest = L.point(this._projectedBounds.min.x, this._projectedBounds.max.y); |
| | | var offset = this._projectedToNewLayerPoint(northWest, event.zoom, event.center); |
| | | |
| | | L.DomUtil.setTransform(this._image, offset, scale); |
| | | }, |
| | | |
| | | _reset: function () { |
| | | var zoom = this._map.getZoom(); |
| | | var pixelOrigin = this._map.getPixelOrigin(); |
| | | var bounds = L.bounds( |
| | | this._transform(this._projectedBounds.min, zoom)._subtract(pixelOrigin), |
| | | this._transform(this._projectedBounds.max, zoom)._subtract(pixelOrigin) |
| | | ); |
| | | var size = bounds.getSize(); |
| | | |
| | | L.DomUtil.setPosition(this._image, bounds.min); |
| | | this._image.style.width = size.x + 'px'; |
| | | this._image.style.height = size.y + 'px'; |
| | | }, |
| | | |
| | | _projectedToNewLayerPoint: function (point, zoom, center) { |
| | | var viewHalf = this._map.getSize()._divideBy(2); |
| | | var newTopLeft = this._map.project(center, zoom)._subtract(viewHalf)._round(); |
| | | var topLeft = newTopLeft.add(this._map._getMapPanePos()); |
| | | |
| | | return this._transform(point, zoom)._subtract(topLeft); |
| | | }, |
| | | |
| | | _transform: function (point, zoom) { |
| | | var crs = this._map.options.crs; |
| | | var transformation = crs.transformation; |
| | | var scale = crs.scale(zoom); |
| | | |
| | | return transformation.transform(point, scale); |
| | | } |
| | | }); |
| | | |
| | | L.Proj.imageOverlay = function (url, bounds, options) { |
| | | return new L.Proj.ImageOverlay(url, bounds, options); |
| | | }; |
| | | |
| | | return L.Proj; |
| | | })); |