Installed leaflet in extlib
This commit is contained in:
464
extlib/leaflet/src/map/Map.js
Normal file
464
extlib/leaflet/src/map/Map.js
Normal file
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
* L.Map is the central class of the API - it is used to create a map.
|
||||
*/
|
||||
|
||||
L.Map = L.Class.extend({
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
// projection
|
||||
crs: L.CRS.EPSG3857 || L.CRS.EPSG4326,
|
||||
scale: function(zoom) { return 256 * (1 << zoom); },
|
||||
|
||||
// state
|
||||
center: null,
|
||||
zoom: null,
|
||||
layers: [],
|
||||
|
||||
// interaction
|
||||
dragging: true,
|
||||
touchZoom: L.Browser.mobileWebkit && !L.Browser.android,
|
||||
scrollWheelZoom: !L.Browser.mobileWebkit,
|
||||
doubleClickZoom: true,
|
||||
shiftDragZoom: true,
|
||||
|
||||
// controls
|
||||
zoomControl: true,
|
||||
attributionControl: true,
|
||||
|
||||
// animation
|
||||
fadeAnimation: L.DomUtil.TRANSITION && !L.Browser.android,
|
||||
zoomAnimation: L.DomUtil.TRANSITION && !L.Browser.android && !L.Browser.mobileOpera,
|
||||
|
||||
// misc
|
||||
trackResize: true,
|
||||
closePopupOnClick: true
|
||||
},
|
||||
|
||||
|
||||
// constructor
|
||||
|
||||
initialize: function(/*HTMLElement or String*/ id, /*Object*/ options) {
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
this._container = L.DomUtil.get(id);
|
||||
|
||||
this._initLayout();
|
||||
|
||||
if (L.DomEvent) {
|
||||
this._initEvents();
|
||||
if (L.Handler) { this._initInteraction(); }
|
||||
if (L.Control) { this._initControls(); }
|
||||
}
|
||||
|
||||
var center = this.options.center,
|
||||
zoom = this.options.zoom;
|
||||
|
||||
if (center !== null && zoom !== null) {
|
||||
this.setView(center, zoom, true);
|
||||
}
|
||||
|
||||
var layers = this.options.layers;
|
||||
layers = (layers instanceof Array ? layers : [layers]);
|
||||
this._tileLayersNum = 0;
|
||||
this._initLayers(layers);
|
||||
},
|
||||
|
||||
|
||||
// public methods that modify map state
|
||||
|
||||
// replaced by animation-powered implementation in Map.PanAnimation.js
|
||||
setView: function(center, zoom, forceReset) {
|
||||
// reset the map view
|
||||
this._resetView(center, this._limitZoom(zoom));
|
||||
return this;
|
||||
},
|
||||
|
||||
setZoom: function(/*Number*/ zoom) {
|
||||
return this.setView(this.getCenter(), zoom);
|
||||
},
|
||||
|
||||
zoomIn: function() {
|
||||
return this.setZoom(this._zoom + 1);
|
||||
},
|
||||
|
||||
zoomOut: function() {
|
||||
return this.setZoom(this._zoom - 1);
|
||||
},
|
||||
|
||||
fitBounds: function(/*LatLngBounds*/ bounds) {
|
||||
var zoom = this.getBoundsZoom(bounds);
|
||||
return this.setView(bounds.getCenter(), zoom);
|
||||
},
|
||||
|
||||
fitWorld: function() {
|
||||
var sw = new L.LatLng(-60, -170),
|
||||
ne = new L.LatLng(85, 179);
|
||||
return this.fitBounds(new L.LatLngBounds(sw, ne));
|
||||
},
|
||||
|
||||
panTo: function(/*LatLng*/ center) {
|
||||
return this.setView(center, this._zoom);
|
||||
},
|
||||
|
||||
panBy: function(/*Point*/ offset) {
|
||||
// replaced with animated panBy in Map.Animation.js
|
||||
this.fire('movestart');
|
||||
|
||||
this._rawPanBy(offset);
|
||||
|
||||
this.fire('move');
|
||||
this.fire('moveend');
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
addLayer: function(layer) {
|
||||
var id = L.Util.stamp(layer);
|
||||
|
||||
if (this._layers[id]) return this;
|
||||
|
||||
this._layers[id] = layer;
|
||||
|
||||
if (layer.options && !isNaN(layer.options.maxZoom)) {
|
||||
this._layersMaxZoom = Math.max(this._layersMaxZoom || 0, layer.options.maxZoom);
|
||||
}
|
||||
if (layer.options && !isNaN(layer.options.minZoom)) {
|
||||
this._layersMinZoom = Math.min(this._layersMinZoom || Infinity, layer.options.minZoom);
|
||||
}
|
||||
//TODO getMaxZoom, getMinZoom in ILayer (instead of options)
|
||||
|
||||
if (this.options.zoomAnimation && L.TileLayer && (layer instanceof L.TileLayer)) {
|
||||
this._tileLayersNum++;
|
||||
layer.on('load', this._onTileLayerLoad, this);
|
||||
}
|
||||
if (this.attributionControl && layer.getAttribution) {
|
||||
this.attributionControl.addAttribution(layer.getAttribution());
|
||||
}
|
||||
|
||||
var onMapLoad = function() {
|
||||
layer.onAdd(this);
|
||||
this.fire('layeradd', {layer: layer});
|
||||
};
|
||||
|
||||
if (this._loaded) {
|
||||
onMapLoad.call(this);
|
||||
} else {
|
||||
this.on('load', onMapLoad, this);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
removeLayer: function(layer) {
|
||||
var id = L.Util.stamp(layer);
|
||||
|
||||
if (this._layers[id]) {
|
||||
layer.onRemove(this);
|
||||
delete this._layers[id];
|
||||
|
||||
if (this.options.zoomAnimation && L.TileLayer && (layer instanceof L.TileLayer)) {
|
||||
this._tileLayersNum--;
|
||||
layer.off('load', this._onTileLayerLoad, this);
|
||||
}
|
||||
if (this.attributionControl && layer.getAttribution) {
|
||||
this.attributionControl.removeAttribution(layer.getAttribution());
|
||||
}
|
||||
|
||||
this.fire('layerremove', {layer: layer});
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
invalidateSize: function() {
|
||||
this._sizeChanged = true;
|
||||
|
||||
this.fire('move');
|
||||
|
||||
clearTimeout(this._sizeTimer);
|
||||
this._sizeTimer = setTimeout(L.Util.bind(function() {
|
||||
this.fire('moveend');
|
||||
}, this), 200);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
// public methods for getting map state
|
||||
|
||||
getCenter: function(/*Boolean*/ unbounded) {
|
||||
var viewHalf = this.getSize().divideBy(2),
|
||||
centerPoint = this._getTopLeftPoint().add(viewHalf);
|
||||
return this.unproject(centerPoint, this._zoom, unbounded);
|
||||
},
|
||||
|
||||
getZoom: function() {
|
||||
return this._zoom;
|
||||
},
|
||||
|
||||
getBounds: function() {
|
||||
var bounds = this.getPixelBounds(),
|
||||
sw = this.unproject(new L.Point(bounds.min.x, bounds.max.y)),
|
||||
ne = this.unproject(new L.Point(bounds.max.x, bounds.min.y));
|
||||
return new L.LatLngBounds(sw, ne);
|
||||
},
|
||||
|
||||
getMinZoom: function() {
|
||||
return isNaN(this.options.minZoom) ? this._layersMinZoom || 0 : this.options.minZoom;
|
||||
},
|
||||
|
||||
getMaxZoom: function() {
|
||||
return isNaN(this.options.maxZoom) ? this._layersMaxZoom || Infinity : this.options.maxZoom;
|
||||
},
|
||||
|
||||
getBoundsZoom: function(/*LatLngBounds*/ bounds) {
|
||||
var size = this.getSize(),
|
||||
zoom = this.getMinZoom(),
|
||||
maxZoom = this.getMaxZoom(),
|
||||
ne = bounds.getNorthEast(),
|
||||
sw = bounds.getSouthWest(),
|
||||
boundsSize,
|
||||
nePoint, swPoint;
|
||||
do {
|
||||
zoom++;
|
||||
nePoint = this.project(ne, zoom);
|
||||
swPoint = this.project(sw, zoom);
|
||||
boundsSize = new L.Point(nePoint.x - swPoint.x, swPoint.y - nePoint.y);
|
||||
} while ((boundsSize.x <= size.x) &&
|
||||
(boundsSize.y <= size.y) && (zoom <= maxZoom));
|
||||
|
||||
return zoom - 1;
|
||||
},
|
||||
|
||||
getSize: function() {
|
||||
if (!this._size || this._sizeChanged) {
|
||||
this._size = new L.Point(this._container.clientWidth, this._container.clientHeight);
|
||||
this._sizeChanged = false;
|
||||
}
|
||||
return this._size;
|
||||
},
|
||||
|
||||
getPixelBounds: function() {
|
||||
var topLeftPoint = this._getTopLeftPoint(),
|
||||
size = this.getSize();
|
||||
return new L.Bounds(topLeftPoint, topLeftPoint.add(size));
|
||||
},
|
||||
|
||||
getPixelOrigin: function() {
|
||||
return this._initialTopLeftPoint;
|
||||
},
|
||||
|
||||
getPanes: function() {
|
||||
return this._panes;
|
||||
},
|
||||
|
||||
|
||||
// conversion methods
|
||||
|
||||
mouseEventToContainerPoint: function(/*MouseEvent*/ e) {
|
||||
return L.DomEvent.getMousePosition(e, this._container);
|
||||
},
|
||||
|
||||
mouseEventToLayerPoint: function(/*MouseEvent*/ e) {
|
||||
return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e));
|
||||
},
|
||||
|
||||
mouseEventToLatLng: function(/*MouseEvent*/ e) {
|
||||
return this.layerPointToLatLng(this.mouseEventToLayerPoint(e));
|
||||
},
|
||||
|
||||
containerPointToLayerPoint: function(/*Point*/ point) {
|
||||
return point.subtract(L.DomUtil.getPosition(this._mapPane));
|
||||
},
|
||||
|
||||
layerPointToContainerPoint: function(/*Point*/ point) {
|
||||
return point.add(L.DomUtil.getPosition(this._mapPane));
|
||||
},
|
||||
|
||||
layerPointToLatLng: function(/*Point*/ point) {
|
||||
return this.unproject(point.add(this._initialTopLeftPoint));
|
||||
},
|
||||
|
||||
latLngToLayerPoint: function(/*LatLng*/ latlng) {
|
||||
return this.project(latlng)._subtract(this._initialTopLeftPoint);
|
||||
},
|
||||
|
||||
project: function(/*LatLng*/ latlng, /*(optional) Number*/ zoom)/*-> Point*/ {
|
||||
zoom = (typeof zoom == 'undefined' ? this._zoom : zoom);
|
||||
return this.options.crs.latLngToPoint(latlng, this.options.scale(zoom));
|
||||
},
|
||||
|
||||
unproject: function(/*Point*/ point, /*(optional) Number*/ zoom, /*(optional) Boolean*/ unbounded)/*-> Object*/ {
|
||||
zoom = (typeof zoom == 'undefined' ? this._zoom : zoom);
|
||||
return this.options.crs.pointToLatLng(point, this.options.scale(zoom), unbounded);
|
||||
},
|
||||
|
||||
|
||||
// private methods that modify map state
|
||||
|
||||
_initLayout: function() {
|
||||
var container = this._container;
|
||||
|
||||
container.className += ' leaflet-container';
|
||||
|
||||
if (this.options.fadeAnimation) {
|
||||
container.className += ' leaflet-fade-anim';
|
||||
}
|
||||
|
||||
var position = L.DomUtil.getStyle(container, 'position');
|
||||
if (position != 'absolute' && position != 'relative') {
|
||||
container.style.position = 'relative';
|
||||
}
|
||||
|
||||
this._initPanes();
|
||||
|
||||
if (this._initControlPos) this._initControlPos();
|
||||
},
|
||||
|
||||
_initPanes: function() {
|
||||
var panes = this._panes = {};
|
||||
|
||||
this._mapPane = panes.mapPane = this._createPane('leaflet-map-pane', this._container);
|
||||
|
||||
this._tilePane = panes.tilePane = this._createPane('leaflet-tile-pane', this._mapPane);
|
||||
this._objectsPane = panes.objectsPane = this._createPane('leaflet-objects-pane', this._mapPane);
|
||||
|
||||
panes.shadowPane = this._createPane('leaflet-shadow-pane');
|
||||
panes.overlayPane = this._createPane('leaflet-overlay-pane');
|
||||
panes.markerPane = this._createPane('leaflet-marker-pane');
|
||||
panes.popupPane = this._createPane('leaflet-popup-pane');
|
||||
},
|
||||
|
||||
_createPane: function(className, container) {
|
||||
return L.DomUtil.create('div', className, container || this._objectsPane);
|
||||
},
|
||||
|
||||
_resetView: function(center, zoom, preserveMapOffset) {
|
||||
var zoomChanged = (this._zoom != zoom);
|
||||
|
||||
this.fire('movestart');
|
||||
|
||||
this._zoom = zoom;
|
||||
|
||||
this._initialTopLeftPoint = this._getNewTopLeftPoint(center);
|
||||
|
||||
if (!preserveMapOffset) {
|
||||
L.DomUtil.setPosition(this._mapPane, new L.Point(0, 0));
|
||||
} else {
|
||||
var offset = L.DomUtil.getPosition(this._mapPane);
|
||||
this._initialTopLeftPoint._add(offset);
|
||||
}
|
||||
|
||||
this._tileLayersToLoad = this._tileLayersNum;
|
||||
this.fire('viewreset');
|
||||
|
||||
this.fire('move');
|
||||
if (zoomChanged) { this.fire('zoomend'); }
|
||||
this.fire('moveend');
|
||||
|
||||
if (!this._loaded) {
|
||||
this._loaded = true;
|
||||
this.fire('load');
|
||||
}
|
||||
},
|
||||
|
||||
_initLayers: function(layers) {
|
||||
this._layers = {};
|
||||
for (var i = 0, len = layers.length; i < len; i++) {
|
||||
this.addLayer(layers[i]);
|
||||
}
|
||||
},
|
||||
|
||||
_initControls: function() {
|
||||
if (this.options.zoomControl) {
|
||||
this.addControl(new L.Control.Zoom());
|
||||
}
|
||||
if (this.options.attributionControl) {
|
||||
this.attributionControl = new L.Control.Attribution();
|
||||
this.addControl(this.attributionControl);
|
||||
}
|
||||
},
|
||||
|
||||
_rawPanBy: function(offset) {
|
||||
var mapPaneOffset = L.DomUtil.getPosition(this._mapPane);
|
||||
L.DomUtil.setPosition(this._mapPane, mapPaneOffset.subtract(offset));
|
||||
},
|
||||
|
||||
|
||||
// map events
|
||||
|
||||
_initEvents: function() {
|
||||
L.DomEvent.addListener(this._container, 'click', this._onMouseClick, this);
|
||||
|
||||
var events = ['dblclick', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove'];
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
L.DomEvent.addListener(this._container, events[i], this._fireMouseEvent, this);
|
||||
}
|
||||
|
||||
if (this.options.trackResize) {
|
||||
L.DomEvent.addListener(window, 'resize', this.invalidateSize, this);
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseClick: function(e) {
|
||||
if (this.dragging && this.dragging.moved()) { return; }
|
||||
|
||||
this.fire('pre' + e.type);
|
||||
this._fireMouseEvent(e);
|
||||
},
|
||||
|
||||
_fireMouseEvent: function(e) {
|
||||
var type = e.type;
|
||||
type = (type == 'mouseenter' ? 'mouseover' : (type == 'mouseleave' ? 'mouseout' : type));
|
||||
if (!this.hasEventListeners(type)) { return; }
|
||||
this.fire(type, {
|
||||
latlng: this.mouseEventToLatLng(e),
|
||||
layerPoint: this.mouseEventToLayerPoint(e)
|
||||
});
|
||||
},
|
||||
|
||||
_initInteraction: function() {
|
||||
var handlers = {
|
||||
dragging: L.Handler.MapDrag,
|
||||
touchZoom: L.Handler.TouchZoom,
|
||||
doubleClickZoom: L.Handler.DoubleClickZoom,
|
||||
scrollWheelZoom: L.Handler.ScrollWheelZoom,
|
||||
shiftDragZoom: L.Handler.ShiftDragZoom
|
||||
};
|
||||
for (var i in handlers) {
|
||||
if (handlers.hasOwnProperty(i) && handlers[i]) {
|
||||
this[i] = new handlers[i](this);
|
||||
if (this.options[i]) this[i].enable();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onTileLayerLoad: function() {
|
||||
// clear scaled tiles after all new tiles are loaded (for performance)
|
||||
this._tileLayersToLoad--;
|
||||
if (this._tileLayersNum && !this._tileLayersToLoad && this._tileBg) {
|
||||
clearTimeout(this._clearTileBgTimer);
|
||||
this._clearTileBgTimer = setTimeout(L.Util.bind(this._clearTileBg, this), 500);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// private methods for getting map state
|
||||
|
||||
_getTopLeftPoint: function() {
|
||||
if (!this._loaded) throw new Error('Set map center and zoom first.');
|
||||
var offset = L.DomUtil.getPosition(this._mapPane);
|
||||
return this._initialTopLeftPoint.subtract(offset);
|
||||
},
|
||||
|
||||
_getNewTopLeftPoint: function(center) {
|
||||
var viewHalf = this.getSize().divideBy(2);
|
||||
return this.project(center).subtract(viewHalf).round();
|
||||
},
|
||||
|
||||
_limitZoom: function(zoom) {
|
||||
var min = this.getMinZoom();
|
||||
var max = this.getMaxZoom();
|
||||
return Math.max(min, Math.min(max, zoom));
|
||||
}
|
||||
});
|
||||
50
extlib/leaflet/src/map/ext/Map.Control.js
Normal file
50
extlib/leaflet/src/map/ext/Map.Control.js
Normal file
@@ -0,0 +1,50 @@
|
||||
L.Map.include({
|
||||
addControl: function(control) {
|
||||
control.onAdd(this);
|
||||
|
||||
var pos = control.getPosition(),
|
||||
corner = this._controlCorners[pos],
|
||||
container = control.getContainer();
|
||||
|
||||
L.DomUtil.addClass(container, 'leaflet-control');
|
||||
|
||||
if (pos.indexOf('bottom') != -1) {
|
||||
corner.insertBefore(container, corner.firstChild);
|
||||
} else {
|
||||
corner.appendChild(container);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
removeControl: function(control) {
|
||||
var pos = control.getPosition(),
|
||||
corner = this._controlCorners[pos],
|
||||
container = control.getContainer();
|
||||
|
||||
corner.removeChild(container);
|
||||
|
||||
if (control.onRemove) {
|
||||
control.onRemove(this);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
_initControlPos: function() {
|
||||
var corners = this._controlCorners = {},
|
||||
classPart = 'leaflet-',
|
||||
top = classPart + 'top',
|
||||
bottom = classPart + 'bottom',
|
||||
left = classPart + 'left',
|
||||
right = classPart + 'right',
|
||||
controlContainer = L.DomUtil.create('div', classPart + 'control-container', this._container);
|
||||
|
||||
if (L.Browser.mobileWebkit) {
|
||||
controlContainer.className += ' ' + classPart + 'big-buttons';
|
||||
}
|
||||
|
||||
corners.topLeft = L.DomUtil.create('div', top + ' ' + left, controlContainer);
|
||||
corners.topRight = L.DomUtil.create('div', top + ' ' + right, controlContainer);
|
||||
corners.bottomLeft = L.DomUtil.create('div', bottom + ' ' + left, controlContainer);
|
||||
corners.bottomRight = L.DomUtil.create('div', bottom + ' ' + right, controlContainer);
|
||||
}
|
||||
});
|
||||
69
extlib/leaflet/src/map/ext/Map.Geolocation.js
Normal file
69
extlib/leaflet/src/map/ext/Map.Geolocation.js
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Provides L.Map with convenient shortcuts for W3C geolocation.
|
||||
*/
|
||||
|
||||
L.Map.include({
|
||||
locate: function(/*Object*/ options) {
|
||||
// W3C Geolocation API Spec position options, http://dev.w3.org/geo/api/spec-source.html#position-options
|
||||
var opts = {timeout: 10000};
|
||||
L.Util.extend(opts, options);
|
||||
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
L.Util.bind(this._handleGeolocationResponse, this),
|
||||
L.Util.bind(this._handleGeolocationError, this),
|
||||
opts);
|
||||
} else {
|
||||
this.fire('locationerror', {
|
||||
code: 0,
|
||||
message: "Geolocation not supported."
|
||||
});
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
locateAndSetView: function(maxZoom, options) {
|
||||
this._setViewOnLocate = true;
|
||||
this._maxLocateZoom = maxZoom || Infinity;
|
||||
return this.locate(options);
|
||||
},
|
||||
|
||||
_handleGeolocationError: function(error) {
|
||||
var c = error.code,
|
||||
message = (c == 1 ? "permission denied" :
|
||||
(c == 2 ? "position unavailable" : "timeout"));
|
||||
|
||||
if (this._setViewOnLocate) {
|
||||
this.fitWorld();
|
||||
this._setViewOnLocate = false;
|
||||
}
|
||||
|
||||
this.fire('locationerror', {
|
||||
code: c,
|
||||
message: "Geolocation error: " + message + "."
|
||||
});
|
||||
},
|
||||
|
||||
_handleGeolocationResponse: function(pos) {
|
||||
var latAccuracy = 180 * pos.coords.accuracy / 4e7,
|
||||
lngAccuracy = latAccuracy * 2,
|
||||
lat = pos.coords.latitude,
|
||||
lng = pos.coords.longitude;
|
||||
|
||||
var sw = new L.LatLng(lat - latAccuracy, lng - lngAccuracy),
|
||||
ne = new L.LatLng(lat + latAccuracy, lng + lngAccuracy),
|
||||
bounds = new L.LatLngBounds(sw, ne);
|
||||
|
||||
if (this._setViewOnLocate) {
|
||||
var zoom = Math.min(this.getBoundsZoom(bounds), this._maxLocateZoom);
|
||||
this.setView(bounds.getCenter(), zoom);
|
||||
this._setViewOnLocate = false;
|
||||
}
|
||||
|
||||
this.fire('locationfound', {
|
||||
latlng: new L.LatLng(lat, lng),
|
||||
bounds: bounds,
|
||||
accuracy: pos.coords.accuracy
|
||||
});
|
||||
}
|
||||
});
|
||||
62
extlib/leaflet/src/map/ext/Map.PanAnimation.js
Normal file
62
extlib/leaflet/src/map/ext/Map.PanAnimation.js
Normal file
@@ -0,0 +1,62 @@
|
||||
L.Map.include(!(L.Transition && L.Transition.implemented()) ? {} : {
|
||||
setView: function(center, zoom, forceReset) {
|
||||
zoom = this._limitZoom(zoom);
|
||||
var zoomChanged = (this._zoom != zoom);
|
||||
|
||||
if (this._loaded && !forceReset && this._layers) {
|
||||
// difference between the new and current centers in pixels
|
||||
var offset = this._getNewTopLeftPoint(center).subtract(this._getTopLeftPoint());
|
||||
|
||||
var done = (zoomChanged ?
|
||||
!!this._zoomToIfCenterInView && this._zoomToIfCenterInView(center, zoom, offset) :
|
||||
this._panByIfClose(offset));
|
||||
|
||||
// exit if animated pan or zoom started
|
||||
if (done) { return this; }
|
||||
}
|
||||
|
||||
// reset the map view
|
||||
this._resetView(center, zoom);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
panBy: function(offset) {
|
||||
if (!this._panTransition) {
|
||||
this._panTransition = new L.Transition(this._mapPane, {duration: 0.3});
|
||||
|
||||
this._panTransition.on('step', this._onPanTransitionStep, this);
|
||||
this._panTransition.on('end', this._onPanTransitionEnd, this);
|
||||
}
|
||||
this.fire(this, 'movestart');
|
||||
|
||||
this._panTransition.run({
|
||||
position: L.DomUtil.getPosition(this._mapPane).subtract(offset)
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_onPanTransitionStep: function() {
|
||||
this.fire('move');
|
||||
},
|
||||
|
||||
_onPanTransitionEnd: function() {
|
||||
this.fire('moveend');
|
||||
},
|
||||
|
||||
_panByIfClose: function(offset) {
|
||||
if (this._offsetIsWithinView(offset)) {
|
||||
this.panBy(offset);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_offsetIsWithinView: function(offset, multiplyFactor) {
|
||||
var m = multiplyFactor || 1,
|
||||
size = this.getSize();
|
||||
return (Math.abs(offset.x) <= size.x * m) &&
|
||||
(Math.abs(offset.y) <= size.y * m);
|
||||
}
|
||||
});
|
||||
15
extlib/leaflet/src/map/ext/Map.Popup.js
Normal file
15
extlib/leaflet/src/map/ext/Map.Popup.js
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
L.Map.include({
|
||||
openPopup: function(popup) {
|
||||
this.closePopup();
|
||||
this._popup = popup;
|
||||
return this.addLayer(popup);
|
||||
},
|
||||
|
||||
closePopup: function() {
|
||||
if (this._popup) {
|
||||
this.removeLayer(this._popup);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
124
extlib/leaflet/src/map/ext/Map.ZoomAnimation.js
Normal file
124
extlib/leaflet/src/map/ext/Map.ZoomAnimation.js
Normal file
@@ -0,0 +1,124 @@
|
||||
L.Map.include(!L.DomUtil.TRANSITION ? {} : {
|
||||
_zoomToIfCenterInView: function(center, zoom, centerOffset) {
|
||||
|
||||
if (this._animatingZoom) { return true; }
|
||||
if (!this.options.zoomAnimation) { return false; }
|
||||
|
||||
var zoomDelta = zoom - this._zoom,
|
||||
scale = Math.pow(2, zoomDelta),
|
||||
offset = centerOffset.divideBy(1 - 1/scale);
|
||||
|
||||
//if offset does not exceed half of the view
|
||||
if (!this._offsetIsWithinView(offset, 1)) { return false; }
|
||||
|
||||
this._mapPane.className += ' leaflet-zoom-anim';
|
||||
|
||||
var centerPoint = this.containerPointToLayerPoint(this.getSize().divideBy(2)),
|
||||
origin = centerPoint.add(offset);
|
||||
|
||||
this._prepareTileBg();
|
||||
|
||||
this._runAnimation(center, zoom, scale, origin);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
_runAnimation: function(center, zoom, scale, origin) {
|
||||
this._animatingZoom = true;
|
||||
|
||||
this._animateToCenter = center;
|
||||
this._animateToZoom = zoom;
|
||||
|
||||
var transform = L.DomUtil.TRANSFORM;
|
||||
|
||||
//dumb FireFox hack, I have no idea why this magic zero translate fixes the scale transition problem
|
||||
if (L.Browser.gecko || window.opera) {
|
||||
this._tileBg.style[transform] += ' translate(0,0)';
|
||||
}
|
||||
|
||||
var scaleStr;
|
||||
|
||||
// Android doesn't like translate/scale chains, transformOrigin + scale works better but
|
||||
// it breaks touch zoom which Anroid doesn't support anyway, so that's a really ugly hack
|
||||
// TODO work around this prettier
|
||||
if (L.Browser.android) {
|
||||
this._tileBg.style[transform + 'Origin'] = origin.x + 'px ' + origin.y + 'px';
|
||||
scaleStr = 'scale(' + scale + ')';
|
||||
} else {
|
||||
scaleStr = L.DomUtil.getScaleString(scale, origin);
|
||||
}
|
||||
|
||||
L.Util.falseFn(this._tileBg.offsetWidth); //hack to make sure transform is updated before running animation
|
||||
|
||||
var options = {};
|
||||
options[transform] = this._tileBg.style[transform] + ' ' + scaleStr;
|
||||
this._tileBg.transition.run(options);
|
||||
},
|
||||
|
||||
_prepareTileBg: function() {
|
||||
if (!this._tileBg) {
|
||||
this._tileBg = this._createPane('leaflet-tile-pane', this._mapPane);
|
||||
this._tileBg.style.zIndex = 1;
|
||||
}
|
||||
|
||||
var tilePane = this._tilePane,
|
||||
tileBg = this._tileBg;
|
||||
|
||||
// prepare the background pane to become the main tile pane
|
||||
//tileBg.innerHTML = '';
|
||||
tileBg.style[L.DomUtil.TRANSFORM] = '';
|
||||
tileBg.style.visibility = 'hidden';
|
||||
|
||||
// tells tile layers to reinitialize their containers
|
||||
tileBg.empty = true;
|
||||
tilePane.empty = false;
|
||||
|
||||
this._tilePane = this._panes.tilePane = tileBg;
|
||||
this._tileBg = tilePane;
|
||||
|
||||
if (!this._tileBg.transition) {
|
||||
this._tileBg.transition = new L.Transition(this._tileBg, {duration: 0.3, easing: 'cubic-bezier(0.25,0.1,0.25,0.75)'});
|
||||
this._tileBg.transition.on('end', this._onZoomTransitionEnd, this);
|
||||
}
|
||||
|
||||
this._stopLoadingBgTiles();
|
||||
},
|
||||
|
||||
// stops loading all tiles in the background layer
|
||||
_stopLoadingBgTiles: function() {
|
||||
var tiles = [].slice.call(this._tileBg.getElementsByTagName('img'));
|
||||
|
||||
for (var i = 0, len = tiles.length; i < len; i++) {
|
||||
if (!tiles[i].complete) {
|
||||
tiles[i].src = '';
|
||||
tiles[i].parentNode.removeChild(tiles[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onZoomTransitionEnd: function() {
|
||||
this._restoreTileFront();
|
||||
|
||||
L.Util.falseFn(this._tileBg.offsetWidth);
|
||||
this._resetView(this._animateToCenter, this._animateToZoom, true);
|
||||
|
||||
//TODO clear tileBg on map layersload
|
||||
|
||||
this._mapPane.className = this._mapPane.className.replace(' leaflet-zoom-anim', ''); //TODO toggleClass util
|
||||
this._animatingZoom = false;
|
||||
},
|
||||
|
||||
_restoreTileFront: function() {
|
||||
this._tilePane.innerHTML = '';
|
||||
this._tilePane.style.visibility = '';
|
||||
this._tilePane.style.zIndex = 2;
|
||||
this._tileBg.style.zIndex = 1;
|
||||
},
|
||||
|
||||
_clearTileBg: function() {
|
||||
if (!this._animatingZoom && !this.touchZoom._zooming) {
|
||||
this._tileBg.innerHTML = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user