Skip to content

Commit 0b213bf

Browse files
committed
[Highlight] Highlight part of route on selection
1 parent 09b8aa6 commit 0b213bf

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

website/src/lib/components/map/gpx-layer/start-end-markers.ts

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import { get } from 'svelte/store';
55
import { map } from '$lib/components/map/map';
66
import { allHidden } from '$lib/logic/hidden';
77

8+
const HIGHLIGHT_SOURCE_ID = 'elevation-selection';
9+
const HIGHLIGHT_LAYER_CASING_ID = 'elevation-selection-casing';
10+
const HIGHLIGHT_LAYER_ID = 'elevation-selection';
11+
812
export class StartEndMarkers {
913
start: mapboxgl.Marker;
1014
end: mapboxgl.Marker;
@@ -29,6 +33,99 @@ export class StartEndMarkers {
2933
this.unsubscribes.push(allHidden.subscribe(this.updateBinded));
3034
}
3135

36+
private ensureHighlightLayers() {
37+
const map_ = get(map);
38+
if (!map_) return;
39+
40+
if (!map_.getSource(HIGHLIGHT_SOURCE_ID)) {
41+
map_.addSource(HIGHLIGHT_SOURCE_ID, {
42+
type: 'geojson',
43+
data: {
44+
type: 'Feature',
45+
geometry: { type: 'LineString', coordinates: [] },
46+
properties: {},
47+
},
48+
});
49+
}
50+
if (!map_.getLayer(HIGHLIGHT_LAYER_CASING_ID)) {
51+
map_.addLayer({
52+
id: HIGHLIGHT_LAYER_CASING_ID,
53+
type: 'line',
54+
source: HIGHLIGHT_SOURCE_ID,
55+
layout: { 'line-join': 'round', 'line-cap': 'round' },
56+
paint: {
57+
'line-color': '#000000',
58+
'line-width': 10,
59+
'line-opacity': 0.9,
60+
'line-blur': 0.2,
61+
},
62+
});
63+
}
64+
if (!map_.getLayer(HIGHLIGHT_LAYER_ID)) {
65+
map_.addLayer({
66+
id: HIGHLIGHT_LAYER_ID,
67+
type: 'line',
68+
source: HIGHLIGHT_SOURCE_ID,
69+
layout: { 'line-join': 'round', 'line-cap': 'round' },
70+
paint: {
71+
'line-color': '#ffeb3b',
72+
'line-width': 6,
73+
'line-opacity': 1,
74+
},
75+
});
76+
}
77+
try {
78+
map_.moveLayer(HIGHLIGHT_LAYER_CASING_ID);
79+
map_.moveLayer(HIGHLIGHT_LAYER_ID);
80+
} catch (e) {
81+
// ignore if already on top or not movable yet
82+
}
83+
}
84+
85+
private removeHighlight() {
86+
const map_ = get(map);
87+
if (!map_) return;
88+
89+
if (map_.getLayer(HIGHLIGHT_LAYER_ID)) map_.removeLayer(HIGHLIGHT_LAYER_ID);
90+
if (map_.getLayer(HIGHLIGHT_LAYER_CASING_ID)) map_.removeLayer(HIGHLIGHT_LAYER_CASING_ID);
91+
if (map_.getSource(HIGHLIGHT_SOURCE_ID)) map_.removeSource(HIGHLIGHT_SOURCE_ID);
92+
}
93+
94+
private updateMapHighlight() {
95+
const map_ = get(map);
96+
if (!map_) return;
97+
98+
let statistics = get(slicedGPXStatistics)?.[0];
99+
if (!statistics) {
100+
this.removeHighlight();
101+
return;
102+
}
103+
const coords: [number, number][] = [];
104+
for (const c of statistics.local.points) {
105+
coords.push([c.getCoordinates().lon, c.getCoordinates().lat]);
106+
}
107+
this.ensureHighlightLayers();
108+
const src = map_.getSource(HIGHLIGHT_SOURCE_ID) as mapboxgl.GeoJSONSource;
109+
if (src) {
110+
src.setData({
111+
type: 'Feature',
112+
geometry: { type: 'LineString', coordinates: coords },
113+
properties: {},
114+
});
115+
}
116+
if (map_.getLayer(HIGHLIGHT_LAYER_CASING_ID)) {
117+
map_.setPaintProperty(
118+
HIGHLIGHT_LAYER_CASING_ID,
119+
'line-color',
120+
'#000000'
121+
);
122+
}
123+
try {
124+
map_.moveLayer(HIGHLIGHT_LAYER_CASING_ID);
125+
map_.moveLayer(HIGHLIGHT_LAYER_ID);
126+
} catch (e) {}
127+
}
128+
32129
update() {
33130
const map_ = get(map);
34131
if (!map_) return;
@@ -43,9 +140,11 @@ export class StartEndMarkers {
43140
statistics.local.points[statistics.local.points.length - 1].getCoordinates()
44141
)
45142
.addTo(map_);
143+
this.updateMapHighlight();
46144
} else {
47145
this.start.remove();
48146
this.end.remove();
147+
this.removeHighlight();
49148
}
50149
}
51150

@@ -54,5 +153,7 @@ export class StartEndMarkers {
54153

55154
this.start.remove();
56155
this.end.remove();
156+
157+
this.removeHighlight();
57158
}
58159
}

0 commit comments

Comments
 (0)