@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 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
  [![Leaflet 1.x compatible!](https://img.shields.io/badge/Leaflet-1.7.0-1EB300.svg?style=flat)](http://leafletjs.com/reference.html)
253
254
  [![d3.js v6 compatibile!](https://img.shields.io/badge/d3.js-6.5-1EB300.svg?style=flat)](https://www.npmjs.com/package/d3)
254
- [![@tmcw/togeojson v4.6.0 compatibile!](https://img.shields.io/badge/@tmcw/togeojson-4.5-1EB300.svg?style=flat)](https://www.npmjs.com/package/@tmcw/togeojson)
255
+ [![@tmcw/togeojson v4.6.0 compatibile!](https://img.shields.io/badge/@tmcw/togeojson-4.6-1EB300.svg?style=flat)](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
- if (typeof layer === "undefined" && d.on) {
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
- * Standard GeoJSON --> doesn't handle "time", "heart", …
624
- */
625
- let geom = d.geometry;
626
- if (geom) {
627
- switch (geom.type) {
628
- case 'LineString':
629
- this._addGeoJSONData(geom.coordinates);
630
- break;
631
-
632
- case 'MultiLineString':
633
- each(geom.coordinates, coords => this._addGeoJSONData(coords));
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 L.Control.Elevation[h] !== "undefined" ? L.Control.Elevation[h] : h);
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 L.Control.Elevation[fn] === "undefined" ) {
1053
- handlers[fn] = L.Control.Elevation[fn] = exported[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 control = this;
1058
+ let { polyline, theme, waypoints, wptIcons, wptLabels, distanceMarkers } = this.options;
1059
+ let style = L.extend({}, polyline);
1066
1060
 
1067
- let { wptIcons, wptLabels } = control.options;
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: control.options.distanceMarkers,
1071
- style: (feature) => {
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 (!control.options.waypoints) return;
1080
-
1081
- let prop = feature.properties;
1082
- let desc = prop.desc ?? '';
1083
- let name = prop.name ?? '';
1084
- let sym = (prop.sym ?? name).replace(' ', '-').replace('"', '').replace("'", '').toLowerCase();
1085
-
1086
- // Handle chart waypoints (dots)
1087
- if ([true, 'dots'].includes(control.options.waypoints)) {
1088
- control._registerCheckPoint({
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
- let marker = L.marker(latlng, { icon: wptIcons[sym] });
1103
- if ([true, 'markers'].includes(wptLabels) && (name || desc)) {
1104
- let content = decodeURI("<b>" + name + "</b>" + (desc.length > 0 ? '<br>' + desc : ''));
1105
- marker.bindPopup(content, { className: 'elevation-popup', keepInView: true }).openPopup();
1106
- marker.bindTooltip(content, { className: 'elevation-tooltip', direction: 'auto', sticky: true, opacity: 1 }).openTooltip();
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
- control.import(control.__D3).then(() => {
1122
- control._initMapIntegrations(control, layer);
1123
- control._fireEvt("eledata_loaded", { data: geojson, layer: layer, name: control.track_info.name, track_info: control.track_info });
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._prepareMultiLineStrings(geojson);
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[props.name] || props.required) {
1398
+ if (this.options[name] || required) {
1432
1399
 
1433
1400
  this._registerDataAttribute({
1434
- name: props.name,
1435
- attr: props.attr,
1436
- skipNull: props.skipNull,
1437
- deltaMax: props.deltaMax,
1438
- clampRange: props.clampRange,
1439
- decimals: props.decimals,
1440
- coordPropsToMeta: coordPropsToMeta(props.coordinateProperties, props.meta || props.name, props.coordPropsToMeta),
1441
- pointToAttr: props.pointToAttr,
1442
- onPointAdded: props.onPointAdded,
1443
- stats: props.stats,
1444
- statsName: props.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 (props.grid) {
1448
- props.grid.name = props.grid.name || props.name;
1449
- this._registerAxisGrid(props.grid);
1414
+ if (grid) {
1415
+ this._registerAxisGrid(L.extend({ name }, grid));
1450
1416
  }
1451
1417
 
1452
- if (this.options[props.name] !== "summary") {
1453
- if (props.scale) {
1454
- props.scale.name = props.scale.name || props.name;
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 (props.summary) {
1477
- for (const key in props.summary) {
1478
- props.summary[key].unit = props.summary[key].unit || props.unit;
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