Skip to Content
ExamplesCircles / Radius Overlays

Circles / Radius Overlays

Use this guide when you need translucent metric circles on a MapVXMap — for example to visualize a geofence or proximity-notification radius around a location. The radius is expressed in meters, so the circle keeps its geographic size at every zoom level.

Setup

Create a map first, then keep its MapVXMap instance around for future circle operations:

import { initializeSDK, type CircleConfig, type LatLng, type MapVXMap } from "@mapvx/web-js" const sdk = initializeSDK("<YOUR_API_KEY>") const mapContainer = document.getElementById("map") as HTMLElement const map: MapVXMap = sdk.createMap(mapContainer, { center: { lat: 4.666918, lng: -74.053065 }, zoom: 17, })

Create a circle

The only required fields in CircleConfig are coordinate and radiusMeters. Styling defaults to the MapVX brand blue with a translucent fill:

const center: LatLng = { lat: 4.666918, lng: -74.053065, } const circle: CircleConfig = { id: "geofence-entrance", coordinate: center, radiusMeters: 150, } const circleId = map.addCircle(circle)

Every styling property can be overridden per circle:

map.addCircle({ id: "geofence-warehouse", coordinate: { lat: 4.6675, lng: -74.0535 }, radiusMeters: 75, fillColor: "#e53935", fillOpacity: 0.2, strokeColor: "#e53935", strokeWidth: 3, strokeOpacity: 0.8, })

Validate before adding

Before adding a circle configuration, you can pre-validate it with isValidCircleConfig:

import { isValidCircleConfig } from "@mapvx/web-js" const userInput = { /* ... */ } if (isValidCircleConfig(userInput)) { map.addCircle(userInput) } else { console.error("Invalid circle configuration") }

This is useful when accepting circle data from users or APIs.

Update a circle

Use updateCircle to fully replace the configuration of an existing circle. The payload must include the same id; omitted styling fields fall back to their defaults:

const result = map.updateCircle({ id: circleId, coordinate: center, radiusMeters: 300, fillOpacity: 0.25, }) if (result === null) { console.error("Circle not found") }

updateCircle returns the circle id on success, or null if no circle matches.

Move or resize without rebuilding

When only the center or radius changes (e.g. while the user drags a location or adjusts a radius slider), updateCirclePosition keeps the styling untouched:

const success = map.updateCirclePosition(circleId, { lat: 4.6672, lng: -74.0528 }) // Optionally pass a new radius in meters as the third argument if (success) { map.updateCirclePosition(circleId, { lat: 4.6672, lng: -74.0528 }, 250) } else { console.error("Circle not found") }

updateCirclePosition returns true on success, false if the circle doesn’t exist.

Update styling without recreating geometry

Use updateCircleStyle to efficiently update only the appearance (colors, opacity, stroke width) without rebuilding the geometric polygon:

// Brighten the circle on hover const success = map.updateCircleStyle(circleId, { fillOpacity: 0.3, strokeOpacity: 0.9, })

This is much faster than updateCircle when geometry stays the same.

Inspect and retrieve circles

Check existence and retrieve circle data:

// Check if a circle exists before operating on it if (map.hasCircle(circleId)) { const circle = map.getCircle(circleId) console.log(`Circle radius: ${circle?.radiusMeters}m`) } // Get all circles on the map const allCircles = map.getCircles() console.log(`Map has ${allCircles.length} circles`) // Find circles in a region const circles = map.getCircles() const nearbyCircles = circles.filter( (c) => Math.hypot(c.coordinate.lat - myLat, c.coordinate.lng - myLng) < 0.01 )

Hide and show circles

Hidden circles keep their identity and configuration. Unlike markers, a hidden circle stays hidden across floor changes and map restyles until you show it again:

// Hide a circle if (map.hideCircle(circleId)) { console.log("Circle hidden") } else { console.error("Circle not found") } // Show it again later if (map.showCircle(circleId)) { console.log("Circle visible again") }

Both hideCircle and showCircle return true on success, false if the circle doesn’t exist.

Remove one circle or all of them

map.removeCircle(circleId) map.removeAllCircles()

Indoor circles

A circle with a floorId is shown only while that floor is displayed, with the same semantics as MarkerConfig.floorId. Circles without a floorId are shown in outdoor contexts:

map.addCircle({ id: "geofence-food-court", coordinate: { lat: 4.6669, lng: -74.0531 }, radiusMeters: 40, floorId: "level-2", })

Circles automatically survive floor transitions and map style changes — there is no need to re-add them after updateFloor or a parent place change.

Render order (z-placement)

By default circles render above every basemap geometry layer — including indoor floor-plate and building polygons — and below the labels that follow them, so a circle is never hidden by the map itself. Use renderOrder when you need a different placement:

// Default: above floor plates and buildings, below labels map.addCircle({ coordinate, radiusMeters: 150 }) // Legacy placement: below the first label layer of the style. // On indoor styles, floor polygons may paint over the circle. map.addCircle({ coordinate, radiusMeters: 150, renderOrder: "belowLabels" }) // Above everything, including labels map.addCircle({ coordinate, radiusMeters: 150, renderOrder: "top" })

The placement is re-asserted automatically after floor changes and map style swaps, so circles keep their z-order without any consumer-side moveLayer calls.

When to use other examples

  • Go to Basic Markers when you need point markers with icons or labels instead of area overlays.
  • Go to Floor Management for parent places and floor transitions that drive indoor circle visibility.
Last updated on