support GeoJSON tiles
This commit is contained in:
parent
b08f63320c
commit
14ec22252d
4 changed files with 122 additions and 123 deletions
|
|
@ -2,6 +2,35 @@
|
|||
* Leaflet.GeoJSONGridLayer
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
function long2tile(lon,zoom) { return (Math.floor((lon+180)/360*Math.pow(2,zoom))); }
|
||||
function lat2tile(lat,zoom) { return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom))); }
|
||||
|
||||
Inverse process:
|
||||
|
||||
function tile2long(x,z) {
|
||||
return (x/Math.pow(2,z)*360-180);
|
||||
}
|
||||
function tile2lat(y,z) {
|
||||
var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
|
||||
return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
|
||||
}
|
||||
|
||||
Example for calculating number of tiles within given extent and zoom-level:
|
||||
|
||||
var zoom = 9;
|
||||
var top_tile = lat2tile(north_edge, zoom); // eg.lat2tile(34.422, 9);
|
||||
var left_tile = lon2tile(west_edge, zoom);
|
||||
var bottom_tile = lat2tile(south_edge, zoom);
|
||||
var right_tile = lon2tile(east_edge, zoom);
|
||||
var width = Math.abs(left_tile - right_tile) + 1;
|
||||
var height = Math.abs(top_tile - bottom_tile) + 1;
|
||||
|
||||
// total tiles
|
||||
var total_tiles = width * height; // -> eg. 377
|
||||
*/
|
||||
|
||||
(function () {
|
||||
|
||||
var console = window.console || {
|
||||
|
|
|
|||
|
|
@ -5,43 +5,41 @@
|
|||
|
||||
includes: L.Evented.prototype,
|
||||
|
||||
url: null,
|
||||
map: null,
|
||||
|
||||
options: {
|
||||
},
|
||||
|
||||
initialize(extraOptions, options) {
|
||||
initialize(url, options) {
|
||||
this.url = url;
|
||||
L.GeoJSON.prototype.initialize.call(this, [], options);
|
||||
L.Util.setOptions(this, extraOptions);
|
||||
},
|
||||
|
||||
_reload: function() {
|
||||
reloadMap: function() {
|
||||
if (this.map) {
|
||||
var url = this._expand(this.options.url);
|
||||
this._ajax('GET', url, false, this._update.bind(this));
|
||||
var url = this.expandUrl(this.url);
|
||||
this.ajaxRequest('GET', url, false, this.updateLayers.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
_update: function(geoData) {
|
||||
updateLayers: function(geoData) {
|
||||
this.clearLayers();
|
||||
this.addData(geoData);
|
||||
},
|
||||
|
||||
onAdd: function(map) {
|
||||
onAdd(map) {
|
||||
L.GeoJSON.prototype.onAdd.call(this, map);
|
||||
this.map = map;
|
||||
map.on('moveend zoomend refresh', this._reload, this);
|
||||
this._reload();
|
||||
map.on('moveend zoomend refresh', this.reloadMap, this);
|
||||
this.reloadMap();
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
map.off('moveend zoomend refresh', this._reload, this);
|
||||
onRemove(map) {
|
||||
map.off('moveend zoomend refresh', this.reloadMap, this);
|
||||
this.map = null;
|
||||
L.GeoJSON.prototype.onRemove.call(this, map);
|
||||
},
|
||||
|
||||
_expand: function(template) {
|
||||
var bbox = this._map.getBounds();
|
||||
expandUrl: function(template) {
|
||||
var bbox = this.map.getBounds();
|
||||
var southWest = bbox.getSouthWest();
|
||||
var northEast = bbox.getNorthEast();
|
||||
var bboxStr = bbox.toBBoxString();
|
||||
|
|
@ -55,7 +53,7 @@
|
|||
return L.Util.template(template, coords);
|
||||
},
|
||||
|
||||
_ajax: function(method, url, data, callback) {
|
||||
ajaxRequest: function(method, url, data, callback) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open(method, url, true);
|
||||
request.onreadystatechange = function() {
|
||||
|
|
@ -74,8 +72,8 @@
|
|||
|
||||
});
|
||||
|
||||
L.geoJSONLayer = function (options) {
|
||||
return new L.GeoJSONLayer(options);
|
||||
L.geoJSONLayer = function (url, options) {
|
||||
return new L.GeoJSONLayer(url, options);
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
@ -1,114 +1,86 @@
|
|||
/* global L */
|
||||
(function() {
|
||||
|
||||
L.GeoJSONTileLayer = L.GeoJSON.extend({
|
||||
L.GeoJSONTileLayer = L.GridLayer.extend({
|
||||
|
||||
includes: L.Evented.prototype,
|
||||
|
||||
includes: L.Evented.prototype,
|
||||
url: null,
|
||||
layer: null,
|
||||
features: null,
|
||||
|
||||
map: null,
|
||||
initialize(url, options) {
|
||||
this.url = url;
|
||||
this.layer = new L.GeoJSON(null, options);
|
||||
this.features = {};
|
||||
L.GridLayer.prototype.initialize.call(this, options);
|
||||
},
|
||||
|
||||
options: {
|
||||
},
|
||||
createTile: function (coords) {
|
||||
var tile = L.DomUtil.create('div', 'leaflet-tile');
|
||||
var url = L.Util.template(this.url, coords);
|
||||
this.ajaxRequest('GET', url, false, this.updateLayers.bind(this));
|
||||
return tile;
|
||||
},
|
||||
|
||||
initialize(extraOptions, options) {
|
||||
L.GeoJSON.prototype.initialize.call(this, [], options);
|
||||
L.Util.setOptions(this, extraOptions);
|
||||
},
|
||||
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;
|
||||
},
|
||||
|
||||
updateLayers: function(geoData) {
|
||||
this.layer.clearLayers();
|
||||
this.layer.addData(geoData);
|
||||
},
|
||||
|
||||
/*
|
||||
function long2tile(lon,zoom) { return (Math.floor((lon+180)/360*Math.pow(2,zoom))); }
|
||||
function lat2tile(lat,zoom) { return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom))); }
|
||||
onAdd(map) {
|
||||
L.GridLayer.prototype.onAdd.call(this, map);
|
||||
map.addLayer(this.layer);
|
||||
this.map = map;
|
||||
//map.on('moveend zoomend refresh', this.reloadMap, this);
|
||||
//this.reloadMap();
|
||||
},
|
||||
|
||||
Inverse process:
|
||||
onRemove(map) {
|
||||
//map.off('moveend zoomend refresh', this.reloadMap, this);
|
||||
this.map = null;
|
||||
map.removeLayer(this.layer)
|
||||
L.GridLayer.prototype.onRemove.call(this, map);
|
||||
},
|
||||
|
||||
function tile2long(x,z) {
|
||||
return (x/Math.pow(2,z)*360-180);
|
||||
}
|
||||
function tile2lat(y,z) {
|
||||
var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
|
||||
return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
|
||||
}
|
||||
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;
|
||||
},
|
||||
|
||||
Example for calculating number of tiles within given extent and zoom-level:
|
||||
});
|
||||
|
||||
var zoom = 9;
|
||||
var top_tile = lat2tile(north_edge, zoom); // eg.lat2tile(34.422, 9);
|
||||
var left_tile = lon2tile(west_edge, zoom);
|
||||
var bottom_tile = lat2tile(south_edge, zoom);
|
||||
var right_tile = lon2tile(east_edge, zoom);
|
||||
var width = Math.abs(left_tile - right_tile) + 1;
|
||||
var height = Math.abs(top_tile - bottom_tile) + 1;
|
||||
|
||||
// total tiles
|
||||
var total_tiles = width * height; // -> eg. 377
|
||||
*/
|
||||
|
||||
_reload: function() {
|
||||
if (this.map) {
|
||||
var urls = this._expand(this.options.url);
|
||||
for (var i=0; i<urls.length; i++) {
|
||||
this._ajax('GET', urls[i], false, this._update.bind(this));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
_update: function(geoData) {
|
||||
this.clearLayers();
|
||||
this.addData(geoData);
|
||||
},
|
||||
|
||||
onAdd: function(map) {
|
||||
L.GeoJSON.prototype.onAdd.call(this, map);
|
||||
this.map = map;
|
||||
map.on('moveend zoomend refresh', this._reload, this);
|
||||
this._reload();
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
map.off('moveend zoomend refresh', this._reload, this);
|
||||
this.map = null;
|
||||
L.GeoJSON.prototype.onRemove.call(this, map);
|
||||
},
|
||||
|
||||
_expand: function(template) {
|
||||
var bbox = this._map.getBounds();
|
||||
var southWest = bbox.getSouthWest();
|
||||
var northEast = bbox.getNorthEast();
|
||||
var bboxStr = bbox.toBBoxString();
|
||||
var coords = {
|
||||
lat1: southWest.lat,
|
||||
lon1: southWest.lng,
|
||||
lat2: northEast.lat,
|
||||
lon2: northEast.lng,
|
||||
bbox: bboxStr
|
||||
};
|
||||
return [L.Util.template(template, coords)];
|
||||
},
|
||||
|
||||
_ajax: 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;
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
L.geoJSONTileLayer = function (options) {
|
||||
return new L.GeoJSONTileLayer(options);
|
||||
};
|
||||
L.geoJSONTileLayer = function (options) {
|
||||
return new L.GeoJSONTileLayer(options);
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
|
@ -19,12 +19,12 @@
|
|||
<script>
|
||||
var mymap = L.map('mapid').setView([20, 30], 3);
|
||||
|
||||
L.tileLayer('https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
|
||||
maxZoom: 18,
|
||||
}).addTo(mymap);
|
||||
//L.tileLayer('https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
|
||||
// maxZoom: 18,
|
||||
//}).addTo(mymap);
|
||||
|
||||
//L.geoJSONLayer({
|
||||
// url: "http://localhost:8000/api.php/geojson/countries/1,2?bbox={bbox}",
|
||||
//L.geoJSONLayer('http://localhost:8000/api.php/geojson/countries/1,2?bbox={bbox}', {
|
||||
// maxZoom: 18,
|
||||
//}).addTo(mymap);
|
||||
|
||||
L.geoJSONTileLayer('http://localhost:8000/api.php/geojson/countries/1,2?tile={z},{y},{x}', {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue