commit
84d81a7827
9 changed files with 412 additions and 54 deletions
|
|
@ -54,7 +54,11 @@ Copyright 2012 Jacob Toye; [MIT License](https://github.com/Leaflet/Leaflet.draw
|
|||
Copyright (c) 2013 Stefano Cudini; [MIT License](https://github.com/stefanocudini/leaflet-search/blob/master/LICENSE.txt)
|
||||
* [leaflet-plugins](https://github.com/shramov/leaflet-plugins)
|
||||
Copyright (c) 2011-2012, Pavel Shramov; [2-clause BSD License](https://github.com/shramov/leaflet-plugins/blob/master/LICENSE)
|
||||
* [normalize.css](https://github.com/necolas/normalize.css)
|
||||
Copyright (c) Nicolas Gallagher and Jonathan Neal; [MIT License](https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
* [Async.js](https://github.com/caolan/async)
|
||||
Copyright (c) 2010-2014 Caolan McMahon; [MIT License](https://github.com/caolan/async/blob/master/LICENSE)
|
||||
* [Bootstrap](http://getbootstrap.com/)
|
||||
Copyright (c) 2011-2014 Twitter, Inc; [MIT License](https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* [jQuery](https://github.com/jquery/jquery)
|
||||
Copyright 2005, 2014 jQuery Foundation and other contributors; [MIT License](https://github.com/jquery/jquery/blob/master/LICENSE.txt)
|
||||
* [DataTables](https://github.com/DataTables/DataTables)
|
||||
Copyright (C) 2008-2014, SpryMedia Ltd.; [MIT License](http://www.datatables.net/license/mit)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
"bower_components"
|
||||
],
|
||||
"dependencies": {
|
||||
"normalize-css": "*",
|
||||
"leaflet-search": "*",
|
||||
"leaflet-plugins": "*",
|
||||
"leaflet-routing": "nrenner/leaflet-routing#styles",
|
||||
|
|
|
|||
113
css/style.css
113
css/style.css
|
|
@ -15,11 +15,6 @@ html, body, #map {
|
|||
div.elevation {
|
||||
margin-bottom: -2px !important;
|
||||
}
|
||||
/*
|
||||
.info, div.elevation {
|
||||
display:table-row;
|
||||
}
|
||||
*/
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
|
|
@ -44,8 +39,6 @@ div.elevation {
|
|||
}
|
||||
.title {
|
||||
padding-top: 4px;
|
||||
/* normalize height, for absolute Profile control positioning */
|
||||
height: 17px;
|
||||
}
|
||||
.title-name {
|
||||
font-size: larger;
|
||||
|
|
@ -75,8 +68,6 @@ div.elevation {
|
|||
|
||||
select {
|
||||
max-width: 176px;
|
||||
/* normalize height, for absolute Profile control positioning */
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
table {
|
||||
|
|
@ -121,32 +112,56 @@ td {
|
|||
|
||||
.leaflet-leftpane .leaflet-control {
|
||||
margin: 3px 5px;
|
||||
width: 370px;
|
||||
width: 386px;
|
||||
}
|
||||
|
||||
/* Profile Control */
|
||||
|
||||
.leaflet-leftpane .leaflet-control:last-child {
|
||||
position: absolute;
|
||||
top: 461px;
|
||||
bottom: 0px;
|
||||
/* flexbox layout: maximize textarea and data table (nested container/box path) */
|
||||
.flex_container,
|
||||
.leaflet-leftpane,
|
||||
.leaflet-leftpane .leaflet-control:last-child,
|
||||
#tabs_div,
|
||||
.tab-content,
|
||||
.tab-pane.active,
|
||||
#profile_upload,
|
||||
#datatable_wrapper,
|
||||
.dataTables_scroll,
|
||||
.dataTables_scrollBody {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#profile_upload input {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 8px;
|
||||
.flex_box_none,
|
||||
.leaflet-leftpane .leaflet-control,
|
||||
#tab,
|
||||
.dataTables_scrollHead {
|
||||
-webkit-flex: none;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
/* http://snook.ca/archives/html_and_css/absolute-position-textarea */
|
||||
#textarea_container {
|
||||
position: absolute;
|
||||
top: 32px;
|
||||
bottom: 6px;
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
|
||||
.flex_box,
|
||||
.leaflet-leftpane .leaflet-control:last-child,
|
||||
#tabs_div,
|
||||
.tab-content,
|
||||
.tab-pane.active,
|
||||
#profile_upload,
|
||||
textarea,
|
||||
#datatable_wrapper,
|
||||
.dataTables_scroll,
|
||||
.dataTables_scrollBody,
|
||||
#datatable {
|
||||
-webkit-flex: auto;
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
#profile_buttons {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
@ -162,6 +177,11 @@ textarea:focus {
|
|||
background-color: rgba(255,255,255,255);
|
||||
}
|
||||
|
||||
/* track messages (data tab) */
|
||||
#tab_data {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
/* dashed line animation, derived from Chris Coyier and others
|
||||
http://css-tricks.com/svg-line-animation-works/
|
||||
*/
|
||||
|
|
@ -185,3 +205,44 @@ textarea:focus {
|
|||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Bootstrap
|
||||
*/
|
||||
|
||||
/* override Bootstrap label for Leaflet layer switcher */
|
||||
.leaflet-control-layers label {
|
||||
max-width: none;
|
||||
margin-bottom: 0px;
|
||||
font-weight: normal;
|
||||
/* normalize label height
|
||||
| Firefox | Chrome |
|
||||
Leaflet only | 21 | 20 |
|
||||
Bootstrap | 23 | 22 |*/
|
||||
height: 21px;
|
||||
}
|
||||
|
||||
/* smaller tab height */
|
||||
.nav > li > a {
|
||||
padding: 2px 15px;
|
||||
}
|
||||
|
||||
/*
|
||||
* DataTables
|
||||
*/
|
||||
|
||||
table.dataTable.mini thead th,
|
||||
table.dataTable.mini thead td {
|
||||
padding: 3px 13px 3px 2px;
|
||||
}
|
||||
|
||||
table.dataTable.mini tbody th,
|
||||
table.dataTable.mini tbody td {
|
||||
padding: 2px 2px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
table.dataTable thead .sorting_asc,
|
||||
table.dataTable thead .sorting_desc,
|
||||
table.dataTable thead .sorting {
|
||||
background-position: center right -3px;
|
||||
}
|
||||
|
|
|
|||
36
index.html
36
index.html
|
|
@ -2,6 +2,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>BRouter web client</title>
|
||||
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
|
||||
|
|
@ -12,7 +14,9 @@
|
|||
<link rel="stylesheet" href="bower_components/Leaflet.Elevation/dist/Leaflet.Elevation-0.0.2.css" />
|
||||
<link rel="stylesheet" href="bower_components/leaflet-search/dist/leaflet-search.min.css" />
|
||||
<link rel="stylesheet" href="css/leaflet-routing.css" />
|
||||
<link rel="stylesheet" href="bower_components/normalize-css/normalize.css" />
|
||||
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.css">
|
||||
<link rel="stylesheet" href="css/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -47,16 +51,29 @@
|
|||
</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="profile_div" class="hidden">
|
||||
<div id="tabs_div" class="hidden">
|
||||
|
||||
<ul id="tab" class="nav nav-tabs" role="tablist">
|
||||
<li class="active"><a href="#tab_profile" role="tab">Profile</a></li>
|
||||
<li><a href="#tab_data" role="tab">Data</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="tab_profile">
|
||||
<form id="profile_upload" name="profile_upload">
|
||||
<button id="clear">Clear</button>
|
||||
<a href="http://brouter.de/brouter/costfunctions.html" target="_blank">Help</a>
|
||||
<input type="submit" value="Upload" />
|
||||
<div id="textarea_container">
|
||||
<textarea type="text" name="profile" spellcheck="false" wrap="off" maxlength="100000" placeholder="... paste your custom routing profile here ..."></textarea>
|
||||
<div id="profile_buttons">
|
||||
<button id="upload" type="button" class="btn btn-default btn-xs" data-uploading-text="Uploading..."><span class="glyphicon glyphicon-upload"></span> Upload</button>
|
||||
<button id="clear" type="button" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-ban-circle"></span> Clear</button>
|
||||
<a href="http://brouter.de/brouter/costfunctions.html" target="_blank" class="btn-xs">Help</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="tab-pane" id="tab_data">
|
||||
<table id="datatable" class="table mini cell-border hover stripe"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet-src.js"></script>
|
||||
|
||||
|
|
@ -80,6 +97,11 @@
|
|||
<script src="bower_components/Leaflet.Elevation/src/L.Control.Elevation.js"></script>
|
||||
<script src="bower_components/async/lib/async.js"></script>
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
|
||||
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
|
||||
|
||||
<script src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.js"></script>
|
||||
|
||||
<script>
|
||||
// global package prefix for BRouter web application
|
||||
BR = {};
|
||||
|
|
@ -95,7 +117,9 @@
|
|||
<script src="js/plugin/Permalink.Routing.js"></script>
|
||||
<script src="js/control/TrackStats.js"></script>
|
||||
<script src="js/control/Download.js"></script>
|
||||
<script src="js/control/Tabs.js"></script>
|
||||
<script src="js/control/Profile.js"></script>
|
||||
<script src="js/control/TrackMessages.js"></script>
|
||||
<script src="js/control/RoutingOptions.js"></script>
|
||||
<script src="js/control/Message.js"></script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,31 +1,33 @@
|
|||
BR.Profile = BR.Control.extend({
|
||||
options: {
|
||||
heading: 'Profile',
|
||||
divId: 'profile_div'
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
L.DomUtil.get('profile_upload').onsubmit = L.bind(this._submit, this);
|
||||
BR.Profile = L.Class.extend({
|
||||
initialize: function () {
|
||||
L.DomUtil.get('upload').onclick = L.bind(this._upload, this);
|
||||
L.DomUtil.get('clear').onclick = L.bind(this.clear, this);
|
||||
|
||||
|
||||
return BR.Control.prototype.onAdd.call(this, map);
|
||||
},
|
||||
|
||||
clear: function(evt) {
|
||||
var button = evt.target || evt.srcElement;
|
||||
|
||||
evt.preventDefault();
|
||||
document.profile_upload.profile.value = null;
|
||||
|
||||
this.fire('clear');
|
||||
button.blur();
|
||||
},
|
||||
|
||||
_submit: function(evt) {
|
||||
var form = evt.target || evt.srcElement,
|
||||
_upload: function(evt) {
|
||||
var button = evt.target || evt.srcElement,
|
||||
profile = document.profile_upload.profile.value;
|
||||
|
||||
$(button).button('uploading');
|
||||
evt.preventDefault();
|
||||
|
||||
this.fire('update', { profileText: profile });
|
||||
this.fire('update', {
|
||||
profileText: profile,
|
||||
callback: function () {
|
||||
$(button).button('reset');
|
||||
$(button).blur();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
42
js/control/Tabs.js
Normal file
42
js/control/Tabs.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
BR.Tabs = BR.Control.extend({
|
||||
options: {
|
||||
divId: 'tabs_div',
|
||||
// tab a.hash > instance
|
||||
tabs: {}
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
L.setOptions(this, options);
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
var tabs = this.options.tabs;
|
||||
|
||||
for (var key in tabs) {
|
||||
if (tabs[key].onAdd) {
|
||||
tabs[key].onAdd(map);
|
||||
}
|
||||
}
|
||||
|
||||
$('#tab a').click(function (e) {
|
||||
e.preventDefault();
|
||||
$(this).tab('show');
|
||||
});
|
||||
|
||||
// e.target = activated tab
|
||||
// e.relatedTarget = previous tab
|
||||
$('#tab a').on('shown.bs.tab', L.bind(function (e) {
|
||||
var tab = this.options.tabs[e.target.hash],
|
||||
prevTab = this.options.tabs[e.relatedTarget.hash];
|
||||
|
||||
if (tab && tab.show) {
|
||||
tab.show();
|
||||
}
|
||||
if (prevTab && prevTab.hide) {
|
||||
prevTab.hide();
|
||||
}
|
||||
}, this));
|
||||
|
||||
return BR.Control.prototype.onAdd.call(this, map);
|
||||
}
|
||||
});
|
||||
201
js/control/TrackMessages.js
Normal file
201
js/control/TrackMessages.js
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
BR.TrackMessages = L.Class.extend({
|
||||
|
||||
options: {
|
||||
edgeStyle: {
|
||||
color: 'yellow',
|
||||
weight: 8
|
||||
}
|
||||
},
|
||||
|
||||
// true when tab is shown, false when hidden
|
||||
active: false,
|
||||
|
||||
columnOptions: {
|
||||
'Longitude': { visible: false },
|
||||
'Latitude': { visible: false },
|
||||
'Elevation': { title: 'elev.', className: 'dt-body-right' },
|
||||
'Distance': { title: 'dist.', className: 'dt-body-right' },
|
||||
'CostPerKm': { title: '$/km', className: 'dt-body-right' },
|
||||
'ElevCost': { title: 'elev$', className: 'dt-body-right' },
|
||||
'TurnCost': { title: 'turn$', className: 'dt-body-right' },
|
||||
'NodeCost': { title: 'node$', className: 'dt-body-right' },
|
||||
'InitialCost': { title: 'initial$', className: 'dt-body-right' },
|
||||
'OsmTags': { title: 'tags'}
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
L.setOptions(this, options);
|
||||
|
||||
var table = document.getElementById('datatable');
|
||||
this.tableClassName = table.className;
|
||||
this.tableParent = table.parentElement;
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
this._map = map;
|
||||
},
|
||||
|
||||
update: function (polyline, segments) {
|
||||
var i, messages, columns, headings,
|
||||
data = [];
|
||||
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; segments && i < segments.length; i++) {
|
||||
messages = segments[i].feature.properties.messages;
|
||||
if (messages) {
|
||||
data = data.concat(messages.slice(1));
|
||||
}
|
||||
}
|
||||
|
||||
this._destroyTable();
|
||||
|
||||
if (data.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
headings = messages[0];
|
||||
columns = this._getColumns(headings, data);
|
||||
|
||||
console.time('datatable');
|
||||
this._table = $('#datatable').DataTable({
|
||||
destroy: true,
|
||||
data: data,
|
||||
columns: columns,
|
||||
paging: false,
|
||||
searching: false,
|
||||
info: false,
|
||||
scrollY: 330,
|
||||
scrollX: 370,
|
||||
scrollCollapse: true,
|
||||
order: []
|
||||
});
|
||||
|
||||
// highlight track segment (graph edge) on row hover
|
||||
this._setEdges(polyline, segments);
|
||||
$('#datatable tbody tr').hover(L.bind(this._handleHover, this), L.bind(this._handleHoverOut, this));
|
||||
|
||||
console.timeEnd('datatable');
|
||||
},
|
||||
|
||||
show: function() {
|
||||
this.active = true;
|
||||
this.options.requestUpdate(this);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.active = false;
|
||||
},
|
||||
|
||||
_destroyTable: function() {
|
||||
var ele;
|
||||
|
||||
if ($.fn.DataTable.isDataTable('#datatable') ) {
|
||||
// destroy option too slow on update, really remove elements with destroy method
|
||||
$('#datatable').DataTable().destroy(true);
|
||||
|
||||
// recreate original table element, destroy removes all
|
||||
ele = document.createElement('table');
|
||||
ele.id = 'datatable';
|
||||
ele.className = this.tableClassName;
|
||||
this.tableParent.appendChild(ele);
|
||||
}
|
||||
|
||||
return ele || document.getElementById('datatable');
|
||||
},
|
||||
|
||||
_getColumns: function(headings, data) {
|
||||
var columns = [],
|
||||
defaultOptions,
|
||||
options,
|
||||
emptyColumns = this._getEmptyColumns(data);
|
||||
|
||||
for (k = 0; k < headings.length; k++) {
|
||||
defaultOptions = {
|
||||
title: headings[k],
|
||||
visible: !emptyColumns[k]
|
||||
};
|
||||
options = L.extend(defaultOptions, this.columnOptions[headings[k]]);
|
||||
columns.push(options);
|
||||
}
|
||||
return columns;
|
||||
},
|
||||
|
||||
_getEmptyColumns: function(data) {
|
||||
var empty = new Array(data[0].length),
|
||||
i;
|
||||
|
||||
for (i = 0; i < empty.length; i++) {
|
||||
empty[i] = true;
|
||||
}
|
||||
|
||||
data.forEach(function(row) {
|
||||
row.forEach(function(val, i) {
|
||||
empty[i] = empty[i] && !val;
|
||||
});
|
||||
});
|
||||
|
||||
return empty;
|
||||
},
|
||||
|
||||
_getMessageLatLng: function(message) {
|
||||
var lon = message[0] / 1000000,
|
||||
lat = message[1] / 1000000;
|
||||
|
||||
return L.latLng(lat, lon);
|
||||
},
|
||||
|
||||
_setEdges: function(polyline, segments) {
|
||||
var messages, segLatLngs, length, si, mi, latLng, i, segIndex,
|
||||
baseIndex = 0;
|
||||
|
||||
// track latLngs index for end node of edge
|
||||
this._edges = [];
|
||||
this._track = polyline;
|
||||
|
||||
for (si = 0; si < segments.length; si++) {
|
||||
messages = segments[si].feature.properties.messages;
|
||||
segLatLngs = segments[si].getLatLngs();
|
||||
length = segLatLngs.length;
|
||||
segIndex = 0;
|
||||
|
||||
for (mi = 1; mi < messages.length; mi++) {
|
||||
latLng = this._getMessageLatLng(messages[mi]);
|
||||
|
||||
for (i = segIndex; i < length; i++) {
|
||||
if (latLng.equals(segLatLngs[i])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i === length) {
|
||||
i = length - 1;
|
||||
if (mi !== messages.length - 1) debugger;
|
||||
}
|
||||
|
||||
segIndex = i + 1;
|
||||
this._edges.push(baseIndex + i);
|
||||
}
|
||||
baseIndex += length;
|
||||
}
|
||||
},
|
||||
|
||||
_handleHover: function(evt) {
|
||||
var tr = $(evt.currentTarget),
|
||||
row = this._table.row(tr),
|
||||
trackLatLngs = this._track.getLatLngs(),
|
||||
startIndex = row.index() > 0 ? this._edges[row.index() - 1] : 0,
|
||||
endIndex = this._edges[row.index()],
|
||||
edgeLatLngs = trackLatLngs.slice(startIndex, endIndex + 1);
|
||||
|
||||
this._selectedEdge = L.polyline(edgeLatLngs, this.options.edgeStyle).addTo(this._map);
|
||||
},
|
||||
|
||||
_handleHoverOut: function(evt) {
|
||||
this._map.removeLayer(this._selectedEdge);
|
||||
this._selectedEdge = null;
|
||||
}
|
||||
});
|
||||
|
||||
BR.TrackMessages.include(L.Mixin.Events);
|
||||
27
js/index.js
27
js/index.js
|
|
@ -76,6 +76,10 @@
|
|||
}).addTo(map);
|
||||
|
||||
map.addControl(new BR.Search());
|
||||
|
||||
// expose map instance for console debugging
|
||||
BR.debug = BR.debug || {};
|
||||
BR.debug.map = map;
|
||||
}
|
||||
|
||||
function initApp() {
|
||||
|
|
@ -88,6 +92,7 @@
|
|||
elevation,
|
||||
download,
|
||||
profile,
|
||||
trackMessages,
|
||||
leftPaneId = 'leftpane',
|
||||
saveWarningShown = false;
|
||||
|
||||
|
|
@ -106,6 +111,13 @@
|
|||
routing.rerouteAllSegments(onUpdate);
|
||||
}
|
||||
|
||||
function requestUpdate(updatable) {
|
||||
var track = routing.toPolyline(),
|
||||
segments = routing.getSegments();
|
||||
|
||||
updatable.update(track, segments);
|
||||
}
|
||||
|
||||
routingOptions = new BR.RoutingOptions();
|
||||
routingOptions.on('update', updateRoute);
|
||||
|
||||
|
|
@ -134,12 +146,19 @@
|
|||
router.setOptions(routingOptions.getOptions());
|
||||
}
|
||||
}
|
||||
|
||||
if (evt.callback) {
|
||||
evt.callback();
|
||||
}
|
||||
});
|
||||
});
|
||||
profile.on('clear', function(evt) {
|
||||
BR.message.hideError();
|
||||
routingOptions.setCustomProfile(null);
|
||||
});
|
||||
trackMessages = new BR.TrackMessages({
|
||||
requestUpdate: requestUpdate
|
||||
});
|
||||
|
||||
routing = new BR.Routing({
|
||||
routing: {
|
||||
|
|
@ -177,6 +196,7 @@
|
|||
|
||||
elevation.update(track);
|
||||
stats.update(track, segments);
|
||||
trackMessages.update(track, segments);
|
||||
|
||||
if (latLngs.length > 1) {
|
||||
urls.gpx = router.getUrl(latLngs, 'gpx');
|
||||
|
|
@ -196,7 +216,12 @@
|
|||
stats.addTo(map);
|
||||
download.addTo(map);
|
||||
elevation.addTo(map);
|
||||
profile.addTo(map);
|
||||
map.addControl(new BR.Tabs({
|
||||
tabs: {
|
||||
'#tab_profile': profile,
|
||||
'#tab_data': trackMessages
|
||||
}
|
||||
}));
|
||||
|
||||
nogos.addTo(map);
|
||||
routing.addTo(map);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ BR.Routing = L.Routing.extend({
|
|||
this._edit._mouseMarker.setIcon(L.divIcon({
|
||||
className: 'line-mouse-marker'
|
||||
,iconAnchor: [8, 8] // size/2 + border/2
|
||||
,iconSize: [8, 8]
|
||||
,iconSize: [16, 16]
|
||||
}));
|
||||
|
||||
this._draw.on('enabled', function() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue