Highlight Selected Features
Select Places to highlight by holding Shift and dragging a selection box over them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maps-sdk.trimblemaps.com/v4/trimblemaps-4.2.5.css" />
<script src="https://maps-sdk.trimblemaps.com/v4/trimblemaps-4.2.5.js"></script>
<style>
body { margin: 0; padding: 0; }
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.boxdraw {
background: rgba(56, 135, 190, 0.1);
border: 2px solid #3887be;
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
TrimbleMaps.setAPIKey('YOUR_API_KEY_HERE');
// Initialize the Trimble Map
const map = new TrimbleMaps.Map({
container: 'map',
style: TrimbleMaps.Common.Style.TRANSPORTATION,
center: [-98, 38.88],
zoom: 3,
});
let selectedFeatureIds = [];
map.on('load', async () => {
// Load GeoJSON data (US States with geometry and properties)
const response = await fetch('https://developer.trimblemaps.com/maps-sdk/assets/us_states.geojson');
const data = await response.json();
// Assign a unique ID to each feature for feature-state tracking
data.features.forEach((feature, i) => {
feature.id = i + 1;
});
// Add GeoJSON source to the map
map.addSource('states', {
type: 'geojson',
data: data
});
// Fill Layer: default and selected state styling
map.addLayer({
id: 'state-fills',
type: 'fill',
source: 'states',
paint: {
'fill-color': [
'case',
['boolean', ['feature-state', 'selected'], false],
'#e55e5e', // Selected state fill
'#627BC1' // Default state fill
],
'fill-opacity': 0.6
}
});
// Border Layer: state outlines
map.addLayer({
id: 'state-borders',
type: 'line',
source: 'states',
paint: {
'line-color': '#627BC1',
'line-width': 2
}
});
// ------------------- Box Selection Implementation -------------------
const canvas = map.getCanvasContainer();
let start, current, box;
// Get mouse position relative to canvas
function mousePos(e) {
const rect = map.getCanvas().getBoundingClientRect();
return {
x: e.clientX - rect.left - map.getCanvas().clientLeft,
y: e.clientY - rect.top - map.getCanvas().clientTop
};
}
// Handle Shift + Mouse Down to begin box selection
function mouseDown(e) {
if (!(e.shiftKey && e.button === 0)) return;
e.preventDefault();
map.dragPan.disable();
start = mousePos(e);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
document.addEventListener('keydown', onKeyDown);
}
// Draw the box as mouse moves
function onMouseMove(e) {
current = mousePos(e);
if (!box) {
box = document.createElement('div');
box.classList.add('boxdraw');
canvas.appendChild(box);
}
const minX = Math.min(start.x, current.x),
maxX = Math.max(start.x, current.x),
minY = Math.min(start.y, current.y),
maxY = Math.max(start.y, current.y);
box.style.transform = `translate(${minX}px, ${minY}px)`;
box.style.width = `${maxX - minX}px`;
box.style.height = `${maxY - minY}px`;
}
// Finalize selection on mouse up
function onMouseUp(e) {
finish([start, mousePos(e)]);
}
// Cancel box selection on Escape key
function onKeyDown(e) {
if (e.key === 'Escape') finish();
}
// Finalize and apply selected state styling
function finish(bbox) {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
document.removeEventListener('keydown', onKeyDown);
if (box) {
box.parentNode.removeChild(box);
box = null;
}
if (bbox) {
const features = map.queryRenderedFeatures(bbox, {
layers: ['state-fills']
});
// Reset previously selected states
selectedFeatureIds.forEach(id => {
map.setFeatureState({ source: 'states', id }, { selected: false });
});
selectedFeatureIds = [];
// Highlight selected states
features.forEach(f => {
if (f.id !== undefined) {
map.setFeatureState({ source: 'states', id: f.id }, { selected: true });
selectedFeatureIds.push(f.id);
}
});
}
map.dragPan.enable();
}
// Register mousedown listener for selection
canvas.addEventListener('mousedown', mouseDown, true);
});
</script>
</body>
</html>
Highlight Selected Features
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maps-sdk.trimblemaps.com/v4/trimblemaps-4.2.5.css" />
<script src="https://maps-sdk.trimblemaps.com/v4/trimblemaps-4.2.5.js"></script>
<style>
body { margin: 0; padding: 0; }
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.boxdraw {
background: rgba(56, 135, 190, 0.1);
border: 2px solid #3887be;
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
TrimbleMaps.setAPIKey('YOUR_API_KEY_HERE');
// Initialize the Trimble Map
const map = new TrimbleMaps.Map({
container: 'map',
style: TrimbleMaps.Common.Style.TRANSPORTATION,
center: [-98, 38.88],
zoom: 3,
});
let selectedFeatureIds = [];
map.on('load', async () => {
// Load GeoJSON data (US States with geometry and properties)
const response = await fetch('https://developer.trimblemaps.com/maps-sdk/assets/us_states.geojson');
const data = await response.json();
// Assign a unique ID to each feature for feature-state tracking
data.features.forEach((feature, i) => {
feature.id = i + 1;
});
// Add GeoJSON source to the map
map.addSource('states', {
type: 'geojson',
data: data
});
// Fill Layer: default and selected state styling
map.addLayer({
id: 'state-fills',
type: 'fill',
source: 'states',
paint: {
'fill-color': [
'case',
['boolean', ['feature-state', 'selected'], false],
'#e55e5e', // Selected state fill
'#627BC1' // Default state fill
],
'fill-opacity': 0.6
}
});
// Border Layer: state outlines
map.addLayer({
id: 'state-borders',
type: 'line',
source: 'states',
paint: {
'line-color': '#627BC1',
'line-width': 2
}
});
// ------------------- Box Selection Implementation -------------------
const canvas = map.getCanvasContainer();
let start, current, box;
// Get mouse position relative to canvas
function mousePos(e) {
const rect = map.getCanvas().getBoundingClientRect();
return {
x: e.clientX - rect.left - map.getCanvas().clientLeft,
y: e.clientY - rect.top - map.getCanvas().clientTop
};
}
// Handle Shift + Mouse Down to begin box selection
function mouseDown(e) {
if (!(e.shiftKey && e.button === 0)) return;
e.preventDefault();
map.dragPan.disable();
start = mousePos(e);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
document.addEventListener('keydown', onKeyDown);
}
// Draw the box as mouse moves
function onMouseMove(e) {
current = mousePos(e);
if (!box) {
box = document.createElement('div');
box.classList.add('boxdraw');
canvas.appendChild(box);
}
const minX = Math.min(start.x, current.x),
maxX = Math.max(start.x, current.x),
minY = Math.min(start.y, current.y),
maxY = Math.max(start.y, current.y);
box.style.transform = `translate(${minX}px, ${minY}px)`;
box.style.width = `${maxX - minX}px`;
box.style.height = `${maxY - minY}px`;
}
// Finalize selection on mouse up
function onMouseUp(e) {
finish([start, mousePos(e)]);
}
// Cancel box selection on Escape key
function onKeyDown(e) {
if (e.key === 'Escape') finish();
}
// Finalize and apply selected state styling
function finish(bbox) {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
document.removeEventListener('keydown', onKeyDown);
if (box) {
box.parentNode.removeChild(box);
box = null;
}
if (bbox) {
const features = map.queryRenderedFeatures(bbox, {
layers: ['state-fills']
});
// Reset previously selected states
selectedFeatureIds.forEach(id => {
map.setFeatureState({ source: 'states', id }, { selected: false });
});
selectedFeatureIds = [];
// Highlight selected states
features.forEach(f => {
if (f.id !== undefined) {
map.setFeatureState({ source: 'states', id: f.id }, { selected: true });
selectedFeatureIds.push(f.id);
}
});
}
map.dragPan.enable();
}
// Register mousedown listener for selection
canvas.addEventListener('mousedown', mouseDown, true);
});
</script>
</body>
</html>