Merge branch 'master' into gh-pages
This commit is contained in:
commit
2ec421749f
16
CHANGELOG.md
16
CHANGELOG.md
@ -18,6 +18,7 @@ Leaflet Changelog
|
||||
* Map now preserves its center after resize.
|
||||
* When panning to another copy of the world (that's infinite horizontally), map overlays now jump to corresponding positions. [#273](https://github.com/CloudMade/Leaflet/issues/273)
|
||||
* Limited maximum zoom change on a single mouse wheel movement (so you won't zoom across the whole zoom range in one scroll). [#149](https://github.com/CloudMade/Leaflet/issues/149)
|
||||
* Significantly improved line simplification performance (noticeable when rendering polylines/polygons with tens of thousands of points)
|
||||
* Improved circles performance by not drawing them if they're off the clip region.
|
||||
|
||||
#### API improvements
|
||||
@ -27,10 +28,13 @@ Leaflet Changelog
|
||||
* Improved `Map` `locate` method, added ability to watch location continuously and more options. [#212](https://github.com/CloudMade/Leaflet/issues/212)
|
||||
* Added second argument `inside` to `Map` `getBoundsZoom` method that allows you to get appropriate zoom for the view to fit *inside* the given bounds.
|
||||
* Added `hasLayer` method to `Map`.
|
||||
* Added `Marker` `zIndexOffset` option to be able to set certain markers below/above others. [#65](https://github.com/CloudMade/Leaflet/issues/65)
|
||||
* Added `urlParams` third optional argument to `TileLayer` constructor for convenience: an object with properties that will be evaluated in the URL template.
|
||||
* Added `TileLayer` `continuousWorld` option to disable tile coordinates checking/wrapping.
|
||||
* Added `TileLayer` `tileunload` event fired when tile gets removed after panning (by [@CodeJosch](https://github.com/CodeJosch)). [#256](https://github.com/CloudMade/Leaflet/pull/256)
|
||||
* Added `TileLayer` `zoomOffset` option useful for non-256px tiles (by [@msaspence](https://github.com/msaspence)).
|
||||
* Added `TileLayer` `zoomReverse` option to reverse zoom numbering (by [@Majiir](https://github.com/Majiir)). [#406](https://github.com/CloudMade/Leaflet/pull/406)
|
||||
* Added `TileLayer.Canvas` `redraw` method (by [@mortenbekditlevsen](https://github.com/mortenbekditlevsen)). [#459](https://github.com/CloudMade/Leaflet/pull/459)
|
||||
* Added `Polyline` `closestLayerPoint` method that's can be useful for interaction features (by [@anru](https://github.com/anru)). [#186](https://github.com/CloudMade/Leaflet/pull/186)
|
||||
* Added `setLatLngs` method to `MultiPolyline` and `MultiPolygon` (by [@anru](https://github.com/anru)). [#194](https://github.com/CloudMade/Leaflet/pull/194)
|
||||
* Added `getBounds` method to `Polyline` and `Polygon` (by [@JasonSanford](https://github.com/JasonSanford)). [#253](https://github.com/CloudMade/Leaflet/pull/253)
|
||||
@ -39,18 +43,27 @@ Leaflet Changelog
|
||||
* Added `ImageOverlay` `load` event. [#213](https://github.com/CloudMade/Leaflet/issues/213)
|
||||
* Added `minWidth` option to `Popup` (by [@marphi](https://github.com/marphi)). [#214](https://github.com/CloudMade/Leaflet/pull/214)
|
||||
* Improved `LatLng` constructor to be more tolerant (and throw descriptive error if latitude or longitude can't be interpreted as a number). [#136](https://github.com/CloudMade/Leaflet/issues/136)
|
||||
* Added `LatLng` `distanceTo` method (great circle distance) (by [@mortenbekditlevsen](https://github.com/mortenbekditlevsen)). [#462](https://github.com/CloudMade/Leaflet/pull/462)
|
||||
* Added `LatLngBounds` `toBBoxString` method for convenience (by [@JasonSanford](https://github.com/JasonSanford)). [#263](https://github.com/CloudMade/Leaflet/pull/263)
|
||||
* Added `LatLngBounds` `intersects(otherBounds)` method (thanks to [@pagameba](https://github.com/pagameba)). [#350](https://github.com/CloudMade/Leaflet/pull/350)
|
||||
* Added `Bounds` `intersects(otherBounds)` method. [#461](https://github.com/CloudMade/Leaflet/issues/461)
|
||||
* Added `L.Util.template` method for simple string template evaluation.
|
||||
* Added `DomUtil.removeClass` method (by [@anru](https://github.com/anru)).
|
||||
* Added ability to pass empty imageUrl to icons for creating transparent clickable regions (by [@mortenbekditlevsen](https://github.com/mortenbekditlevsen)). [#460](https://github.com/CloudMade/Leaflet/pull/460)
|
||||
* Improved browser-specific code to rely more on feature detection rather than user agent string.
|
||||
* Improved superclass access mechanism to work with inheritance chains of 3 or more classes; now you should use `Klass.superclass` instead of `this.superclass` (by [@anru](https://github.com/anru)). [#179](https://github.com/CloudMade/Leaflet/pull/179)
|
||||
|
||||
#### Development workflow improvements
|
||||
|
||||
* Build system completely overhauled to be based on Node.js, Jake, JSHint and UglifyJS.
|
||||
* All code is now linted for errors and conformity with a strict code style (with JSHint), and wont build unless the check passes.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
#### General bugfixes
|
||||
|
||||
* Fixed a bug where `Circle` was rendered with incorrect radius (didn't take projection exagerration into account). [#331](https://github.com/CloudMade/Leaflet/issues/331)
|
||||
* Fixed a bug where `Map` `getBounds` would work incorrectly on a date line cross. [#295](https://github.com/CloudMade/Leaflet/issues/295)
|
||||
* Fixed a bug where polygons and polylines sometimes rendered incorrectly on some zoom levels. [#381](https://github.com/CloudMade/Leaflet/issues/381)
|
||||
* Fixed a bug where fast mouse wheel zoom worked incorrectly when approaching min/max zoom values.
|
||||
* Fixed a bug where `GeoJSON` `pointToLayer` option wouldn't work in a `GeometryCollection`. [#391](https://github.com/CloudMade/Leaflet/issues/391)
|
||||
@ -66,6 +79,7 @@ Leaflet Changelog
|
||||
* Fixed broken popup `closePopup` option (by [@jgerigmeyer](https://github.com/jgerigmeyer)).
|
||||
* Fixed a bug that caused en error when dragging marker with icon without shadow (by [@anru](https://github.com/anru)). [#178](https://github.com/CloudMade/Leaflet/issues/178)
|
||||
* Fixed a typo in `Bounds` `contains` method (by [@anru](https://github.com/anru)). [#180](https://github.com/CloudMade/Leaflet/pull/180)
|
||||
* Fixed a bug where creating an empty `Polygon` with `new L.Polygon()` would raise an error.
|
||||
* Fixed a bug where drag event fired before the actual movement of layer (by [@anru](https://github.com/anru)). [#197](https://github.com/CloudMade/Leaflet/pull/197)
|
||||
* Fixed a bug where map click caused an error if dragging is initially disabled. [#196](https://github.com/CloudMade/Leaflet/issues/196)
|
||||
* Fixed a bug where map `movestart` event would fire after zoom animation.
|
||||
@ -81,6 +95,7 @@ Leaflet Changelog
|
||||
#### Browser bugfixes
|
||||
|
||||
* Fixed occasional crashes on Mac Safari (thanks to [@lapinos03](https://github.com/lapinos03)). [#191](https://github.com/CloudMade/Leaflet/issues/191)
|
||||
* Fixed a bug where resizing the map would sometimes make it blurry on WebKit (by [@mortenbekditlevsen](https://github.com/mortenbekditlevsen)). [#453](https://github.com/CloudMade/Leaflet/pull/453)
|
||||
* Fixed a bug that raised error in IE6-8 when clicking on popup close button. [#235](https://github.com/CloudMade/Leaflet/issues/235)
|
||||
* Fixed a bug with Safari not redrawing UI immediately after closing a popup. [#296](https://github.com/CloudMade/Leaflet/issues/296)
|
||||
* Fixed a bug that caused performance drop and high CPU usage when calling `setView` or `panTo` to the current center. [#231](https://github.com/CloudMade/Leaflet/issues/231)
|
||||
@ -91,6 +106,7 @@ Leaflet Changelog
|
||||
|
||||
* Fixed a bug that caused an error when clicking vector layers under iOS. [#204](https://github.com/CloudMade/Leaflet/issues/204)
|
||||
* Fixed crash on Android 3+ when panning or zooming (by [@florian](https://github.com/florianf)). [#137](https://github.com/CloudMade/Leaflet/issues/137)
|
||||
* Fixed a bug that caused the map to pan when touch-panning inside a popup. [#452](https://github.com/CloudMade/Leaflet/issues/452)
|
||||
|
||||
|
||||
## 0.2.1 (2011-06-18)
|
||||
|
@ -47,7 +47,7 @@ exports.uglify = function (code) {
|
||||
ast = pro.ast_squeeze(ast, {keep_comps: false});
|
||||
ast = pro.ast_squeeze_more(ast);
|
||||
|
||||
return pro.gen_code(ast);
|
||||
return pro.gen_code(ast) + ';';
|
||||
};
|
||||
|
||||
exports.combineFiles = function (files) {
|
||||
|
266
dist/leaflet-src.js
vendored
266
dist/leaflet-src.js
vendored
@ -451,7 +451,20 @@ L.Bounds = L.Class.extend({
|
||||
(max.x <= this.max.x) &&
|
||||
(min.y >= this.min.y) &&
|
||||
(max.y <= this.max.y);
|
||||
},
|
||||
|
||||
intersects: function (/*Bounds*/ bounds) {
|
||||
var min = this.min,
|
||||
max = this.max,
|
||||
min2 = bounds.min,
|
||||
max2 = bounds.max;
|
||||
|
||||
var xIntersects = (max2.x >= min.x) && (min2.x <= max.x),
|
||||
yIntersects = (max2.y >= min.y) && (min2.y <= max.y);
|
||||
|
||||
return xIntersects && yIntersects;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
@ -659,7 +672,7 @@ L.LatLng = function (/*Number*/ rawLat, /*Number*/ rawLng, /*Boolean*/ noWrap) {
|
||||
|
||||
if (noWrap !== true) {
|
||||
lat = Math.max(Math.min(lat, 90), -90); // clamp latitude into -90..90
|
||||
lng = (lng + 180) % 360 + (lng < -180 ? 180 : -180); // wrap longtitude into -180..180
|
||||
lng = (lng + 180) % 360 + ((lng < -180 || lng === 180) ? 180 : -180); // wrap longtitude into -180..180
|
||||
}
|
||||
|
||||
//TODO change to lat() & lng()
|
||||
@ -687,6 +700,22 @@ L.LatLng.prototype = {
|
||||
return 'LatLng(' +
|
||||
L.Util.formatNum(this.lat) + ', ' +
|
||||
L.Util.formatNum(this.lng) + ')';
|
||||
},
|
||||
|
||||
// Haversine distance formula, see http://en.wikipedia.org/wiki/Haversine_formula
|
||||
distanceTo: function (/*LatLng*/ other)/*->Double*/ {
|
||||
var R = 6378137, // earth radius in meters
|
||||
d2r = L.LatLng.DEG_TO_RAD,
|
||||
dLat = (other.lat - this.lat) * d2r,
|
||||
dLon = (other.lng - this.lng) * d2r,
|
||||
lat1 = this.lat * d2r,
|
||||
lat2 = other.lat * d2r,
|
||||
sin1 = Math.sin(dLat / 2),
|
||||
sin2 = Math.sin(dLon / 2);
|
||||
|
||||
var a = sin1 * sin1 + sin2 * sin2 * Math.cos(lat1) * Math.cos(lat2);
|
||||
|
||||
return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
}
|
||||
};
|
||||
|
||||
@ -709,8 +738,8 @@ L.LatLngBounds = L.Class.extend({
|
||||
// extend the bounds to contain the given point
|
||||
extend: function (/*LatLng*/ latlng) {
|
||||
if (!this._southWest && !this._northEast) {
|
||||
this._southWest = new L.LatLng(latlng.lat, latlng.lng);
|
||||
this._northEast = new L.LatLng(latlng.lat, latlng.lng);
|
||||
this._southWest = new L.LatLng(latlng.lat, latlng.lng, true);
|
||||
this._northEast = new L.LatLng(latlng.lat, latlng.lng, true);
|
||||
} else {
|
||||
this._southWest.lat = Math.min(latlng.lat, this._southWest.lat);
|
||||
this._southWest.lng = Math.min(latlng.lng, this._southWest.lng);
|
||||
@ -734,11 +763,11 @@ L.LatLngBounds = L.Class.extend({
|
||||
},
|
||||
|
||||
getNorthWest: function () {
|
||||
return new L.LatLng(this._northEast.lat, this._southWest.lng);
|
||||
return new L.LatLng(this._northEast.lat, this._southWest.lng, true);
|
||||
},
|
||||
|
||||
getSouthEast: function () {
|
||||
return new L.LatLng(this._southWest.lat, this._northEast.lng);
|
||||
return new L.LatLng(this._southWest.lat, this._northEast.lng, true);
|
||||
},
|
||||
|
||||
contains: function (/*LatLngBounds or LatLng*/ obj) /*-> Boolean*/ {
|
||||
@ -1125,7 +1154,7 @@ L.Map = L.Class.extend({
|
||||
return this;
|
||||
}
|
||||
|
||||
this._rawPanBy(oldSize.subtract(this.getSize()).divideBy(2));
|
||||
this._rawPanBy(oldSize.subtract(this.getSize()).divideBy(2, true));
|
||||
|
||||
this.fire('move');
|
||||
|
||||
@ -1152,8 +1181,8 @@ L.Map = L.Class.extend({
|
||||
|
||||
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));
|
||||
sw = this.unproject(new L.Point(bounds.min.x, bounds.max.y), this._zoom, true),
|
||||
ne = this.unproject(new L.Point(bounds.max.x, bounds.min.y), this._zoom, true);
|
||||
return new L.LatLngBounds(sw, ne);
|
||||
},
|
||||
|
||||
@ -1200,7 +1229,7 @@ L.Map = L.Class.extend({
|
||||
}
|
||||
} while (zoomNotFound && (zoom <= maxZoom));
|
||||
|
||||
if (zoomNotFound) {
|
||||
if (zoomNotFound && inside) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1382,7 +1411,7 @@ L.Map = L.Class.extend({
|
||||
_initEvents: function () {
|
||||
L.DomEvent.addListener(this._container, 'click', this._onMouseClick, this);
|
||||
|
||||
var events = ['dblclick', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove'];
|
||||
var events = ['dblclick', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'contextmenu'];
|
||||
|
||||
var i, len;
|
||||
|
||||
@ -1420,6 +1449,10 @@ L.Map = L.Class.extend({
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === 'contextmenu') {
|
||||
L.DomEvent.preventDefault(e);
|
||||
}
|
||||
|
||||
this.fire(type, {
|
||||
latlng: this.mouseEventToLatLng(e),
|
||||
layerPoint: this.mouseEventToLayerPoint(e)
|
||||
@ -1568,6 +1601,7 @@ L.TileLayer = L.Class.extend({
|
||||
continuousWorld: false,
|
||||
noWrap: false,
|
||||
zoomOffset: 0,
|
||||
zoomReverse: false,
|
||||
|
||||
unloadInvisibleTiles: L.Browser.mobile,
|
||||
updateWhenIdle: L.Browser.mobile
|
||||
@ -1676,6 +1710,10 @@ L.TileLayer = L.Class.extend({
|
||||
}
|
||||
this._tiles = {};
|
||||
|
||||
if (this.options.reuseTiles) {
|
||||
this._unusedTiles = [];
|
||||
}
|
||||
|
||||
if (clearOldContainer && this._container) {
|
||||
this._container.innerHTML = "";
|
||||
}
|
||||
@ -1696,7 +1734,8 @@ L.TileLayer = L.Class.extend({
|
||||
|
||||
this._addTilesFromCenterOut(tileBounds);
|
||||
|
||||
if (this.options.unloadInvisibleTiles) {
|
||||
if (this.options.unloadInvisibleTiles ||
|
||||
this.options.reuseTiles) {
|
||||
this._removeOtherTiles(tileBounds);
|
||||
}
|
||||
},
|
||||
@ -1750,6 +1789,9 @@ L.TileLayer = L.Class.extend({
|
||||
if (tile.parentNode === this._container) {
|
||||
this._container.removeChild(tile);
|
||||
}
|
||||
if (this.options.reuseTiles) {
|
||||
this._unusedTiles.push(this._tiles[key]);
|
||||
}
|
||||
delete this._tiles[key];
|
||||
}
|
||||
}
|
||||
@ -1760,7 +1802,7 @@ L.TileLayer = L.Class.extend({
|
||||
var tilePos = this._getTilePos(tilePoint),
|
||||
zoom = this._map.getZoom(),
|
||||
key = tilePoint.x + ':' + tilePoint.y,
|
||||
tileLimit = Math.pow(2, (zoom + this.options.zoomOffset));
|
||||
tileLimit = Math.pow(2, this._getOffsetZoom(zoom));
|
||||
|
||||
// wrap tile coordinates
|
||||
if (!this.options.continuousWorld) {
|
||||
@ -1777,8 +1819,8 @@ L.TileLayer = L.Class.extend({
|
||||
}
|
||||
}
|
||||
|
||||
// create tile
|
||||
var tile = this._createTile();
|
||||
// get unused tile - or create a new tile
|
||||
var tile = this._getTile();
|
||||
L.DomUtil.setPosition(tile, tilePos);
|
||||
|
||||
this._tiles[key] = tile;
|
||||
@ -1792,6 +1834,11 @@ L.TileLayer = L.Class.extend({
|
||||
container.appendChild(tile);
|
||||
},
|
||||
|
||||
_getOffsetZoom: function (zoom) {
|
||||
zoom = this.options.zoomReverse ? this.options.maxZoom - zoom : zoom;
|
||||
return zoom + this.options.zoomOffset;
|
||||
},
|
||||
|
||||
_getTilePos: function (tilePoint) {
|
||||
var origin = this._map.getPixelOrigin(),
|
||||
tileSize = this.options.tileSize;
|
||||
@ -1807,7 +1854,7 @@ L.TileLayer = L.Class.extend({
|
||||
|
||||
return L.Util.template(this._url, L.Util.extend({
|
||||
s: s,
|
||||
z: zoom + this.options.zoomOffset,
|
||||
z: this._getOffsetZoom(zoom),
|
||||
x: tilePoint.x,
|
||||
y: tilePoint.y
|
||||
}, this._urlParams));
|
||||
@ -1822,6 +1869,19 @@ L.TileLayer = L.Class.extend({
|
||||
this._tileImg.style.height = tileSize + 'px';
|
||||
},
|
||||
|
||||
_getTile: function () {
|
||||
if (this.options.reuseTiles && this._unusedTiles.length > 0) {
|
||||
var tile = this._unusedTiles.pop();
|
||||
this._resetTile(tile);
|
||||
return tile;
|
||||
}
|
||||
return this._createTile();
|
||||
},
|
||||
|
||||
_resetTile: function (tile) {
|
||||
// Override if data stored on a tile needs to be cleaned up before reuse
|
||||
},
|
||||
|
||||
_createTile: function () {
|
||||
var tile = this._tileImg.cloneNode(false);
|
||||
tile.onselectstart = tile.onmousemove = L.Util.falseFn;
|
||||
@ -1919,6 +1979,17 @@ L.TileLayer.Canvas = L.TileLayer.extend({
|
||||
L.Util.setOptions(this, options);
|
||||
},
|
||||
|
||||
redraw: function () {
|
||||
for (var i in this._tiles) {
|
||||
var tile = this._tiles[i];
|
||||
this._redrawTile(tile);
|
||||
}
|
||||
},
|
||||
|
||||
_redrawTile: function (tile) {
|
||||
this.drawTile(tile, tile._tilePoint, tile._zoom);
|
||||
},
|
||||
|
||||
_createTileProto: function () {
|
||||
this._canvasProto = L.DomUtil.create('canvas', 'leaflet-tile');
|
||||
|
||||
@ -1935,6 +2006,8 @@ L.TileLayer.Canvas = L.TileLayer.extend({
|
||||
|
||||
_loadTile: function (tile, tilePoint, zoom) {
|
||||
tile._layer = this;
|
||||
tile._tilePoint = tilePoint;
|
||||
tile._zoom = zoom;
|
||||
|
||||
this.drawTile(tile, tilePoint, zoom);
|
||||
|
||||
@ -2039,13 +2112,19 @@ L.Icon = L.Class.extend({
|
||||
|
||||
_createIcon: function (name) {
|
||||
var size = this[name + 'Size'],
|
||||
src = this[name + 'Url'],
|
||||
img = this._createImg(src);
|
||||
|
||||
if (!src) {
|
||||
src = this[name + 'Url'];
|
||||
if (!src && name === 'shadow') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var img;
|
||||
if (!src) {
|
||||
img = this._createDiv();
|
||||
}
|
||||
else {
|
||||
img = this._createImg(src);
|
||||
}
|
||||
|
||||
img.className = 'leaflet-marker-' + name;
|
||||
|
||||
img.style.marginLeft = (-this.iconAnchor.x) + 'px';
|
||||
@ -2069,6 +2148,10 @@ L.Icon = L.Class.extend({
|
||||
el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '")';
|
||||
}
|
||||
return el;
|
||||
},
|
||||
|
||||
_createDiv: function () {
|
||||
return document.createElement('div');
|
||||
}
|
||||
});
|
||||
|
||||
@ -2085,7 +2168,8 @@ L.Marker = L.Class.extend({
|
||||
icon: new L.Icon(),
|
||||
title: '',
|
||||
clickable: true,
|
||||
draggable: false
|
||||
draggable: false,
|
||||
zIndexOffset: 0
|
||||
},
|
||||
|
||||
initialize: function (latlng, options) {
|
||||
@ -2179,8 +2263,7 @@ L.Marker = L.Class.extend({
|
||||
L.DomUtil.setPosition(this._shadow, pos);
|
||||
}
|
||||
|
||||
this._icon.style.zIndex = pos.y;
|
||||
// TODO zIndex offset
|
||||
this._icon.style.zIndex = pos.y + this.options.zIndexOffset;
|
||||
},
|
||||
|
||||
_initInteraction: function () {
|
||||
@ -2227,7 +2310,8 @@ L.Popup = L.Class.extend({
|
||||
autoPan: true,
|
||||
closeButton: true,
|
||||
offset: new L.Point(0, 2),
|
||||
autoPanPadding: new L.Point(5, 5)
|
||||
autoPanPadding: new L.Point(5, 5),
|
||||
className: ''
|
||||
},
|
||||
|
||||
initialize: function (options, source) {
|
||||
@ -2294,7 +2378,7 @@ L.Popup = L.Class.extend({
|
||||
},
|
||||
|
||||
_initLayout: function () {
|
||||
this._container = L.DomUtil.create('div', 'leaflet-popup');
|
||||
this._container = L.DomUtil.create('div', 'leaflet-popup ' + this.options.className);
|
||||
|
||||
if (this.options.closeButton) {
|
||||
this._closeButton = L.DomUtil.create('a', 'leaflet-popup-close-button', this._container);
|
||||
@ -2404,7 +2488,9 @@ L.Popup = L.Class.extend({
|
||||
L.Marker.include({
|
||||
openPopup: function () {
|
||||
this._popup.setLatLng(this._latlng);
|
||||
this._map.openPopup(this._popup);
|
||||
if (this._map) {
|
||||
this._map.openPopup(this._popup);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
@ -2816,7 +2902,7 @@ L.Map.include({
|
||||
L.Path.include({
|
||||
bindPopup: function (content, options) {
|
||||
if (!this._popup || this._popup.options !== options) {
|
||||
this._popup = new L.Popup(options);
|
||||
this._popup = new L.Popup(options, this);
|
||||
}
|
||||
this._popup.setContent(content);
|
||||
|
||||
@ -2945,72 +3031,80 @@ L.LineUtil = {
|
||||
return points.slice();
|
||||
}
|
||||
|
||||
var sqTolerance = tolerance * tolerance;
|
||||
|
||||
// stage 1: vertex reduction
|
||||
points = this.reducePoints(points, tolerance);
|
||||
points = this._reducePoints(points, sqTolerance);
|
||||
|
||||
// stage 2: Douglas-Peucker simplification
|
||||
points = this.simplifyDP(points, tolerance);
|
||||
points = this._simplifyDP(points, sqTolerance);
|
||||
|
||||
return points;
|
||||
},
|
||||
|
||||
// distance from a point to a segment between two points
|
||||
pointToSegmentDistance: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
|
||||
return Math.sqrt(this._sqPointToSegmentDist(p, p1, p2));
|
||||
return Math.sqrt(this._sqClosestPointOnSegment(p, p1, p2, true));
|
||||
},
|
||||
|
||||
closestPointOnSegment: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
|
||||
var point = this._sqClosestPointOnSegment(p, p1, p2);
|
||||
point.distance = Math.sqrt(point._sqDist);
|
||||
return point;
|
||||
return this._sqClosestPointOnSegment(p, p1, p2);
|
||||
},
|
||||
|
||||
// Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm
|
||||
simplifyDP: function (points, tol) {
|
||||
var maxDist2 = 0,
|
||||
index = 0,
|
||||
t2 = tol * tol,
|
||||
len = points.length,
|
||||
i, dist2;
|
||||
_simplifyDP: function (points, sqTolerance) {
|
||||
|
||||
if (len < 3) {
|
||||
return points;
|
||||
}
|
||||
var len = points.length,
|
||||
ArrayConstructor = typeof Uint8Array !== 'undefined' ? Uint8Array : Array,
|
||||
markers = new ArrayConstructor(len);
|
||||
|
||||
for (i = 0; i < len - 1; i++) {
|
||||
dist2 = this._sqPointToSegmentDist(points[i], points[0], points[len - 1]);
|
||||
if (dist2 > maxDist2) {
|
||||
index = i;
|
||||
maxDist2 = dist2;
|
||||
markers[0] = markers[len - 1] = 1;
|
||||
|
||||
this._simplifyDPStep(points, markers, sqTolerance, 0, len - 1);
|
||||
|
||||
var i,
|
||||
newPoints = [];
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (markers[i]) {
|
||||
newPoints.push(points[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var part1, part2;
|
||||
return newPoints;
|
||||
},
|
||||
|
||||
if (maxDist2 >= t2) {
|
||||
part1 = points.slice(0, index);
|
||||
part2 = points.slice(index);
|
||||
_simplifyDPStep: function (points, markers, sqTolerance, first, last) {
|
||||
|
||||
part1 = this.simplifyDP(part1, tol);
|
||||
part2 = this.simplifyDP(part2, tol);
|
||||
var maxSqDist = 0,
|
||||
index, i, sqDist;
|
||||
|
||||
return part1.concat(part2);
|
||||
} else {
|
||||
return [points[0], points[len - 1]];
|
||||
for (i = first + 1; i <= last - 1; i++) {
|
||||
sqDist = this._sqClosestPointOnSegment(points[i], points[first], points[last], true);
|
||||
|
||||
if (sqDist > maxSqDist) {
|
||||
index = i;
|
||||
maxSqDist = sqDist;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxSqDist > sqTolerance) {
|
||||
markers[index] = 1;
|
||||
|
||||
this._simplifyDPStep(points, markers, sqTolerance, first, index);
|
||||
this._simplifyDPStep(points, markers, sqTolerance, index, last);
|
||||
}
|
||||
},
|
||||
|
||||
// reduce points that are too close to each other to a single point
|
||||
reducePoints: function (points, tol) {
|
||||
var reducedPoints = [points[0]],
|
||||
t2 = tol * tol;
|
||||
_reducePoints: function (points, sqTolerance) {
|
||||
var reducedPoints = [points[0]];
|
||||
|
||||
for (var i = 1, prev = 0, len = points.length; i < len; i++) {
|
||||
if (this._sqDist(points[i], points[prev]) < t2) {
|
||||
continue;
|
||||
if (this._sqDist(points[i], points[prev]) > sqTolerance) {
|
||||
reducedPoints.push(points[i]);
|
||||
prev = i;
|
||||
}
|
||||
reducedPoints.push(points[i]);
|
||||
prev = i;
|
||||
}
|
||||
if (prev < len - 1) {
|
||||
reducedPoints.push(points[len - 1]);
|
||||
@ -3100,28 +3194,31 @@ L.LineUtil = {
|
||||
return dx * dx + dy * dy;
|
||||
},
|
||||
|
||||
// return closest point on segment with attribute _sqDist - square distance to segment
|
||||
_sqClosestPointOnSegment: function (p, p1, p2) {
|
||||
var x2 = p2.x - p1.x,
|
||||
y2 = p2.y - p1.y,
|
||||
apoint = p1;
|
||||
if (x2 || y2) {
|
||||
var dot = (p.x - p1.x) * x2 + (p.y - p1.y) * y2,
|
||||
t = dot / this._sqDist(p1, p2);
|
||||
// return closest point on segment or distance to that point
|
||||
_sqClosestPointOnSegment: function (p, p1, p2, sqDist) {
|
||||
var x = p1.x,
|
||||
y = p1.y,
|
||||
dx = p2.x - x,
|
||||
dy = p2.y - y,
|
||||
dot = dx * dx + dy * dy,
|
||||
t;
|
||||
|
||||
if (dot > 0) {
|
||||
t = ((p.x - x) * dx + (p.y - y) * dy) / dot;
|
||||
|
||||
if (t > 1) {
|
||||
apoint = p2;
|
||||
x = p2.x;
|
||||
y = p2.y;
|
||||
} else if (t > 0) {
|
||||
apoint = new L.Point(p1.x + x2 * t, p1.y + y2 * t);
|
||||
x += dx * t;
|
||||
y += dy * t;
|
||||
}
|
||||
}
|
||||
apoint._sqDist = this._sqDist(p, apoint);
|
||||
return apoint;
|
||||
},
|
||||
|
||||
// distance from a point to a segment between two points
|
||||
_sqPointToSegmentDist: function (p, p1, p2) {
|
||||
return this._sqClosestPointOnSegment(p, p1, p2)._sqDist;
|
||||
dx = p.x - x;
|
||||
dy = p.y - y;
|
||||
|
||||
return sqDist ? dx * dx + dy * dy : new L.Point(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
@ -3347,7 +3444,7 @@ L.Polygon = L.Polyline.extend({
|
||||
initialize: function (latlngs, options) {
|
||||
L.Polyline.prototype.initialize.call(this, latlngs, options);
|
||||
|
||||
if (latlngs[0] instanceof Array) {
|
||||
if (latlngs && (latlngs[0] instanceof Array)) {
|
||||
this._latlngs = latlngs[0];
|
||||
this._holes = latlngs.slice(1);
|
||||
}
|
||||
@ -3987,7 +4084,7 @@ L.DomEvent = {
|
||||
},
|
||||
|
||||
disableClickPropagation: function (/*HTMLElement*/ el) {
|
||||
L.DomEvent.addListener(el, 'mousedown', L.DomEvent.stopPropagation);
|
||||
L.DomEvent.addListener(el, L.Draggable.START, L.DomEvent.stopPropagation);
|
||||
L.DomEvent.addListener(el, 'click', L.DomEvent.stopPropagation);
|
||||
L.DomEvent.addListener(el, 'dblclick', L.DomEvent.stopPropagation);
|
||||
},
|
||||
@ -4745,12 +4842,15 @@ L.Control.Zoom = L.Class.extend({
|
||||
|
||||
|
||||
L.Control.Attribution = L.Class.extend({
|
||||
initialize: function (prefix) {
|
||||
this._prefix = prefix || 'Powered by <a href="http://leaflet.cloudmade.com">Leaflet</a>';
|
||||
this._attributions = {};
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-attribution');
|
||||
L.DomEvent.disableClickPropagation(this._container);
|
||||
this._map = map;
|
||||
this._prefix = 'Powered by <a href="http://leaflet.cloudmade.com">Leaflet</a>';
|
||||
this._attributions = {};
|
||||
this._update();
|
||||
},
|
||||
|
||||
@ -5491,7 +5591,7 @@ L.Map.include({
|
||||
options = L.Util.extend({
|
||||
maxZoom: maxZoom || Infinity,
|
||||
setView: true
|
||||
});
|
||||
}, options);
|
||||
return this.locate(options);
|
||||
},
|
||||
|
||||
|
2
dist/leaflet.js
vendored
2
dist/leaflet.js
vendored
File diff suppressed because one or more lines are too long
@ -21,7 +21,7 @@ describe('LatLng', function() {
|
||||
it("should clamp longtitude to lie between -180 and 180", function() {
|
||||
var a = new L.LatLng(0, 190).lng;
|
||||
expect(a).toEqual(-170);
|
||||
|
||||
|
||||
var b = new L.LatLng(0, 360).lng;
|
||||
expect(b).toEqual(0);
|
||||
|
||||
@ -36,7 +36,13 @@ describe('LatLng', function() {
|
||||
|
||||
var f = new L.LatLng(0, -380).lng;
|
||||
expect(f).toEqual(-20);
|
||||
});
|
||||
|
||||
var g = new L.LatLng(0, 90).lng;
|
||||
expect(g).toEqual(90);
|
||||
|
||||
var h = new L.LatLng(0, 180).lng;
|
||||
expect(h).toEqual(180);
|
||||
});
|
||||
|
||||
it("should not clamp latitude and longtitude if unbounded flag set to true", function() {
|
||||
var a = new L.LatLng(150, 0, true).lat;
|
||||
|
@ -1,10 +1,13 @@
|
||||
L.Control.Attribution = L.Class.extend({
|
||||
initialize: function (prefix) {
|
||||
this._prefix = prefix || 'Powered by <a href="http://leaflet.cloudmade.com">Leaflet</a>';
|
||||
this._attributions = {};
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-attribution');
|
||||
L.DomEvent.disableClickPropagation(this._container);
|
||||
this._map = map;
|
||||
this._prefix = 'Powered by <a href="http://leaflet.cloudmade.com">Leaflet</a>';
|
||||
this._attributions = {};
|
||||
this._update();
|
||||
},
|
||||
|
||||
|
@ -112,7 +112,7 @@ L.DomEvent = {
|
||||
},
|
||||
|
||||
disableClickPropagation: function (/*HTMLElement*/ el) {
|
||||
L.DomEvent.addListener(el, 'mousedown', L.DomEvent.stopPropagation);
|
||||
L.DomEvent.addListener(el, L.Draggable.START, L.DomEvent.stopPropagation);
|
||||
L.DomEvent.addListener(el, 'click', L.DomEvent.stopPropagation);
|
||||
L.DomEvent.addListener(el, 'dblclick', L.DomEvent.stopPropagation);
|
||||
},
|
||||
|
@ -12,7 +12,7 @@ L.LatLng = function (/*Number*/ rawLat, /*Number*/ rawLng, /*Boolean*/ noWrap) {
|
||||
|
||||
if (noWrap !== true) {
|
||||
lat = Math.max(Math.min(lat, 90), -90); // clamp latitude into -90..90
|
||||
lng = (lng + 180) % 360 + (lng < -180 ? 180 : -180); // wrap longtitude into -180..180
|
||||
lng = (lng + 180) % 360 + ((lng < -180 || lng === 180) ? 180 : -180); // wrap longtitude into -180..180
|
||||
}
|
||||
|
||||
//TODO change to lat() & lng()
|
||||
@ -40,5 +40,21 @@ L.LatLng.prototype = {
|
||||
return 'LatLng(' +
|
||||
L.Util.formatNum(this.lat) + ', ' +
|
||||
L.Util.formatNum(this.lng) + ')';
|
||||
},
|
||||
|
||||
// Haversine distance formula, see http://en.wikipedia.org/wiki/Haversine_formula
|
||||
distanceTo: function (/*LatLng*/ other)/*->Double*/ {
|
||||
var R = 6378137, // earth radius in meters
|
||||
d2r = L.LatLng.DEG_TO_RAD,
|
||||
dLat = (other.lat - this.lat) * d2r,
|
||||
dLon = (other.lng - this.lng) * d2r,
|
||||
lat1 = this.lat * d2r,
|
||||
lat2 = other.lat * d2r,
|
||||
sin1 = Math.sin(dLat / 2),
|
||||
sin2 = Math.sin(dLon / 2);
|
||||
|
||||
var a = sin1 * sin1 + sin2 * sin2 * Math.cos(lat1) * Math.cos(lat2);
|
||||
|
||||
return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
}
|
||||
};
|
||||
|
@ -16,8 +16,8 @@ L.LatLngBounds = L.Class.extend({
|
||||
// extend the bounds to contain the given point
|
||||
extend: function (/*LatLng*/ latlng) {
|
||||
if (!this._southWest && !this._northEast) {
|
||||
this._southWest = new L.LatLng(latlng.lat, latlng.lng);
|
||||
this._northEast = new L.LatLng(latlng.lat, latlng.lng);
|
||||
this._southWest = new L.LatLng(latlng.lat, latlng.lng, true);
|
||||
this._northEast = new L.LatLng(latlng.lat, latlng.lng, true);
|
||||
} else {
|
||||
this._southWest.lat = Math.min(latlng.lat, this._southWest.lat);
|
||||
this._southWest.lng = Math.min(latlng.lng, this._southWest.lng);
|
||||
@ -41,11 +41,11 @@ L.LatLngBounds = L.Class.extend({
|
||||
},
|
||||
|
||||
getNorthWest: function () {
|
||||
return new L.LatLng(this._northEast.lat, this._southWest.lng);
|
||||
return new L.LatLng(this._northEast.lat, this._southWest.lng, true);
|
||||
},
|
||||
|
||||
getSouthEast: function () {
|
||||
return new L.LatLng(this._southWest.lat, this._northEast.lng);
|
||||
return new L.LatLng(this._southWest.lat, this._northEast.lng, true);
|
||||
},
|
||||
|
||||
contains: function (/*LatLngBounds or LatLng*/ obj) /*-> Boolean*/ {
|
||||
|
@ -46,5 +46,18 @@ L.Bounds = L.Class.extend({
|
||||
(max.x <= this.max.x) &&
|
||||
(min.y >= this.min.y) &&
|
||||
(max.y <= this.max.y);
|
||||
},
|
||||
|
||||
intersects: function (/*Bounds*/ bounds) {
|
||||
var min = this.min,
|
||||
max = this.max,
|
||||
min2 = bounds.min,
|
||||
max2 = bounds.max;
|
||||
|
||||
var xIntersects = (max2.x >= min.x) && (min2.x <= max.x),
|
||||
yIntersects = (max2.y >= min.y) && (min2.y <= max.y);
|
||||
|
||||
return xIntersects && yIntersects;
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -13,72 +13,80 @@ L.LineUtil = {
|
||||
return points.slice();
|
||||
}
|
||||
|
||||
var sqTolerance = tolerance * tolerance;
|
||||
|
||||
// stage 1: vertex reduction
|
||||
points = this.reducePoints(points, tolerance);
|
||||
points = this._reducePoints(points, sqTolerance);
|
||||
|
||||
// stage 2: Douglas-Peucker simplification
|
||||
points = this.simplifyDP(points, tolerance);
|
||||
points = this._simplifyDP(points, sqTolerance);
|
||||
|
||||
return points;
|
||||
},
|
||||
|
||||
// distance from a point to a segment between two points
|
||||
pointToSegmentDistance: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
|
||||
return Math.sqrt(this._sqPointToSegmentDist(p, p1, p2));
|
||||
return Math.sqrt(this._sqClosestPointOnSegment(p, p1, p2, true));
|
||||
},
|
||||
|
||||
closestPointOnSegment: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
|
||||
var point = this._sqClosestPointOnSegment(p, p1, p2);
|
||||
point.distance = Math.sqrt(point._sqDist);
|
||||
return point;
|
||||
return this._sqClosestPointOnSegment(p, p1, p2);
|
||||
},
|
||||
|
||||
// Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm
|
||||
simplifyDP: function (points, tol) {
|
||||
var maxDist2 = 0,
|
||||
index = 0,
|
||||
t2 = tol * tol,
|
||||
len = points.length,
|
||||
i, dist2;
|
||||
_simplifyDP: function (points, sqTolerance) {
|
||||
|
||||
if (len < 3) {
|
||||
return points;
|
||||
}
|
||||
var len = points.length,
|
||||
ArrayConstructor = typeof Uint8Array !== 'undefined' ? Uint8Array : Array,
|
||||
markers = new ArrayConstructor(len);
|
||||
|
||||
for (i = 0; i < len - 1; i++) {
|
||||
dist2 = this._sqPointToSegmentDist(points[i], points[0], points[len - 1]);
|
||||
if (dist2 > maxDist2) {
|
||||
index = i;
|
||||
maxDist2 = dist2;
|
||||
markers[0] = markers[len - 1] = 1;
|
||||
|
||||
this._simplifyDPStep(points, markers, sqTolerance, 0, len - 1);
|
||||
|
||||
var i,
|
||||
newPoints = [];
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (markers[i]) {
|
||||
newPoints.push(points[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var part1, part2;
|
||||
return newPoints;
|
||||
},
|
||||
|
||||
if (maxDist2 >= t2) {
|
||||
part1 = points.slice(0, index);
|
||||
part2 = points.slice(index);
|
||||
_simplifyDPStep: function (points, markers, sqTolerance, first, last) {
|
||||
|
||||
part1 = this.simplifyDP(part1, tol);
|
||||
part2 = this.simplifyDP(part2, tol);
|
||||
var maxSqDist = 0,
|
||||
index, i, sqDist;
|
||||
|
||||
return part1.concat(part2);
|
||||
} else {
|
||||
return [points[0], points[len - 1]];
|
||||
for (i = first + 1; i <= last - 1; i++) {
|
||||
sqDist = this._sqClosestPointOnSegment(points[i], points[first], points[last], true);
|
||||
|
||||
if (sqDist > maxSqDist) {
|
||||
index = i;
|
||||
maxSqDist = sqDist;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxSqDist > sqTolerance) {
|
||||
markers[index] = 1;
|
||||
|
||||
this._simplifyDPStep(points, markers, sqTolerance, first, index);
|
||||
this._simplifyDPStep(points, markers, sqTolerance, index, last);
|
||||
}
|
||||
},
|
||||
|
||||
// reduce points that are too close to each other to a single point
|
||||
reducePoints: function (points, tol) {
|
||||
var reducedPoints = [points[0]],
|
||||
t2 = tol * tol;
|
||||
_reducePoints: function (points, sqTolerance) {
|
||||
var reducedPoints = [points[0]];
|
||||
|
||||
for (var i = 1, prev = 0, len = points.length; i < len; i++) {
|
||||
if (this._sqDist(points[i], points[prev]) < t2) {
|
||||
continue;
|
||||
if (this._sqDist(points[i], points[prev]) > sqTolerance) {
|
||||
reducedPoints.push(points[i]);
|
||||
prev = i;
|
||||
}
|
||||
reducedPoints.push(points[i]);
|
||||
prev = i;
|
||||
}
|
||||
if (prev < len - 1) {
|
||||
reducedPoints.push(points[len - 1]);
|
||||
@ -168,27 +176,30 @@ L.LineUtil = {
|
||||
return dx * dx + dy * dy;
|
||||
},
|
||||
|
||||
// return closest point on segment with attribute _sqDist - square distance to segment
|
||||
_sqClosestPointOnSegment: function (p, p1, p2) {
|
||||
var x2 = p2.x - p1.x,
|
||||
y2 = p2.y - p1.y,
|
||||
apoint = p1;
|
||||
if (x2 || y2) {
|
||||
var dot = (p.x - p1.x) * x2 + (p.y - p1.y) * y2,
|
||||
t = dot / this._sqDist(p1, p2);
|
||||
// return closest point on segment or distance to that point
|
||||
_sqClosestPointOnSegment: function (p, p1, p2, sqDist) {
|
||||
var x = p1.x,
|
||||
y = p1.y,
|
||||
dx = p2.x - x,
|
||||
dy = p2.y - y,
|
||||
dot = dx * dx + dy * dy,
|
||||
t;
|
||||
|
||||
if (dot > 0) {
|
||||
t = ((p.x - x) * dx + (p.y - y) * dy) / dot;
|
||||
|
||||
if (t > 1) {
|
||||
apoint = p2;
|
||||
x = p2.x;
|
||||
y = p2.y;
|
||||
} else if (t > 0) {
|
||||
apoint = new L.Point(p1.x + x2 * t, p1.y + y2 * t);
|
||||
x += dx * t;
|
||||
y += dy * t;
|
||||
}
|
||||
}
|
||||
apoint._sqDist = this._sqDist(p, apoint);
|
||||
return apoint;
|
||||
},
|
||||
|
||||
// distance from a point to a segment between two points
|
||||
_sqPointToSegmentDist: function (p, p1, p2) {
|
||||
return this._sqClosestPointOnSegment(p, p1, p2)._sqDist;
|
||||
dx = p.x - x;
|
||||
dy = p.y - y;
|
||||
|
||||
return sqDist ? dx * dx + dy * dy : new L.Point(x, y);
|
||||
}
|
||||
};
|
||||
|
@ -8,7 +8,8 @@ L.Popup = L.Class.extend({
|
||||
autoPan: true,
|
||||
closeButton: true,
|
||||
offset: new L.Point(0, 2),
|
||||
autoPanPadding: new L.Point(5, 5)
|
||||
autoPanPadding: new L.Point(5, 5),
|
||||
className: ''
|
||||
},
|
||||
|
||||
initialize: function (options, source) {
|
||||
@ -75,7 +76,7 @@ L.Popup = L.Class.extend({
|
||||
},
|
||||
|
||||
_initLayout: function () {
|
||||
this._container = L.DomUtil.create('div', 'leaflet-popup');
|
||||
this._container = L.DomUtil.create('div', 'leaflet-popup ' + this.options.className);
|
||||
|
||||
if (this.options.closeButton) {
|
||||
this._closeButton = L.DomUtil.create('a', 'leaflet-popup-close-button', this._container);
|
||||
|
@ -24,13 +24,19 @@ L.Icon = L.Class.extend({
|
||||
|
||||
_createIcon: function (name) {
|
||||
var size = this[name + 'Size'],
|
||||
src = this[name + 'Url'],
|
||||
img = this._createImg(src);
|
||||
|
||||
if (!src) {
|
||||
src = this[name + 'Url'];
|
||||
if (!src && name === 'shadow') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var img;
|
||||
if (!src) {
|
||||
img = this._createDiv();
|
||||
}
|
||||
else {
|
||||
img = this._createImg(src);
|
||||
}
|
||||
|
||||
img.className = 'leaflet-marker-' + name;
|
||||
|
||||
img.style.marginLeft = (-this.iconAnchor.x) + 'px';
|
||||
@ -54,5 +60,9 @@ L.Icon = L.Class.extend({
|
||||
el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '")';
|
||||
}
|
||||
return el;
|
||||
},
|
||||
|
||||
_createDiv: function () {
|
||||
return document.createElement('div');
|
||||
}
|
||||
});
|
||||
|
@ -5,7 +5,9 @@
|
||||
L.Marker.include({
|
||||
openPopup: function () {
|
||||
this._popup.setLatLng(this._latlng);
|
||||
this._map.openPopup(this._popup);
|
||||
if (this._map) {
|
||||
this._map.openPopup(this._popup);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
@ -10,7 +10,8 @@ L.Marker = L.Class.extend({
|
||||
icon: new L.Icon(),
|
||||
title: '',
|
||||
clickable: true,
|
||||
draggable: false
|
||||
draggable: false,
|
||||
zIndexOffset: 0
|
||||
},
|
||||
|
||||
initialize: function (latlng, options) {
|
||||
@ -104,8 +105,7 @@ L.Marker = L.Class.extend({
|
||||
L.DomUtil.setPosition(this._shadow, pos);
|
||||
}
|
||||
|
||||
this._icon.style.zIndex = pos.y;
|
||||
// TODO zIndex offset
|
||||
this._icon.style.zIndex = pos.y + this.options.zIndexOffset;
|
||||
},
|
||||
|
||||
_initInteraction: function () {
|
||||
|
@ -7,6 +7,17 @@ L.TileLayer.Canvas = L.TileLayer.extend({
|
||||
L.Util.setOptions(this, options);
|
||||
},
|
||||
|
||||
redraw: function () {
|
||||
for (var i in this._tiles) {
|
||||
var tile = this._tiles[i];
|
||||
this._redrawTile(tile);
|
||||
}
|
||||
},
|
||||
|
||||
_redrawTile: function (tile) {
|
||||
this.drawTile(tile, tile._tilePoint, tile._zoom);
|
||||
},
|
||||
|
||||
_createTileProto: function () {
|
||||
this._canvasProto = L.DomUtil.create('canvas', 'leaflet-tile');
|
||||
|
||||
@ -23,6 +34,8 @@ L.TileLayer.Canvas = L.TileLayer.extend({
|
||||
|
||||
_loadTile: function (tile, tilePoint, zoom) {
|
||||
tile._layer = this;
|
||||
tile._tilePoint = tilePoint;
|
||||
tile._zoom = zoom;
|
||||
|
||||
this.drawTile(tile, tilePoint, zoom);
|
||||
|
||||
|
@ -17,9 +17,11 @@ L.TileLayer = L.Class.extend({
|
||||
continuousWorld: false,
|
||||
noWrap: false,
|
||||
zoomOffset: 0,
|
||||
zoomReverse: false,
|
||||
|
||||
unloadInvisibleTiles: L.Browser.mobile,
|
||||
updateWhenIdle: L.Browser.mobile
|
||||
updateWhenIdle: L.Browser.mobile,
|
||||
reuseTiles: false
|
||||
},
|
||||
|
||||
initialize: function (url, options, urlParams) {
|
||||
@ -125,6 +127,10 @@ L.TileLayer = L.Class.extend({
|
||||
}
|
||||
this._tiles = {};
|
||||
|
||||
if (this.options.reuseTiles) {
|
||||
this._unusedTiles = [];
|
||||
}
|
||||
|
||||
if (clearOldContainer && this._container) {
|
||||
this._container.innerHTML = "";
|
||||
}
|
||||
@ -145,7 +151,7 @@ L.TileLayer = L.Class.extend({
|
||||
|
||||
this._addTilesFromCenterOut(tileBounds);
|
||||
|
||||
if (this.options.unloadInvisibleTiles) {
|
||||
if (this.options.unloadInvisibleTiles || this.options.reuseTiles) {
|
||||
this._removeOtherTiles(tileBounds);
|
||||
}
|
||||
},
|
||||
@ -196,9 +202,14 @@ L.TileLayer = L.Class.extend({
|
||||
// evil, don't do this! crashes Android 3, produces load errors, doesn't solve memory leaks
|
||||
// this._tiles[key].src = '';
|
||||
|
||||
//tile.src = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
|
||||
|
||||
if (tile.parentNode === this._container) {
|
||||
this._container.removeChild(tile);
|
||||
}
|
||||
if (this.options.reuseTiles) {
|
||||
this._unusedTiles.push(this._tiles[key]);
|
||||
}
|
||||
delete this._tiles[key];
|
||||
}
|
||||
}
|
||||
@ -209,7 +220,7 @@ L.TileLayer = L.Class.extend({
|
||||
var tilePos = this._getTilePos(tilePoint),
|
||||
zoom = this._map.getZoom(),
|
||||
key = tilePoint.x + ':' + tilePoint.y,
|
||||
tileLimit = Math.pow(2, (zoom + this.options.zoomOffset));
|
||||
tileLimit = Math.pow(2, this._getOffsetZoom(zoom));
|
||||
|
||||
// wrap tile coordinates
|
||||
if (!this.options.continuousWorld) {
|
||||
@ -226,8 +237,8 @@ L.TileLayer = L.Class.extend({
|
||||
}
|
||||
}
|
||||
|
||||
// create tile
|
||||
var tile = this._createTile();
|
||||
// get unused tile - or create a new tile
|
||||
var tile = this._getTile();
|
||||
L.DomUtil.setPosition(tile, tilePos);
|
||||
|
||||
this._tiles[key] = tile;
|
||||
@ -241,6 +252,11 @@ L.TileLayer = L.Class.extend({
|
||||
container.appendChild(tile);
|
||||
},
|
||||
|
||||
_getOffsetZoom: function (zoom) {
|
||||
zoom = this.options.zoomReverse ? this.options.maxZoom - zoom : zoom;
|
||||
return zoom + this.options.zoomOffset;
|
||||
},
|
||||
|
||||
_getTilePos: function (tilePoint) {
|
||||
var origin = this._map.getPixelOrigin(),
|
||||
tileSize = this.options.tileSize;
|
||||
@ -256,7 +272,7 @@ L.TileLayer = L.Class.extend({
|
||||
|
||||
return L.Util.template(this._url, L.Util.extend({
|
||||
s: s,
|
||||
z: zoom + this.options.zoomOffset,
|
||||
z: this._getOffsetZoom(zoom),
|
||||
x: tilePoint.x,
|
||||
y: tilePoint.y
|
||||
}, this._urlParams));
|
||||
@ -271,6 +287,19 @@ L.TileLayer = L.Class.extend({
|
||||
this._tileImg.style.height = tileSize + 'px';
|
||||
},
|
||||
|
||||
_getTile: function () {
|
||||
if (this.options.reuseTiles && this._unusedTiles.length > 0) {
|
||||
var tile = this._unusedTiles.pop();
|
||||
this._resetTile(tile);
|
||||
return tile;
|
||||
}
|
||||
return this._createTile();
|
||||
},
|
||||
|
||||
_resetTile: function (tile) {
|
||||
// Override if data stored on a tile needs to be cleaned up before reuse
|
||||
},
|
||||
|
||||
_createTile: function () {
|
||||
var tile = this._tileImg.cloneNode(false);
|
||||
tile.onselectstart = tile.onmousemove = L.Util.falseFn;
|
||||
|
@ -5,7 +5,7 @@
|
||||
L.Path.include({
|
||||
bindPopup: function (content, options) {
|
||||
if (!this._popup || this._popup.options !== options) {
|
||||
this._popup = new L.Popup(options);
|
||||
this._popup = new L.Popup(options, this);
|
||||
}
|
||||
this._popup.setContent(content);
|
||||
|
||||
|
@ -10,7 +10,7 @@ L.Polygon = L.Polyline.extend({
|
||||
initialize: function (latlngs, options) {
|
||||
L.Polyline.prototype.initialize.call(this, latlngs, options);
|
||||
|
||||
if (latlngs[0] instanceof Array) {
|
||||
if (latlngs && (latlngs[0] instanceof Array)) {
|
||||
this._latlngs = latlngs[0];
|
||||
this._holes = latlngs.slice(1);
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ L.Map = L.Class.extend({
|
||||
return this;
|
||||
}
|
||||
|
||||
this._rawPanBy(oldSize.subtract(this.getSize()).divideBy(2));
|
||||
this._rawPanBy(oldSize.subtract(this.getSize()).divideBy(2, true));
|
||||
|
||||
this.fire('move');
|
||||
|
||||
@ -280,8 +280,8 @@ L.Map = L.Class.extend({
|
||||
|
||||
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));
|
||||
sw = this.unproject(new L.Point(bounds.min.x, bounds.max.y), this._zoom, true),
|
||||
ne = this.unproject(new L.Point(bounds.max.x, bounds.min.y), this._zoom, true);
|
||||
return new L.LatLngBounds(sw, ne);
|
||||
},
|
||||
|
||||
@ -328,7 +328,7 @@ L.Map = L.Class.extend({
|
||||
}
|
||||
} while (zoomNotFound && (zoom <= maxZoom));
|
||||
|
||||
if (zoomNotFound) {
|
||||
if (zoomNotFound && inside) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -510,7 +510,7 @@ L.Map = L.Class.extend({
|
||||
_initEvents: function () {
|
||||
L.DomEvent.addListener(this._container, 'click', this._onMouseClick, this);
|
||||
|
||||
var events = ['dblclick', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove'];
|
||||
var events = ['dblclick', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'contextmenu'];
|
||||
|
||||
var i, len;
|
||||
|
||||
@ -548,6 +548,10 @@ L.Map = L.Class.extend({
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === 'contextmenu') {
|
||||
L.DomEvent.preventDefault(e);
|
||||
}
|
||||
|
||||
this.fire(type, {
|
||||
latlng: this.mouseEventToLatLng(e),
|
||||
layerPoint: this.mouseEventToLayerPoint(e)
|
||||
|
@ -42,7 +42,7 @@ L.Map.include({
|
||||
options = L.Util.extend({
|
||||
maxZoom: maxZoom || Infinity,
|
||||
setView: true
|
||||
});
|
||||
}, options);
|
||||
return this.locate(options);
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user