Highlight Selected Features
Select Places to highlight by holding Shift and dragging a selection box over them.x
181
1
2
<html lang="en">
3
<head>
4
<meta charset="utf-8" />
5
<link rel="stylesheet" href="https://maps-sdk.trimblemaps.com/v4/trimblemaps-4.2.3.css" />
6
<script src="https://maps-sdk.trimblemaps.com/v4/trimblemaps-4.2.3.js"></script>
7
<style>
8
body { margin: 0; padding: 0; }
9
10
#map {
11
position: absolute;
12
top: 0;
13
bottom: 0;
14
width: 100%;
15
}
16
17
.boxdraw {
18
background: rgba(56, 135, 190, 0.1);
19
border: 2px solid #3887be;
20
position: absolute;
21
top: 0;
22
left: 0;
23
width: 0;
24
height: 0;
25
}
26
</style>
27
</head>
28
<body>
29
<div id="map"></div>
30
31
<script>
32
TrimbleMaps.setAPIKey('YOUR_API_KEY_HERE');
33
// Initialize the Trimble Map
34
const map = new TrimbleMaps.Map({
35
container: 'map',
36
style: TrimbleMaps.Common.Style.TRANSPORTATION,
37
center: [-98, 38.88],
38
zoom: 3,
39
});
40
41
let selectedFeatureIds = [];
42
43
map.on('load', async () => {
44
// Load GeoJSON data (US States with geometry and properties)
45
const response = await fetch('https://developer.trimblemaps.com/maps-sdk/assets/us_states.geojson');
46
const data = await response.json();
47
48
// Assign a unique ID to each feature for feature-state tracking
49
data.features.forEach((feature, i) => {
50
feature.id = i + 1;
51
});
52
53
// Add GeoJSON source to the map
54
map.addSource('states', {
55
type: 'geojson',
56
data: data
57
});
58
59
// Fill Layer: default and selected state styling
60
map.addLayer({
61
id: 'state-fills',
62
type: 'fill',
63
source: 'states',
64
paint: {
65
'fill-color': [
66
'case',
67
['boolean', ['feature-state', 'selected'], false],
68
'#e55e5e', // Selected state fill
69
'#627BC1' // Default state fill
70
],
71
'fill-opacity': 0.6
72
}
73
});
74
75
// Border Layer: state outlines
76
map.addLayer({
77
id: 'state-borders',
78
type: 'line',
79
source: 'states',
80
paint: {
81
'line-color': '#627BC1',
82
'line-width': 2
83
}
84
});
85
86
// ------------------- Box Selection Implementation -------------------
87
88
const canvas = map.getCanvasContainer();
89
let start, current, box;
90
91
// Get mouse position relative to canvas
92
function mousePos(e) {
93
const rect = map.getCanvas().getBoundingClientRect();
94
return {
95
x: e.clientX - rect.left - map.getCanvas().clientLeft,
96
y: e.clientY - rect.top - map.getCanvas().clientTop
97
};
98
}
99
100
// Handle Shift + Mouse Down to begin box selection
101
function mouseDown(e) {
102
if (!(e.shiftKey && e.button === 0)) return;
103
e.preventDefault();
104
map.dragPan.disable();
105
106
start = mousePos(e);
107
document.addEventListener('mousemove', onMouseMove);
108
document.addEventListener('mouseup', onMouseUp);
109
document.addEventListener('keydown', onKeyDown);
110
}
111
112
// Draw the box as mouse moves
113
function onMouseMove(e) {
114
current = mousePos(e);
115
if (!box) {
116
box = document.createElement('div');
117
box.classList.add('boxdraw');
118
canvas.appendChild(box);
119
}
120
121
const minX = Math.min(start.x, current.x),
122
maxX = Math.max(start.x, current.x),
123
minY = Math.min(start.y, current.y),
124
maxY = Math.max(start.y, current.y);
125
126
box.style.transform = `translate(${minX}px, ${minY}px)`;
127
box.style.width = `${maxX - minX}px`;
128
box.style.height = `${maxY - minY}px`;
129
}
130
131
// Finalize selection on mouse up
132
function onMouseUp(e) {
133
finish([start, mousePos(e)]);
134
}
135
136
// Cancel box selection on Escape key
137
function onKeyDown(e) {
138
if (e.key === 'Escape') finish();
139
}
140
141
// Finalize and apply selected state styling
142
function finish(bbox) {
143
document.removeEventListener('mousemove', onMouseMove);
144
document.removeEventListener('mouseup', onMouseUp);
145
document.removeEventListener('keydown', onKeyDown);
146
147
if (box) {
148
box.parentNode.removeChild(box);
149
box = null;
150
}
151
152
if (bbox) {
153
const features = map.queryRenderedFeatures(bbox, {
154
layers: ['state-fills']
155
});
156
157
// Reset previously selected states
158
selectedFeatureIds.forEach(id => {
159
map.setFeatureState({ source: 'states', id }, { selected: false });
160
});
161
selectedFeatureIds = [];
162
163
// Highlight selected states
164
features.forEach(f => {
165
if (f.id !== undefined) {
166
map.setFeatureState({ source: 'states', id: f.id }, { selected: true });
167
selectedFeatureIds.push(f.id);
168
}
169
});
170
}
171
172
map.dragPan.enable();
173
}
174
175
// Register mousedown listener for selection
176
canvas.addEventListener('mousedown', mouseDown, true);
177
});
178
</script>
179
</body>
180
</html>
181