more global refactoring
This commit is contained in:
parent
0474023675
commit
e5f934e97f
@ -11,16 +11,25 @@ L.Control.Attribution = L.Control.extend({
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
this._map = map;
|
||||
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-attribution');
|
||||
L.DomEvent.disableClickPropagation(this._container);
|
||||
|
||||
map
|
||||
.on('layeradd', this._onLayerAdd, this)
|
||||
.on('layerremove', this._onLayerRemove, this);
|
||||
|
||||
this._update();
|
||||
|
||||
return this._container;
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
map
|
||||
.off('layeradd', this._onLayerAdd)
|
||||
.off('layerremove', this._onLayerRemove);
|
||||
|
||||
},
|
||||
|
||||
setPrefix: function (prefix) {
|
||||
this.options.prefix = prefix;
|
||||
this._update();
|
||||
@ -65,5 +74,27 @@ L.Control.Attribution = L.Control.extend({
|
||||
}
|
||||
|
||||
this._container.innerHTML = prefixAndAttribs.join(' — ');
|
||||
},
|
||||
|
||||
_onLayerAdd: function (e) {
|
||||
if (e.layer.getAttribution) {
|
||||
this.addAttribution(e.layer.getAttribution());
|
||||
}
|
||||
},
|
||||
|
||||
_onLayerRemove: function (e) {
|
||||
if (e.layer.getAttribution) {
|
||||
this.removeAttribution(e.layer.getAttribution());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.mergeOptions({
|
||||
attributionControl: true
|
||||
});
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
if (this.options.attributionControl) {
|
||||
this.attributionControl = (new L.Control.Attribution()).addTo(this);
|
||||
}
|
||||
});
|
@ -6,7 +6,7 @@ L.Control.Zoom = L.Control.extend({
|
||||
onAdd: function (map) {
|
||||
var className = 'leaflet-control-zoom',
|
||||
container = L.DomUtil.create('div', className);
|
||||
|
||||
|
||||
this._createButton('Zoom in', className + '-in', container, map.zoomIn, map);
|
||||
this._createButton('Zoom out', className + '-out', container, map.zoomOut, map);
|
||||
|
||||
@ -26,3 +26,14 @@ L.Control.Zoom = L.Control.extend({
|
||||
return link;
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.mergeOptions({
|
||||
zoomControl: true
|
||||
});
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
if (this.options.zoomControl) {
|
||||
this.zoomControl = new L.Control.Zoom();
|
||||
this.addControl(this.zoomControl);
|
||||
}
|
||||
});
|
@ -16,9 +16,10 @@ L.Util = {
|
||||
return dest;
|
||||
},
|
||||
|
||||
bind: function (/*Function*/ fn, /*Object*/ obj) /*-> Object*/ {
|
||||
bind: function (fn, obj) { // (Function, Object) -> Function
|
||||
var args = Array.prototype.slice.call(arguments, 2);
|
||||
return function () {
|
||||
return fn.apply(obj, arguments);
|
||||
return fn.apply(obj, args || arguments);
|
||||
};
|
||||
},
|
||||
|
||||
@ -101,6 +102,7 @@ L.Util = {
|
||||
|
||||
setOptions: function (obj, options) {
|
||||
obj.options = L.Util.extend({}, obj.options, options);
|
||||
return obj.options;
|
||||
},
|
||||
|
||||
getParamString: function (obj) {
|
||||
|
@ -3,6 +3,7 @@ L.CRS.EPSG3395 = L.Util.extend({}, L.CRS, {
|
||||
code: 'EPSG:3395',
|
||||
|
||||
projection: L.Projection.Mercator,
|
||||
|
||||
transformation: (function () {
|
||||
var m = L.Projection.Mercator,
|
||||
r = m.R_MAJOR,
|
||||
|
@ -5,7 +5,7 @@ L.CRS.EPSG3857 = L.Util.extend({}, L.CRS, {
|
||||
projection: L.Projection.SphericalMercator,
|
||||
transformation: new L.Transformation(0.5 / Math.PI, 0.5, -0.5 / Math.PI, 0.5),
|
||||
|
||||
project: function (/*LatLng*/ latlng)/*-> Point*/ {
|
||||
project: function (latlng) { // (LatLng) -> Point
|
||||
var projectedPoint = this.projection.project(latlng),
|
||||
earthRadius = 6378137;
|
||||
return projectedPoint.multiplyBy(earthRadius);
|
||||
|
5
src/geo/crs/CRS.Simple.js
Normal file
5
src/geo/crs/CRS.Simple.js
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
L.CRS.Simple = L.Util.extend({}, L.CRS, {
|
||||
projection: L.Projection.LonLat,
|
||||
transformation: new L.Transformation(1, 0, 1, 0)
|
||||
});
|
@ -1,17 +1,25 @@
|
||||
|
||||
L.CRS = {
|
||||
latLngToPoint: function (/*LatLng*/ latlng, /*Number*/ scale)/*-> Point*/ {
|
||||
var projectedPoint = this.projection.project(latlng);
|
||||
latLngToPoint: function (latlng, zoom) { // (LatLng, Number) -> Point
|
||||
var projectedPoint = this.projection.project(latlng),
|
||||
scale = this.scale(zoom);
|
||||
|
||||
return this.transformation._transform(projectedPoint, scale);
|
||||
},
|
||||
|
||||
pointToLatLng: function (/*Point*/ point, /*Number*/ scale, /*(optional) Boolean*/ unbounded)/*-> LatLng*/ {
|
||||
var untransformedPoint = this.transformation.untransform(point, scale);
|
||||
pointToLatLng: function (point, zoom, unbounded) { // (Point, Number[, Boolean]) -> LatLng
|
||||
var scale = this.scale(zoom),
|
||||
untransformedPoint = this.transformation.untransform(point, scale);
|
||||
|
||||
return this.projection.unproject(untransformedPoint, unbounded);
|
||||
//TODO get rid of 'unbounded' everywhere
|
||||
},
|
||||
|
||||
project: function (latlng) {
|
||||
return this.projection.project(latlng);
|
||||
},
|
||||
|
||||
scale: function (zoom) {
|
||||
return 256 * Math.pow(2, zoom);
|
||||
}
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ L.Projection.Mercator = {
|
||||
R_MINOR: 6356752.3142,
|
||||
R_MAJOR: 6378137,
|
||||
|
||||
project: function (/*LatLng*/ latlng) /*-> Point*/ {
|
||||
project: function (latlng) { // (LatLng) -> Point
|
||||
var d = L.LatLng.DEG_TO_RAD,
|
||||
max = this.MAX_LATITUDE,
|
||||
lat = Math.max(Math.min(max, latlng.lat), -max),
|
||||
@ -25,7 +25,7 @@ L.Projection.Mercator = {
|
||||
return new L.Point(x, y);
|
||||
},
|
||||
|
||||
unproject: function (/*Point*/ point, /*Boolean*/ unbounded) /*-> LatLng*/ {
|
||||
unproject: function (point, unbounded) { // (Point, Boolean) -> LatLng
|
||||
var d = L.LatLng.RAD_TO_DEG,
|
||||
r = this.R_MAJOR,
|
||||
r2 = this.R_MINOR,
|
||||
|
@ -2,7 +2,7 @@
|
||||
L.Projection.SphericalMercator = {
|
||||
MAX_LATITUDE: 85.0511287798,
|
||||
|
||||
project: function (/*LatLng*/ latlng) /*-> Point*/ {
|
||||
project: function (latlng) { // (LatLng) -> Point
|
||||
var d = L.LatLng.DEG_TO_RAD,
|
||||
max = this.MAX_LATITUDE,
|
||||
lat = Math.max(Math.min(max, latlng.lat), -max),
|
||||
@ -13,7 +13,7 @@ L.Projection.SphericalMercator = {
|
||||
return new L.Point(x, y);
|
||||
},
|
||||
|
||||
unproject: function (/*Point*/ point, /*Boolean*/ unbounded) /*-> LatLng*/ {
|
||||
unproject: function (point, unbounded) { // (Point, Boolean) -> LatLng
|
||||
var d = L.LatLng.RAD_TO_DEG,
|
||||
lng = point.x * d,
|
||||
lat = (2 * Math.atan(Math.exp(point.y)) - (Math.PI / 2)) * d;
|
||||
|
@ -71,9 +71,14 @@ L.Popup = L.Class.extend({
|
||||
},
|
||||
|
||||
_close: function () {
|
||||
if (this._map) {
|
||||
this._map._popup = null;
|
||||
this._map.removeLayer(this);
|
||||
var map = this._map;
|
||||
|
||||
if (map) {
|
||||
map._popup = null;
|
||||
|
||||
map
|
||||
.removeLayer(this)
|
||||
.fire('popupclose', {popup: this});
|
||||
}
|
||||
},
|
||||
|
||||
|
140
src/map/Map.js
140
src/map/Map.js
@ -6,66 +6,32 @@ L.Map = L.Class.extend({
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
// projection
|
||||
crs: L.CRS.EPSG3857 || L.CRS.EPSG4326,
|
||||
scale: function (zoom) {
|
||||
return 256 * Math.pow(2, zoom);
|
||||
},
|
||||
crs: L.CRS.EPSG3857,
|
||||
|
||||
// state
|
||||
center: null,
|
||||
zoom: null,
|
||||
layers: [],
|
||||
/*
|
||||
center: LatLng,
|
||||
zoom: Number,
|
||||
layers: Array,
|
||||
*/
|
||||
|
||||
// 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,
|
||||
worldCopyJump: true
|
||||
trackResize: true
|
||||
},
|
||||
|
||||
|
||||
initialize: function (id, options) { // (HTMLElement or String, Object)
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
// TODO method is too big, refactor
|
||||
|
||||
var container = this._container = L.DomUtil.get(id);
|
||||
|
||||
if (container._leaflet) {
|
||||
throw new Error("Map container is already initialized.");
|
||||
}
|
||||
container._leaflet = true;
|
||||
options = L.Util.setOptions(this, options);
|
||||
|
||||
this._initContainer(id);
|
||||
this._initLayout();
|
||||
|
||||
if (L.DomEvent) {
|
||||
this._initEvents();
|
||||
if (L.Handler) {
|
||||
this._initInteraction();
|
||||
}
|
||||
if (L.Control) {
|
||||
this._initControls();
|
||||
}
|
||||
}
|
||||
|
||||
options = this.options;
|
||||
this._initHooks();
|
||||
this._initEvents();
|
||||
|
||||
if (options.maxBounds) {
|
||||
this.setMaxBounds(options.maxBounds);
|
||||
}
|
||||
|
||||
var center = options.center,
|
||||
zoom = options.zoom;
|
||||
|
||||
if (center && typeof zoom !== 'undefined') {
|
||||
this.setView(center, zoom, true);
|
||||
if (options.center && typeof options.zoom !== 'undefined') {
|
||||
this.setView(options.center, options.zoom, true);
|
||||
}
|
||||
|
||||
this._initLayers(options.layers);
|
||||
@ -76,7 +42,6 @@ L.Map = L.Class.extend({
|
||||
|
||||
// replaced by animation-powered implementation in Map.PanAnimation.js
|
||||
setView: function (center, zoom) {
|
||||
// reset the map view
|
||||
this._resetView(center, this._limitZoom(zoom));
|
||||
return this;
|
||||
},
|
||||
@ -172,9 +137,7 @@ L.Map = L.Class.extend({
|
||||
|
||||
var id = L.Util.stamp(layer);
|
||||
|
||||
if (this._layers[id]) {
|
||||
return this;
|
||||
}
|
||||
if (this._layers[id]) { return this; }
|
||||
|
||||
this._layers[id] = layer;
|
||||
|
||||
@ -192,10 +155,6 @@ L.Map = L.Class.extend({
|
||||
layer.on('load', this._onTileLayerLoad, this);
|
||||
}
|
||||
|
||||
if (this.attributionControl && layer.getAttribution) {
|
||||
this.attributionControl.addAttribution(layer.getAttribution());
|
||||
}
|
||||
|
||||
var onMapLoad = function () {
|
||||
layer.onAdd(this, insertAtTheBottom);
|
||||
this.fire('layeradd', {layer: layer});
|
||||
@ -225,10 +184,6 @@ L.Map = L.Class.extend({
|
||||
layer.off('load', this._onTileLayerLoad, this);
|
||||
}
|
||||
|
||||
if (this.attributionControl && layer.getAttribution) {
|
||||
this.attributionControl.removeAttribution(layer.getAttribution());
|
||||
}
|
||||
|
||||
return this.fire('layerremove', {layer: layer});
|
||||
},
|
||||
|
||||
@ -253,16 +208,13 @@ L.Map = L.Class.extend({
|
||||
|
||||
this.fire('move');
|
||||
|
||||
function fireMoveEnd() {
|
||||
this.fire('moveend');
|
||||
}
|
||||
|
||||
clearTimeout(this._sizeTimer);
|
||||
this._sizeTimer = setTimeout(L.Util.bind(fireMoveEnd, this), 200);
|
||||
this._sizeTimer = setTimeout(L.Util.bind(this.fire, this, 'moveend'), 200);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// TODO handler.addTo
|
||||
addHandler: function (name, HandlerClass) {
|
||||
if (!HandlerClass) { return; }
|
||||
|
||||
@ -278,7 +230,7 @@ L.Map = L.Class.extend({
|
||||
|
||||
// public methods for getting map state
|
||||
|
||||
getCenter: function (unbounded) { // (Boolean)
|
||||
getCenter: function (unbounded) { // (Boolean) -> LatLng
|
||||
var viewHalf = this.getSize().divideBy(2),
|
||||
centerPoint = this._getTopLeftPoint().add(viewHalf);
|
||||
|
||||
@ -412,18 +364,28 @@ L.Map = L.Class.extend({
|
||||
|
||||
project: function (latlng, zoom) { // (LatLng[, Number]) -> Point
|
||||
zoom = typeof zoom === 'undefined' ? this._zoom : zoom;
|
||||
return this.options.crs.latLngToPoint(latlng, this.options.scale(zoom));
|
||||
return this.options.crs.latLngToPoint(latlng, zoom);
|
||||
},
|
||||
|
||||
unproject: function (point, zoom, unbounded) { // (Point[, Number, Boolean]) -> LatLng
|
||||
// TODO remove unbounded, making it true all the time?
|
||||
zoom = typeof zoom === 'undefined' ? this._zoom : zoom;
|
||||
return this.options.crs.pointToLatLng(point, this.options.scale(zoom), unbounded);
|
||||
return this.options.crs.pointToLatLng(point, zoom, unbounded);
|
||||
},
|
||||
|
||||
|
||||
// private methods that modify map state
|
||||
|
||||
_initContainer: function (id) {
|
||||
var container = this._container = L.DomUtil.get(id);
|
||||
|
||||
if (container._leaflet) {
|
||||
throw new Error("Map container is already initialized.");
|
||||
}
|
||||
|
||||
container._leaflet = true;
|
||||
},
|
||||
|
||||
_initLayout: function () {
|
||||
var container = this._container;
|
||||
|
||||
@ -469,6 +431,15 @@ L.Map = L.Class.extend({
|
||||
return L.DomUtil.create('div', className, container || this._objectsPane);
|
||||
},
|
||||
|
||||
_initializers: [],
|
||||
|
||||
_initHooks: function () {
|
||||
var i, len;
|
||||
for (i = 0, len = this._initializers.length; i < len; i++) {
|
||||
this._initializers[i].call(this);
|
||||
}
|
||||
},
|
||||
|
||||
_resetView: function (center, zoom, preserveMapOffset, afterZoomAnim) {
|
||||
|
||||
var zoomChanged = (this._zoom !== zoom);
|
||||
@ -510,7 +481,7 @@ L.Map = L.Class.extend({
|
||||
},
|
||||
|
||||
_initLayers: function (layers) {
|
||||
layers = layers instanceof Array ? layers : [layers];
|
||||
layers = layers ? (layers instanceof Array ? layers : [layers]) : [];
|
||||
|
||||
this._layers = {};
|
||||
this._tileLayersNum = 0;
|
||||
@ -522,18 +493,6 @@ L.Map = L.Class.extend({
|
||||
}
|
||||
},
|
||||
|
||||
_initControls: function () {
|
||||
// TODO refactor, this should happen automatically
|
||||
if (this.options.zoomControl) {
|
||||
this.zoomControl = new L.Control.Zoom();
|
||||
this.addControl(this.zoomControl);
|
||||
}
|
||||
if (this.options.attributionControl) {
|
||||
this.attributionControl = new L.Control.Attribution();
|
||||
this.addControl(this.attributionControl);
|
||||
}
|
||||
},
|
||||
|
||||
_rawPanBy: function (offset) {
|
||||
var newPos = L.DomUtil.getPosition(this._mapPane).subtract(offset);
|
||||
L.DomUtil.setPosition(this._mapPane, newPos);
|
||||
@ -543,6 +502,8 @@ L.Map = L.Class.extend({
|
||||
// map events
|
||||
|
||||
_initEvents: function () {
|
||||
if (!L.DomEvent) { return; }
|
||||
|
||||
L.DomEvent.addListener(this._container, 'click', this._onMouseClick, this);
|
||||
|
||||
var events = ['dblclick', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'contextmenu'];
|
||||
@ -594,15 +555,6 @@ L.Map = L.Class.extend({
|
||||
});
|
||||
},
|
||||
|
||||
_initInteraction: function () {
|
||||
this
|
||||
.addHandler('dragging', L.Map.Drag)
|
||||
.addHandler('touchZoom', L.Map.TouchZoom)
|
||||
.addHandler('doubleClickZoom', L.Map.DoubleClickZoom)
|
||||
.addHandler('scrollWheelZoom', L.Map.ScrollWheelZoom)
|
||||
.addHandler('boxZoom', L.Map.BoxZoom);
|
||||
},
|
||||
|
||||
_onTileLayerLoad: function () {
|
||||
// TODO super-ugly, refactor!!!
|
||||
// clear scaled tiles after all new tiles are loaded (for performance)
|
||||
@ -638,3 +590,13 @@ L.Map = L.Class.extend({
|
||||
return Math.max(min, Math.min(max, zoom));
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.addInitHook = function (fn) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
var init = typeof fn === 'function' ? fn : function () {
|
||||
this[fn].apply(this, args);
|
||||
};
|
||||
|
||||
this.prototype._initializers.push(init);
|
||||
};
|
@ -1,3 +1,4 @@
|
||||
|
||||
L.Map.include(!(L.Transition && L.Transition.implemented()) ? {} : {
|
||||
setView: function (center, zoom, forceReset) {
|
||||
zoom = this._limitZoom(zoom);
|
||||
|
@ -1,3 +1,7 @@
|
||||
L.Map.mergeOptions({
|
||||
zoomAnimation: L.DomUtil.TRANSITION && !L.Browser.android && !L.Browser.mobileOpera
|
||||
});
|
||||
|
||||
L.Map.include(!L.DomUtil.TRANSITION ? {} : {
|
||||
_zoomToIfCenterInView: function (center, zoom, centerOffset) {
|
||||
|
||||
|
@ -12,11 +12,7 @@ L.Map.include({
|
||||
|
||||
closePopup: function () {
|
||||
if (this._popup) {
|
||||
this
|
||||
.removeLayer(this._popup)
|
||||
.fire('popupclose', {popup: this._popup});
|
||||
|
||||
this._popup = null;
|
||||
this._popup._close();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -78,3 +78,5 @@ L.Map.BoxZoom = L.Handler.extend({
|
||||
map.fitBounds(bounds);
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.addInitHook('addHandler', 'boxZoom', L.Map.BoxZoom);
|
@ -19,3 +19,5 @@ L.Map.DoubleClickZoom = L.Handler.extend({
|
||||
this.setView(e.latlng, this._zoom + 1);
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.addInitHook('addHandler', 'doubleClickZoom', L.Map.DoubleClickZoom);
|
@ -4,10 +4,15 @@
|
||||
|
||||
L.Map.mergeOptions({
|
||||
dragging: true,
|
||||
|
||||
inertia: !L.Browser.android,
|
||||
inertiaDeceleration: L.Browser.touch ? 3000 : 2000, // px/s^2
|
||||
inertiaMaxSpeed: L.Browser.touch ? 1500 : 1000, // px/s
|
||||
inertiaThreshold: L.Browser.touch ? 32 : 16 // ms
|
||||
inertiaThreshold: L.Browser.touch ? 32 : 16, // ms
|
||||
|
||||
// TODO refactor, move to CRS
|
||||
worldCopyJump: true,
|
||||
continuousWorld: false
|
||||
});
|
||||
|
||||
L.Map.Drag = L.Handler.extend({
|
||||
@ -83,7 +88,7 @@ L.Map.Drag = L.Handler.extend({
|
||||
|
||||
_onPreDrag: function () {
|
||||
var map = this._map,
|
||||
worldWidth = map.options.scale(map.getZoom()),
|
||||
worldWidth = map.options.crs.scale(map.getZoom()),
|
||||
halfWidth = Math.round(worldWidth / 2),
|
||||
dx = this._initialWorldOffset.x,
|
||||
x = this._draggable._newPos.x,
|
||||
@ -142,3 +147,5 @@ L.Map.Drag = L.Handler.extend({
|
||||
this.panInsideBounds(this.options.maxBounds);
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.addInitHook('addHandler', 'dragging', L.Map.Drag);
|
@ -56,3 +56,5 @@ L.Map.ScrollWheelZoom = L.Handler.extend({
|
||||
return map.unproject(newCenterPoint, map._zoom, true);
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.addInitHook('addHandler', 'scrollWheelZoom', L.Map.ScrollWheelZoom);
|
@ -95,3 +95,5 @@ L.Map.TouchZoom = L.Handler.extend({
|
||||
this._map._runAnimation(center, zoom, finalScale / this._scale, this._startCenter.add(centerOffset));
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.addInitHook('addHandler', 'touchZoom', L.Map.TouchZoom);
|
Loading…
Reference in New Issue
Block a user