src\AbstractOverlay.js - leaflet.ptv

API Docs for: 0.1.0
Show:

File: src\AbstractOverlay.js

  1. /**
  2. @module L.PtvLayer
  3. **/
  4. L.PtvLayer = L.PtvLayer || {};
  5.  
  6. /**
  7. Provides the PTV AbstractOverlay Layer class.
  8. @class L.PtvLayer.AbstractOverlay
  9. @extends L.ILayer
  10. @params {Object} options The options object
  11. @params {String} [options.format] The image format used in tile requests.
  12. @params {String} [options.beforeSend] Function to be called before sending the request with the request object given as first parameter. The (modified) request object must be returned.
  13. @constructor
  14. **/
  15. L.PtvLayer.AbstractOverlay = L.Class.extend({
  16. includes: L.Mixin.Events,
  17.  
  18. _el1: null,
  19. _el2: null,
  20. _elCur: 0,
  21. _client: null,
  22. _map: null,
  23. _requestObject: null,
  24.  
  25. /**
  26. Default options used in this class.
  27. @property options
  28. @type Object
  29. **/
  30. options: {
  31. /**
  32. The image format used in tile requests.
  33. @property options.format
  34. @type String
  35. @default "PNG"
  36. **/
  37. format: 'PNG',
  38. /**
  39. Function to be called before sending the request with the request object given as first parameter. The (modified) request object must be returned.
  40. @property options.beforeSend
  41. @type function
  42. @default null
  43. **/
  44. beforeSend: null,
  45.  
  46. /**
  47. The world bounds for PTV Maps.
  48. @property options.bounds
  49. @type L.LatLngBounds
  50. @default [[85.0, -178.965000], [-66.5, 178.965000]]
  51. **/
  52. bounds: new L.LatLngBounds([[85.0, -178.965000], [-66.5, 178.965000]])
  53. },
  54.  
  55. /**
  56. Constructor
  57. @method L.PtvLayer.AbstractOverlay
  58. @param {XMapClient} client optional XMapClient object
  59. @param {Object} options optional options object
  60. **/
  61. initialize: function(client, options) {
  62. this._client = client;
  63. if (typeof client !== 'object' ) {
  64. if (typeof XMapClient !== 'function') {
  65. throw Error('The XMapClient object is not accessible globally. Have you loaded "xmap-client.js" properly?');
  66. } else {
  67. this._client = new XMapClient(null, 1);
  68. }
  69. }
  70. L.Util.setOptions(this, options);
  71. },
  72.  
  73. onAdd: function(map) {
  74. this._map = map;
  75.  
  76. // create a DOM element and put it into one of the map panes
  77. this._el1 = L.DomUtil.create('img', 'leaflet-tile leaflet-zoom-hide');
  78. this._el2 = L.DomUtil.create('img', 'leaflet-tile leaflet-zoom-hide');
  79. this._el1.style.cssText = '-webkit-transition: none; -moz-transition: none; -o-transition: opacity 0 linear; transition: none;';
  80. this._el2.style.cssText = '-webkit-transition: none; -moz-transition: none; -o-transition: opacity 0 linear; transition: none;';
  81. this._el1.onload = (function(self, el) { return function() { self._setActiveEl.call(self, el); }; })(this, this._el1);
  82. this._el2.onload = (function(self, el) { return function() { self._setActiveEl.call(self, el); }; })(this, this._el2);
  83.  
  84. map.getPanes().overlayPane.appendChild(this._el1);
  85. map.getPanes().overlayPane.appendChild(this._el2);
  86.  
  87. map.on({
  88. 'moveend': this._update
  89. }, this);
  90.  
  91. this._update();
  92. },
  93.  
  94. onRemove: function(map) {
  95. map.off({
  96. 'moveend': this._update
  97. }, this);
  98.  
  99. map.getPanes().overlayPane.removeChild(this._el1);
  100. map.getPanes().overlayPane.removeChild(this._el2);
  101. },
  102. _setActiveEl: function(el) {
  103. if(el === this._el1) {
  104. L.DomUtil.addClass(this._el1, 'leaflet-tile-loaded');
  105. L.DomUtil.removeClass(this._el2, 'leaflet-tile-loaded');
  106. } else {
  107. L.DomUtil.addClass(this._el2, 'leaflet-tile-loaded');
  108. L.DomUtil.removeClass(this._el1, 'leaflet-tile-loaded');
  109. }
  110. },
  111.  
  112. _update: function() {
  113. var bounds = this._map.getBounds(), mapSize = this._map.getSize(), el = (!this._elCur ? this._el1 : this._el2);
  114. this._elCur = (this._elCur + 1) % 2;
  115. if (this._map.getZoom() > this._map.getMaxZoom() || this._map.getZoom() < this._map.getMinZoom()) {
  116. return;
  117. }
  118.  
  119. if (this.options.bounds) {
  120. bounds.clip(this.options.bounds);
  121. }
  122.  
  123. if ( typeof this._client.cancelPendingRequests === 'function') {
  124. this._client.cancelPendingRequests();
  125. }
  126.  
  127. var se = this._map.project(bounds.getSouthEast()), nw = this._map.project(bounds.getNorthWest());
  128.  
  129. mapSize.x = Math.max(256, se.x - nw.x);
  130. mapSize.y = Math.max(256, se.y - nw.y);
  131. var tileUrl = this._requestTile(bounds, mapSize, el);
  132.  
  133. var pos = this._map.latLngToLayerPoint(bounds.getNorthWest());
  134. L.DomUtil.setPosition(el, pos, false);
  135. },
  136.  
  137. _getRequestObject: function() {
  138. return {
  139. mapSection: {
  140. leftTop: {
  141. "$type": "Point",
  142. point: {
  143. "$type": "PlainPoint",
  144. x: 0,
  145. y: 0
  146. }
  147. },
  148. rightBottom: {
  149. "$type": "Point",
  150. point: {
  151. "$type": "PlainPoint",
  152. x: 0,
  153. y: 0
  154. }
  155. }
  156. },
  157. mapParams: {
  158. showScale: false,
  159. useMiles: false
  160. },
  161. imageInfo: {
  162. format: '',
  163. width: 0,
  164. height: 0
  165. },
  166. layers: [],
  167. includeImageInResponse: true,
  168. callerContext: {
  169. properties: [{
  170. key: "Profile",
  171. value: ""
  172. }, {
  173. "key": "CoordFormat",
  174. "value": "OG_GEODECIMAL"
  175. }]
  176. }
  177. };
  178. },
  179.  
  180. _requestTile: function(bounds, mapSize, el) {
  181. var self = this, map = this._map, crs = map.options.crs, nw = crs.project(bounds.getNorthWest()), se = crs.project(bounds.getSouthEast()), bbox = new L.LatLngBounds([se.y, nw.x], [nw.y, se.x]);
  182.  
  183. var req = this._getRequestObject();
  184. req.mapSection.leftTop.point.x = bbox.getNorthWest().lng;
  185. req.mapSection.leftTop.point.y = bbox.getNorthWest().lat;
  186. req.mapSection.rightBottom.point.x = bbox.getSouthEast().lng;
  187. req.mapSection.rightBottom.point.y = bbox.getSouthEast().lat;
  188. req.imageInfo.format = this.options.format;
  189. req.imageInfo.width = mapSize.x;
  190. req.imageInfo.height = mapSize.y;
  191. if (typeof this.options.beforeSend === "function") {
  192. req = this.options.beforeSend(req);
  193. }
  194.  
  195. this._client.renderMapBoundingBox(req.mapSection, req.mapParams, req.imageInfo, req.layers, req.includeImageInResponse, req.callerContext, (function(el) {
  196. return function(resp, error) {
  197. self._renderMapCallback.call(self, resp, error, el);
  198. };
  199. })(el));
  200.  
  201. this.fire('loading');
  202. },
  203.  
  204. _renderMapCallback: function(resp, error, el) {
  205. if (!error) {
  206. el.src = L.PtvUtils.createDataURI(resp.image.rawImage);
  207. } else {
  208. el.src = L.Util.emptyImageUrl;
  209. console.log(error.errorMessage);
  210. }
  211. this.fire('load', {
  212. tile: el,
  213. url: el.src
  214. });
  215. }
  216. });
  217.