diff --git a/index.html b/index.html
index 949624c..65bdec0 100644
--- a/index.html
+++ b/index.html
@@ -92,6 +92,7 @@
+
diff --git a/js/control/RoutingOptions.js b/js/control/RoutingOptions.js
index 7a85b5b..6030128 100644
--- a/js/control/RoutingOptions.js
+++ b/js/control/RoutingOptions.js
@@ -17,7 +17,16 @@ BR.RoutingOptions = BR.Control.extend({
alternative: L.DomUtil.get('alternative').value
};
},
-
+
+ setOptions: function(options) {
+ if (options.profile) {
+ L.DomUtil.get('profile').value = options.profile;
+ }
+ if (options.alternative) {
+ L.DomUtil.get('alternative').value = options.alternative;
+ }
+ },
+
_getChangeHandler: function() {
return L.bind(function(evt) {
this.fire('update', {options: this.getOptions()});
diff --git a/js/index.js b/js/index.js
index ee88a75..dfdccc5 100644
--- a/js/index.js
+++ b/js/index.js
@@ -6,6 +6,9 @@
(function() {
+ var map,
+ layersControl;
+
function initMap() {
var osmAttribution = '© OpenStreetMap contributors';
@@ -50,7 +53,7 @@
+ '(CC-BY-SA 3.0 DE)'
});
- var map = new L.Map('map', {
+ map = new L.Map('map', {
layers: [osm],
center: new L.LatLng(50.99, 9.86),
zoom: 6
@@ -60,7 +63,7 @@
+ 'routing + map data © OpenStreetMap contributors '
+ '(ODbL)');
- var layersControl = L.control.layers({
+ layersControl = L.control.layers({
'OpenStreetMap': osm,
'OpenStreetMap.de': osmde,
'OpenTopoMap': topo,
@@ -71,13 +74,10 @@
'Hiking (Waymarked Trails)': hiking
}).addTo(map);
- map.addControl(new L.Control.Permalink({text: 'Permalink', position: 'bottomright', layers: layersControl}));
map.addControl(new BR.Search());
-
- return map;
}
- function initApp(map) {
+ function initApp() {
var router,
routing,
routesLayer,
@@ -147,9 +147,19 @@
nogos.addTo(map);
routing.addTo(map);
+
+ map.addControl(new L.Control.Permalink({
+ text: 'Permalink',
+ position: 'bottomright',
+ layers: layersControl,
+ routingOptions: routingOptions,
+ nogos: nogos,
+ router: router,
+ routing: routing
+ }));
}
- map = initMap();
- initApp(map);
+ initMap();
+ initApp();
})();
diff --git a/js/plugin/NogoAreas.js b/js/plugin/NogoAreas.js
index 66fad17..4570ab3 100644
--- a/js/plugin/NogoAreas.js
+++ b/js/plugin/NogoAreas.js
@@ -58,6 +58,16 @@ BR.NogoAreas = L.Control.Draw.extend({
};
},
+ setOptions: function(options) {
+ var nogos = options.nogos;
+ if (nogos) {
+ this.drawnItems.clearLayers();
+ for (var i = 0; i < nogos.length; i++) {
+ this.drawnItems.addLayer(nogos[i]);
+ }
+ }
+ },
+
_fireUpdate: function () {
this.fire('update', {options: this.getOptions()});
}
diff --git a/js/plugin/Permalink.Routing.js b/js/plugin/Permalink.Routing.js
new file mode 100644
index 0000000..8c6a356
--- /dev/null
+++ b/js/plugin/Permalink.Routing.js
@@ -0,0 +1,85 @@
+//#include "Permalink.js
+
+// patch to not encode URL (beside 'layer', better readable/hackable, Browser can handle)
+L.Control.Permalink.include({
+ _update_href: function() {
+ //var params = L.Util.getParamString(this._params);
+ var params = this.getParamString(this._params);
+
+ var sep = '?';
+ if (this.options.useAnchor) sep = '#';
+ var url = this._url_base + sep + params.slice(1);
+ if (this._href) this._href.setAttribute('href', url);
+ if (this.options.useLocation)
+ location.replace('#' + params.slice(1));
+ return url;
+ },
+
+ getParamString: function (obj, existingUrl, uppercase) {
+ var params = [];
+ for (var i in obj) {
+ // do encode layer (e.g. spaces)
+ if (i === 'layer') {
+ params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i]));
+ } else {
+ params.push(uppercase ? i.toUpperCase() : i + '=' + obj[i]);
+ }
+ }
+ return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');
+ }
+});
+
+
+L.Control.Permalink.include({
+
+ initialize_routing: function() {
+ this.on('update', this._set_routing, this);
+ this.on('add', this._onadd_routing, this);
+ },
+
+ _onadd_routing: function(e) {
+ this.options.routingOptions.on('update', this._update_routing, this);
+ this.options.nogos.on('update', this._update_routing, this);
+ // waypoint add, move, delete (but last)
+ this.options.routing.on('routing:routeWaypointEnd', this._update_routing, this);
+ // delete last waypoint
+ this.options.routing.on('waypoint:click', function(evt) {
+ var r = evt.marker._routing;
+ if (!r.prevMarker && ! r.nextMarker) {
+ console.log('delete last');
+ this._update_routing(evt);
+ }
+ }, this);
+ },
+
+ _update_routing: function(evt) {
+ var router = this.options.router,
+ routing = this.options.routing,
+ latLngs;
+
+ if (evt && evt.options) {
+ router.setOptions(evt.options);
+ }
+
+ latLngs = routing.getWaypoints();
+ this._update(router.getUrlParams(latLngs));
+ },
+
+ _set_routing: function(e) {
+ var router = this.options.router,
+ routing = this.options.routing,
+ routingOptions = this.options.routingOptions,
+ nogos = this.options.nogos;
+
+ var opts = router.parseUrlParams(e.params);
+ router.setOptions(opts);
+ routingOptions.setOptions(opts);
+ nogos.setOptions(opts);
+
+ if (opts.lonlats) {
+ routing.draw(false);
+ routing.clear();
+ routing.setWaypoints(opts.lonlats);
+ }
+ }
+});
diff --git a/js/plugin/Routing.js b/js/plugin/Routing.js
index f35fd29..ab94d57 100644
--- a/js/plugin/Routing.js
+++ b/js/plugin/Routing.js
@@ -26,4 +26,47 @@ BR.Routing = L.Routing.extend({
return container;
}
+
+ ,_removeMarkerEvents: function(marker) {
+ marker.off('mouseover', this._fireWaypointEvent, this);
+ marker.off('mouseout' , this._fireWaypointEvent, this);
+ marker.off('dragstart', this._fireWaypointEvent, this);
+ marker.off('dragend' , this._fireWaypointEvent, this);
+ marker.off('drag' , this._fireWaypointEvent, this);
+ marker.off('click' , this._fireWaypointEvent, this);
+ }
+
+ ,clear: function() {
+ var current = this._waypoints._first;
+ if (current === null) { return; }
+ this._removeMarkerEvents(current);
+ while (current._routing.nextMarker) {
+ var marker = current._routing.nextMarker;
+ this._removeMarkerEvents(marker);
+ current = marker;
+ };
+
+ this._waypoints._first = null;
+ this._waypoints._last = null;
+ this._waypoints.clearLayers();
+ this._segments.clearLayers();
+ }
+
+ ,setWaypoints: function(latLngs) {
+ var $this = this;
+ var index = 0;
+
+ var add = function() {
+ if (!latLngs || index >= latLngs.length) { return; }
+
+ var prev = $this._waypoints._last;
+
+ $this.addWaypoint(latLngs[index], prev, null, function(err, m) {
+ add(++index);
+ });
+ };
+
+ add();
+ }
+
});
diff --git a/js/router/BRouter.js b/js/router/BRouter.js
index 0cae7a7..6d384f3 100644
--- a/js/router/BRouter.js
+++ b/js/router/BRouter.js
@@ -19,14 +19,38 @@ L.BRouter = L.Class.extend({
L.setOptions(this, options);
},
- getUrl: function(latLngs, format) {
- var urlParams = {
+ getUrlParams: function(latLngs, format) {
+ return {
lonlats: this._getLonLatsString(latLngs),
nogos: this._getNogosString(this.options.nogos),
profile: this.options.profile,
alternativeidx: this.options.alternative,
format: format || this.options.format
};
+ },
+
+ parseUrlParams: function(params) {
+ var opts = {};
+ if (params.lonlats) {
+ opts.lonlats = this._parseLonLats(params.lonlats);
+ }
+ if (params.nogos) {
+ opts.nogos = this._parseNogos(params.nogos);
+ }
+ if (params.alternativeidx) {
+ opts.alternative = params.alternativeidx;
+ }
+ if (params.profile) {
+ opts.profile = params.profile;
+ }
+ if (params.format) {
+ opts.format = params.format;
+ }
+ return opts;
+ },
+
+ getUrl: function(latLngs, format) {
+ var urlParams = this.getUrlParams(latLngs, format);
var url = L.Util.template(L.BRouter.URL_TEMPLATE, urlParams);
return url;
},
@@ -74,7 +98,26 @@ L.BRouter = L.Class.extend({
}
return s;
},
-
+
+ _parseLonLats: function(s) {
+ var groups,
+ numbers,
+ lonlats = [];
+
+ if (!s) {
+ return lonlats;
+ }
+
+ groups = s.split(L.BRouter.GROUP_SEPARATOR);
+ for (var i = 0; i < groups.length; i++) {
+ // lng,lat
+ numbers = groups[i].split(L.BRouter.NUMBER_SEPARATOR);
+ lonlats.push(L.latLng(numbers[1], numbers[0]));
+ }
+
+ return lonlats;
+ },
+
_getNogosString: function(nogos) {
var s = '';
for (var i = 0, circle; i < nogos.length; i++) {
@@ -89,6 +132,27 @@ L.BRouter = L.Class.extend({
return s;
},
+ _parseNogos: function(s) {
+ var groups,
+ numbers,
+ nogos = [];
+
+ if (!s) {
+ return nogos;
+ }
+
+ groups = s.split(L.BRouter.GROUP_SEPARATOR);
+ for (var i = 0; i < groups.length; i++) {
+ // lng,lat,radius
+ numbers = groups[i].split(L.BRouter.NUMBER_SEPARATOR);
+ // TODO refactor: pass simple obj, create circle in NogoAreas; use shapeOptions of instance
+ // [lat,lng],radius
+ nogos.push(L.circle([numbers[1], numbers[0]], numbers[2], L.Draw.Circle.prototype.options.shapeOptions));
+ }
+
+ return nogos;
+ },
+
// formats L.LatLng object as lng,lat string
_formatLatLng: function(latLng) {
var s = '';