API Docs for: 0.1.0
Show:

File: src\AbstractOverlay.js

/**
 @module L.PtvLayer
 **/
L.PtvLayer = L.PtvLayer || {};

/**
 Provides the PTV AbstractOverlay Layer class.
 @class L.PtvLayer.AbstractOverlay
 @extends L.ILayer
 @params {Object} options The options object
 @params {String} [options.format] The image format used in tile requests.
 @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.
 @constructor
 **/
L.PtvLayer.AbstractOverlay = L.Class.extend({
  includes: L.Mixin.Events,

  _el1: null,
  _el2: null,
  _elCur: 0,
  _client: null,
  _map: null,
  _requestObject: null,

  /**
   Default options used in this class.
   @property options
   @type Object
   **/
  options: {
    /**
     The image format used in tile requests.
     @property options.format
     @type String
     @default "PNG"
     **/
    format: 'PNG',
	
	/**
     Function to be called before sending the request with the request object given as first parameter. The (modified) request object must be returned.
     @property options.beforeSend
     @type function
     @default null
     **/
    beforeSend: null,

    /**
     The world bounds for PTV Maps.
     @property options.bounds
     @type L.LatLngBounds
     @default [[85.0, -178.965000], [-66.5, 178.965000]]
     **/
    bounds: new L.LatLngBounds([[85.0, -178.965000], [-66.5, 178.965000]])
  },

  /**
   Constructor
   @method L.PtvLayer.AbstractOverlay
   @param {XMapClient} client optional XMapClient object
   @param {Object} options optional options object
   **/
  initialize: function(client, options) {
    this._client = client;
    if (typeof client !== 'object' ) {
      if (typeof XMapClient !== 'function') {
        throw Error('The XMapClient object is not accessible globally. Have you loaded "xmap-client.js" properly?');
      } else {
        this._client = new XMapClient(null, 1);
      }
	}
    L.Util.setOptions(this, options);
  },

  onAdd: function(map) {
    this._map = map;

    // create a DOM element and put it into one of the map panes
    this._el1 = L.DomUtil.create('img', 'leaflet-tile leaflet-zoom-hide');
	this._el2 = L.DomUtil.create('img', 'leaflet-tile leaflet-zoom-hide');
	this._el1.style.cssText = '-webkit-transition: none; -moz-transition: none; -o-transition: opacity 0 linear; transition: none;';
	this._el2.style.cssText = '-webkit-transition: none; -moz-transition: none; -o-transition: opacity 0 linear; transition: none;';
    this._el1.onload = (function(self, el) { return function() { self._setActiveEl.call(self, el); }; })(this, this._el1);
	this._el2.onload = (function(self, el) { return function() { self._setActiveEl.call(self, el); }; })(this, this._el2);

    map.getPanes().overlayPane.appendChild(this._el1);
	map.getPanes().overlayPane.appendChild(this._el2);

    map.on({
      'moveend': this._update
    }, this);

    this._update();
  },

  onRemove: function(map) {
    map.off({
      'moveend': this._update
    }, this);

    map.getPanes().overlayPane.removeChild(this._el1);
	map.getPanes().overlayPane.removeChild(this._el2);
  },
  
  _setActiveEl: function(el) {
	if(el === this._el1) {
		L.DomUtil.addClass(this._el1, 'leaflet-tile-loaded');
		L.DomUtil.removeClass(this._el2, 'leaflet-tile-loaded');
	} else {
		L.DomUtil.addClass(this._el2, 'leaflet-tile-loaded');
		L.DomUtil.removeClass(this._el1, 'leaflet-tile-loaded');
	}
  },

  _update: function() {
    var bounds = this._map.getBounds(), mapSize = this._map.getSize(), el = (!this._elCur ? this._el1 : this._el2);
	this._elCur = (this._elCur + 1) % 2;
	
    if (this._map.getZoom() > this._map.getMaxZoom() || this._map.getZoom() < this._map.getMinZoom()) {
      return;
    }

    if (this.options.bounds) {
      bounds.clip(this.options.bounds);
    }

    if ( typeof this._client.cancelPendingRequests === 'function') {
      this._client.cancelPendingRequests();
    }

    var se = this._map.project(bounds.getSouthEast()), nw = this._map.project(bounds.getNorthWest());

    mapSize.x = Math.max(256, se.x - nw.x);
    mapSize.y = Math.max(256, se.y - nw.y);
    var tileUrl = this._requestTile(bounds, mapSize, el);

    var pos = this._map.latLngToLayerPoint(bounds.getNorthWest());
    L.DomUtil.setPosition(el, pos, false);
  },

  _getRequestObject: function() {
    return {
      mapSection: {
        leftTop: {
          "$type": "Point",
          point: {
            "$type": "PlainPoint",
            x: 0,
            y: 0
          }
        },
        rightBottom: {
          "$type": "Point",
          point: {
            "$type": "PlainPoint",
            x: 0,
            y: 0
          }
        }
      },
      mapParams: {
        showScale: false,
        useMiles: false
      },
      imageInfo: {
        format: '',
        width: 0,
        height: 0
      },
      layers: [],
      includeImageInResponse: true,
      callerContext: {
        properties: [{
          key: "Profile",
          value: ""
        }, {
          "key": "CoordFormat",
          "value": "OG_GEODECIMAL"
        }]
      }
    };
  },

  _requestTile: function(bounds, mapSize, el) {
    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]);

    var req = this._getRequestObject();
    req.mapSection.leftTop.point.x = bbox.getNorthWest().lng;
    req.mapSection.leftTop.point.y = bbox.getNorthWest().lat;
    req.mapSection.rightBottom.point.x = bbox.getSouthEast().lng;
    req.mapSection.rightBottom.point.y = bbox.getSouthEast().lat;
    req.imageInfo.format = this.options.format;
    req.imageInfo.width = mapSize.x;
    req.imageInfo.height = mapSize.y;
	
	if (typeof this.options.beforeSend === "function") {
		req = this.options.beforeSend(req);
	}

    this._client.renderMapBoundingBox(req.mapSection, req.mapParams, req.imageInfo, req.layers, req.includeImageInResponse, req.callerContext, (function(el) {
      return function(resp, error) {
        self._renderMapCallback.call(self, resp, error, el);
      };
    })(el));

    this.fire('loading');
  },

  _renderMapCallback: function(resp, error, el) {
    if (!error) {
      el.src = L.PtvUtils.createDataURI(resp.image.rawImage);
    } else {
      el.src = L.Util.emptyImageUrl;
      console.log(error.errorMessage);
    }
	
    this.fire('load', {
      tile: el,
      url: el.src
    });
  }
});