1(function (factory) { 2 var L, proj4; 3 if (typeof define === 'function' && define.amd) { 4 // AMD 5 define(['leaflet', 'proj4'], factory); 6 } else if (typeof module === 'object' && typeof module.exports === "object") { 7 // Node/CommonJS 8 L = require('leaflet'); 9 proj4 = require('proj4'); 10 module.exports = factory(L, proj4); 11 } else { 12 // Browser globals 13 if (typeof window.L === 'undefined' || typeof window.proj4 === 'undefined') 14 throw 'Leaflet and proj4 must be loaded first'; 15 factory(window.L, window.proj4); 16 } 17}(function (L, proj4) { 18 19 L.Proj = {}; 20 21 L.Proj._isProj4Obj = function(a) { 22 return (typeof a.inverse !== 'undefined' && 23 typeof a.forward !== 'undefined'); 24 }; 25 26 L.Proj.Projection = L.Class.extend({ 27 initialize: function(code, def, bounds) { 28 var isP4 = L.Proj._isProj4Obj(code); 29 this._proj = isP4 ? code : this._projFromCodeDef(code, def); 30 this.bounds = isP4 ? def : bounds; 31 }, 32 33 project: function (latlng) { 34 var point = this._proj.forward([latlng.lng, latlng.lat]); 35 return new L.Point(point[0], point[1]); 36 }, 37 38 unproject: function (point, unbounded) { 39 var point2 = this._proj.inverse([point.x, point.y]); 40 return new L.LatLng(point2[1], point2[0], unbounded); 41 }, 42 43 _projFromCodeDef: function(code, def) { 44 if (def) { 45 proj4.defs(code, def); 46 } else if (proj4.defs[code] === undefined) { 47 var urn = code.split(':'); 48 if (urn.length > 3) { 49 code = urn[urn.length - 3] + ':' + urn[urn.length - 1]; 50 } 51 if (proj4.defs[code] === undefined) { 52 throw 'No projection definition for code ' + code; 53 } 54 } 55 56 return proj4(code); 57 } 58 }); 59 60 L.Proj.CRS = L.Class.extend({ 61 includes: L.CRS, 62 63 options: { 64 transformation: new L.Transformation(1, 0, -1, 0) 65 }, 66 67 initialize: function(a, b, c) { 68 var code, 69 proj, 70 def, 71 options; 72 73 if (L.Proj._isProj4Obj(a)) { 74 proj = a; 75 code = proj.srsCode; 76 options = b || {}; 77 78 this.projection = new L.Proj.Projection(proj, options.bounds); 79 } else { 80 code = a; 81 def = b; 82 options = c || {}; 83 this.projection = new L.Proj.Projection(code, def, options.bounds); 84 } 85 86 L.Util.setOptions(this, options); 87 this.code = code; 88 this.transformation = this.options.transformation; 89 90 if (this.options.origin) { 91 this.transformation = 92 new L.Transformation(1, -this.options.origin[0], 93 -1, this.options.origin[1]); 94 } 95 96 if (this.options.scales) { 97 this._scales = this.options.scales; 98 } else if (this.options.resolutions) { 99 this._scales = []; 100 for (var i = this.options.resolutions.length - 1; i >= 0; i--) { 101 if (this.options.resolutions[i]) { 102 this._scales[i] = 1 / this.options.resolutions[i]; 103 } 104 } 105 } 106 107 this.infinite = !this.options.bounds; 108 109 }, 110 111 scale: function(zoom) { 112 var iZoom = Math.floor(zoom), 113 baseScale, 114 nextScale, 115 scaleDiff, 116 zDiff; 117 if (zoom === iZoom) { 118 return this._scales[zoom]; 119 } else { 120 // Non-integer zoom, interpolate 121 baseScale = this._scales[iZoom]; 122 nextScale = this._scales[iZoom + 1]; 123 scaleDiff = nextScale - baseScale; 124 zDiff = (zoom - iZoom); 125 return baseScale + scaleDiff * zDiff; 126 } 127 }, 128 129 zoom: function(scale) { 130 // Find closest number in this._scales, down 131 var downScale = this._closestElement(this._scales, scale), 132 downZoom = this._scales.indexOf(downScale), 133 nextScale, 134 nextZoom, 135 scaleDiff; 136 // Check if scale is downScale => return array index 137 if (scale === downScale) { 138 return downZoom; 139 } 140 // Interpolate 141 nextZoom = downZoom + 1; 142 nextScale = this._scales[nextZoom]; 143 if (nextScale === undefined) { 144 return Infinity; 145 } 146 scaleDiff = nextScale - downScale; 147 return (scale - downScale) / scaleDiff + downZoom; 148 }, 149 150 distance: L.CRS.Earth.distance, 151 152 R: L.CRS.Earth.R, 153 154 /* Get the closest lowest element in an array */ 155 _closestElement: function(array, element) { 156 var low; 157 for (var i = array.length; i--;) { 158 if (array[i] <= element && (low === undefined || low < array[i])) { 159 low = array[i]; 160 } 161 } 162 return low; 163 } 164 }); 165 166 L.Proj.GeoJSON = L.GeoJSON.extend({ 167 initialize: function(geojson, options) { 168 this._callLevel = 0; 169 L.GeoJSON.prototype.initialize.call(this, geojson, options); 170 }, 171 172 addData: function(geojson) { 173 var crs; 174 175 if (geojson) { 176 if (geojson.crs && geojson.crs.type === 'name') { 177 crs = new L.Proj.CRS(geojson.crs.properties.name); 178 } else if (geojson.crs && geojson.crs.type) { 179 crs = new L.Proj.CRS(geojson.crs.type + ':' + geojson.crs.properties.code); 180 } 181 182 if (crs !== undefined) { 183 this.options.coordsToLatLng = function(coords) { 184 var point = L.point(coords[0], coords[1]); 185 return crs.projection.unproject(point); 186 }; 187 } 188 } 189 190 // Base class' addData might call us recursively, but 191 // CRS shouldn't be cleared in that case, since CRS applies 192 // to the whole GeoJSON, inluding sub-features. 193 this._callLevel++; 194 try { 195 L.GeoJSON.prototype.addData.call(this, geojson); 196 } finally { 197 this._callLevel--; 198 if (this._callLevel === 0) { 199 delete this.options.coordsToLatLng; 200 } 201 } 202 } 203 }); 204 205 L.Proj.geoJson = function(geojson, options) { 206 return new L.Proj.GeoJSON(geojson, options); 207 }; 208 209 L.Proj.ImageOverlay = L.ImageOverlay.extend({ 210 initialize: function (url, bounds, options) { 211 L.ImageOverlay.prototype.initialize.call(this, url, null, options); 212 this._projectedBounds = bounds; 213 }, 214 215 // Danger ahead: Overriding internal methods in Leaflet. 216 // Decided to do this rather than making a copy of L.ImageOverlay 217 // and doing very tiny modifications to it. 218 // Future will tell if this was wise or not. 219 _animateZoom: function (event) { 220 var scale = this._map.getZoomScale(event.zoom); 221 var northWest = L.point(this._projectedBounds.min.x, this._projectedBounds.max.y); 222 var offset = this._projectedToNewLayerPoint(northWest, event.zoom, event.center); 223 224 L.DomUtil.setTransform(this._image, offset, scale); 225 }, 226 227 _reset: function () { 228 var zoom = this._map.getZoom(); 229 var pixelOrigin = this._map.getPixelOrigin(); 230 var bounds = L.bounds( 231 this._transform(this._projectedBounds.min, zoom)._subtract(pixelOrigin), 232 this._transform(this._projectedBounds.max, zoom)._subtract(pixelOrigin) 233 ); 234 var size = bounds.getSize(); 235 236 L.DomUtil.setPosition(this._image, bounds.min); 237 this._image.style.width = size.x + 'px'; 238 this._image.style.height = size.y + 'px'; 239 }, 240 241 _projectedToNewLayerPoint: function (point, zoom, center) { 242 var viewHalf = this._map.getSize()._divideBy(2); 243 var newTopLeft = this._map.project(center, zoom)._subtract(viewHalf)._round(); 244 var topLeft = newTopLeft.add(this._map._getMapPanePos()); 245 246 return this._transform(point, zoom)._subtract(topLeft); 247 }, 248 249 _transform: function (point, zoom) { 250 var crs = this._map.options.crs; 251 var transformation = crs.transformation; 252 var scale = crs.scale(zoom); 253 254 return transformation.transform(point, scale); 255 } 256 }); 257 258 L.Proj.imageOverlay = function (url, bounds, options) { 259 return new L.Proj.ImageOverlay(url, bounds, options); 260 }; 261 262 return L.Proj; 263}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.