@raruto/leaflet-elevation 2.0.1 → 2.0.2
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 +2 -1
- package/dist/leaflet-elevation.js +121 -158
- 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-distance-marker.js +97 -92
- package/libs/leaflet-distance-marker.min.js +1 -1
- package/package.json +1 -1
- package/src/control.js +119 -156
- package/src/handlers/altitude.js +4 -1
- package/src/utils.js +2 -2
package/README.md
CHANGED
|
@@ -241,6 +241,7 @@ var map = L.map('map', {
|
|
|
241
241
|
- https://wordpress.org/plugins/extensions-leaflet-map/
|
|
242
242
|
- https://github.com/der-stefan/OpenTopoMap
|
|
243
243
|
- https://gpx.n-peloton.fr/
|
|
244
|
+
- https://walkaholic.me/map
|
|
244
245
|
|
|
245
246
|
</details>
|
|
246
247
|
|
|
@@ -251,7 +252,7 @@ _Related: [Leaflet-UI presets](https://github.com/raruto/leaflet-ui), [QGIS Inte
|
|
|
251
252
|
**Compatibile with:**
|
|
252
253
|
[](http://leafletjs.com/reference.html)
|
|
253
254
|
[](https://www.npmjs.com/package/d3)
|
|
254
|
-
[](https://www.npmjs.com/package/@tmcw/togeojson)
|
|
255
256
|
|
|
256
257
|
|
|
257
258
|
---
|
|
@@ -135,11 +135,11 @@
|
|
|
135
135
|
* Loop and extract GPX Extensions handled by "@tmcw/toGeoJSON" (eg. "coordinateProperties" > "times")
|
|
136
136
|
*/
|
|
137
137
|
function coordPropsToMeta(coordProps, name, parser) {
|
|
138
|
-
return coordProps && (({props, point, id}) => {
|
|
138
|
+
return coordProps && (({props, point, id, isMulti }) => {
|
|
139
139
|
if (props) {
|
|
140
140
|
for (const key of coordProps) {
|
|
141
141
|
if (key in props) {
|
|
142
|
-
point.meta[name] = (parser || parseInt).call(this, props[key], id);
|
|
142
|
+
point.meta[name] = (parser || parseInt).call(this, (isMulti ? props[key][isMulti] : props[key]), id);
|
|
143
143
|
break;
|
|
144
144
|
}
|
|
145
145
|
}
|
|
@@ -348,9 +348,7 @@
|
|
|
348
348
|
addData: function(d, layer) {
|
|
349
349
|
this.import(this.__D3)
|
|
350
350
|
.then(() => {
|
|
351
|
-
|
|
352
|
-
layer = d;
|
|
353
|
-
}
|
|
351
|
+
layer = layer ?? (d.on && d);
|
|
354
352
|
this._addData(d);
|
|
355
353
|
this._addLayer(layer);
|
|
356
354
|
this._fireEvt("eledata_added", { data: d, layer: layer, track_info: this.track_info });
|
|
@@ -619,51 +617,44 @@
|
|
|
619
617
|
return;
|
|
620
618
|
}
|
|
621
619
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
this._addGeoJSONData(geom.coordinates);
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
break;
|
|
635
|
-
|
|
636
|
-
default:
|
|
637
|
-
return console.warn('Unsopperted GeoJSON feature geometry type:' + geom.type);
|
|
620
|
+
// Standard GeoJSON
|
|
621
|
+
if (d.type === "FeatureCollection" ) {
|
|
622
|
+
return each(d.features, feature => this._addData(feature));
|
|
623
|
+
} else if (d.type === "Feature") {
|
|
624
|
+
let geom = d.geometry;
|
|
625
|
+
if (geom) {
|
|
626
|
+
switch (geom.type) {
|
|
627
|
+
case 'LineString': return this._addGeoJSONData(geom.coordinates, d.properties);
|
|
628
|
+
case 'MultiLineString': return each(geom.coordinates, (coords, i) => this._addGeoJSONData(coords, d.properties, i));
|
|
629
|
+
case 'Point':
|
|
630
|
+
default: return console.warn('Unsopperted GeoJSON feature geometry type:' + geom.type);
|
|
631
|
+
}
|
|
638
632
|
}
|
|
639
633
|
}
|
|
640
|
-
if (d.type === "FeatureCollection") {
|
|
641
|
-
each(d.features, feature => this._addData(feature));
|
|
642
|
-
}
|
|
643
634
|
|
|
644
|
-
|
|
645
|
-
* Extended GeoJSON --> rely on leaflet implementation
|
|
646
|
-
*/
|
|
635
|
+
// Fallback for leaflet layers (eg. L.Gpx)
|
|
647
636
|
if (d._latlngs) {
|
|
648
|
-
this._addGeoJSONData(d._latlngs, d.feature && d.feature.properties);
|
|
637
|
+
return this._addGeoJSONData(d._latlngs, d.feature && d.feature.properties);
|
|
649
638
|
}
|
|
639
|
+
|
|
650
640
|
},
|
|
651
641
|
|
|
652
642
|
/*
|
|
653
643
|
* Parsing of GeoJSON data lines and their elevation in z-coordinate
|
|
654
644
|
*/
|
|
655
|
-
_addGeoJSONData: function(coords, properties) {
|
|
645
|
+
_addGeoJSONData: function(coords, properties, nestingLevel) {
|
|
646
|
+
|
|
647
|
+
// "coordinateProperties" property is generated inside "@tmcw/toGeoJSON"
|
|
648
|
+
let props = (properties && properties.coordinateProperties) || properties;
|
|
649
|
+
|
|
656
650
|
coords.forEach((point, i) => {
|
|
657
651
|
|
|
658
652
|
// GARMIN_EXTENSIONS = ["hr", "cad", "atemp", "wtemp", "depth", "course", "bearing"];
|
|
659
653
|
point.meta = point.meta ?? { time: null, ele: null };
|
|
660
654
|
|
|
661
|
-
// "coordinateProperties" property is generated inside "@tmcw/toGeoJSON"
|
|
662
|
-
let props = (properties && properties.coordinateProperties) || properties;
|
|
663
|
-
|
|
664
655
|
point.prev = (attr) => (attr ? this._data[i > 0 ? i - 1 : 0][attr] : this._data[i > 0 ? i - 1 : 0]);
|
|
665
656
|
|
|
666
|
-
this.fire("elepoint_init", { point: point, props: props, id: i });
|
|
657
|
+
this.fire("elepoint_init", { point: point, props: props, id: i, isMulti: nestingLevel });
|
|
667
658
|
|
|
668
659
|
this._addPoint(
|
|
669
660
|
point.lat ?? point[1],
|
|
@@ -703,10 +694,12 @@
|
|
|
703
694
|
if (layer && this.options.distanceMarkers && this.options.distanceMarkers.lazy) {
|
|
704
695
|
layer.on('add remove', ({target, type}) => L.DistanceMarkers && target instanceof L.Polyline && target[type + 'DistanceMarkers']());
|
|
705
696
|
}
|
|
697
|
+
return layer;
|
|
706
698
|
},
|
|
707
699
|
|
|
708
700
|
_addMarker: function(marker) {
|
|
709
701
|
if (marker) this._markers.addLayer(marker);
|
|
702
|
+
return marker;
|
|
710
703
|
},
|
|
711
704
|
|
|
712
705
|
/**
|
|
@@ -1038,7 +1031,7 @@
|
|
|
1038
1031
|
*/
|
|
1039
1032
|
_loadModules: function(handlers) {
|
|
1040
1033
|
// First map known classnames (eg. "Altitude" --> L.Control.Elevation.Altitude)
|
|
1041
|
-
handlers = handlers.map((h) => typeof h === 'string' && typeof
|
|
1034
|
+
handlers = handlers.map((h) => typeof h === 'string' && typeof Elevation[h] !== "undefined" ? Elevation[h] : h);
|
|
1042
1035
|
// Then load optional classes and custom imports (eg. "Cadence" --> import('../src/handlers/cadence.js'))
|
|
1043
1036
|
Promise.
|
|
1044
1037
|
all(
|
|
@@ -1049,8 +1042,8 @@
|
|
|
1049
1042
|
.then((m) => {
|
|
1050
1043
|
each(m, (exported) => {
|
|
1051
1044
|
let fn = Object.keys(exported)[0];
|
|
1052
|
-
if (fn && typeof
|
|
1053
|
-
handlers[fn] =
|
|
1045
|
+
if (fn && typeof Elevation[fn] === "undefined" ) {
|
|
1046
|
+
handlers[fn] = Elevation[fn] = exported[fn];
|
|
1054
1047
|
|
|
1055
1048
|
}
|
|
1056
1049
|
});
|
|
@@ -1062,65 +1055,48 @@
|
|
|
1062
1055
|
* Simple GeoJSON data loader (L.GeoJSON).
|
|
1063
1056
|
*/
|
|
1064
1057
|
_loadLayer: function(geojson) {
|
|
1065
|
-
let
|
|
1058
|
+
let { polyline, theme, waypoints, wptIcons, wptLabels, distanceMarkers } = this.options;
|
|
1059
|
+
let style = L.extend({}, polyline);
|
|
1066
1060
|
|
|
1067
|
-
|
|
1061
|
+
if (theme) {
|
|
1062
|
+
style.className += ' ' + theme;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
if (geojson.name) {
|
|
1066
|
+
this.track_info.name = geojson.name;
|
|
1067
|
+
}
|
|
1068
1068
|
|
|
1069
1069
|
let layer = L.geoJson(geojson, {
|
|
1070
|
-
distanceMarkers:
|
|
1071
|
-
style:
|
|
1072
|
-
let style = L.extend({}, control.options.polyline);
|
|
1073
|
-
if (control.options.theme) {
|
|
1074
|
-
style.className += ' ' + control.options.theme;
|
|
1075
|
-
}
|
|
1076
|
-
return style;
|
|
1077
|
-
},
|
|
1070
|
+
distanceMarkers: distanceMarkers,
|
|
1071
|
+
style: style,
|
|
1078
1072
|
pointToLayer: (feature, latlng) => {
|
|
1079
|
-
if (
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
latlng: latlng,
|
|
1090
|
-
label: ([true, 'dots'].includes(wptLabels) ? name : '')
|
|
1091
|
-
});
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
// Handle map waypoints (markers)
|
|
1095
|
-
if ([true, 'markers'].includes(control.options.waypoints) && wptIcons != false) {
|
|
1096
|
-
// generate and cache appropriate icon symbol
|
|
1097
|
-
if (!wptIcons.hasOwnProperty(sym)) {
|
|
1098
|
-
wptIcons[sym] = L.divIcon(
|
|
1099
|
-
L.extend({}, wptIcons[""].options, { html: '<i class="elevation-waypoint-icon ' + sym + '"></i>' } )
|
|
1100
|
-
);
|
|
1073
|
+
if (waypoints) {
|
|
1074
|
+
let { desc, name, sym } = feature.properties;
|
|
1075
|
+
desc = desc || '';
|
|
1076
|
+
name = name || '';
|
|
1077
|
+
// Handle chart waypoints (dots)
|
|
1078
|
+
if ([true, 'dots'].includes(waypoints)) {
|
|
1079
|
+
this._registerCheckPoint({
|
|
1080
|
+
latlng: latlng,
|
|
1081
|
+
label : ([true, 'dots'].includes(wptLabels) ? name : '')
|
|
1082
|
+
});
|
|
1101
1083
|
}
|
|
1102
|
-
|
|
1103
|
-
if ([true, 'markers'].includes(
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1084
|
+
// Handle map waypoints (markers)
|
|
1085
|
+
if ([true, 'markers'].includes(waypoints) && wptIcons != false) {
|
|
1086
|
+
return this._registerMarker({
|
|
1087
|
+
latlng : latlng,
|
|
1088
|
+
sym : (sym ?? name).replace(' ', '-').replace('"', '').replace("'", '').toLowerCase(),
|
|
1089
|
+
content: [true, 'markers'].includes(wptLabels) && (name || desc) && decodeURI("<b>" + name + "</b>" + (desc.length > 0 ? '<br>' + desc : ''))
|
|
1090
|
+
});
|
|
1107
1091
|
}
|
|
1108
|
-
control._addMarker(marker);
|
|
1109
|
-
control.fire('waypoint_added', { point: marker, element: latlng, properties: prop });
|
|
1110
|
-
return marker;
|
|
1111
1092
|
}
|
|
1112
1093
|
},
|
|
1113
|
-
onEachFeature: (feature, layer) =>
|
|
1114
|
-
if (feature.geometry && feature.geometry.type != 'Point') {
|
|
1115
|
-
control.addData(layer);
|
|
1116
|
-
control.track_info = L.extend({}, control.track_info, { name: geojson.name });
|
|
1117
|
-
}
|
|
1118
|
-
},
|
|
1094
|
+
onEachFeature: (feature, layer) => feature.geometry && feature.geometry.type != 'Point' && this.addData(feature, layer),
|
|
1119
1095
|
});
|
|
1120
1096
|
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1097
|
+
this.import(this.__D3).then(() => {
|
|
1098
|
+
this._initMapIntegrations(this, layer);
|
|
1099
|
+
this._fireEvt("eledata_loaded", { data: geojson, layer: layer, name: this.track_info.name, track_info: this.track_info });
|
|
1124
1100
|
});
|
|
1125
1101
|
|
|
1126
1102
|
return layer;
|
|
@@ -1250,8 +1226,7 @@
|
|
|
1250
1226
|
geojson = this._parseFromGeoJSONString(data.toString());
|
|
1251
1227
|
}
|
|
1252
1228
|
if (geojson) {
|
|
1253
|
-
geojson = this.
|
|
1254
|
-
geojson = this._prepareAdditionalProperties(geojson);
|
|
1229
|
+
geojson.name = geojson.name || (this._downloadURL || '').split('/').pop().split('#')[0].split('?')[0];
|
|
1255
1230
|
}
|
|
1256
1231
|
resolve(geojson);
|
|
1257
1232
|
})
|
|
@@ -1279,37 +1254,6 @@
|
|
|
1279
1254
|
return geojson;
|
|
1280
1255
|
},
|
|
1281
1256
|
|
|
1282
|
-
/**
|
|
1283
|
-
* Extend GeoJSON properties (name, time, ...)
|
|
1284
|
-
*/
|
|
1285
|
-
_prepareAdditionalProperties: function(geojson) {
|
|
1286
|
-
if (!geojson.name && this._downloadURL) {
|
|
1287
|
-
geojson.name = this._downloadURL.split('/').pop().split('#')[0].split('?')[0];
|
|
1288
|
-
}
|
|
1289
|
-
return geojson;
|
|
1290
|
-
},
|
|
1291
|
-
|
|
1292
|
-
/**
|
|
1293
|
-
* Just a temporary fix for MultiLineString data (trk > trkseg + trkseg),
|
|
1294
|
-
* just split them into seperate LineStrings (trk > trkseg, trk > trkseg)
|
|
1295
|
-
*
|
|
1296
|
-
* @link https://github.com/Raruto/leaflet-elevation/issues/56
|
|
1297
|
-
*/
|
|
1298
|
-
_prepareMultiLineStrings: function(geojson) {
|
|
1299
|
-
geojson.features.forEach(feauture => {
|
|
1300
|
-
if (feauture.geometry.type == "MultiLineString") {
|
|
1301
|
-
feauture.geometry.coordinates.forEach(coords => {
|
|
1302
|
-
geojson.features.push({
|
|
1303
|
-
geometry: { type: 'LineString', coordinates: coords },
|
|
1304
|
-
properties: feauture.properties,
|
|
1305
|
-
type: 'Feature'
|
|
1306
|
-
});
|
|
1307
|
-
});
|
|
1308
|
-
}
|
|
1309
|
-
});
|
|
1310
|
-
return geojson.features.filter(feauture => feauture.geometry.type != "MultiLineString");
|
|
1311
|
-
},
|
|
1312
|
-
|
|
1313
1257
|
/**
|
|
1314
1258
|
* Add chart profile to diagram
|
|
1315
1259
|
*/
|
|
@@ -1427,60 +1371,79 @@
|
|
|
1427
1371
|
return this._registerHandler(props.call(this));
|
|
1428
1372
|
}
|
|
1429
1373
|
|
|
1374
|
+
let {
|
|
1375
|
+
name,
|
|
1376
|
+
attr,
|
|
1377
|
+
required,
|
|
1378
|
+
skipNull,
|
|
1379
|
+
deltaMax,
|
|
1380
|
+
clampRange,
|
|
1381
|
+
decimals,
|
|
1382
|
+
meta,
|
|
1383
|
+
unit,
|
|
1384
|
+
coordinateProperties,
|
|
1385
|
+
coordPropsToMeta: coordPropsToMeta$1,
|
|
1386
|
+
pointToAttr,
|
|
1387
|
+
onPointAdded,
|
|
1388
|
+
stats,
|
|
1389
|
+
statsName,
|
|
1390
|
+
grid,
|
|
1391
|
+
scale,
|
|
1392
|
+
path,
|
|
1393
|
+
tooltip,
|
|
1394
|
+
summary
|
|
1395
|
+
} = props;
|
|
1396
|
+
|
|
1430
1397
|
// eg. "altitude" == true
|
|
1431
|
-
if (this.options[
|
|
1398
|
+
if (this.options[name] || required) {
|
|
1432
1399
|
|
|
1433
1400
|
this._registerDataAttribute({
|
|
1434
|
-
name
|
|
1435
|
-
attr
|
|
1436
|
-
skipNull
|
|
1437
|
-
deltaMax
|
|
1438
|
-
clampRange
|
|
1439
|
-
decimals
|
|
1440
|
-
coordPropsToMeta: coordPropsToMeta(
|
|
1441
|
-
pointToAttr
|
|
1442
|
-
onPointAdded
|
|
1443
|
-
stats
|
|
1444
|
-
statsName
|
|
1401
|
+
name,
|
|
1402
|
+
attr,
|
|
1403
|
+
skipNull,
|
|
1404
|
+
deltaMax,
|
|
1405
|
+
clampRange,
|
|
1406
|
+
decimals,
|
|
1407
|
+
coordPropsToMeta: coordPropsToMeta(coordinateProperties, meta || name, coordPropsToMeta$1),
|
|
1408
|
+
pointToAttr,
|
|
1409
|
+
onPointAdded,
|
|
1410
|
+
stats,
|
|
1411
|
+
statsName,
|
|
1445
1412
|
});
|
|
1446
1413
|
|
|
1447
|
-
if (
|
|
1448
|
-
|
|
1449
|
-
this._registerAxisGrid(props.grid);
|
|
1414
|
+
if (grid) {
|
|
1415
|
+
this._registerAxisGrid(L.extend({ name }, grid));
|
|
1450
1416
|
}
|
|
1451
1417
|
|
|
1452
|
-
if (this.options[
|
|
1453
|
-
if (
|
|
1454
|
-
|
|
1455
|
-
props.scale.label = props.scale.label || props.unit;
|
|
1456
|
-
this._registerAxisScale(props.scale);
|
|
1457
|
-
}
|
|
1458
|
-
if (props.path) {
|
|
1459
|
-
props.path.name = props.path.name || props.name;
|
|
1460
|
-
this._registerAreaPath(props.path);
|
|
1461
|
-
}
|
|
1418
|
+
if (this.options[name] !== "summary") {
|
|
1419
|
+
if (scale) this._registerAxisScale(L.extend({ name, label: unit }, scale));
|
|
1420
|
+
if (path) this._registerAreaPath(L.extend({ name }, path));
|
|
1462
1421
|
}
|
|
1463
1422
|
|
|
1464
|
-
if (props.tooltips) {
|
|
1465
|
-
each(props.tooltips, t => {
|
|
1466
|
-
if (t) {
|
|
1467
|
-
t.name = t.name || props.name;
|
|
1468
|
-
this._registerTooltip(t);
|
|
1469
|
-
}
|
|
1470
|
-
});
|
|
1471
|
-
} else if (props.tooltip) {
|
|
1472
|
-
props.tooltip.name = props.tooltip.name || props.name;
|
|
1473
|
-
this._registerTooltip(props.tooltip);
|
|
1423
|
+
if (tooltip || props.tooltips) {
|
|
1424
|
+
each([tooltip, ...(props.tooltips || [])], t => t && this._registerTooltip(L.extend({ name }, t)));
|
|
1474
1425
|
}
|
|
1475
1426
|
|
|
1476
|
-
if (
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
}
|
|
1480
|
-
this._registerSummary(props.summary);
|
|
1427
|
+
if (summary) {
|
|
1428
|
+
each(summary, (s, k) => summary[k] = L.extend({ unit }, s));
|
|
1429
|
+
this._registerSummary(summary);
|
|
1481
1430
|
}
|
|
1482
1431
|
}
|
|
1483
1432
|
},
|
|
1433
|
+
|
|
1434
|
+
_registerMarker({latlng, sym, content}) {
|
|
1435
|
+
let { wptIcons } = this.options;
|
|
1436
|
+
// generate and cache appropriate icon symbol
|
|
1437
|
+
if (!wptIcons.hasOwnProperty(sym)) {
|
|
1438
|
+
wptIcons[sym] = L.divIcon(L.extend({}, wptIcons[""].options, { html: '<i class="elevation-waypoint-icon ' + sym + '"></i>' } ));
|
|
1439
|
+
}
|
|
1440
|
+
let marker = L.marker(latlng, { icon: wptIcons[sym] });
|
|
1441
|
+
if (content) {
|
|
1442
|
+
marker.bindPopup(content, { className: 'elevation-popup', keepInView: true }).openPopup();
|
|
1443
|
+
marker.bindTooltip(content, { className: 'elevation-tooltip', direction: 'auto', sticky: true, opacity: 1 }).openTooltip();
|
|
1444
|
+
}
|
|
1445
|
+
return this._addMarker(marker)
|
|
1446
|
+
},
|
|
1484
1447
|
|
|
1485
1448
|
/**
|
|
1486
1449
|
* Add chart or marker tooltip info
|