@raruto/leaflet-elevation 2.3.3 → 2.4.0
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.
- package/README.md +1 -0
- package/dist/leaflet-elevation.js +1619 -1566
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.js +1 -1
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/libs/leaflet-gpxgroup.js +346 -340
- package/libs/leaflet-gpxgroup.min.js +1 -1
- package/libs/leaflet-hotline.js +1 -1
- package/package.json +74 -74
- package/src/control.js +1337 -1325
- package/src/handlers/labels.js +45 -0
- package/src/handlers/runner.js +109 -0
- package/src/options.js +88 -88
- package/src/utils.js +203 -163
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see https://github.com/Raruto/leaflet-elevation/issues/211
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```js
|
|
6
|
+
* L.control.Elevation({ handlers: [ 'Labels' ], labelsRotation: 25, labelsAlign: 'start' })
|
|
7
|
+
* ```
|
|
8
|
+
*/
|
|
9
|
+
export function Labels() {
|
|
10
|
+
|
|
11
|
+
this.on('elechart_init elechart_axis', function(e) {
|
|
12
|
+
|
|
13
|
+
const pointG = this._chart._chart.pane('point');
|
|
14
|
+
|
|
15
|
+
const textRotation = this.options.labelsRotation ?? -90;
|
|
16
|
+
const textAnchor = this.options.labelsAlign;
|
|
17
|
+
|
|
18
|
+
if (90 == Math.abs(textRotation)) {
|
|
19
|
+
|
|
20
|
+
pointG.selectAll('text')
|
|
21
|
+
.attr('dy', '4px')
|
|
22
|
+
.attr("dx", (d, i, el) => Math.sign(textRotation) * (this._height() - d3.select(el[i].parentElement).datum().y - 8) + 'px')
|
|
23
|
+
.attr('text-anchor', textRotation > 0 ? 'end' : 'start')
|
|
24
|
+
.attr('transform', 'rotate(' + textRotation + ')')
|
|
25
|
+
|
|
26
|
+
pointG.selectAll('circle')
|
|
27
|
+
.attr('r', '2.5')
|
|
28
|
+
.attr('fill', '#fff')
|
|
29
|
+
.attr("stroke", '#000')
|
|
30
|
+
.attr("stroke-width", '1.1');
|
|
31
|
+
|
|
32
|
+
} else if (!isNaN(textRotation)) {
|
|
33
|
+
|
|
34
|
+
pointG.selectAll('text')
|
|
35
|
+
.attr("dx", "4px")
|
|
36
|
+
.attr("dy", "-9px")
|
|
37
|
+
.attr('text-anchor', textAnchor ?? (0 == textRotation ? 'start' : 'middle'))
|
|
38
|
+
.attr('transform', 'rotate('+ -textRotation +')')
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return { };
|
|
45
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see https://github.com/Igor-Vladyka/leaflet.motion
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```js
|
|
6
|
+
* L.control.Elevation({ handlers: [ 'Runner' ], runnerOptions: { polyline: {..}, motion: {..}, marker {..} } })
|
|
7
|
+
* ```
|
|
8
|
+
*/
|
|
9
|
+
export async function Runner() {
|
|
10
|
+
|
|
11
|
+
await this.import(this.__LMOTION || 'https://unpkg.com/leaflet.motion@0.3.2/dist/leaflet.motion.min.js', typeof L.Motion !== 'object')
|
|
12
|
+
|
|
13
|
+
let { runnerOptions } = this.options;
|
|
14
|
+
|
|
15
|
+
runnerOptions = L.extend(
|
|
16
|
+
{ polyline: {}, motion: {}, marker: undefined },
|
|
17
|
+
'object' === typeof runnerOptions ? runnerOptions : {}
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
// Custom tooltips
|
|
21
|
+
this._registerTooltip({
|
|
22
|
+
name: 'here',
|
|
23
|
+
marker: (item) => L._("You are here: "),
|
|
24
|
+
order: 1,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
this._registerTooltip({
|
|
28
|
+
name: 'distance',
|
|
29
|
+
marker: (item) => Math.round(item.dist) + " " + this.options.xLabel,
|
|
30
|
+
order: 2,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
this.addCheckpoint = function (checkpoint) {
|
|
34
|
+
return this._registerCheckPoint({ // <-- NB these are private functions use them at your own risk!
|
|
35
|
+
latlng: this._findItemForX(this._x(checkpoint.dist)).latlng,
|
|
36
|
+
label: checkpoint.label || ''
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.addRunner = function (runner) {
|
|
41
|
+
let x = this._x(runner.dist);
|
|
42
|
+
let y = this._y(this._findItemForX(x).z)
|
|
43
|
+
let g = d3.select(this._container)
|
|
44
|
+
.select('svg > g')
|
|
45
|
+
.append("svg:circle")
|
|
46
|
+
.attr("class", "runner " + this.options.theme + " height-focus circle-lower")
|
|
47
|
+
.attr("r", 6)
|
|
48
|
+
.attr("cx", x)
|
|
49
|
+
.attr("cy", y);
|
|
50
|
+
return g;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.setPositionFromLatLng = function (latlng) {
|
|
54
|
+
this._onMouseMoveLayer({ latlng: latlng }); // Update map and chart "markers" from latlng
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
this.tick = function (runner, dist = 0, inc = 0.1) {
|
|
58
|
+
dist = (dist <= this.track_info.distance - inc) ? dist + inc : 0;
|
|
59
|
+
this.updateRunnerPos(runner, dist);
|
|
60
|
+
setTimeout(() => this.tick(runner, dist), 150);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
this.updateRunnerPos = function (runner, pos) {
|
|
64
|
+
let curr, x;
|
|
65
|
+
|
|
66
|
+
if (pos instanceof L.LatLng) {
|
|
67
|
+
curr = this._findItemForLatLng(pos);
|
|
68
|
+
x = this._x(curr.dist);
|
|
69
|
+
} else {
|
|
70
|
+
x = this._x(pos);
|
|
71
|
+
curr = this._findItemForX(x);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
runner
|
|
75
|
+
.attr("cx", x)
|
|
76
|
+
.attr("cy", this._y(curr.z));
|
|
77
|
+
this.setPositionFromLatLng(curr.latlng);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
this.animate = function (layer, speed = 1500) {
|
|
81
|
+
|
|
82
|
+
if (this._runner) {
|
|
83
|
+
this._runner.remove();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
layer.setStyle({ opacity: 0.5 });
|
|
87
|
+
|
|
88
|
+
const geo = L.geoJson(layer.toGeoJSON(), { coordsToLatLng: (coords) => L.latLng(coords[0], coords[1], coords[2] * (this.options.altitudeFactor || 1)) });
|
|
89
|
+
this._runner = L.motion.polyline(
|
|
90
|
+
geo.toGeoJSON().features[0].geometry.coordinates,
|
|
91
|
+
L.extend({}, { color: 'red', pane: 'elevationPane', attribution: '' }, runnerOptions.polyline),
|
|
92
|
+
L.extend({}, { auto: true, speed: speed, }, runnerOptions.motion),
|
|
93
|
+
runnerOptions.marker || undefined
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// Override default function behavior: `L.Motion.Polyline::_drawMarker()`
|
|
97
|
+
this._runner._drawMarker = new Proxy(this._runner._drawMarker, {
|
|
98
|
+
apply: (target, thisArg, argArray) => {
|
|
99
|
+
thisArg._runner = thisArg._runner || this.addRunner({ dist: 0 });
|
|
100
|
+
this.updateRunnerPos(thisArg._runner, argArray[0]);
|
|
101
|
+
return target.apply(thisArg, argArray);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
this._runner.addTo(this._map);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
return {};
|
|
109
|
+
}
|
package/src/options.js
CHANGED
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
import * as _ from './utils';
|
|
2
|
-
|
|
3
|
-
export var Options = {
|
|
4
|
-
autofitBounds: true,
|
|
5
|
-
autohide: false,
|
|
6
|
-
autohideMarker: true,
|
|
7
|
-
almostover: true,
|
|
8
|
-
altitude: true,
|
|
9
|
-
closeBtn: true,
|
|
10
|
-
collapsed: false,
|
|
11
|
-
detached: true,
|
|
12
|
-
distance: true,
|
|
13
|
-
distanceMarkers: { lazy: true, distance: true, direction: true },
|
|
14
|
-
dragging: !L.Browser.mobile,
|
|
15
|
-
downloadLink: 'link',
|
|
16
|
-
elevationDiv: "#elevation-div",
|
|
17
|
-
edgeScale: { bar: true, icon: false, coords: false },
|
|
18
|
-
followMarker: true,
|
|
19
|
-
imperial: false,
|
|
20
|
-
legend: true,
|
|
21
|
-
handlers: ["Distance", "Time", "Altitude", "Slope", "Speed", "Acceleration"],
|
|
22
|
-
hotline: 'elevation',
|
|
23
|
-
marker: 'elevation-line',
|
|
24
|
-
markerIcon: L.divIcon({
|
|
25
|
-
className: 'elevation-position-marker',
|
|
26
|
-
html: '<i class="elevation-position-icon"></i>',
|
|
27
|
-
iconSize: [32, 32],
|
|
28
|
-
iconAnchor: [16, 16],
|
|
29
|
-
}),
|
|
30
|
-
position: "topright",
|
|
31
|
-
polyline: {
|
|
32
|
-
className: 'elevation-polyline',
|
|
33
|
-
color: '#000',
|
|
34
|
-
opacity: 0.75,
|
|
35
|
-
weight: 5,
|
|
36
|
-
lineCap: 'round'
|
|
37
|
-
},
|
|
38
|
-
polylineSegments: {
|
|
39
|
-
className: 'elevation-polyline-segments',
|
|
40
|
-
color: '#F00',
|
|
41
|
-
interactive: false,
|
|
42
|
-
},
|
|
43
|
-
preferCanvas: false,
|
|
44
|
-
reverseCoords: false,
|
|
45
|
-
ruler: true,
|
|
46
|
-
theme: "lightblue-theme",
|
|
47
|
-
summary: 'inline',
|
|
48
|
-
slope: false,
|
|
49
|
-
speed: false,
|
|
50
|
-
time: true,
|
|
51
|
-
timeFactor: 3600,
|
|
52
|
-
timestamps: false,
|
|
53
|
-
trkStart: { className: 'start-marker', radius: 6, weight: 2, color: '#fff', fillColor: '#00d800', fillOpacity: 1, interactive: false },
|
|
54
|
-
trkEnd: { className: 'end-marker', radius: 6, weight: 2, color: '#fff', fillColor: '#ff0606', fillOpacity: 1, interactive: false },
|
|
55
|
-
waypoints: true,
|
|
56
|
-
wptIcons: {
|
|
57
|
-
'': L.divIcon({
|
|
58
|
-
className: 'elevation-waypoint-marker',
|
|
59
|
-
html: '<i class="elevation-waypoint-icon default"></i>',
|
|
60
|
-
iconSize: [30, 30],
|
|
61
|
-
iconAnchor: [8, 30],
|
|
62
|
-
}),
|
|
63
|
-
},
|
|
64
|
-
wptLabels: true,
|
|
65
|
-
xAttr: "dist",
|
|
66
|
-
xLabel: "km",
|
|
67
|
-
yAttr: "z",
|
|
68
|
-
yLabel: "m",
|
|
69
|
-
zFollow: false,
|
|
70
|
-
zooming: !L.Browser.Mobile,
|
|
71
|
-
|
|
72
|
-
// Quite uncommon and undocumented options
|
|
73
|
-
margins: { top: 30, right: 30, bottom: 30, left: 40 },
|
|
74
|
-
height: (screen.height * 0.3) || 200,
|
|
75
|
-
width: (screen.width * 0.6) || 600,
|
|
76
|
-
xTicks: undefined,
|
|
77
|
-
yTicks: undefined,
|
|
78
|
-
|
|
79
|
-
decimalsX: 2,
|
|
80
|
-
decimalsY: 0,
|
|
81
|
-
forceAxisBounds: false,
|
|
82
|
-
interpolation: "curveLinear",
|
|
83
|
-
yAxisMax: undefined,
|
|
84
|
-
yAxisMin: undefined,
|
|
85
|
-
|
|
86
|
-
// Prevent CORS issues for relative locations (dynamic import)
|
|
87
|
-
srcFolder: ((document.currentScript && document.currentScript.src) || (import.meta && import.meta.url)).split("/").slice(0,-1).join("/") + '/',
|
|
88
|
-
};
|
|
1
|
+
import * as _ from './utils';
|
|
2
|
+
|
|
3
|
+
export var Options = {
|
|
4
|
+
autofitBounds: true,
|
|
5
|
+
autohide: false,
|
|
6
|
+
autohideMarker: true,
|
|
7
|
+
almostover: true,
|
|
8
|
+
altitude: true,
|
|
9
|
+
closeBtn: true,
|
|
10
|
+
collapsed: false,
|
|
11
|
+
detached: true,
|
|
12
|
+
distance: true,
|
|
13
|
+
distanceMarkers: { lazy: true, distance: true, direction: true },
|
|
14
|
+
dragging: !L.Browser.mobile,
|
|
15
|
+
downloadLink: 'link',
|
|
16
|
+
elevationDiv: "#elevation-div",
|
|
17
|
+
edgeScale: { bar: true, icon: false, coords: false },
|
|
18
|
+
followMarker: true,
|
|
19
|
+
imperial: false,
|
|
20
|
+
legend: true,
|
|
21
|
+
handlers: ["Distance", "Time", "Altitude", "Slope", "Speed", "Acceleration"],
|
|
22
|
+
hotline: 'elevation',
|
|
23
|
+
marker: 'elevation-line',
|
|
24
|
+
markerIcon: L.divIcon({
|
|
25
|
+
className: 'elevation-position-marker',
|
|
26
|
+
html: '<i class="elevation-position-icon"></i>',
|
|
27
|
+
iconSize: [32, 32],
|
|
28
|
+
iconAnchor: [16, 16],
|
|
29
|
+
}),
|
|
30
|
+
position: "topright",
|
|
31
|
+
polyline: {
|
|
32
|
+
className: 'elevation-polyline',
|
|
33
|
+
color: '#000',
|
|
34
|
+
opacity: 0.75,
|
|
35
|
+
weight: 5,
|
|
36
|
+
lineCap: 'round'
|
|
37
|
+
},
|
|
38
|
+
polylineSegments: {
|
|
39
|
+
className: 'elevation-polyline-segments',
|
|
40
|
+
color: '#F00',
|
|
41
|
+
interactive: false,
|
|
42
|
+
},
|
|
43
|
+
preferCanvas: false,
|
|
44
|
+
reverseCoords: false,
|
|
45
|
+
ruler: true,
|
|
46
|
+
theme: "lightblue-theme",
|
|
47
|
+
summary: 'inline',
|
|
48
|
+
slope: false,
|
|
49
|
+
speed: false,
|
|
50
|
+
time: true,
|
|
51
|
+
timeFactor: 3600,
|
|
52
|
+
timestamps: false,
|
|
53
|
+
trkStart: { className: 'start-marker', radius: 6, weight: 2, color: '#fff', fillColor: '#00d800', fillOpacity: 1, interactive: false },
|
|
54
|
+
trkEnd: { className: 'end-marker', radius: 6, weight: 2, color: '#fff', fillColor: '#ff0606', fillOpacity: 1, interactive: false },
|
|
55
|
+
waypoints: true,
|
|
56
|
+
wptIcons: {
|
|
57
|
+
'': L.divIcon({
|
|
58
|
+
className: 'elevation-waypoint-marker',
|
|
59
|
+
html: '<i class="elevation-waypoint-icon default"></i>',
|
|
60
|
+
iconSize: [30, 30],
|
|
61
|
+
iconAnchor: [8, 30],
|
|
62
|
+
}),
|
|
63
|
+
},
|
|
64
|
+
wptLabels: true,
|
|
65
|
+
xAttr: "dist",
|
|
66
|
+
xLabel: "km",
|
|
67
|
+
yAttr: "z",
|
|
68
|
+
yLabel: "m",
|
|
69
|
+
zFollow: false,
|
|
70
|
+
zooming: !L.Browser.Mobile,
|
|
71
|
+
|
|
72
|
+
// Quite uncommon and undocumented options
|
|
73
|
+
margins: { top: 30, right: 30, bottom: 30, left: 40 },
|
|
74
|
+
height: (screen.height * 0.3) || 200,
|
|
75
|
+
width: (screen.width * 0.6) || 600,
|
|
76
|
+
xTicks: undefined,
|
|
77
|
+
yTicks: undefined,
|
|
78
|
+
|
|
79
|
+
decimalsX: 2,
|
|
80
|
+
decimalsY: 0,
|
|
81
|
+
forceAxisBounds: false,
|
|
82
|
+
interpolation: "curveLinear",
|
|
83
|
+
yAxisMax: undefined,
|
|
84
|
+
yAxisMin: undefined,
|
|
85
|
+
|
|
86
|
+
// Prevent CORS issues for relative locations (dynamic import)
|
|
87
|
+
srcFolder: ((document.currentScript && document.currentScript.src) || (import.meta && import.meta.url)).split("/").slice(0,-1).join("/") + '/',
|
|
88
|
+
};
|