@raruto/leaflet-elevation 1.6.9 → 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -100,11 +100,10 @@ L.control.layersLegend = function(baseLayers, overlays, options) {
100
100
  return new L.Control.LayersLegend(baseLayers, overlays, options);
101
101
  };
102
102
 
103
- L.GPX.include(L.Mixin.Selectable);
103
+ L.GeoJSON.include(L.Mixin.Selectable);
104
104
 
105
105
  L.GpxGroup = L.Class.extend({
106
106
  options: {
107
- async: true,
108
107
  highlight: {
109
108
  color: '#ff0',
110
109
  opacity: 1,
@@ -125,7 +124,6 @@ L.GpxGroup = L.Class.extend({
125
124
  elevation: true,
126
125
  elevation_options: {
127
126
  theme: 'yellow-theme',
128
- // width: 500,
129
127
  detachedView: true,
130
128
  elevationDiv: '#elevation-div',
131
129
  },
@@ -133,11 +131,6 @@ L.GpxGroup = L.Class.extend({
133
131
  distanceMarkers_options: {
134
132
  lazy: true
135
133
  },
136
- marker_options: {
137
- startIconUrl: null,
138
- endIconUrl: null,
139
- shadowUrl: null,
140
- }
141
134
  },
142
135
 
143
136
  initialize: function(tracks, options) {
@@ -187,10 +180,38 @@ L.GpxGroup = L.Class.extend({
187
180
  },
188
181
 
189
182
  addTrack: function(track) {
190
- this._get(track, this._loadRoute.bind(this));
183
+ fetch(track).then(response => {
184
+ if (response.ok) {
185
+ response.text().then(doc => {
186
+ let geojson;
187
+ doc = doc.trim();
188
+
189
+ try {
190
+ let xml = (new DOMParser()).parseFromString(doc, "text/xml");
191
+ let type = xml.documentElement.tagName.toLowerCase(); // "kml" or "gpx"
192
+ let name = xml.getElementsByTagName('name');
193
+ if (!(type in toGeoJSON)) {
194
+ type = xml.documentElement.tagName == "TrainingCenterDatabase" ? 'tcx' : 'gpx';
195
+ }
196
+ geojson = toGeoJSON[type](xml);
197
+ geojson.name = name.length > 0 ? name[0].textContent : '';
198
+ } catch (e) {
199
+ try {
200
+ geojson = JSON.parse(doc.toString());
201
+ geojson.name = geojson.name || '';
202
+ } catch (e) {
203
+ console.warn("Error parsing track: " + track);
204
+ }
205
+ }
206
+ this._loadRoute(geojson);
207
+ });
208
+ }
209
+ });
191
210
  },
192
211
 
193
212
  _loadRoute: function(data) {
213
+ if (!data) return;
214
+
194
215
  var colors = this._uniqueColors(this._tracks.length);
195
216
  var color = colors[this._count++];
196
217
 
@@ -201,23 +222,23 @@ L.GpxGroup = L.Class.extend({
201
222
  distanceMarkers: this.options.distanceMarkers_options,
202
223
  };
203
224
 
204
- var route = new L.GPX(data, {
205
- async: this.options.async,
206
- marker_options: this.options.marker_options,
207
- polyline_options: line_style
225
+ var route = L.geoJson(data, {
226
+ name: data.name || '',
227
+ style: (feature) => line_style,
228
+ distanceMarkers: line_style.distanceMarkers,
229
+ originalStyle: line_style,
208
230
  });
209
231
 
210
- route.originalStyle = line_style;
211
-
212
- route.on('addline', L.bind(this._onRouteAddLine, this, route));
213
- route.on('loaded', L.bind(this._onRouteLoaded, this, route));
214
-
215
232
  route.addTo(this._layers);
216
233
  this._routes[route._leaflet_id] = route;
234
+
235
+ route.eachLayer((layer) => this._onRouteLayer(route, layer));
236
+ this._onRouteLoaded(route);
237
+
217
238
  },
218
239
 
219
- _onRouteAddLine: function(route, e) {
220
- var polyline = e.line;
240
+ _onRouteLayer: function(route, layer) {
241
+ var polyline = layer;
221
242
 
222
243
  route.on('selected', L.bind(this._onRouteSelected, this, route, polyline));
223
244
 
@@ -225,7 +246,7 @@ L.GpxGroup = L.Class.extend({
225
246
  polyline.on('mouseout', L.bind(this._onRouteMouseOut, this, route, polyline));
226
247
  polyline.on('click', L.bind(this._onRouteClick, this, route, polyline));
227
248
 
228
- polyline.bindTooltip(route.get_name(), {
249
+ polyline.bindTooltip(route.options.name, {
229
250
  direction: 'auto',
230
251
  sticky: true,
231
252
  });
@@ -239,7 +260,7 @@ L.GpxGroup = L.Class.extend({
239
260
  },
240
261
 
241
262
  unhighlight: function(route, polyline) {
242
- polyline.setStyle(route.originalStyle);
263
+ polyline.setStyle(route.options.originalStyle);
243
264
  if (this.options.distanceMarkers) {
244
265
  polyline.removeDistanceMarkers();
245
266
  }
@@ -281,7 +302,7 @@ L.GpxGroup = L.Class.extend({
281
302
 
282
303
  _onRouteLoaded: function(route) {
283
304
  if (this.options.legend) {
284
- this._legend.addBaseLayer(route, '<svg id="legend_' + route._leaflet_id + '" width="25" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">' + '<line x1="0" x2="50" y1="5" y2="5" stroke="' + route.options.polyline_options.color + '" fill="transparent" stroke-width="5" /></svg>' + ' ' + route.get_name());
305
+ this._legend.addBaseLayer(route, '<svg id="legend_' + route._leaflet_id + '" width="25" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">' + '<line x1="0" x2="50" y1="5" y2="5" stroke="' + route.options.originalStyle.color + '" fill="transparent" stroke-width="5" /></svg>' + ' ' + route.options.name);
285
306
  }
286
307
  this.fire('route_loaded', {
287
308
  route: route,
@@ -314,7 +335,7 @@ L.GpxGroup = L.Class.extend({
314
335
  }
315
336
  route.getLayers().forEach(function(layer) {
316
337
  if (layer instanceof L.Polyline) {
317
- elevation.addData(layer);
338
+ elevation.addData(layer, false);
318
339
  layer.bringToFront();
319
340
  }
320
341
  });
@@ -353,17 +374,6 @@ L.GpxGroup = L.Class.extend({
353
374
  }
354
375
  },
355
376
 
356
- _get: function(url, callback) {
357
- var xhr = new XMLHttpRequest();
358
- xhr.open("GET", url);
359
- xhr.onreadystatechange = function() {
360
- if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
361
- callback(xhr.response);
362
- }
363
- };
364
- xhr.send();
365
- },
366
-
367
377
  _uniqueColors: function(count) {
368
378
  if (count === 0) return [];
369
379
  if (count === 1) return ['#0000ff'];
@@ -1,16 +1,17 @@
1
1
  'use strict';L.Mixin.Selectable={includes:L.Mixin.Events,setSelected:function(s){var selected=!!s;if(this._selected!==selected){this._selected=selected;this.fire("selected")}},isSelected:function(){return!!this._selected}};
2
2
  L.Mixin.Selection={includes:L.Mixin.Events,getSelection:function(){return this._selected},setSelection:function(item){if(this._selected===item){if(item!==null){item.setSelected(!item.isSelected());if(!item.isSelected())this._selected=null}}else{if(this._selected)this._selected.setSelected(false);this._selected=item;if(this._selected)this._selected.setSelected(true)}this.fire("selection_changed")}};
3
3
  L.Control.LayersLegend=L.Control.Layers.extend({_onInputClick:function(){var inputs=this._layerControlInputs,input,layer;var addedLayers=[],removedLayers=[];this._handlingClick=true;for(var i=inputs.length-1;i>=0;i--){input=inputs[i];layer=this._getLayer(input.layerId).layer;if(input.checked)this._map.fireEvent("legend_selected",{layer:layer,input:input},true)}this._handlingClick=false;this._refocusOnMap()}});
4
- L.control.layersLegend=function(baseLayers,overlays,options){return new L.Control.LayersLegend(baseLayers,overlays,options)};L.GPX.include(L.Mixin.Selectable);
5
- L.GpxGroup=L.Class.extend({options:{async:true,highlight:{color:"#ff0",opacity:1},points:[],points_options:{icon:{iconUrl:"../images/elevation-poi.png",iconSize:[12,12]}},flyToBounds:true,legend:false,legend_options:{position:"topright",collapsed:false},elevation:true,elevation_options:{theme:"yellow-theme",detachedView:true,elevationDiv:"#elevation-div"},distanceMarkers:true,distanceMarkers_options:{lazy:true},marker_options:{startIconUrl:null,endIconUrl:null,shadowUrl:null}},initialize:function(tracks,
6
- options){L.Util.setOptions(this,options);this._count=0;this._loadedCount=0;this._tracks=tracks;this._routes={};this._layers=L.featureGroup();this._markers=L.featureGroup();this._elevation=L.control.elevation(this.options.elevation_options);this._legend=L.control.layersLegend(null,null,this.options.legend_options);var icon=L.icon(this.options.points_options.icon);this.options.points.forEach(function(poi){var marker=L.marker(poi.latlng,{icon:icon});marker.bindTooltip(poi.name,{direction:"auto"});marker.addTo(this._markers)},
7
- this);if(typeof L.DistanceMarkers==="undefined")this.options.distanceMarkers=false},getBounds:function(){return this._layers.getBounds()},addTo:function(map){this._layers.addTo(map);this._markers.addTo(map);this._map=map;this.on("selection_changed",this._onSelectionChanged,this);this._map.on("legend_selected",this._onLegendSelected,this);this._tracks.forEach(this.addTrack,this)},addTrack:function(track){this._get(track,this._loadRoute.bind(this))},_loadRoute:function(data){var colors=this._uniqueColors(this._tracks.length);
8
- var color=colors[this._count++];var line_style={color:color,opacity:.75,weight:5,distanceMarkers:this.options.distanceMarkers_options};var route=new L.GPX(data,{async:this.options.async,marker_options:this.options.marker_options,polyline_options:line_style});route.originalStyle=line_style;route.on("addline",L.bind(this._onRouteAddLine,this,route));route.on("loaded",L.bind(this._onRouteLoaded,this,route));route.addTo(this._layers);this._routes[route._leaflet_id]=route},_onRouteAddLine:function(route,
9
- e){var polyline=e.line;route.on("selected",L.bind(this._onRouteSelected,this,route,polyline));polyline.on("mouseover",L.bind(this._onRouteMouseOver,this,route,polyline));polyline.on("mouseout",L.bind(this._onRouteMouseOut,this,route,polyline));polyline.on("click",L.bind(this._onRouteClick,this,route,polyline));polyline.bindTooltip(route.get_name(),{direction:"auto",sticky:true})},highlight:function(route,polyline){polyline.setStyle(this.options.highlight);if(this.options.distanceMarkers)polyline.addDistanceMarkers()},
10
- unhighlight:function(route,polyline){polyline.setStyle(route.originalStyle);if(this.options.distanceMarkers)polyline.removeDistanceMarkers()},_onRouteMouseOver:function(route,polyline){if(!route.isSelected()){this.highlight(route,polyline);if(this.options.legend){this.setSelection(route);L.DomUtil.get("legend_"+route._leaflet_id).parentNode.previousSibling.click()}}this.fire("route_mouseover",{route:route,polyline:polyline})},_onRouteMouseOut:function(route,polyline){if(!route.isSelected())this.unhighlight(route,
11
- polyline);this.fire("route_mouseout",{route:route,polyline:polyline})},_onRouteClick:function(route,polyline){this.setSelection(route)},_onRouteSelected:function(route,polyline){if(!route.isSelected())this.unhighlight(route,polyline)},_onRouteLoaded:function(route){if(this.options.legend)this._legend.addBaseLayer(route,'<svg id="legend_'+route._leaflet_id+'" width="25" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">'+'<line x1="0" x2="50" y1="5" y2="5" stroke="'+route.options.polyline_options.color+
12
- '" fill="transparent" stroke-width="5" /></svg>'+" "+route.get_name());this.fire("route_loaded",{route:route});if(++this._loadedCount===this._tracks.length){this.fire("loaded");if(this.options.flyToBounds)this._map.flyToBounds(this.getBounds(),{duration:.25,easeLinearity:.25,noMoveStart:true});if(this.options.legend)this._legend.addTo(this._map)}},_onSelectionChanged:function(e){var elevation=this._elevation;var eleDiv=elevation.getContainer();var route=this.getSelection();elevation.clear();if(route&&
13
- route.isSelected()){if(!eleDiv)elevation.loadChart(this._map);route.getLayers().forEach(function(layer){if(layer instanceof L.Polyline){elevation.addData(layer);layer.bringToFront()}})}else if(eleDiv)elevation.remove()},_onLegendSelected:function(e){var layers=this._layers._layers;var route=e.layer;if(!route.isSelected()){this.setSelection(route);for(var i in route._layers)this.highlight(route,route._layers[i]);this._map.flyToBounds(e.layer.getBounds())}var parent=e.input.closest(".leaflet-control-layers-list");
14
- var offset=e.input.offsetTop-parent.offsetTop;parent.scroll({top:offset||0,behavior:"smooth"});for(var j in layers){var selected=layers[j].isSelected();var legend=L.DomUtil.get("legend_"+layers[j]._leaflet_id);legend.querySelector("line").style.stroke=selected?this.options.highlight.color:"";legend.parentNode.style.fontWeight=selected?"700":""}},_get:function(url,callback){var xhr=new XMLHttpRequest;xhr.open("GET",url);xhr.onreadystatechange=function(){if(xhr.readyState===XMLHttpRequest.DONE&&xhr.status===
15
- 200)callback(xhr.response)};xhr.send()},_uniqueColors:function(count){if(count===0)return[];if(count===1)return["#0000ff"];var increment=1/count;var colors=[];for(var i=0;i<count;++i){var hue=i*increment;var rgb=this._hsvToRgb(hue,1,.7);var hex="#"+this._rgbToHex(rgb[0],rgb[1],rgb[2]);colors.push(hex)}return colors},_hsvToRgb:function(h,s,v){var r,g,b;var i=Math.floor(h*6);var f=h*6-i;var p=v*(1-s);var q=v*(1-f*s);var t=v*(1-(1-f)*s);switch(i%6){case 0:r=v;g=t;b=p;break;case 1:r=q;g=v;b=p;break;case 2:r=
16
- p;g=v;b=t;break;case 3:r=p;g=q;b=v;break;case 4:r=t;g=p;b=v;break;case 5:r=v;g=p;b=q;break}return[r*255,g*255,b*255]},_rgbToHex:function(r,g,b){return this._byteToHex(r)+this._byteToHex(g)+this._byteToHex(b)},_byteToHex:function(n){return(n>>4&15).toString(16)+(n&15).toString(16)},removeFrom:function(map){this._layers.removeFrom(map)}});L.GpxGroup.include(L.Mixin.Events);L.GpxGroup.include(L.Mixin.Selection);L.gpxGroup=function(tracks,options){return new L.GpxGroup(tracks,options)};
4
+ L.control.layersLegend=function(baseLayers,overlays,options){return new L.Control.LayersLegend(baseLayers,overlays,options)};L.GeoJSON.include(L.Mixin.Selectable);
5
+ L.GpxGroup=L.Class.extend({options:{highlight:{color:"#ff0",opacity:1},points:[],points_options:{icon:{iconUrl:"../images/elevation-poi.png",iconSize:[12,12]}},flyToBounds:true,legend:false,legend_options:{position:"topright",collapsed:false},elevation:true,elevation_options:{theme:"yellow-theme",detachedView:true,elevationDiv:"#elevation-div"},distanceMarkers:true,distanceMarkers_options:{lazy:true}},initialize:function(tracks,options){L.Util.setOptions(this,options);this._count=0;this._loadedCount=
6
+ 0;this._tracks=tracks;this._routes={};this._layers=L.featureGroup();this._markers=L.featureGroup();this._elevation=L.control.elevation(this.options.elevation_options);this._legend=L.control.layersLegend(null,null,this.options.legend_options);var icon=L.icon(this.options.points_options.icon);this.options.points.forEach(function(poi){var marker=L.marker(poi.latlng,{icon:icon});marker.bindTooltip(poi.name,{direction:"auto"});marker.addTo(this._markers)},this);if(typeof L.DistanceMarkers==="undefined")this.options.distanceMarkers=
7
+ false},getBounds:function(){return this._layers.getBounds()},addTo:function(map){this._layers.addTo(map);this._markers.addTo(map);this._map=map;this.on("selection_changed",this._onSelectionChanged,this);this._map.on("legend_selected",this._onLegendSelected,this);this._tracks.forEach(this.addTrack,this)},addTrack:function(track){fetch(track).then((response)=>{if(response.ok)response.text().then((doc)=>{let geojson;doc=doc.trim();try{let xml=(new DOMParser).parseFromString(doc,"text/xml");let type=
8
+ xml.documentElement.tagName.toLowerCase();let name=xml.getElementsByTagName("name");if(!(type in toGeoJSON))type=xml.documentElement.tagName=="TrainingCenterDatabase"?"tcx":"gpx";geojson=toGeoJSON[type](xml);geojson.name=name.length>0?name[0].textContent:""}catch(e){try{geojson=JSON.parse(doc.toString());geojson.name=geojson.name||""}catch(e){console.warn("Error parsing track: "+track)}}this._loadRoute(geojson)})})},_loadRoute:function(data){if(!data)return;var colors=this._uniqueColors(this._tracks.length);
9
+ var color=colors[this._count++];var line_style={color:color,opacity:.75,weight:5,distanceMarkers:this.options.distanceMarkers_options};var route=L.geoJson(data,{name:data.name||"",style:(feature)=>line_style,distanceMarkers:line_style.distanceMarkers,originalStyle:line_style});route.addTo(this._layers);this._routes[route._leaflet_id]=route;route.eachLayer((layer)=>this._onRouteLayer(route,layer));this._onRouteLoaded(route)},_onRouteLayer:function(route,layer){var polyline=layer;route.on("selected",
10
+ L.bind(this._onRouteSelected,this,route,polyline));polyline.on("mouseover",L.bind(this._onRouteMouseOver,this,route,polyline));polyline.on("mouseout",L.bind(this._onRouteMouseOut,this,route,polyline));polyline.on("click",L.bind(this._onRouteClick,this,route,polyline));polyline.bindTooltip(route.options.name,{direction:"auto",sticky:true})},highlight:function(route,polyline){polyline.setStyle(this.options.highlight);if(this.options.distanceMarkers)polyline.addDistanceMarkers()},unhighlight:function(route,
11
+ polyline){polyline.setStyle(route.options.originalStyle);if(this.options.distanceMarkers)polyline.removeDistanceMarkers()},_onRouteMouseOver:function(route,polyline){if(!route.isSelected()){this.highlight(route,polyline);if(this.options.legend){this.setSelection(route);L.DomUtil.get("legend_"+route._leaflet_id).parentNode.previousSibling.click()}}this.fire("route_mouseover",{route:route,polyline:polyline})},_onRouteMouseOut:function(route,polyline){if(!route.isSelected())this.unhighlight(route,polyline);
12
+ this.fire("route_mouseout",{route:route,polyline:polyline})},_onRouteClick:function(route,polyline){this.setSelection(route)},_onRouteSelected:function(route,polyline){if(!route.isSelected())this.unhighlight(route,polyline)},_onRouteLoaded:function(route){if(this.options.legend)this._legend.addBaseLayer(route,'<svg id="legend_'+route._leaflet_id+'" width="25" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">'+'<line x1="0" x2="50" y1="5" y2="5" stroke="'+route.options.originalStyle.color+
13
+ '" fill="transparent" stroke-width="5" /></svg>'+" "+route.options.name);this.fire("route_loaded",{route:route});if(++this._loadedCount===this._tracks.length){this.fire("loaded");if(this.options.flyToBounds)this._map.flyToBounds(this.getBounds(),{duration:.25,easeLinearity:.25,noMoveStart:true});if(this.options.legend)this._legend.addTo(this._map)}},_onSelectionChanged:function(e){var elevation=this._elevation;var eleDiv=elevation.getContainer();var route=this.getSelection();elevation.clear();if(route&&
14
+ route.isSelected()){if(!eleDiv)elevation.loadChart(this._map);route.getLayers().forEach(function(layer){if(layer instanceof L.Polyline){elevation.addData(layer,false);layer.bringToFront()}})}else if(eleDiv)elevation.remove()},_onLegendSelected:function(e){var layers=this._layers._layers;var route=e.layer;if(!route.isSelected()){this.setSelection(route);for(var i in route._layers)this.highlight(route,route._layers[i]);this._map.flyToBounds(e.layer.getBounds())}var parent=e.input.closest(".leaflet-control-layers-list");
15
+ var offset=e.input.offsetTop-parent.offsetTop;parent.scroll({top:offset||0,behavior:"smooth"});for(var j in layers){var selected=layers[j].isSelected();var legend=L.DomUtil.get("legend_"+layers[j]._leaflet_id);legend.querySelector("line").style.stroke=selected?this.options.highlight.color:"";legend.parentNode.style.fontWeight=selected?"700":""}},_uniqueColors:function(count){if(count===0)return[];if(count===1)return["#0000ff"];var increment=1/count;var colors=[];for(var i=0;i<count;++i){var hue=i*
16
+ increment;var rgb=this._hsvToRgb(hue,1,.7);var hex="#"+this._rgbToHex(rgb[0],rgb[1],rgb[2]);colors.push(hex)}return colors},_hsvToRgb:function(h,s,v){var r,g,b;var i=Math.floor(h*6);var f=h*6-i;var p=v*(1-s);var q=v*(1-f*s);var t=v*(1-(1-f)*s);switch(i%6){case 0:r=v;g=t;b=p;break;case 1:r=q;g=v;b=p;break;case 2:r=p;g=v;b=t;break;case 3:r=p;g=q;b=v;break;case 4:r=t;g=p;b=v;break;case 5:r=v;g=p;b=q;break}return[r*255,g*255,b*255]},_rgbToHex:function(r,g,b){return this._byteToHex(r)+this._byteToHex(g)+
17
+ this._byteToHex(b)},_byteToHex:function(n){return(n>>4&15).toString(16)+(n&15).toString(16)},removeFrom:function(map){this._layers.removeFrom(map)}});L.GpxGroup.include(L.Mixin.Events);L.GpxGroup.include(L.Mixin.Selection);L.gpxGroup=function(tracks,options){return new L.GpxGroup(tracks,options)};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raruto/leaflet-elevation",
3
- "version": "1.6.9",
3
+ "version": "1.7.3",
4
4
  "description": "A Leaflet plugin that allows to add elevation profiles using d3js",
5
5
  "main": "dist/leaflet-elevation.min.js",
6
6
  "module": "src/index.js",
package/src/chart.js CHANGED
@@ -97,8 +97,10 @@ export var Chart = L.Class.extend({
97
97
 
98
98
  clear: function() {
99
99
  this._resetDrag();
100
+ this._hideDiagramIndicator()
100
101
  this._area.selectAll('path').attr("d", "M0 0");
101
102
  this._context.clearRect(0, 0, this._width(), this._height());
103
+
102
104
  if (this._path) {
103
105
  // this._x.domain([0, 1]);
104
106
  // this._y.domain([0, 1]);
@@ -173,6 +175,7 @@ export var Chart = L.Class.extend({
173
175
  */
174
176
  _initBrush: function(e) {
175
177
  const brush = (e) => {
178
+ if (!this._data.length) return;
176
179
  let extent = e.selection;
177
180
  if (extent) {
178
181
  let start = this._findIndexForXCoord(extent[0]);
@@ -182,6 +185,7 @@ export var Chart = L.Class.extend({
182
185
  }
183
186
 
184
187
  const focus = (e) => {
188
+ if (!this._data.length) return;
185
189
  if (e.type == 'brush' && !e.sourceEvent) return;
186
190
  let rect = this._chart.panes.brush.select('.overlay').node();
187
191
  let coords = d3.pointers(e, rect)[0];
package/src/components.js CHANGED
@@ -506,6 +506,12 @@ export const Chart = ({
506
506
 
507
507
  g.attr("transform", "translate(" + margins.left + "," + margins.top + ")");
508
508
 
509
+ // Partially fix: https://github.com/Raruto/leaflet-elevation/issues/123
510
+ if(/Mac|iPod|iPhone|iPad/.test(navigator.platform) && /AppleWebkit/i.test(navigator.userAgent)) {
511
+ canvas
512
+ .style("transform", "translate(" + margins.left + "px," + margins.top + "px)");
513
+ }
514
+
509
515
  clipRect
510
516
  .attr("x", 0)
511
517
  .attr("y", 0)
package/src/control.js CHANGED
@@ -17,13 +17,13 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
17
17
  __TOGEOJSON: 'https://unpkg.com/@tmcw/togeojson@4.3.0/dist/togeojson.umd.js',
18
18
  __LGEOMUTIL: 'https://unpkg.com/leaflet-geometryutil@0.9.3/src/leaflet.geometryutil.js',
19
19
  __LALMOSTOVER: 'https://unpkg.com/leaflet-almostover@1.0.1/src/leaflet.almostover.js',
20
- __LDISTANCEM: 'https://unpkg.com/@raruto/leaflet-elevation@1.6.9/libs/leaflet-distance-marker.min.js',
20
+ __LDISTANCEM: 'https://unpkg.com/@raruto/leaflet-elevation@1.7.3/libs/leaflet-distance-marker.min.js',
21
21
 
22
22
  /*
23
23
  * Add data to the diagram either from GPX or GeoJSON and update the axis domain and data
24
24
  */
25
25
  addData: function(d, layer) {
26
- if ((typeof layer === "undefined" || layer === null) && d.on) {
26
+ if (typeof layer === "undefined" && d.on) {
27
27
  layer = d;
28
28
  }
29
29
  Elevation._d3LazyLoader = _.lazyLoader(
@@ -56,13 +56,40 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
56
56
  */
57
57
  clear: function() {
58
58
  if (this._marker) this._marker.remove();
59
- if (this._chart) this._chart.clear();
60
- if (this._layers) this._layers.clearLayers();
59
+ if (this._chart) this._clearChart();
60
+ if (this._layers) this._clearLayers();
61
+ if (this._markers) this._clearMarkers();
61
62
 
62
63
  this._data = [];
63
64
  this.track_info = {};
64
65
 
65
66
  this._fireEvt("eledata_clear");
67
+
68
+ this._updateChart();
69
+ },
70
+
71
+ _clearChart: function() {
72
+ if (this._events && this._events.elechart_updated) {
73
+ this._events.elechart_updated.forEach(e => controlElevation.off('elechart_updated', e.fn, e.ctx));
74
+ }
75
+ if (this._chart && this._chart._container) {
76
+ this._chart._container.selectAll('g.point .point').remove();
77
+ this._chart.clear();
78
+ }
79
+ },
80
+
81
+ _clearLayers: function() {
82
+ if (this._layers && this._layers.eachLayer) {
83
+ this._layers.eachLayer(l => l.remove())
84
+ this._layers.clearLayers();
85
+ }
86
+ },
87
+
88
+ _clearMarkers: function() {
89
+ if (this._markers && this._markers.eachLayer) {
90
+ this._markers.eachLayer(l => l.remove())
91
+ this._markers.clearLayers();
92
+ }
66
93
  },
67
94
 
68
95
  /**
@@ -142,6 +169,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
142
169
  initialize: function(options) {
143
170
  this._data = [];
144
171
  this._layers = L.featureGroup();
172
+ this._markers = L.featureGroup();
145
173
  this._markedSegments = L.polyline([]);
146
174
  this._chartEnabled = true,
147
175
 
@@ -420,7 +448,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
420
448
  */
421
449
  _addGPXData: function(coords) {
422
450
  _.each(coords, point => {
423
- this._addPoint(point.lat, point.lng, point.meta.ele);
451
+ this._addPoint(point.lat, point.lng, typeof point.alt !== "undefined" ? point.alt : point.meta.ele);
424
452
  this._fireEvt("elepoint_added", { point: point, index: this._data.length - 1 });
425
453
  });
426
454
  this._fireEvt("eletrack_added", { coords: coords, index: this._data.length - 1 });
@@ -448,6 +476,10 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
448
476
  if (layer) this._layers.addLayer(layer)
449
477
  },
450
478
 
479
+ _addMarker: function(marker) {
480
+ if (marker) this._markers.addLayer(marker)
481
+ },
482
+
451
483
  /**
452
484
  * Adds the control to the given "detached" div.
453
485
  */
@@ -886,7 +918,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
886
918
  * Calculates [x, y] domain and then update chart.
887
919
  */
888
920
  _updateChart: function() {
889
- if (!this._data.length || !this._container) return;
921
+ if (/*!this._data.length ||*/ !this._container) return;
890
922
 
891
923
  this._fireEvt("elechart_axis");
892
924
  this._fireEvt("elechart_area");
package/src/index.css CHANGED
@@ -33,6 +33,7 @@
33
33
  overflow: visible;
34
34
  display: block;
35
35
  touch-action: none;
36
+ user-select: none;
36
37
  }
37
38
 
38
39
  .elevation-control.elevation .background.zoomed .point,
package/src/options.js CHANGED
@@ -18,22 +18,6 @@ export var Options = {
18
18
  elevationDiv: "#elevation-div",
19
19
  followMarker: true,
20
20
  forceAxisBounds: false,
21
- gpxOptions: {
22
- async: true,
23
- marker_options: {
24
- startIconUrl: null,
25
- endIconUrl: null,
26
- shadowUrl: null,
27
- wptIcons: {
28
- '': L.divIcon({
29
- className: 'elevation-waypoint-marker',
30
- html: '<i class="elevation-waypoint-icon"></i>',
31
- iconSize: [30, 30],
32
- iconAnchor: [8, 30],
33
- })
34
- },
35
- },
36
- },
37
21
  height: 200,
38
22
  heightFactor: 1,
39
23
  imperial: false,
@@ -88,6 +72,15 @@ export var Options = {
88
72
  sInterpolation: "curveStepAfter",
89
73
  sRange: undefined,
90
74
  width: 600,
75
+ waypoints: true,
76
+ wptIcons: {
77
+ '': L.divIcon({
78
+ className: 'elevation-waypoint-marker',
79
+ html: '<i class="elevation-waypoint-icon"></i>',
80
+ iconSize: [30, 30],
81
+ iconAnchor: [8, 30],
82
+ }),
83
+ },
91
84
  xAttr: "dist",
92
85
  xLabel: "km",
93
86
  xTicks: undefined,
package/src/utils.js CHANGED
@@ -79,7 +79,7 @@ export function GeoJSONLoader(data, control) {
79
79
  : L.extend({ lazy: true }, control.options.distanceMarkers)
80
80
  );
81
81
 
82
- let wptIcons = control.options.gpxOptions.marker_options.wptIcons;
82
+ let wptIcons = control.options.wptIcons;
83
83
 
84
84
  let layer = L.geoJson(data, {
85
85
  distanceMarkers: distanceMarkers,
@@ -91,22 +91,24 @@ export function GeoJSONLoader(data, control) {
91
91
  return style;
92
92
  },
93
93
  pointToLayer: (feature, latlng) => {
94
+ if (!control.options.waypoints) return;
95
+
94
96
  let prop = feature.properties;
95
97
  let desc = prop.desc ? prop.desc : '';
96
98
  let name = prop.name ? prop.name : '';
97
99
  let sym = (prop.sym ? prop.sym : name).replace(' ', '-').replace('"', '').replace("'", '').toLowerCase();
98
100
 
99
- // generate appropriate icon symbol or retrieve it from cache
100
- wptIcons[sym] = (wptIcons[sym] ? wptIcons[sym] : L.divIcon({
101
- className: 'elevation-waypoint-marker',
102
- html: '<i class="elevation-waypoint-icon ' + sym + '"></i>',
103
- iconSize: [30, 30],
104
- iconAnchor: [8, 30],
105
- }));
101
+ // generate and cache appropriate icon symbol
102
+ if (!wptIcons.hasOwnProperty(sym)) {
103
+ wptIcons[sym] = L.divIcon(
104
+ L.extend({}, wptIcons[""].options, { html: '<i class="elevation-waypoint-icon ' + sym + '"></i>' } )
105
+ );
106
+ }
106
107
  let marker = L.marker(latlng, { icon: wptIcons[sym] });
107
108
  if (name || desc) {
108
109
  marker.bindPopup("<b>" + name + "</b>" + (desc.length > 0 ? '<br>' + desc : '')).openPopup();
109
110
  }
111
+ control._addMarker(marker);
110
112
  control._registerCheckPoint({latlng: latlng, label: name}, true);
111
113
  control.fire('waypoint_added', { point: marker, element: latlng, properties: prop });
112
114
  return marker;