diff --git a/README.md b/README.md index 90f0abc..438ae36 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,6 @@ Copyright (c) 2013 Felix Bache; [MIT License](https://github.com/MrMufflon/Leafl Copyright (c) 2013, Michael Bostock. All rights reserved.; [3-clause BSD License](https://github.com/mbostock/d3/blob/master/LICENSE) * [Leaflet.draw](https://github.com/Leaflet/Leaflet.draw) Copyright 2012 Jacob Toye; [MIT License](https://github.com/Leaflet/Leaflet.draw/blob/master/MIT-LICENCE.txt) -* [leaflet-gpx](https://github.com/mpetazzoni/leaflet-gpx) -Copyright (C) 2011-2012 Pavel Shramov, Copyright (C) 2013 Maxime Petazzoni -All rights reserved. [2-clause BSD License](https://github.com/mpetazzoni/leaflet-gpx/blob/master/LICENSE) * [Leaflet.Control.Search](https://github.com/stefanocudini/leaflet-search) 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) diff --git a/bower.json b/bower.json index 692dc6e..8532a7a 100644 --- a/bower.json +++ b/bower.json @@ -8,7 +8,6 @@ ], "dependencies": { "normalize-css": "*", - "leaflet-gpx": "mpetazzoni/leaflet-gpx", "leaflet-search": "*", "leaflet-plugins": "*", "leaflet-routing": "Turistforeningen/leaflet-routing#gh-pages", diff --git a/bower_components/leaflet-gpx/.bower.json b/bower_components/leaflet-gpx/.bower.json deleted file mode 100644 index 2650246..0000000 --- a/bower_components/leaflet-gpx/.bower.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "leaflet-gpx", - "homepage": "https://github.com/mpetazzoni/leaflet-gpx", - "_release": "ad9d5adf0a", - "_resolution": { - "type": "branch", - "branch": "master", - "commit": "ad9d5adf0ae5450bc5bc60e1e86307beb7667772" - }, - "_source": "git://github.com/mpetazzoni/leaflet-gpx.git", - "_target": "*", - "_originalSource": "mpetazzoni/leaflet-gpx" -} \ No newline at end of file diff --git a/bower_components/leaflet-gpx/LICENSE b/bower_components/leaflet-gpx/LICENSE deleted file mode 100644 index ff83736..0000000 --- a/bower_components/leaflet-gpx/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (C) 2011-2012 Pavel Shramov -Copyright (C) 2013 Maxime Petazzoni -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/bower_components/leaflet-gpx/README.md b/bower_components/leaflet-gpx/README.md deleted file mode 100644 index 5b5980f..0000000 --- a/bower_components/leaflet-gpx/README.md +++ /dev/null @@ -1,147 +0,0 @@ -GPX plugin for Leaflet -====================== - -[Leaflet](http://www.leafletjs.com) is a Javascript library for displaying -interactive maps. This plugin, based on the work of [Pavel -Shramov](http://github.com/shramov) and his -[leaflet-plugins](http://github.com/shramov/leaflet-plugins), it allows for the -analysis and parsing of a GPX track in order to display it as a Leaflet map -layer. As it parses the GPX data, it will record information about the recorded -track, including total time, moving time, total distance, elevation stats and -heart-rate. - -GPX parsing will automatically handle pauses in the track with a default -tolerance interval of 15 seconds between points. You can configure this -interval by setting `max_point_interval`, in milliseconds, in the options -passed to the `GPX` constructor. - -I've put together a complete example as a -[demo](http://mpetazzoni.github.com/leaflet-gpx/). - - -License -------- - -`leaflet-gpx` is under the *BSD 2-clause license*. Please refer to the -attached LICENSE file and/or to the copyright header in gpx.js for more -information. - -Usage ------ - -Usage is very simple. Let's consider we have a Leaflet map: - -```javascript -var map = L.map('map'); -L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - attribution: 'Map data © OpenStreetMap' -}).addTo(map); -``` - -Displaying the GPX track is as easy as: - -```javascript -var gpx = '...'; // URL to your GPX file or the GPX itself -new L.GPX(gpx, {async: true}).on('loaded', function(e) { - map.fitBounds(e.target.getBounds()); -}).addTo(map); -``` - -If you want to display additional information about the GPX track, you can do -so in the 'loaded' event handler, calling one of the following methods on the -`GPX` object `e.target`: - -* `get_name()`: returns the name of the GPX track -* `get_distance()`: returns the total track distance, in meters -* `get_start_time()`: returns a Javascript `Date` object representing the - starting time -* `get_end_time()`: returns a Javascript `Date` object representing when the - last point was recorded -* `get_moving_time()`: returns the moving time, in milliseconds -* `get_total_time()`: returns the total track time, in milliseconds -* `get_moving_pace()`: returns the average moving pace in milliseconds per km -* `get_moving_speed()`: returns the average moving speed in km per hour -* `get_elevation_gain()`: returns the cumulative elevation gain, in meters -* `get_elevation_loss()`: returns the cumulative elevation loss, in meters -* `get_average_hr()`: returns the average heart rate (if available) - -If you're not a fan of the metric system, you also have the following methods -at your disposal: - -* `get_distance_imp()`: returns the total track distance in miles -* `get_moving_pace_imp()`: returns the average moving pace in milliseconds per - hour -* `get_moving_speed()`: returns the average moving pace in miles per - hour - -The reason why these methods return milliseconds is that you have at your -disposal a nice helper method to format a duration in milliseconds into a cool -string like `3:07'48"` or `59'32.431`: - -* `get_duration_string(duration, hidems)`, where `duration` is in - milliseconds and `hidems` is an optional boolean you can use to request never - to display millisecond precision. - -You can also get full elevation and heartrate data with: - -* `get_elevation_data()` and `get_elevation_data_imp()` -* `get_heartrate_data()` and `get_heartrate_data_imp()` - -These methods all return an array of points `[distance, value, tooltip]` where -the distance is either in kilometers or in miles and the elevation in meters of -feet, depending on whether you use the `_imp` variant or not. Heart rate, -obviously, doesn't change. - -You can reload remote gpx file every 5 seconds with: -```javascript -var gpxLayer = new L.GPX(gpxFile); - -setInterval(function() { - gpxLayer.reload(); -},5000); -``` - - -About marker icons ------------------- - -By default `gpx.js` will use `pin-icon-start.png`, `pin-icon-end.png` and -`pin-shadow.png` as the marker icons URLs for, respectively, the start marker, -the end marker and their drop shadow. Since it might not be convenient that -these images have to reside under the same directory as your HTML page, it is -possible to override the marker icon URLs and sizes by passing a -`marker_options` object to the `GPX` options object. - -The field names are the same as for custom Leaflet icons, as explained in the -[Markers with custom icons](http://leafletjs.com/examples/custom-icons.html) -page in Leaflet's documentation. The only difference is that instead of -`iconUrl` you should specify `startIconUrl` and `endIconUrl` for the start and -end markers, respectively. - -Note that you do not need to override all the marker icon options as `gpx.js` -will use sensible defaults with sizes matching the provided icon images. Here -is how you would override the URL of the provided icons if you decided to place -them in an `images/` directory: - -```javascript -var url = '...'; // URL to your GPX file -new L.GPX(url, { - async: true, - marker_options: { - startIconUrl: 'images/pin-icon-start.png', - endIconUrl: 'images/pin-icon-end.png', - shadowUrl: 'images/pin-shadow.png' - } -}).on('loaded', function(e) { - map.fitBounds(e.target.getBounds()); -}).addTo(map); -``` - -Caveats -------- - - * Distance calculation is relatively accurate, but elevation change - calculation is not topographically adjusted, so the total elevation - gain/loss/change might appear inaccurate in some situations. - * Currently doesn't seem to work in IE8/9. See #9 and #11 for - discussion. diff --git a/bower_components/leaflet-gpx/gpx.js b/bower_components/leaflet-gpx/gpx.js deleted file mode 100644 index ddee4ff..0000000 --- a/bower_components/leaflet-gpx/gpx.js +++ /dev/null @@ -1,361 +0,0 @@ -/** - * Copyright (C) 2011-2012 Pavel Shramov - * Copyright (C) 2013 Maxime Petazzoni - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Thanks to Pavel Shramov who provided the initial implementation and Leaflet - * integration. Original code was at https://github.com/shramov/leaflet-plugins. - * - * It was then cleaned-up and modified to record and make available more - * information about the GPX track while it is being parsed so that the result - * can be used to display additional information about the track that is - * rendered on the Leaflet map. - */ - -var _MAX_POINT_INTERVAL_MS = 15000; -var _SECOND_IN_MILLIS = 1000; -var _MINUTE_IN_MILLIS = 60 * _SECOND_IN_MILLIS; -var _HOUR_IN_MILLIS = 60 * _MINUTE_IN_MILLIS; - -var _DEFAULT_MARKER_OPTS = { - startIconUrl: 'pin-icon-start.png', - endIconUrl: 'pin-icon-end.png', - shadowUrl: 'pin-shadow.png', - iconSize: [33, 50], - shadowSize: [50, 50], - iconAnchor: [16, 45], - shadowAnchor: [16, 47] -}; -var _DEFAULT_POLYLINE_OPTS = { - color:'blue' -}; -L.GPX = L.FeatureGroup.extend({ - initialize: function(gpx, options) { - options.max_point_interval = options.max_point_interval || _MAX_POINT_INTERVAL_MS; - options.marker_options = this._merge_objs( - _DEFAULT_MARKER_OPTS, - options.marker_options || {}); - options.polyline_options = this._merge_objs( - _DEFAULT_POLYLINE_OPTS, - options.polyline_options || {}); - - L.Util.setOptions(this, options); - - // Base icon class for track pins. - L.GPXTrackIcon = L.Icon.extend({ options: options.marker_options }); - - this._gpx = gpx; - this._layers = {}; - this._info = { - name: null, - length: 0.0, - elevation: {gain: 0.0, loss: 0.0, _points: []}, - hr: {avg: 0, _total: 0, _points: []}, - duration: {start: null, end: null, moving: 0, total: 0}, - }; - - if (gpx) { - this._parse(gpx, options, this.options.async); - } - }, - - get_duration_string: function(duration, hidems) { - var s = ''; - - if (duration >= _HOUR_IN_MILLIS) { - s += Math.floor(duration / _HOUR_IN_MILLIS) + ':'; - duration = duration % _HOUR_IN_MILLIS; - } - - var mins = Math.floor(duration / _MINUTE_IN_MILLIS); - duration = duration % _MINUTE_IN_MILLIS; - if (mins < 10) s += '0'; - s += mins + '\''; - - var secs = Math.floor(duration / _SECOND_IN_MILLIS); - duration = duration % _SECOND_IN_MILLIS; - if (secs < 10) s += '0'; - s += secs; - - if (!hidems && duration > 0) s += '.' + Math.round(Math.floor(duration)*1000)/1000; - else s += '"'; - - return s; - }, - - // Public methods - to_miles: function(v) { return v / 1.60934; }, - to_ft: function(v) { return v * 3.28084; }, - m_to_km: function(v) { return v / 1000; }, - m_to_mi: function(v) { return v / 1609.34; }, - - get_name: function() { return this._info.name; }, - get_desc: function() { return this._info.desc; }, - get_author: function() { return this._info.author; }, - get_copyright: function() { return this._info.copyright; }, - get_desc: function() { return this._info.desc; }, - get_distance: function() { return this._info.length; }, - get_distance_imp: function() { return this.to_miles(this.m_to_km(this.get_distance())); }, - - get_start_time: function() { return this._info.duration.start; }, - get_end_time: function() { return this._info.duration.end; }, - get_moving_time: function() { return this._info.duration.moving; }, - get_total_time: function() { return this._info.duration.total; }, - - get_moving_pace: function() { return this.get_moving_time() / this.m_to_km(this.get_distance()); }, - get_moving_pace_imp: function() { return this.get_moving_time() / this.get_distance_imp(); }, - - get_moving_speed: function() { return this.m_to_km(this.get_distance()) / (this.get_moving_time() / (3600 * 1000)) ; }, - get_moving_speed_imp:function() { return this.to_miles(this.m_to_km(this.get_distance())) / (this.get_moving_time() / (3600 * 1000)) ; }, - - get_elevation_gain: function() { return this._info.elevation.gain; }, - get_elevation_loss: function() { return this._info.elevation.loss; }, - get_elevation_data: function() { - var _this = this; - return this._info.elevation._points.map( - function(p) { return _this._prepare_data_point(p, _this.m_to_km, null, - function(a, b) { return a.toFixed(2) + ' km, ' + b.toFixed(0) + ' m'; }); - }); - }, - get_elevation_data_imp: function() { - var _this = this; - return this._info.elevation._points.map( - function(p) { return _this._prepare_data_point(p, _this.m_to_mi, _this.to_ft, - function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' ft'; }); - }); - }, - - get_average_hr: function() { return this._info.hr.avg; }, - get_heartrate_data: function() { - var _this = this; - return this._info.hr._points.map( - function(p) { return _this._prepare_data_point(p, _this.m_to_km, null, - function(a, b) { return a.toFixed(2) + ' km, ' + b.toFixed(0) + ' bpm'; }); - }); - }, - get_heartrate_data_imp: function() { - var _this = this; - return this._info.hr._points.map( - function(p) { return _this._prepare_data_point(p, _this.m_to_mi, null, - function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' bpm'; }); - }); - }, - - reload: function() { - this.clearLayers(); - this._parse(this._gpx, this.options, this.options.async); - }, - - // Private methods - _merge_objs: function(a, b) { - var _ = {}; - for (var attr in a) { _[attr] = a[attr]; } - for (var attr in b) { _[attr] = b[attr]; } - return _; - }, - - _prepare_data_point: function(p, trans1, trans2, trans_tooltip) { - var r = [trans1 && trans1(p[0]) || p[0], trans2 && trans2(p[1]) || p[1]]; - r.push(trans_tooltip && trans_tooltip(r[0], r[1]) || (r[0] + ': ' + r[1])); - return r; - }, - - _load_xml: function(url, cb, options, async) { - if (async == undefined) async = this.options.async; - if (options == undefined) options = this.options; - - var req = new window.XMLHttpRequest(); - req.open('GET', url, async); - try { - req.overrideMimeType('text/xml'); // unsupported by IE - } catch(e) {} - req.onreadystatechange = function() { - if (req.readyState != 4) return; - if(req.status == 200) cb(req.responseXML, options); - }; - req.send(null); - }, - - _parse: function(input, options, async) { - var _this = this; - var cb = function(gpx, options) { - var layers = _this._parse_gpx_data(gpx, options); - if (!layers) return; - _this.addLayer(layers); - _this.fire('loaded'); - } - if (input.substr(0,1)==='<') { // direct XML has to start with a < - var parser = new DOMParser(); - setTimeout(function() { - cb(parser.parseFromString(input, "text/xml"), options); - }); - } else { - this._load_xml(input, cb, options, async); - } - }, - - _parse_gpx_data: function(xml, options) { - var j, i, el, layers = []; - var tags = [['rte','rtept'], ['trkseg','trkpt']]; - - var name = xml.getElementsByTagName('name'); - if (name.length > 0) { - this._info.name = name[0].textContent; - } - var desc = xml.getElementsByTagName('desc'); - if (desc.length > 0) { - this._info.desc = desc[0].textContent; - } - var author = xml.getElementsByTagName('author'); - if (author.length > 0) { - this._info.author = author[0].textContent; - } - var copyright = xml.getElementsByTagName('copyright'); - if (copyright.length > 0) { - this._info.copyright = copyright[0].textContent; - } - - for (j = 0; j < tags.length; j++) { - el = xml.getElementsByTagName(tags[j][0]); - for (i = 0; i < el.length; i++) { - var coords = this._parse_trkseg(el[i], xml, options, tags[j][1]); - if (coords.length === 0) continue; - - // add track - var l = new L.Polyline(coords, options.polyline_options); - this.fire('addline', { line: l }) - layers.push(l); - - if (options.marker_options.startIconUrl) { - // add start pin - var p = new L.Marker(coords[0], { - clickable: false, - icon: new L.GPXTrackIcon({iconUrl: options.marker_options.startIconUrl}) - }); - this.fire('addpoint', { point: p }); - layers.push(p); - } - - if (options.marker_options.endIconUrl) { - // add end pin - p = new L.Marker(coords[coords.length-1], { - clickable: false, - icon: new L.GPXTrackIcon({iconUrl: options.marker_options.endIconUrl}) - }); - this.fire('addpoint', { point: p }); - layers.push(p); - } - } - } - - this._info.hr.avg = Math.round(this._info.hr._total / this._info.hr._points.length); - - if (!layers.length) return; - var layer = layers[0]; - if (layers.length > 1) - layer = new L.FeatureGroup(layers); - return layer; - }, - - _parse_trkseg: function(line, xml, options, tag) { - var el = line.getElementsByTagName(tag); - if (!el.length) return []; - var coords = []; - var last = null; - - for (var i = 0; i < el.length; i++) { - var _, ll = new L.LatLng( - el[i].getAttribute('lat'), - el[i].getAttribute('lon')); - ll.meta = { time: null, ele: null, hr: null }; - - _ = el[i].getElementsByTagName('time'); - if (_.length > 0) { - ll.meta.time = new Date(Date.parse(_[0].textContent)); - } - - _ = el[i].getElementsByTagName('ele'); - if (_.length > 0) { - ll.meta.ele = parseFloat(_[0].textContent); - } - - _ = el[i].getElementsByTagNameNS('*', 'hr'); - if (_.length > 0) { - ll.meta.hr = parseInt(_[0].textContent); - this._info.hr._points.push([this._info.length, ll.meta.hr]); - this._info.hr._total += ll.meta.hr; - } - - this._info.elevation._points.push([this._info.length, ll.meta.ele]); - this._info.duration.end = ll.meta.time; - - if (last != null) { - this._info.length += this._dist3d(last, ll); - - var t = ll.meta.ele - last.meta.ele; - if (t > 0) this._info.elevation.gain += t; - else this._info.elevation.loss += Math.abs(t); - - t = Math.abs(ll.meta.time - last.meta.time); - this._info.duration.total += t; - if (t < options.max_point_interval) this._info.duration.moving += t; - } else { - this._info.duration.start = ll.meta.time; - } - - last = ll; - coords.push(ll); - } - - return coords; - }, - - _dist2d: function(a, b) { - var R = 6371000; - var dLat = this._deg2rad(b.lat - a.lat); - var dLon = this._deg2rad(b.lng - a.lng); - var r = Math.sin(dLat/2) * - Math.sin(dLat/2) + - Math.cos(this._deg2rad(a.lat)) * - Math.cos(this._deg2rad(b.lat)) * - Math.sin(dLon/2) * - Math.sin(dLon/2); - var c = 2 * Math.atan2(Math.sqrt(r), Math.sqrt(1-r)); - var d = R * c; - return d; - }, - - _dist3d: function(a, b) { - var planar = this._dist2d(a, b); - var height = Math.abs(b.meta.ele - a.meta.ele); - return Math.sqrt(Math.pow(planar, 2) + Math.pow(height, 2)); - }, - - _deg2rad: function(deg) { - return deg * Math.PI / 180; - } -}); diff --git a/bower_components/leaflet-gpx/pin-icon-end.png b/bower_components/leaflet-gpx/pin-icon-end.png deleted file mode 100644 index d8d7998..0000000 Binary files a/bower_components/leaflet-gpx/pin-icon-end.png and /dev/null differ diff --git a/bower_components/leaflet-gpx/pin-icon-start.png b/bower_components/leaflet-gpx/pin-icon-start.png deleted file mode 100644 index d921f0e..0000000 Binary files a/bower_components/leaflet-gpx/pin-icon-start.png and /dev/null differ diff --git a/bower_components/leaflet-gpx/pin-shadow.png b/bower_components/leaflet-gpx/pin-shadow.png deleted file mode 100644 index bfe3cfa..0000000 Binary files a/bower_components/leaflet-gpx/pin-shadow.png and /dev/null differ diff --git a/css/style.css b/css/style.css index 45c6c49..7773486 100644 --- a/css/style.css +++ b/css/style.css @@ -74,7 +74,7 @@ div.elevation { } select { - max-width: 180px; + max-width: 176px; /* normalize height, for absolute Profile control positioning */ height: 24px; } @@ -96,7 +96,7 @@ td { .heading, tr > td:first-child, .label { /* 1/4 of net info control width (370), so that values start at 50% */ - width: 92.5px; + width: 95px; } .routing-draw-enabled { @@ -128,7 +128,7 @@ td { .leaflet-leftpane .leaflet-control:last-child { position: absolute; - top: 441px; + top: 461px; bottom: 0px; } diff --git a/index.html b/index.html index 06c48aa..49b6cec 100644 --- a/index.html +++ b/index.html @@ -61,7 +61,6 @@ -