Merge branch 'master' into nested-polygons

This commit is contained in:
Yohan Boniface 2015-05-08 13:10:49 +02:00
commit 8b97b905e8
14 changed files with 109 additions and 22 deletions

4
FAQ.md
View File

@ -30,7 +30,7 @@ with over seventy different layers to choose from.
Popular commercial options, free up to a particular number of requests, include
[MapBox](http://mapbox.com),
[Bing Maps](http://www.microsoft.com/maps/choose-your-bing-maps-API.aspx) (using a [plugin](https://github.com/shramov/leaflet-plugins)),
[Esri ArcGIS](http://www.arcgis.com/features/maps/imagery.html) ([official plugin](https://github.com/Esri/esri-leaflet))
[Esri ArcGIS](http://www.esri.com/software/arcgis/arcgisonline/maps/maps-and-map-layers) ([official plugin](https://github.com/Esri/esri-leaflet))
and [Nokia Here](http://developer.here.com/web-experiences).
A notable exception is [MapQuest Open](http://developer.mapquest.com/web/products/open/map), which is free for any number of requests.
@ -40,7 +40,7 @@ Always be sure to **read the terms of use** of a chosen tile provider, **know it
[MapBox](http://mapbox.com),
[Bing Maps](http://www.microsoft.com/maps/choose-your-bing-maps-API.aspx),
[ArcGIS](http://www.arcgis.com/features/maps/imagery.html)
[ArcGIS](http://www.esri.com/software/arcgis/arcgisonline/maps/maps-and-map-layers)
and [MapQuest Open](http://developer.mapquest.com/web/products/open/map) provide satellite imagery among others.
#### I want to use Google Maps API tiles with Leaflet, can I do that?

View File

@ -33,6 +33,8 @@
var latlngs = L.rectangle(bounds).getLatLngs();
L.polyline(latlngs.concat([latlngs[0]])).addTo(map);
map.setMaxBounds(bounds); // Should not enter infinite recursion
</script>
</body>
</html>

View File

@ -27,6 +27,7 @@
<button id="kyiv">Kyiv</button> -->
<button id="dc">DC</button>
<button id="sf">SF</button>
<button id="trd">TRD</button>
<button id="stop">stop</button>
</div>
@ -36,6 +37,7 @@
london = [51.51, -0.12],
sf = [37.77, -122.42],
dc = [38.91, -77.04];
trd = [63.41, 10.41];
var map = L.map('map').setView(dc, 10);
@ -51,6 +53,7 @@
document.getElementById('dc').onclick = function () { map.flyTo(dc, 10); };
document.getElementById('sf').onclick = function () { map.flyTo(sf, 10); };
document.getElementById('trd').onclick = function () { map.flyTo(trd, 10, {duration: 20}); };
document.getElementById('stop').onclick = function () { map.stop(); };
// document.getElementById('london').onclick = function () { map.flyTo(london); };
// document.getElementById('kyiv').onclick = function () { map.flyTo(kyiv); };

View File

@ -63,6 +63,14 @@ describe("CRS.EPSG3857", function () {
expect(crs.wrapLatLng(new L.LatLng(0, 180)).lng).to.eql(180);
});
it("does not drop altitude", function () {
expect(crs.wrapLatLng(new L.LatLng(0, 190, 1234)).lng).to.eql(-170);
expect(crs.wrapLatLng(new L.LatLng(0, 190, 1234)).alt).to.eql(1234);
expect(crs.wrapLatLng(new L.LatLng(0, 380, 1234)).lng).to.eql(20);
expect(crs.wrapLatLng(new L.LatLng(0, 380, 1234)).alt).to.eql(1234);
});
});
});

View File

@ -116,4 +116,25 @@ describe('LatLng', function () {
expect(L.latLng({lat: 50, lon: 30, alt: 100})).to.eql(new L.LatLng(50, 30, 100));
});
});
describe('#clone', function () {
it('should clone attributes', function () {
var a = new L.LatLng(50.5, 30.5, 100);
var b = a.clone();
expect(b.lat).to.equal(50.5);
expect(b.lng).to.equal(30.5);
expect(b.alt).to.equal(100);
});
it('should create another reference', function () {
var a = new L.LatLng(50.5, 30.5, 100);
var b = a.clone();
expect(a === b).to.be(false);
});
});
});

View File

@ -108,4 +108,29 @@ describe('Polyline', function () {
});
describe('#_flat', function () {
var layer = L.polyline([]);
it('should return true for an array of LatLngs', function () {
expect(L.Polyline._flat([L.latLng([0, 0])])).to.be(true);
});
it('should return true for an array of LatLngs arrays', function () {
expect(L.Polyline._flat([[0, 0]])).to.be(true);
});
it('should return true for an empty array', function () {
expect(L.Polyline._flat([])).to.be(true);
});
it('should return false for a nested array of LatLngs', function () {
expect(L.Polyline._flat([[L.latLng([0, 0])]])).to.be(false);
});
it('should return false for a nested empty array', function () {
expect(L.Polyline._flat([[]])).to.be(false);
});
});
});

View File

@ -13,8 +13,9 @@
phantomjs = ua.indexOf('phantom') !== -1,
android23 = ua.search('android [23]') !== -1,
chrome = ua.indexOf('chrome') !== -1,
gecko = ua.indexOf('gecko') !== -1 && !webkit && !window.opera && !ie,
mobile = typeof orientation !== 'undefined',
mobile = typeof orientation !== 'undefined' || ua.indexOf('mobile') !== -1,
msPointer = navigator.msPointerEnabled && navigator.msMaxTouchPoints && !window.PointerEvent,
pointer = (window.PointerEvent && navigator.pointerEnabled && navigator.maxTouchPoints) || msPointer,
@ -30,7 +31,7 @@
ie: ie,
ielt9: ie && !document.addEventListener,
webkit: webkit,
gecko: (ua.indexOf('gecko') !== -1) && !webkit && !window.opera && !ie,
gecko: gecko,
android: ua.indexOf('android') !== -1,
android23: android23,
chrome: chrome,
@ -46,6 +47,7 @@
mobileWebkit: mobile && webkit,
mobileWebkit3d: mobile && webkit3d,
mobileOpera: mobile && window.opera,
mobileGecko: mobile && gecko,
touch: !!touch,
msPointer: !!msPointer,

View File

@ -49,6 +49,10 @@ L.LatLng.prototype = {
return L.latLngBounds(
[this.lat - latAccuracy, this.lng - lngAccuracy],
[this.lat + latAccuracy, this.lng + lngAccuracy]);
},
clone: function () {
return new L.LatLng(this.lat, this.lng, this.alt);
}
};

View File

@ -56,8 +56,9 @@ L.CRS = {
// wraps geo coords in certain ranges if applicable
wrapLatLng: function (latlng) {
var lng = this.wrapLng ? L.Util.wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng,
lat = this.wrapLat ? L.Util.wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat;
lat = this.wrapLat ? L.Util.wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat,
alt = latlng.alt;
return L.latLng(lat, lng);
return L.latLng(lat, lng, alt);
}
};

View File

@ -190,7 +190,7 @@ L.Circle.include(PointToGeoJSON);
L.CircleMarker.include(PointToGeoJSON);
L.Polyline.prototype.toGeoJSON = function () {
var multi = !this._flat(this._latlngs);
var multi = !L.Polyline._flat(this._latlngs);
var coords = L.GeoJSON.latLngsToCoords(this._latlngs, multi ? 1 : 0);
@ -201,8 +201,8 @@ L.Polyline.prototype.toGeoJSON = function () {
};
L.Polygon.prototype.toGeoJSON = function () {
var holes = !this._flat(this._latlngs),
multi = holes && !this._flat(this._latlngs[0]);
var holes = !L.Polyline._flat(this._latlngs),
multi = holes && !L.Polyline._flat(this._latlngs[0]);
var coords = L.GeoJSON.latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true);

View File

@ -98,7 +98,7 @@ L.Polyline = L.Path.extend({
// recursively convert latlngs input into actual LatLng instances; calculate bounds along the way
_convertLatLngs: function (latlngs) {
var result = [],
flat = this._flat(latlngs);
flat = L.Polyline._flat(latlngs);
for (var i = 0, len = latlngs.length; i < len; i++) {
if (flat) {
@ -112,11 +112,6 @@ L.Polyline = L.Path.extend({
return result;
},
_flat: function (latlngs) {
// true if it's a flat array of latlngs; false if nested
return !L.Util.isArray(latlngs[0]) || typeof latlngs[0][0] !== 'object';
},
_project: function () {
this._rings = [];
this._projectLatlngs(this._latlngs, this._rings);
@ -211,3 +206,8 @@ L.Polyline = L.Path.extend({
L.polyline = function (latlngs, options) {
return new L.Polyline(latlngs, options);
};
L.Polyline._flat = function (latlngs) {
// true if it's a flat array of latlngs; false if nested
return !L.Util.isArray(latlngs[0]) || (typeof latlngs[0][0] !== 'object' && typeof latlngs[0][0] !== 'undefined');
};

View File

@ -88,7 +88,7 @@ L.Map = L.Evented.extend({
return this.setView(newCenter, zoom, {zoom: options});
},
fitBounds: function (bounds, options) {
_getBoundsCenterZoom: function (bounds, options) {
options = options || {};
bounds = bounds.getBounds ? bounds.getBounds() : L.latLngBounds(bounds);
@ -106,7 +106,15 @@ L.Map = L.Evented.extend({
nePoint = this.project(bounds.getNorthEast(), zoom),
center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom);
return this.setView(center, zoom, options);
return {
center: center,
zoom: zoom
};
},
fitBounds: function (bounds, options) {
var target = this._getBoundsCenterZoom(bounds, options);
return this.setView(target.center, target.zoom, options);
},
fitWorld: function (options) {
@ -130,12 +138,14 @@ L.Map = L.Evented.extend({
setMaxBounds: function (bounds) {
bounds = L.latLngBounds(bounds);
this.options.maxBounds = bounds;
if (!bounds) {
return this.off('moveend', this._panInsideMaxBounds);
} else if (this.options.maxBounds) {
this.off('moveend', this._panInsideMaxBounds);
}
this.options.maxBounds = bounds;
if (this._loaded) {
this._panInsideMaxBounds();
}

View File

@ -1,6 +1,11 @@
L.Map.include({
flyTo: function (targetCenter, targetZoom) {
flyTo: function (targetCenter, targetZoom, options) {
options = options || {};
if (options.animate === false) {
return this.setView(targetCenter, targetZoom, options);
}
this.stop();
@ -36,7 +41,7 @@ L.Map.include({
var start = Date.now(),
S = (r(1) - r0) / rho,
duration = 1000 * S * 0.8;
duration = options.duration ? 1000 * options.duration : 1000 * S * 0.8;
function frame() {
var t = (Date.now() - start) / duration,
@ -56,5 +61,11 @@ L.Map.include({
this.fire('zoomstart');
frame.call(this);
return this;
},
flyToBounds: function(bounds, options) {
var target = this._getBoundsCenterZoom(bounds, options);
return this.flyTo(target.center, target.zoom, options);
}
});

View File

@ -16,7 +16,7 @@ L.Map.include({
options = this._locateOptions = L.extend({}, this._defaultLocateOptions, options);
if (!navigator.geolocation) {
if (!('geolocation' in navigator)) {
this._handleGeolocationError({
code: 0,
message: 'Geolocation not supported.'