123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /* global L */
- (function() {
-
- L.GeoJSONTileLayer = L.GridLayer.extend({
-
- includes: L.Evented.prototype,
-
- url: null,
- map: null,
- layer: null,
- features: null,
- cache: null,
-
- //
- // Leaflet layer methods
- //
- initialize(url, options) {
- this.url = url;
- this.layer = new L.GeoJSON(null, options);
- this.features = {};
- this.cache = {};
- L.GridLayer.prototype.initialize.call(this, options);
- },
-
- createTile(coords, done) {
- var tile = L.DomUtil.create('div', 'leaflet-tile');
- tile.style['box-shadow'] = 'inset 0 0 2px #f00';
- var url = this._expandUrl(this.url, coords);
- if (this.cache[coords]) {
- done.call(this);
- } else {
- this._ajaxRequest('GET', url, false, this._updateCache.bind(this, done, coords));
- }
- return tile;
- },
-
- onAdd(map) {
- L.GridLayer.prototype.onAdd.call(this, map);
- map.addLayer(this.layer);
- this.map = map;
- map.on('zoomanim', this._onZoomAnim.bind(this));
- this.on('loading', this._onLoading.bind(this));
- this.on('tileload', this._onTileLoad.bind(this));
- this.on('tileunload', this._onTileUnLoad.bind(this));
- },
-
- onRemove(map) {
- this.off('tileunload', this._onTileUnLoad.bind(this));
- this.off('tileload', this._onTileLoad.bind(this));
- this.off('loading', this._onLoading.bind(this));
- map.off('zoomanim', this._onZoomAnim.bind(this));
- this.map = null;
- map.removeLayer(this.layer)
- L.GridLayer.prototype.onRemove.call(this, map);
- },
-
- //
- // Custom methods
- //
- _expandUrl: function(template, coords) {
- return L.Util.template(template, coords);
- },
-
- _updateTiles: function() {
- this.layer.clearLayers();
- this.features = {};
- for (var coords in this.cache) {
- if (this.cache.hasOwnProperty(coords)) {
- this._drawTile(coords);
- }
- }
- },
-
- _drawTile(coords) {
- var geoData = this.cache[coords];
- if (geoData.type == 'FeatureCollection'){
- geoData = geoData.features;
- }
- for (var i=0;i<geoData.length;i++) {
- var id = geoData[i].id;
- if (!this.features[id]) {
- this.layer.addData(geoData[i]);
- this.features[id] = true;
- }
- }
- if (!this.cache[coords]) {
- this.cache[coords] = geoData;
- }
- },
-
- _updateCache: function(done, coords, geoData) {
- this.cache[coords] = geoData;
- done.call(this);
- },
-
- _ajaxRequest: function(method, url, data, callback) {
- var request = new XMLHttpRequest();
- request.open(method, url, true);
- request.onreadystatechange = function() {
- if (request.readyState === 4 && request.status === 200) {
- callback(JSON.parse(request.responseText));
- }
- };
- if (data) {
- request.setRequestHeader('Content-type', 'application/json');
- request.send(JSON.stringify(data));
- } else {
- request.send();
- }
- return request;
- },
-
- _onZoomAnim: function (e) {
- var zoom = e.zoom;
- if ((this.options.maxZoom && zoom > this.options.maxZoom) ||
- (this.options.minZoom && zoom < this.options.minZoom)) {
- this.map.removeLayer(this.layer);
- this.cache = {};
- this.layer.clearLayers();
- } else {
- this._updateTiles();
- this.map.addLayer(this.layer);
- }
- },
-
- _onLoading: function (e) {
- this._updateTiles();
- },
-
- _onTileLoad: function (e) {
- this._drawTile(e.coords);
- },
-
- _onTileUnLoad: function (e) {
- delete this.cache[e.coords]
- },
-
- });
-
- L.geoJSONTileLayer = function (url, options) {
- return new L.GeoJSONTileLayer(url, options);
- };
-
- })();
|