Skip to content

Commit c73fb12

Browse files
authored
Merge branch 'master' into recenter-route
2 parents a36bf79 + 756fcd3 commit c73fb12

File tree

6 files changed

+113
-7
lines changed

6 files changed

+113
-7
lines changed

src/components/map/index.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import { RecenterControl } from './parts/recenter-control';
5050
import {
5151
VALHALLA_EDGES_LAYER_ID,
5252
VALHALLA_NODES_LAYER_ID,
53+
VALHALLA_SHORTCUTS_LAYER_ID,
5354
} from '@/components/tiles/valhalla-layers';
5455
import { MarkerIcon, type MarkerColor } from './parts/marker-icon';
5556
import { maxBounds } from './constants';
@@ -506,6 +507,7 @@ export const MapComponent = () => {
506507
const availableLayers = [
507508
VALHALLA_EDGES_LAYER_ID,
508509
VALHALLA_NODES_LAYER_ID,
510+
VALHALLA_SHORTCUTS_LAYER_ID,
509511
].filter((layerId) => map.getLayer(layerId));
510512

511513
if (availableLayers.length === 0) return;
@@ -736,7 +738,8 @@ export const MapComponent = () => {
736738
features &&
737739
features.length > 0 &&
738740
(features[0]?.layer?.id === VALHALLA_EDGES_LAYER_ID ||
739-
features[0]?.layer?.id === VALHALLA_NODES_LAYER_ID);
741+
features[0]?.layer?.id === VALHALLA_NODES_LAYER_ID ||
742+
features[0]?.layer?.id === VALHALLA_SHORTCUTS_LAYER_ID);
740743

741744
if (isOverRoute) {
742745
onRouteLineHover(event);
@@ -790,7 +793,11 @@ export const MapComponent = () => {
790793
onMouseLeave={handleMouseLeave}
791794
interactiveLayerIds={
792795
activeTab === 'tiles'
793-
? [VALHALLA_EDGES_LAYER_ID, VALHALLA_NODES_LAYER_ID]
796+
? [
797+
VALHALLA_EDGES_LAYER_ID,
798+
VALHALLA_NODES_LAYER_ID,
799+
VALHALLA_SHORTCUTS_LAYER_ID,
800+
]
794801
: ['routes-line']
795802
}
796803
mapStyle={resolvedMapStyle}

src/components/map/parts/tiles-info-popup.spec.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ describe('TilesInfoPopup', () => {
7171

7272
expect(screen.getByText('Node')).toBeInTheDocument();
7373
});
74+
// Ensures that features from the 'shortcuts' layer are correctly labeled as "Shortcut"
75+
// in the popup header instead of defaulting to "Node"
76+
it('should display "Shortcut" label for shortcut features', () => {
77+
const shortcutFeature = createMockFeature('shortcuts', {
78+
id: '23456',
79+
shortcut: true,
80+
});
81+
82+
render(<TilesInfoPopup features={[shortcutFeature]} onClose={vi.fn()} />);
83+
84+
expect(screen.getByText('Shortcut')).toBeInTheDocument();
85+
});
7486

7587
it('should display all properties of a feature', () => {
7688
render(<TilesInfoPopup {...defaultProps} />);

src/components/map/parts/tiles-info-popup.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ export function TilesInfoPopup({ features, onClose }: TilesInfoPopupProps) {
2525

2626
{features.map((feature, index) => {
2727
const isEdge = feature.sourceLayer === 'edges';
28-
const layerType = isEdge ? 'Edge' : 'Node';
28+
const isShortcut = feature.sourceLayer === 'shortcuts';
29+
const isEdgeLike = isEdge || isShortcut;
30+
let layerType = 'Node';
31+
if (isEdge) layerType = 'Edge';
32+
else if (isShortcut) layerType = 'Shortcut';
2933
const properties = feature.properties || {};
30-
const Icon = isEdge ? Route : MapPin;
34+
const Icon = isEdgeLike ? Route : MapPin;
3135

3236
return (
3337
<div

src/components/tiles/valhalla-layers-toggle.spec.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
VALHALLA_LAYERS,
88
VALHALLA_EDGES_LAYER_ID,
99
VALHALLA_NODES_LAYER_ID,
10+
VALHALLA_SHORTCUTS_LAYER_ID,
1011
} from './valhalla-layers';
1112

1213
const createMockMap = () => {
@@ -151,6 +152,9 @@ describe('ValhallaLayersToggle', () => {
151152
await user.click(toggle);
152153

153154
expect(mockMap.removeLayer).toHaveBeenCalledWith(VALHALLA_EDGES_LAYER_ID);
155+
expect(mockMap.removeLayer).toHaveBeenCalledWith(
156+
VALHALLA_SHORTCUTS_LAYER_ID
157+
);
154158
expect(mockMap.removeLayer).toHaveBeenCalledWith(VALHALLA_NODES_LAYER_ID);
155159
});
156160

@@ -188,7 +192,9 @@ describe('ValhallaLayersToggle', () => {
188192
const toggle = screen.getByRole('switch');
189193
await user.click(toggle);
190194

191-
expect(mockMap.addLayer).toHaveBeenCalledTimes(1);
195+
expect(mockMap.addLayer).toHaveBeenCalledTimes(
196+
VALHALLA_LAYERS.length - 1
197+
);
192198
});
193199

194200
it('should update checked state when toggled', async () => {

src/components/tiles/valhalla-layers.spec.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import type {
77
import {
88
VALHALLA_SOURCE_ID,
99
VALHALLA_EDGES_LAYER_ID,
10+
VALHALLA_SHORTCUTS_LAYER_ID,
1011
VALHALLA_NODES_LAYER_ID,
1112
VALHALLA_EDGES_LAYER,
13+
VALHALLA_SHORTCUTS_LAYER,
1214
VALHALLA_NODES_LAYER,
1315
VALHALLA_LAYERS,
1416
getValhallaTileUrl,
@@ -32,12 +34,14 @@ describe('valhalla-layers', () => {
3234

3335
it('should export correct layer IDs', () => {
3436
expect(VALHALLA_EDGES_LAYER_ID).toBe('valhalla-edges');
37+
expect(VALHALLA_SHORTCUTS_LAYER_ID).toBe('valhalla-shortcuts');
3538
expect(VALHALLA_NODES_LAYER_ID).toBe('valhalla-nodes');
3639
});
3740

38-
it('should export VALHALLA_LAYERS array with both layers', () => {
39-
expect(VALHALLA_LAYERS).toHaveLength(2);
41+
it('should export VALHALLA_LAYERS array with all layers', () => {
42+
expect(VALHALLA_LAYERS).toHaveLength(3);
4043
expect(VALHALLA_LAYERS).toContain(VALHALLA_EDGES_LAYER);
44+
expect(VALHALLA_LAYERS).toContain(VALHALLA_SHORTCUTS_LAYER);
4145
expect(VALHALLA_LAYERS).toContain(VALHALLA_NODES_LAYER);
4246
});
4347
});
@@ -78,6 +82,33 @@ describe('valhalla-layers', () => {
7882
});
7983
});
8084

85+
//Shortcut is now a separate map layer.
86+
//It uses the same styling as edges.
87+
describe('VALHALLA_SHORTCUTS_LAYER', () => {
88+
const shortcutsLayer = VALHALLA_SHORTCUTS_LAYER as LineLayerSpecification;
89+
90+
it('should have correct id', () => {
91+
expect(shortcutsLayer.id).toBe(VALHALLA_SHORTCUTS_LAYER_ID);
92+
});
93+
94+
it('should be a line type layer', () => {
95+
expect(shortcutsLayer.type).toBe('line');
96+
});
97+
98+
it('should reference correct source', () => {
99+
expect(shortcutsLayer.source).toBe(VALHALLA_SOURCE_ID);
100+
});
101+
102+
it('should have shortcuts source-layer', () => {
103+
expect(shortcutsLayer['source-layer']).toBe('shortcuts');
104+
});
105+
106+
it('should clone edges paint and layout styling', () => {
107+
expect(shortcutsLayer.paint).toEqual(VALHALLA_EDGES_LAYER.paint);
108+
expect(shortcutsLayer.layout).toEqual(VALHALLA_EDGES_LAYER.layout);
109+
});
110+
});
111+
81112
describe('VALHALLA_NODES_LAYER', () => {
82113
const nodesLayer = VALHALLA_NODES_LAYER as CircleLayerSpecification;
83114

src/components/tiles/valhalla-layers.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { getBaseUrl, normalizeBaseUrl } from '@/utils/base-url';
33

44
export const VALHALLA_SOURCE_ID = 'valhalla-tiles';
55
export const VALHALLA_EDGES_LAYER_ID = 'valhalla-edges';
6+
export const VALHALLA_SHORTCUTS_LAYER_ID = 'valhalla-shortcuts';
67
export const VALHALLA_NODES_LAYER_ID = 'valhalla-nodes';
78

89
// Pre-encoded JSON: {"tile":{"z":{z},"x":{x},"y":{y}}}
@@ -67,6 +68,50 @@ export const VALHALLA_EDGES_LAYER: LayerSpecification = {
6768
},
6869
};
6970

71+
// Shortcuts is now a separate tile layer.
72+
// and It uses the same line style as edges.
73+
export const VALHALLA_SHORTCUTS_LAYER: LayerSpecification = {
74+
id: VALHALLA_SHORTCUTS_LAYER_ID,
75+
type: 'line',
76+
source: VALHALLA_SOURCE_ID,
77+
'source-layer': 'shortcuts',
78+
minzoom: 7,
79+
maxzoom: 22,
80+
filter: ['all'],
81+
layout: { visibility: 'visible' },
82+
paint: {
83+
'line-color': [
84+
'match',
85+
['get', 'tile_level'],
86+
0,
87+
'#ff0000',
88+
1,
89+
'#ff8800',
90+
2,
91+
'#ffdd00',
92+
'#ff00ff',
93+
],
94+
'line-width': [
95+
'interpolate',
96+
['exponential', 1.5],
97+
['zoom'],
98+
12,
99+
['match', ['get', 'tile_level'], 0, 3, 1, 2, 2, 1, 2],
100+
14,
101+
['match', ['get', 'tile_level'], 0, 4, 1, 3, 2, 2, 3],
102+
16,
103+
['match', ['get', 'tile_level'], 0, 6, 1, 4, 2, 3, 4],
104+
18,
105+
['match', ['get', 'tile_level'], 0, 8, 1, 6, 2, 4, 6],
106+
20,
107+
['match', ['get', 'tile_level'], 0, 10, 1, 8, 2, 6, 8],
108+
22,
109+
['match', ['get', 'tile_level'], 0, 12, 1, 10, 2, 8, 10],
110+
],
111+
'line-opacity': 0.8,
112+
},
113+
};
114+
70115
export const VALHALLA_NODES_LAYER: LayerSpecification = {
71116
id: VALHALLA_NODES_LAYER_ID,
72117
type: 'circle',
@@ -85,5 +130,6 @@ export const VALHALLA_NODES_LAYER: LayerSpecification = {
85130

86131
export const VALHALLA_LAYERS: LayerSpecification[] = [
87132
VALHALLA_EDGES_LAYER,
133+
VALHALLA_SHORTCUTS_LAYER,
88134
VALHALLA_NODES_LAYER,
89135
];

0 commit comments

Comments
 (0)