Advertisement
Guest User

Untitled

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