feat: add elevation gain and loss in extended properties

This commit is contained in:
Yohan Boniface 2024-12-06 11:08:50 +01:00
parent d0156bc7a6
commit 89acf8f0ec
5 changed files with 260 additions and 1 deletions

View file

@ -77,6 +77,7 @@ Toute propriété de l'élément sera disponible, ainsi que:
- `{locale}` → la langue sous la forme `fr` ou `fr_CA` quand une variante est utilisée
- `{lang}` → la langue sous la forme `fr` ou `fr-ca` quand une variante est utilisée
- `{measure}` → la longueur d'une ligne ou la surface d'un polygone
- `{gain}`/`{loss}` → la dénivelée positive/négative d'une ligne (seulement si elle contient les altitudes)
- `{rank}` → la rang d'un élément dans son calque
- `{layer}` → le nom du calque de l'élément
- `{zoom}` → le zoom actuel de la carte

View file

@ -77,6 +77,7 @@ Any property of the feature will be available, plus:
- `{locale}` → the locale in the form `en` or `en_US` when a variant is used
- `{lang}` → the lang in the form `en` or `en-us` when a variant is used
- `{measure}` → the length of a line or the area of a polygon
- `{gain}`/`{loss}` → the elevation gain/loss of a line (only if it contains the altitude information)
- `{rank}` → the rank of the feature in the layer
- `{layer}` → the name of the feature's layer
- `{zoom}` → the current map zoom

View file

@ -591,7 +591,7 @@ class Feature {
properties.measure = this.ui.getMeasure()
}
}
return L.extend(properties, this.properties)
return Object.assign(properties, this.properties)
}
getRank() {
@ -1060,6 +1060,11 @@ export class LineString extends Path {
})
return items
}
extendedProperties() {
const [gain, loss] = this.ui.getElevation()
return Object.assign({ gain, loss }, super.extendedProperties())
}
}
export class Polygon extends Path {

View file

@ -400,6 +400,35 @@ export const LeafletPolyline = Polyline.extend({
)
return L.GeoUtil.readableDistance(length, this._map.measureTools.getMeasureUnit())
},
getElevation: function () {
const lineElevation = (latlngs) => {
let gain = 0
let loss = 0
for (let i = 0, n = latlngs.length - 1; i < n; i++) {
const fromAlt = latlngs[i].alt
const toAlt = latlngs[i + 1].alt
if (fromAlt === undefined || toAlt === undefined) continue
if (fromAlt > toAlt) loss += fromAlt - toAlt
else gain += toAlt - fromAlt
}
return [gain, loss]
}
let shapes
if (LineUtil.isFlat(this._latlngs)) {
shapes = [this._latlngs]
} else {
shapes = this._latlngs
}
let totalGain = 0
let totalLoss = 0
for (const shape of shapes) {
const [gain, loss] = lineElevation(shape)
totalGain += gain
totalLoss += loss
}
return [Math.round(totalGain), Math.round(totalLoss)]
},
})
export const LeafletPolygon = Polygon.extend({

View file

@ -1,3 +1,5 @@
from pathlib import Path
import pytest
from playwright.sync_api import expect
@ -83,3 +85,224 @@ def test_can_use_measure_on_name(live_server, map, page):
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/10/50")
expect(page.get_by_text("linestring (99.7 km)")).to_be_visible()
expect(page.get_by_text("multilinestring (592 km)")).to_be_visible()
def test_can_use_gain_and_loss(live_server, map, page):
data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[8.420888, 39.327819, 12.1],
[8.420915, 39.327745, 12.9],
[8.420906, 39.327543, 14.8],
[8.420876, 39.327312, 17],
[8.420754, 39.327023, 16.8],
[8.420609, 39.326776, 16.6],
[8.42051, 39.326467, 16.4],
[8.420409, 39.326254, 16.3],
[8.420367, 39.326108, 16.2],
[8.420287, 39.326044, 16.2],
[8.420294, 39.325794, 15.1],
[8.419974, 39.325549, 12.5],
[8.419887, 39.325508, 11.9],
[8.419702, 39.325343, 10.3],
[8.419574, 39.325289, 9.4],
[8.41943, 39.325183, 8.2],
[8.419393, 39.325127, 7.8],
[8.419297, 39.325108, 7.2],
[8.419179, 39.325014, 6.2],
[8.419179, 39.324979, 6.1],
[8.419179, 39.324979, 6.1],
[8.419182, 39.324653, 6],
[8.419129, 39.324508, 5.9],
[8.419074, 39.324482, 5.9],
[8.419007, 39.324362, 5.8],
[8.418957, 39.324324, 5.8],
[8.418944, 39.324291, 5.8],
[8.418947, 39.324233, 5.8],
[8.418967, 39.324196, 5.7],
[8.41895, 39.324126, 5.6],
[8.418838, 39.323996, 5.4],
[8.418814, 39.323774, 5],
[8.418931, 39.323546, 10.1],
[8.41896, 39.323444, 12.3],
[8.418971, 39.323232, 16.9],
[8.419068, 39.322974, 13.5],
[8.41914, 39.322946, 12.7],
[8.419245, 39.322895, 12.3],
[8.419342, 39.322857, 11.9],
[8.419492, 39.322855, 11.3],
[8.419591, 39.322768, 11.1],
[8.419672, 39.322724, 11],
[8.419776, 39.322704, 10.9],
[8.419823, 39.322711, 10.8],
[8.41971, 39.322631, 8.5],
[8.419668, 39.322581, 7.3],
[8.419653, 39.322537, 6.3],
[8.419628, 39.32243, 5.3],
[8.419629, 39.322384, 5.4],
[8.419656, 39.322346, 5.5],
[8.419703, 39.322304, 5.6],
[8.419802, 39.322305, 5.7],
[8.419868, 39.32228, 5.8],
[8.419994, 39.322223, 6.1],
[8.420066, 39.322174, 6.2],
[8.42013, 39.32211, 6.4],
[8.420142, 39.322013, 6.5],
[8.420167, 39.321924, 6.7],
[8.420188, 39.321788, 7],
[8.420269, 39.32165, 7.3],
[8.420342, 39.321625, 7.4],
[8.420427, 39.321609, 7.5],
[8.420645, 39.321582, 7.8],
[8.420753, 39.321699, 8.1],
[8.420881, 39.321801, 8.4],
[8.421082, 39.321898, 8.7],
[8.421184, 39.321868, 8.9],
[8.421351, 39.321877, 9.1],
[8.421451, 39.321834, 8.2],
[8.421545, 39.321811, 7.5],
[8.421815, 39.321691, 5.1],
[8.421877, 39.321632, 4.3],
[8.42196, 39.321602, 3.7],
[8.422083, 39.321621, 4.5],
[8.422462, 39.321579, 8.7],
[8.422875, 39.321691, 13.5],
[8.423069, 39.321732, 15.7],
[8.423231, 39.321687, 17.6],
[8.423405, 39.321726, 19.6],
[8.423626, 39.321719, 22.1],
[8.424103, 39.321776, 27.4],
[8.424214, 39.321746, 28.7],
[8.424402, 39.321632, 27.5],
[8.424486, 39.321559, 26.8],
[8.424524, 39.321501, 26.3],
[8.424916, 39.321097, 22.6],
[8.424969, 39.321007, 21.9],
[8.425387, 39.320766, 19],
[8.425489, 39.320645, 20.4],
[8.425621, 39.320556, 22.1],
[8.425699, 39.320574, 22.8],
[8.425774, 39.320511, 23.9],
[8.425831, 39.320336, 19.6],
[8.425822, 39.32021, 16.1],
[8.42575, 39.320086, 12.4],
[8.425788, 39.320004, 10],
[8.425946, 39.319822, 10.7],
[8.426039, 39.319781, 11],
[8.426264, 39.319776, 11.8],
[8.426305, 39.319718, 12],
[8.426362, 39.319433, 6.8],
[8.426414, 39.31936, 5.3],
[8.426422, 39.319161, 1.6],
[8.426449, 39.319085, 0.2],
[8.426568, 39.31904, 0.4],
[8.426608, 39.318981, 1.8],
[8.426714, 39.318923, 3.8],
[8.427072, 39.318862, 9.6],
[8.427204, 39.31886, 11.7],
[8.427359, 39.318896, 14.3],
[8.427434, 39.31895, 15.9],
[8.427519, 39.318968, 17.3],
[8.427558, 39.318972, 18.4],
[8.427616, 39.318991, 19.2],
[8.427685, 39.319082, 21.3],
[8.42773, 39.31921, 25.1],
[8.427914, 39.319306, 29.9],
[8.42849, 39.319358, 46.7],
[8.429645, 39.319309, 79.8],
[8.430532, 39.319314, 85],
[8.430582, 39.319297, 85.2],
[8.430808, 39.319195, 84.8],
[8.43098, 39.319076, 84.5],
[8.431138, 39.318999, 84.2],
[8.431283, 39.318985, 84],
[8.431288, 39.318946, 84.8],
[8.431373, 39.318825, 87.6],
[8.431411, 39.318796, 87.9],
[8.431678, 39.318827, 87.1],
[8.431773, 39.318752, 88.3],
[8.431854, 39.318552, 90.7],
[8.431832, 39.31847, 91.7],
[8.431959, 39.318284, 94.1],
[8.431968, 39.318034, 97],
[8.43207, 39.31791, 98.7],
[8.432118, 39.317736, 100.8],
[8.432263, 39.317582, 103],
[8.432291, 39.317263, 106.7],
[8.432279, 39.316848, 111.5],
[8.432358, 39.31652, 115.3],
[8.432327, 39.316486, 115.8],
[8.432336, 39.316437, 116.4],
[8.432287, 39.316409, 116.4],
[8.432257, 39.316391, 116.2],
[8.432179, 39.316251, 115.4],
[8.432156, 39.316183, 115.6],
[8.43223, 39.316138, 116.5],
[8.43223, 39.316043, 117.7],
[8.432274, 39.315918, 119.4],
[8.432254, 39.315799, 121],
[8.432377, 39.315713, 122.6],
[8.43248, 39.315542, 125.1],
[8.43257, 39.315451, 126],
[8.432652, 39.315352, 127],
[8.432724, 39.315291, 127.7],
[8.432779, 39.315208, 128.5],
[8.432863, 39.315109, 129.5],
[8.432945, 39.315038, 130.3],
[8.433002, 39.315014, 130.7],
[8.433092, 39.315007, 131.3],
[8.43318, 39.315012, 131.9],
[8.433295, 39.315111, 133],
[8.433346, 39.315126, 133.4],
[8.43338, 39.315113, 133.6],
[8.433404, 39.31509, 133.8],
[8.433408, 39.315058, 132.4],
[8.433422, 39.31498, 131.6],
[8.43347, 39.314876, 130.3],
[8.433562, 39.314771, 128.2],
[8.433817, 39.314543, 123],
[8.434004, 39.314434, 119.9],
[8.434262, 39.314344, 121.2],
[8.434729, 39.314236, 123.9],
[8.435085, 39.31388, 127.2],
[8.435254, 39.313808, 128.4],
[8.435388, 39.313779, 128.4],
[8.435547, 39.313774, 129.9],
[8.4357, 39.313825, 131.6],
[8.435802, 39.313882, 132.8],
[8.435866, 39.313979, 134.1],
[8.435902, 39.314064, 135.2],
[8.435973, 39.314103, 136],
[8.436062, 39.314107, 136.9],
[8.436143, 39.314101, 137.7],
[8.436215, 39.313989, 137.7],
[8.436162, 39.313752, 137.5],
[8.436209, 39.313402, 137.2],
[8.436413, 39.313182, 137],
[8.436559, 39.313127, 136.9],
[8.43664, 39.313115, 136.8],
[8.436682, 39.313058, 137.7],
[8.436798, 39.312789, 139.1],
[8.436706, 39.312486, 140.7],
[8.436703, 39.312448, 141],
],
},
"properties": {"name": "some track"},
"id": "MzMTI",
}
],
"_umap_options": {"popupContentTemplate": "{name}\n{gain} m\n{loss} m"},
}
DataLayerFactory(map=map, data=data)
page.goto(
f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=databrowser#16/39.3201/8.4278"
)
# We can't make PW to click on the path, so let's use the browser for that
page.get_by_text("some track").click()
expect(page.get_by_text("⭧ 211 m")).to_be_visible()
expect(page.get_by_text("⭨ 82 m")).to_be_visible()