diff options
Diffstat (limited to 'extlib/leaflet/src/map/ext')
-rw-r--r-- | extlib/leaflet/src/map/ext/Map.Control.js | 50 | ||||
-rw-r--r-- | extlib/leaflet/src/map/ext/Map.Geolocation.js | 69 | ||||
-rw-r--r-- | extlib/leaflet/src/map/ext/Map.PanAnimation.js | 62 | ||||
-rw-r--r-- | extlib/leaflet/src/map/ext/Map.Popup.js | 15 | ||||
-rw-r--r-- | extlib/leaflet/src/map/ext/Map.ZoomAnimation.js | 124 |
5 files changed, 320 insertions, 0 deletions
diff --git a/extlib/leaflet/src/map/ext/Map.Control.js b/extlib/leaflet/src/map/ext/Map.Control.js new file mode 100644 index 00000000..46711a82 --- /dev/null +++ b/extlib/leaflet/src/map/ext/Map.Control.js @@ -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); + } +});
\ No newline at end of file diff --git a/extlib/leaflet/src/map/ext/Map.Geolocation.js b/extlib/leaflet/src/map/ext/Map.Geolocation.js new file mode 100644 index 00000000..328662b9 --- /dev/null +++ b/extlib/leaflet/src/map/ext/Map.Geolocation.js @@ -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
+ });
+ }
+});
\ No newline at end of file diff --git a/extlib/leaflet/src/map/ext/Map.PanAnimation.js b/extlib/leaflet/src/map/ext/Map.PanAnimation.js new file mode 100644 index 00000000..02ccfd15 --- /dev/null +++ b/extlib/leaflet/src/map/ext/Map.PanAnimation.js @@ -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);
+ }
+});
\ No newline at end of file diff --git a/extlib/leaflet/src/map/ext/Map.Popup.js b/extlib/leaflet/src/map/ext/Map.Popup.js new file mode 100644 index 00000000..8b8de937 --- /dev/null +++ b/extlib/leaflet/src/map/ext/Map.Popup.js @@ -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;
+ }
+});
\ No newline at end of file diff --git a/extlib/leaflet/src/map/ext/Map.ZoomAnimation.js b/extlib/leaflet/src/map/ext/Map.ZoomAnimation.js new file mode 100644 index 00000000..4bf7b9bf --- /dev/null +++ b/extlib/leaflet/src/map/ext/Map.ZoomAnimation.js @@ -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 = '';
+ }
+ }
+});
\ No newline at end of file |