From 8ed2ab1f1fc6457989fe19b4bde0c0481bcf80c6 Mon Sep 17 00:00:00 2001 From: leosw Date: Fri, 29 Dec 2017 15:39:27 +0100 Subject: [PATCH] Add support for nights in GPX tracks --- iFrameGPX/index.php | 18 +++-- iFrameGPX/leaflet-gpx/gpx.js | 117 +++++++++++++++++++++++++++----- iFrameGPX/leaflet-gpx/night.png | Bin 0 -> 603 bytes 3 files changed, 112 insertions(+), 23 deletions(-) mode change 100644 => 100755 iFrameGPX/index.php mode change 100644 => 100755 iFrameGPX/leaflet-gpx/gpx.js create mode 100755 iFrameGPX/leaflet-gpx/night.png diff --git a/iFrameGPX/index.php b/iFrameGPX/index.php old mode 100644 new mode 100755 index 01d7654..e2d1616 --- a/iFrameGPX/index.php +++ b/iFrameGPX/index.php @@ -35,7 +35,7 @@ // IGN URL to the IGN layer var KeyIGN = "ataevimogohmg1wxpg1jo2wh" // professionels.ign.fr -var url_wmts_ign = "http://wxs.ign.fr/"+ +var url_wmts_ign = "//wxs.ign.fr/"+ KeyIGN + "/geoportail/wmts?LAYER="+ "GEOGRAPHICALGRIDSYSTEMS.MAPS"+ @@ -46,10 +46,10 @@ var url_wmts_ign = "http://wxs.ign.fr/"+ "&TILEMATRIXSET=PM&&TILEMATRIX={z}&TILECOL={x}&TILEROW={y}"; // Correct tile // Differents layers for the map -var osmfr = L.tileLayer('http://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {maxZoom: 20, attribution: 'Maps © OpenSreetMap France, Data © OpenStreetMap contributors'}); - outdoor = L.tileLayer('http://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png', {maxZoom: 18, attribution: 'Maps © Thunderforest, Data © OpenStreetMap contributors'}), - outdoora = L.tileLayer('http://s1.outdooractive.com/osm/OSMSummer/{z}/{x}/{y}.png', {maxZoom: 18, attribution: 'Maps © Outdoor Active, Data © OpenStreetMap contributors'}), - ostopo = L.tileLayer('http://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {maxZoom: 16, attribution: 'Maps © OpenTopoMap, Data © OpenStreetMap contributors'}), +var osmfr = L.tileLayer('//{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {maxZoom: 20, attribution: 'Maps © OpenSreetMap France, Data © OpenStreetMap contributors'}); + outdoor = L.tileLayer('//{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png', {maxZoom: 18, attribution: 'Maps © Thunderforest, Data © OpenStreetMap contributors'}), + outdoora = L.tileLayer('//s1.outdooractive.com/osm/OSMSummer/{z}/{x}/{y}.png', {maxZoom: 18, attribution: 'Maps © Outdoor Active, Data © OpenStreetMap contributors'}), + ostopo = L.tileLayer('//{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {maxZoom: 16, attribution: 'Maps © OpenTopoMap, Data © OpenStreetMap contributors'}), ign = L.tileLayer(url_wmts_ign, {maxZoom: 18, attribution: 'Maps & Data © IGN'}); // Creation of the map @@ -147,7 +147,13 @@ var g = new L.GPX(gpx, { marker_options: { startIconUrl: './leaflet-gpx/start.png', endIconUrl: './leaflet-gpx/finish.png', - shadowUrl: '' + wptIconUrls : { + 'night': './leaflet-gpx/night.png', + }, + shadowUrl: '', + iconSize: [32, 37], + iconAnchor: [16, 37], + clickable: false } }); g.on('loaded', function(e) { diff --git a/iFrameGPX/leaflet-gpx/gpx.js b/iFrameGPX/leaflet-gpx/gpx.js old mode 100644 new mode 100755 index e7dd665..3eea561 --- a/iFrameGPX/leaflet-gpx/gpx.js +++ b/iFrameGPX/leaflet-gpx/gpx.js @@ -36,20 +36,30 @@ * rendered on the Leaflet map. */ +var L = L || require('leaflet'); + 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 _DAY_IN_MILLIS = 24 * _HOUR_IN_MILLIS; var _DEFAULT_MARKER_OPTS = { - startIconUrl: './leaflet-gpx/start.png', - endIconUrl: './leaflet-gpx/finish.png', + startIconUrl: 'pin-icon-start.png', + endIconUrl: 'pin-icon-end.png', + shadowUrl: '', + wptIconUrls : { + }, iconSize: [32, 37], - iconAnchor: [16, 37] + iconAnchor: [16, 37], + clickable: false }; var _DEFAULT_POLYLINE_OPTS = { color:'blue' }; +var _DEFAULT_GPX_OPTS = { + parseElements: ['track', 'route', 'waypoint'] +}; L.GPX = L.FeatureGroup.extend({ initialize: function(gpx, options) { options.max_point_interval = options.max_point_interval || _MAX_POINT_INTERVAL_MS; @@ -59,6 +69,9 @@ L.GPX = L.FeatureGroup.extend({ options.polyline_options = this._merge_objs( _DEFAULT_POLYLINE_OPTS, options.polyline_options || {}); + options.gpx_options = this._merge_objs( + _DEFAULT_GPX_OPTS, + options.gpx_options || {}); L.Util.setOptions(this, options); @@ -70,9 +83,9 @@ L.GPX = L.FeatureGroup.extend({ this._info = { name: null, length: 0.0, - elevation: {gain: 0.0, loss: 0.0, _points: []}, + elevation: {gain: 0.0, loss: 0.0, max: 0.0, min: Infinity, _points: []}, hr: {avg: 0, _total: 0, _points: []}, - duration: {start: null, end: null, moving: 0, total: 0}, + duration: {start: null, end: null, moving: 0, total: 0} }; if (gpx) { @@ -83,6 +96,11 @@ L.GPX = L.FeatureGroup.extend({ get_duration_string: function(duration, hidems) { var s = ''; + if (duration >= _DAY_IN_MILLIS) { + s += Math.floor(duration / _DAY_IN_MILLIS) + 'd '; + duration = duration % _DAY_IN_MILLIS; + } + if (duration >= _HOUR_IN_MILLIS) { s += Math.floor(duration / _HOUR_IN_MILLIS) + ':'; duration = duration % _HOUR_IN_MILLIS; @@ -114,7 +132,6 @@ L.GPX = L.FeatureGroup.extend({ 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())); }, @@ -125,12 +142,17 @@ L.GPX = L.FeatureGroup.extend({ 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_total_speed: function() { return this.m_to_km(this.get_distance()) / (this.get_total_time() / (3600 * 1000)); }, + get_total_speed_imp: function() { return this.to_miles(this.m_to_km(this.get_distance())) / (this.get_total_time() / (3600 * 1000)); }, + get_elevation_gain: function() { return this._info.elevation.gain; }, get_elevation_loss: function() { return this._info.elevation.loss; }, + get_elevation_gain_imp: function() { return this.to_ft(this.get_elevation_gain()); }, + get_elevation_loss_imp: function() { return this.to_ft(this.get_elevation_loss()); }, get_elevation_data: function() { var _this = this; return this._info.elevation._points.map( @@ -145,6 +167,10 @@ L.GPX = L.FeatureGroup.extend({ function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' ft'; }); }); }, + get_elevation_max: function() { return this._info.elevation.max; }, + get_elevation_min: function() { return this._info.elevation.min; }, + get_elevation_max_imp: function() { return this.to_ft(this.get_elevation_max()); }, + get_elevation_min_imp: function() { return this.to_ft(this.get_elevation_min()); }, get_average_hr: function() { return this._info.hr.avg; }, get_heartrate_data: function() { @@ -217,7 +243,15 @@ L.GPX = L.FeatureGroup.extend({ _parse_gpx_data: function(xml, options) { var j, i, el, layers = []; - var tags = [['rte','rtept'], ['trkseg','trkpt']]; + var tags = []; + + var parseElements = options.gpx_options.parseElements; + if (parseElements.indexOf('route') > -1) { + tags.push(['rte','rtept']); + } + if (parseElements.indexOf('track') > -1) { + tags.push(['trkseg','trkpt']); + } var name = xml.getElementsByTagName('name'); if (name.length > 0) { @@ -250,20 +284,20 @@ L.GPX = L.FeatureGroup.extend({ if (options.marker_options.startIconUrl) { // add start pin var p = new L.Marker(coords[0], { - clickable: false, + clickable: options.marker_options.clickable, icon: new L.GPXTrackIcon({iconUrl: options.marker_options.startIconUrl}) }); - this.fire('addpoint', { point: p }); + this.fire('addpoint', { point: p, point_type: 'start' }); layers.push(p); } if (options.marker_options.endIconUrl) { // add end pin p = new L.Marker(coords[coords.length-1], { - clickable: false, + clickable: options.marker_options.clickable, icon: new L.GPXTrackIcon({iconUrl: options.marker_options.endIconUrl}) }); - this.fire('addpoint', { point: p }); + this.fire('addpoint', { point: p, point_type: 'end' }); layers.push(p); } } @@ -271,11 +305,48 @@ L.GPX = L.FeatureGroup.extend({ 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 waypoints and add markers for each of them + if (parseElements.indexOf('waypoint') > -1) { + el = xml.getElementsByTagName('wpt'); + for (i = 0; i < el.length; i++) { + var ll = new L.LatLng( + el[i].getAttribute('lat'), + el[i].getAttribute('lon')); + + var nameEl = el[i].getElementsByTagName('name'); + var name = ''; + if (nameEl.length > 0) { + name = nameEl[0].textContent; + } + + var descEl = el[i].getElementsByTagName('desc'); + var desc = ''; + if (descEl.length > 0) { + desc = descEl[0].textContent; + } + + var symEl = el[i].getElementsByTagName('sym'); + var symKey = ''; + if (symEl.length > 0) { + symKey = symEl[0].textContent; + } + + // add WayPointMarker, based on "sym" element if avail and icon is configured + var symIcon = options.marker_options.wptIconUrls[name]; + var marker = new L.Marker(ll, { + clickable: false, + icon: symIcon ? new L.GPXTrackIcon({iconUrl: symIcon}) : new L.Icon.Default() + }); + this.fire('addpoint', { point: marker, point_type: 'waypoint' }); + layers.push(marker); + } + } + + if (layers.length > 1) { + return new L.FeatureGroup(layers); + } else if (layers.length == 1) { + return layers[0]; + } }, _parse_trkseg: function(line, xml, options, tag) { @@ -307,6 +378,12 @@ L.GPX = L.FeatureGroup.extend({ this._info.hr._total += ll.meta.hr; } + if(ll.meta.ele > this._info.elevation.max) + this._info.elevation.max = ll.meta.ele; + + if(ll.meta.ele < this._info.elevation.min) + this._info.elevation.min = ll.meta.ele; + this._info.elevation._points.push([this._info.length, ll.meta.ele]); this._info.duration.end = ll.meta.time; @@ -356,3 +433,9 @@ L.GPX = L.FeatureGroup.extend({ return deg * Math.PI / 180; } }); + +if (typeof module === 'object' && typeof module.exports === 'object') { + module.exports = L; +} else if (typeof define === 'function' && define.amd) { + define(L); +} diff --git a/iFrameGPX/leaflet-gpx/night.png b/iFrameGPX/leaflet-gpx/night.png new file mode 100755 index 0000000000000000000000000000000000000000..4f0e917202a0537f69cfd1f5171069f2d8680b6a GIT binary patch literal 603 zcmV-h0;K(kP)kOE3FjiM+U%;$40?g5W7x^zU*%^GWM=6- zKMprR5a4+puIsictdt^25{Sdie!6}_UV~{o7wAMBxO}GenWNpVvlH8*j|5EfBwQGI1+m((dlga-D0QmXw1AyghRRU@g#(KA_gRzNgz+c{OHPEflz;zJT zCS1-|EN81m;x^Ydeg$oZHGrOdF97$>{u=!E-H6QiYWZy{XYGNen~&{YaTVZRucTn2C3ZL**lxF#=cF-7F#3XA4nF0AC(5na$tQ963%CiP#rM5cYWk7oP!Q3YX$&&(2E093c<*FwNt;6c*!1@Khi+l8lVE=Q6Sy{{mze^%w;X!2;c(3lN`yZlvC-G pCgP0&3