We need more flexibility than L.Hash provides.
from 'git://github.com/jfirebaugh/leaflet-osm.git' do
file 'leaflet.osm.js', 'leaflet-osm.js'
end
-
- from 'git://github.com/mlevans/leaflet-hash.git' do
- file 'leaflet.hash.js', 'leaflet-hash.js'
- end
end
folder 'ohauth' do
//= require osm
//= require leaflet
//= require leaflet.osm
-//= require leaflet.hash
//= require leaflet.map
//= require leaflet.zoom
//= require leaflet.locationfilter
map.attributionControl.setPrefix('');
- map.hash = L.hash(map);
-
- $(window).on('popstate', function(e) {
- // popstate is triggered when the hash changes as well as on actual navigation
- // events. We want to update the hash on the latter and not the former.
- if (e.originalEvent.state) {
- map.hash.update();
- }
- });
-
- map.updateLayers(params);
-
- $(window).on("hashchange", function () {
- map.updateLayers(OSM.mapParams());
- });
+ map.updateLayers(params.layers);
map.on("baselayerchange", function (e) {
if (map.getZoom() > e.layer.options.maxZoom) {
var expiry = new Date();
expiry.setYear(expiry.getFullYear() + 10);
$.cookie("_osm_location", cookieContent(map), { expires: expiry });
-
- // Trigger hash update on layer changes.
- map.hash.onMapMove();
});
if (OSM.PIWIK) {
var history = OSM.History(map),
note = OSM.Note(map);
- OSM.route = OSM.Router({
+ OSM.route = OSM.Router(map, {
"/": OSM.Index(map),
"/search": OSM.Search(map),
"/export": OSM.Export(map),
} else {
map.removeLayer(layer);
}
+ map.fire('overlaylayerchange', {layer: layer});
});
map.on('layeradd layerremove', function() {
this.dataLayer.options.code = 'D';
},
- updateLayers: function(params) {
- var layerParam = params.layers || "M";
+ updateLayers: function(layerParam) {
+ layerParam = layerParam || "M";
var layersAdded = "";
for (var i = this.baseLayers.length - 1; i >= 0; i--) {
}
});
-L.Hash.prototype.parseHash = OSM.parseHash;
-L.Hash.prototype.formatHash = OSM.formatHash;
-
function getUserIcon(url) {
return L.icon({
iconUrl: url || <%= asset_path('marker-red.png').to_json %>,
},
parseHash: function(hash) {
- if (hash.indexOf('#') === 0) {
- hash = hash.substr(1);
+ var i = hash.indexOf('#');
+ if (i < 0) {
+ return false;
}
+
+ hash = hash.substr(i + 1);
+
if (hash === '') {
return false;
}
+
hash = querystring.parse(hash);
- var args = L.Hash.parseHash(hash.map || '') || {};
- if (hash.layers) args.layers = hash.layers;
+
+ var args = hash.map.split("/");
+ if (args.length !== 3) {
+ return false;
+ }
+
+ var zoom = parseInt(args[0], 10),
+ lat = parseFloat(args[1]),
+ lon = parseFloat(args[2]);
+
+ if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
+ return false;
+ }
+
+ args = {
+ center: new L.LatLng(lat, lon),
+ zoom: zoom
+ };
+
+ if (hash.layers) {
+ args.layers = hash.layers;
+ }
+
return args;
},
-OSM.Router = function(rts) {
+OSM.Router = function(map, rts) {
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
var optionalParam = /\((.*?)\)/g;
var namedParam = /(\(\?)?:\w+/g;
};
var currentPath = window.location.pathname + window.location.search,
- currentRoute = routes.recognize(currentPath);
+ currentRoute = routes.recognize(currentPath),
+ currentHash = location.hash || OSM.formatHash(map);
currentRoute.run('load', currentPath);
+ var stateChange;
+
+ map.on('moveend baselayerchange overlaylayerchange', function() {
+ var hash = OSM.formatHash(map);
+ if (hash === currentHash) return;
+ currentHash = hash;
+ stateChange(OSM.parseHash(hash), hash);
+ });
+
+ $(window).on('hashchange', function() {
+ var hash = location.hash;
+ if (hash === currentHash) return;
+ currentHash = hash;
+ var state = OSM.parseHash(hash);
+ if (!state) return;
+ map.setView(state.center, state.zoom);
+ map.updateLayers(state.layers);
+ stateChange(state, hash);
+ });
+
if (window.history && window.history.pushState) {
+ stateChange = function(state, hash) {
+ window.history.replaceState(state, document.title, hash);
+ };
+
// Set a non-null initial state, so that the e.originalEvent.state
// check below works correctly when going back to the initial page.
- window.history.replaceState({}, document.title, window.location);
+ stateChange(OSM.parseHash(currentHash), currentPath + currentHash);
$(window).on('popstate', function(e) {
if (!e.originalEvent.state) return; // Is it a real popstate event or just a hash change?
currentPath = path;
currentRoute = routes.recognize(currentPath);
currentRoute.run('popstate', currentPath);
+ var state = e.originalEvent.state;
+ map.setView(state.center, state.zoom);
+ map.updateLayers(state.layers);
});
return function (url) {
var path = url.replace(/#.*/, ''),
route = routes.recognize(path);
if (!route) return false;
- window.history.pushState({}, document.title, url);
+ window.history.pushState(OSM.parseHash(url) || {}, document.title, url);
currentRoute.run('unload');
currentPath = path;
currentRoute = route;
return true;
}
} else {
+ stateChange = function(state, hash) {
+ window.location.replace(hash);
+ };
+
return function (url) {
window.location.assign(url);
}
+++ /dev/null
-(function(window) {
- var HAS_HASHCHANGE = (function() {
- var doc_mode = window.documentMode;
- return ('onhashchange' in window) &&
- (doc_mode === undefined || doc_mode > 7);
- })();
-
- L.Hash = function(map) {
- this.onHashChange = L.Util.bind(this.onHashChange, this);
-
- if (map) {
- this.init(map);
- }
- };
-
- L.Hash.parseHash = function(hash) {
- if(hash.indexOf('#') === 0) {
- hash = hash.substr(1);
- }
- var args = hash.split("/");
- if (args.length == 3) {
- var zoom = parseInt(args[0], 10),
- lat = parseFloat(args[1]),
- lon = parseFloat(args[2]);
- if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
- return false;
- } else {
- return {
- center: new L.LatLng(lat, lon),
- zoom: zoom
- };
- }
- } else {
- return false;
- }
- };
-
- L.Hash.formatHash = function(map) {
- var center = map.getCenter(),
- zoom = map.getZoom(),
- precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
-
- return "#" + [zoom,
- center.lat.toFixed(precision),
- center.lng.toFixed(precision)
- ].join("/");
- },
-
- L.Hash.prototype = {
- map: null,
- lastHash: null,
-
- parseHash: L.Hash.parseHash,
- formatHash: L.Hash.formatHash,
-
- init: function(map) {
- this.map = map;
-
- // reset the hash
- this.lastHash = null;
- this.onHashChange();
-
- if (!this.isListening) {
- this.startListening();
- }
- },
-
- remove: function() {
- if (this.changeTimeout) {
- clearTimeout(this.changeTimeout);
- }
-
- if (this.isListening) {
- this.stopListening();
- }
-
- this.map = null;
- },
-
- onMapMove: function() {
- // bail if we're moving the map (updating from a hash),
- // or if the map is not yet loaded
-
- if (this.movingMap || !this.map._loaded) {
- return false;
- }
-
- var hash = this.formatHash(this.map);
- if (this.lastHash != hash) {
- location.replace(hash);
- this.lastHash = hash;
- }
- },
-
- movingMap: false,
- update: function() {
- var hash = location.hash;
- if (hash === this.lastHash) {
- return;
- }
- var parsed = this.parseHash(hash);
- if (parsed) {
- this.movingMap = true;
-
- this.map.setView(parsed.center, parsed.zoom);
-
- this.movingMap = false;
- } else {
- this.onMapMove(this.map);
- }
- },
-
- // defer hash change updates every 100ms
- changeDefer: 100,
- changeTimeout: null,
- onHashChange: function() {
- // throttle calls to update() so that they only happen every
- // `changeDefer` ms
- if (!this.changeTimeout) {
- var that = this;
- this.changeTimeout = setTimeout(function() {
- that.update();
- that.changeTimeout = null;
- }, this.changeDefer);
- }
- },
-
- isListening: false,
- hashChangeInterval: null,
- startListening: function() {
- this.map.on("moveend", this.onMapMove, this);
-
- if (HAS_HASHCHANGE) {
- L.DomEvent.addListener(window, "hashchange", this.onHashChange);
- } else {
- clearInterval(this.hashChangeInterval);
- this.hashChangeInterval = setInterval(this.onHashChange, 50);
- }
- this.isListening = true;
- },
-
- stopListening: function() {
- this.map.off("moveend", this.onMapMove, this);
-
- if (HAS_HASHCHANGE) {
- L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
- } else {
- clearInterval(this.hashChangeInterval);
- }
- this.isListening = false;
- }
- };
- L.hash = function(map) {
- return new L.Hash(map);
- };
- L.Map.prototype.addHash = function() {
- this._hash = L.hash(this);
- };
- L.Map.prototype.removeHash = function() {
- this._hash.remove();
- };
-})(window);