@raruto/leaflet-elevation 1.8.0 → 1.8.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.
@@ -1,6 +1 @@
1
- 'use strict';L.DistanceMarkers=L.LayerGroup.extend({initialize:function(line,map,options){options=options||{};var offset=options.offset||1E3;var showAll=Math.min(map.getMaxZoom(),options.showAll||12);var cssClass=options.cssClass||"dist-marker";var iconSize=options.iconSize!==undefined?options.iconSize:[12,12];var textFunction=options.textFunction||function(distance,i,offset){return i};var zoomLayers={};var coords=line;if(typeof line.getLatLngs=="function")coords=line.getLatLngs();var accumulated=
2
- L.GeometryUtil.accumulatedLengths(line);var length=accumulated.length>0?accumulated[accumulated.length-1]:0;var j=0;var count=Math.floor(length/offset);for(var i=1;i<=count;++i){var distance=offset*i;while(j<accumulated.length-1&&accumulated[j]<distance)++j;var p1=coords[j-1];var p2=coords[j];var m_line=L.polyline([p1,p2]);var ratio=(distance-accumulated[j-1])/(accumulated[j]-accumulated[j-1]);var position=L.GeometryUtil.interpolateOnLine(map,m_line,ratio);var text=textFunction.call(this,distance,
3
- i,offset);var icon=L.divIcon({className:cssClass,html:text,iconSize:iconSize});var marker=L.marker(position.latLng,{title:text,icon:icon});var zoom=this._minimumZoomLevelForItem(i,showAll);if(zoomLayers[zoom]===undefined)zoomLayers[zoom]=L.layerGroup();zoomLayers[zoom].addLayer(marker)}var currentZoomLevel=0;var markerLayer=this;var updateMarkerVisibility=function(){var oldZoom=currentZoomLevel;var newZoom=currentZoomLevel=map.getZoom();if(newZoom>oldZoom)for(var i=oldZoom+1;i<=newZoom;++i){if(zoomLayers[i]!==
4
- undefined)markerLayer.addLayer(zoomLayers[i])}else if(newZoom<oldZoom)for(var i=oldZoom;i>newZoom;--i)if(zoomLayers[i]!==undefined)markerLayer.removeLayer(zoomLayers[i])};map.on("zoomend",updateMarkerVisibility);this._layers={};updateMarkerVisibility()},_minimumZoomLevelForItem:function(item,showAllLevel){var zoom=showAllLevel;var i=item;while(i>0&&i%2===0){--zoom;i=Math.floor(i/2)}return zoom}});
5
- L.Polyline.include({_originalOnAdd:L.Polyline.prototype.onAdd,_originalOnRemove:L.Polyline.prototype.onRemove,addDistanceMarkers:function(){if(this._map&&this._distanceMarkers)this._map.addLayer(this._distanceMarkers)},removeDistanceMarkers:function(){if(this._map&&this._distanceMarkers)this._map.removeLayer(this._distanceMarkers)},onAdd:function(map){this._originalOnAdd(map);var opts=this.options.distanceMarkers||{};if(this._distanceMarkers===undefined&&this.options.distanceMarkers)this._distanceMarkers=
6
- new L.DistanceMarkers(this,map,opts);if(opts.lazy===undefined||opts.lazy===false)this.addDistanceMarkers()},onRemove:function(map){this.removeDistanceMarkers();this._originalOnRemove(map)}});
1
+ L.DistanceMarkers=L.LayerGroup.extend({initialize:function(line,map,options){var offset=(options=options||{}).offset||1e3,showAll=Math.min(map.getMaxZoom(),options.showAll||12),cssClass=options.cssClass||"dist-marker",iconSize=void 0!==options.iconSize?options.iconSize:[12,12],textFunction=options.textFunction||function(distance,i,offset){return i},zoomLayers={},coords=line;"function"==typeof line.getLatLngs&&(coords=line.getLatLngs());for(var accumulated=L.GeometryUtil.accumulatedLengths(line),length=accumulated.length>0?accumulated[accumulated.length-1]:0,j=0,count=Math.floor(length/offset),i=1;i<=count;++i){for(var distance=offset*i;j<accumulated.length-1&&accumulated[j]<distance;)++j;var p1=coords[j-1],p2=coords[j],m_line=L.polyline([p1,p2]),ratio=(distance-accumulated[j-1])/(accumulated[j]-accumulated[j-1]),position=L.GeometryUtil.interpolateOnLine(map,m_line,ratio),text=textFunction.call(this,distance,i,offset),icon=L.divIcon({className:cssClass,html:text,iconSize:iconSize}),marker=L.marker(position.latLng,{title:text,icon:icon}),zoom=this._minimumZoomLevelForItem(i,showAll);void 0===zoomLayers[zoom]&&(zoomLayers[zoom]=L.layerGroup()),zoomLayers[zoom].addLayer(marker)}var currentZoomLevel=0,markerLayer=this,updateMarkerVisibility=function(){var oldZoom=currentZoomLevel,newZoom=currentZoomLevel=map.getZoom();if(newZoom>oldZoom)for(var i=oldZoom+1;i<=newZoom;++i)void 0!==zoomLayers[i]&&markerLayer.addLayer(zoomLayers[i]);else if(newZoom<oldZoom)for(var i=oldZoom;i>newZoom;--i)void 0!==zoomLayers[i]&&markerLayer.removeLayer(zoomLayers[i])};map.on("zoomend",updateMarkerVisibility),this._layers={},updateMarkerVisibility()},_minimumZoomLevelForItem:function(item,showAllLevel){for(var zoom=showAllLevel,i=item;i>0&&i%2==0;)--zoom,i=Math.floor(i/2);return zoom}}),L.Polyline.include({_originalOnAdd:L.Polyline.prototype.onAdd,_originalOnRemove:L.Polyline.prototype.onRemove,addDistanceMarkers:function(){this._map&&this._distanceMarkers&&this._map.addLayer(this._distanceMarkers)},removeDistanceMarkers:function(){this._map&&this._distanceMarkers&&this._map.removeLayer(this._distanceMarkers)},onAdd:function(map){this._originalOnAdd(map);var opts=this.options.distanceMarkers||{};void 0===this._distanceMarkers&&this.options.distanceMarkers&&(this._distanceMarkers=new L.DistanceMarkers(this,map,opts)),void 0!==opts.lazy&&!1!==opts.lazy||this.addDistanceMarkers()},onRemove:function(map){this.removeDistanceMarkers(),this._originalOnRemove(map)}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raruto/leaflet-elevation",
3
- "version": "1.8.0",
3
+ "version": "1.8.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
@@ -49,7 +49,7 @@ export var Chart = L.Class.extend({
49
49
  this._initScale();
50
50
 
51
51
  // Helpers
52
- this._clipPath = chart.get('clipPath');
52
+ this._mask = chart.get('mask');
53
53
  this._context = chart.get('context');
54
54
  this._brush = chart.get('brush');
55
55
 
@@ -61,6 +61,13 @@ export var Chart = L.Class.extend({
61
61
 
62
62
  // svg.on('resize', (e)=>console.log(e.detail));
63
63
 
64
+ // Handle multi-track segments (BETA)
65
+ this._maskGaps = [];
66
+ control.on('eletrack_added', (e) => {
67
+ this._maskGaps.push(e.index);
68
+ control.once('eledata_updated', (e) => this._maskGaps.push(e.index));
69
+ });
70
+
64
71
  },
65
72
 
66
73
  update: function(props) {
@@ -92,6 +99,9 @@ export var Chart = L.Class.extend({
92
99
  // this._x.domain([0, 1]);
93
100
  // this._y.domain([0, 1]);
94
101
  // }
102
+
103
+ this._maskGaps = [];
104
+ this._mask.selectAll(".gap").remove();
95
105
  },
96
106
 
97
107
  _drawPath: function(name) {
@@ -178,6 +188,10 @@ export var Chart = L.Class.extend({
178
188
  if (e.sourceEvent && e.sourceEvent.type == "mousedown") svg.style('cursor', 'grabbing');
179
189
  if (e.transform.k == 1 && e.transform.x == 0) {
180
190
  this._container.classed('zoomed', true);
191
+ // Apply d3-zoom (bind <clipPath> mask)
192
+ if (this._mask) {
193
+ this._point.attr('mask', 'url(#' + this._mask.attr('id') + ')');
194
+ }
181
195
  }
182
196
  this.zooming = true;
183
197
  };
@@ -185,6 +199,10 @@ export var Chart = L.Class.extend({
185
199
  const onEnd = (e) => {
186
200
  if (e.transform.k ==1 && e.transform.x == 0){
187
201
  this._container.classed('zoomed', false);
202
+ // Apply d3-zoom (bind <clipPath> mask)
203
+ if (this._mask) {
204
+ this._point.attr('mask', null);
205
+ }
188
206
  }
189
207
  this.zooming = false;
190
208
  svg.style('cursor', '');
@@ -497,6 +515,24 @@ export var Chart = L.Class.extend({
497
515
  [this._width() - margin.right, Infinity]
498
516
  ]);
499
517
 
518
+ // Apply svg mask on multi-track segments (BETA)
519
+ this._mask.selectAll(".gap").remove()
520
+ this._maskGaps.forEach((d, i) => {
521
+ if(i >= this._maskGaps.length - 2) return;
522
+ let d1 = this._data[this._maskGaps[i]];
523
+ let d2 = this._data[this._maskGaps[i + 1]];
524
+ let x1 = this._x(this._data[this._findIndexForLatLng(d1.latlng)].dist);
525
+ let x2 = this._x(this._data[this._findIndexForLatLng(d2.latlng)].dist);
526
+ this._mask
527
+ .append("rect")
528
+ .attr("x", x1)
529
+ .attr("y", 0)
530
+ .attr("width", x2 - x1 )
531
+ .attr("height", this._height())
532
+ .attr('class', 'gap')
533
+ .attr('fill-opacity', '0.8')
534
+ .attr("fill", 'black'); // black = hide
535
+ });
500
536
  },
501
537
 
502
538
  _updateLegend: function () {
@@ -573,8 +609,8 @@ export var Chart = L.Class.extend({
573
609
  }
574
610
 
575
611
  // Apply d3-zoom (bind <clipPath> mask)
576
- if (this._clipPath) {
577
- path.attr('clip-path', 'url(#' + this._clipPath.attr('id') + ')');
612
+ if (this._mask) {
613
+ path.attr('mask', 'url(#' + this._mask.attr('id') + ')');
578
614
  }
579
615
 
580
616
  });
package/src/components.js CHANGED
@@ -505,11 +505,11 @@ export const Chart = ({
505
505
  };
506
506
 
507
507
  // SVG Paths
508
- const clipPath = panes.area.append("svg:clipPath").attr("id", 'elevation-clipper');
509
- const clipRect = clipPath.append("svg:rect");
508
+ const mask = panes.area.append("svg:mask").attr("id", 'elevation-clipper').attr('fill-opacity', 1);
509
+ const maskRect = mask.append("svg:rect").attr('class', 'zoom').attr('fill', 'white'); // white = transparent
510
510
 
511
511
  // Canvas Paths
512
- const foreignObject = panes.area.append('svg:foreignObject');
512
+ const foreignObject = panes.area.append('svg:foreignObject').attr('mask', 'url(#' + mask.attr('id') + ')');
513
513
  const canvas = foreignObject.append('xhtml:canvas').attr('class', 'canvas-plot');
514
514
  const context = canvas.node().getContext('2d');
515
515
 
@@ -523,7 +523,7 @@ export const Chart = ({
523
523
  const scale = (opts) => ({ x: Scale(opts.x), y: Scale(opts.y)});
524
524
 
525
525
  let utils = {
526
- clipPath,
526
+ mask,
527
527
  canvas,
528
528
  context,
529
529
  brush,
@@ -560,7 +560,7 @@ export const Chart = ({
560
560
  .style("transform", "translate(" + margins.left + "px," + margins.top + "px)");
561
561
  }
562
562
 
563
- clipRect
563
+ maskRect
564
564
  .attr("x", 0)
565
565
  .attr("y", 0)
566
566
  .attr("width", _width)
package/src/control.js CHANGED
@@ -17,7 +17,7 @@ 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.7.5/libs/leaflet-distance-marker.min.js',
20
+ __LDISTANCEM: 'https://unpkg.com/@raruto/leaflet-elevation@1.8.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
@@ -997,6 +997,7 @@ Elevation.addInitHook(function() {
997
997
  }
998
998
  });
999
999
  }
1000
+
1000
1001
  });
1001
1002
 
1002
1003
  // Basic canvas renderer support.
package/src/index.css CHANGED
@@ -36,7 +36,6 @@
36
36
  user-select: none;
37
37
  }
38
38
 
39
- .elevation-control.elevation .background.zoomed .point,
40
39
  .elevation-control.elevation .background.zoomed .axis.time {
41
40
  display: none;
42
41
  }
package/src/utils.js CHANGED
@@ -58,6 +58,23 @@ export function GeoJSONLoader(data, control) {
58
58
 
59
59
  let { wptIcons, wptLabels } = control.options;
60
60
 
61
+ // Partially fix MultiLineStrings (trk > trkseg + trkseg) splitting them into seperate LineStrings (trk > trkseg, trk > trkseg)
62
+ data.features.forEach(d => {
63
+ if(d.type == 'Feature' && d.geometry.type == "MultiLineString") {
64
+ d.geometry.coordinates.forEach(coords => {
65
+ data.features.push({
66
+ type: 'Feature',
67
+ geometry: {
68
+ type: 'LineString',
69
+ coordinates: coords,
70
+ },
71
+ properties: d.properties
72
+ });
73
+ });
74
+ }
75
+ });
76
+ data.features = data.features.filter(d=> d.type && d.geometry.type != "MultiLineString");
77
+
61
78
  let layer = L.geoJson(data, {
62
79
  distanceMarkers: distanceMarkers,
63
80
  style: (feature) => {