Map Controls and Bounds


This guide covers the APIs that shape the current viewport and map state after creation.
Setup
const sdk = initializeSDK("<YOUR_API_KEY>", { lang: "es" })
const map = sdk.createMap(document.getElementById("map") as HTMLElement, {
center: { lat: 4.666918, lng: -74.053065 },
zoom: 17,
showCompass: true,
showZoom: true,
navigationPosition: "top-right",
onMapReady: () => {
console.log("Map ready")
},
onZoomEnd: (zoomLevel) => {
console.log("Zoom changed", zoomLevel)
},
onRotate: (degrees) => {
console.log("Map bearing", degrees)
},
})Fit several coordinates
map.fitCoordinates(
[
{ lat: 4.666918, lng: -74.053065 },
{ lat: 4.66715, lng: -74.0528 },
{ lat: 4.6665, lng: -74.0535 },
],
{
padding: {
top: 80,
right: 40,
bottom: 120,
left: 40,
},
maxZoom: 18,
onComplete: () => {
console.log("Fit completed")
},
}
)Fit coordinates under a bearing
fitCoordinates always fits a north-up rectangle, so a rotated
or diagonal set of coordinates (e.g. a route drawn under a bearing) ends up framed with extra empty
viewport. easeToCoordinates fits the same list of
coordinates but computes an oriented bounding box aligned to the target bearing, so the frame stays
tight. It accepts the same options as fitCoordinates; only the camera-change strategy differs
(easeTo instead of fitBounds).
map.easeToCoordinates(routeCoordinates, {
bearing: 140,
padding: { top: 40, right: 40, bottom: 200, left: 40 },
duration: 800,
})Because the fitted frame is tighter than fitCoordinates, make sure the padding leaves enough room
for any overlaid UI (instruction panels, buttons) so markers or route lines aren’t hidden behind it.
Update the camera explicitly

map.updateCamera(
{
center: { lat: 4.667, lng: -74.0529 },
zoom: 18.5,
pitch: 45,
bearing: 20,
duration: 1500,
},
() => {
console.log("Camera animation finished")
}
)Set zoom limits
map.setMinZoom(15)
map.setMaxZoom(20)Lock the map orientation (totems / kiosks)
For fixed installations such as a totem or kiosk, the map should usually face a constant direction
so that “up” on screen matches “forward” for the person standing in front of it. Set an initial
bearing and disable user rotation with rotateEnabled: false — pinch‑to‑zoom keeps working, only
rotation is locked.
const map = sdk.createMap(container, {
center: { lat: 4.666918, lng: -74.053065 },
zoom: 19,
bearing: 135, // degrees clockwise from north — align "up" with the totem
rotateEnabled: false, // disable drag/touch/keyboard rotation, keep zoom
})You can also change the orientation at runtime — for example after the visitor picks which totem they are standing at — and toggle rotation on or off without re‑creating the map:
// Snap to a new orientation (use { animate: true } to ease into it instead)
map.setBearing(90)
map.setBearing(90, { animate: true, onComplete: () => console.log("aligned") })
// Lock / unlock user rotation at runtime
map.setRotationEnabled(false)For totem projects the per‑device angle is configured on the backend and returned by
getConfiguration in Configuration.mapRotations, indexed by the totem’s place id (mapvxId).
Resolve the totem (e.g. with getPlaceDetail(alias)), read its angle and apply it:
const config = await sdk.getConfiguration(parentPlaceId)
const totem = await sdk.getPlaceDetail("PA11") // alias -> place
const angle = config.mapRotations?.[totem.mapvxId]?.angle ?? config.initialBearing ?? 0
map.setBearing(angle)Restrict user interactions (static screen)
To present a static screen where the visitor can only zoom in and out — no rotation and no panning —
disable the corresponding gestures. Every flag defaults to true, so only set the ones you want to
turn off.
const map = sdk.createMap(container, {
center: { lat: 4.666918, lng: -74.053065 },
zoom: 19,
rotateEnabled: false, // no rotation
dragPan: false, // no panning
scrollZoom: true, // keep wheel/trackpad zoom (default)
})Available interaction flags on MapConfig:
interactive— master switch;falsedisables all pan/zoom/rotate at oncerotateEnabled— drag/touch/keyboard rotation (keeps pinch‑to‑zoom whenfalse)dragPan— pan by dragging/swipingscrollZoom— scroll wheel / trackpad zoomdoubleClickZoom— double‑click / double‑tap zoomtouchZoomRotate— pinch zoom on touch deviceskeyboard— keyboard pan/zoom/rotate shortcuts
The same restrictions can be toggled at runtime:
map.setRotationEnabled(false)
map.setPanEnabled(false)
map.setScrollZoomEnabled(true)Restrict the navigable area

Use setMaxBounds when the user should stay inside a known area:
map.setMaxBounds(
[
{ lat: 4.6675, lng: -74.0525 },
{ lat: 4.6663, lng: -74.0537 },
],
{
onComplete: () => {
console.log("Bounds locked")
},
}
)Camera movements via updateCamera are automatically constrained — if you try to move outside the
bounds, the map snaps back to the nearest valid position:
// This will be constrained to stay within bounds
map.updateCamera({ center: { lat: 0, lng: 0 }, duration: 1000 })
// The camera snaps back instead of moving to (0, 0)You can also check programmatically if a coordinate is inside the bounds:
const isAllowed = map.isInsideBounds({
lat: 4.6669,
lng: -74.053,
})Switch map label language at runtime

map.setLang("en")This updates the language used in map layers without re-creating the map instance.
Clear tile cache after a style update
map.clearTileCache()This is useful when:
- the backend style was updated
- tiles look stale or corrupted
- you want to force visible tiles to be requested again
Tile cache configuration at creation time
const map = sdk.createMap(container, {
center: { lat: 4.666918, lng: -74.053065 },
zoom: 17,
tileCache: {
enabled: true,
maxTiles: 600,
ttlMs: 60 * 60 * 1000,
persistToServiceWorker: true,
preloadAdjacentZooms: false,
},
})