Skip to Content
ExamplesPlace Interaction

Place Interaction and Polygon Styling

Selected places highlighted with teal polygons and borders

Places are the core data model behind indoor maps. This example covers searching, selecting, and visually highlighting places on the map — the foundation for any directory or wayfinding UI.

It uses these place-centric APIs:

  • getInstitutions
  • getPlacesByInput
  • searchPlacesByTags
  • getPlaceDetail
  • startClickListener
  • setPlacesAsSelected
  • addBorderToPlaces

Setup

import { initializeSDK } from "@mapvx/web-js" 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, onMapReady: () => { console.log("Ready for place interactions") }, })

Fetch institutions

Use institutions when search results should be scoped to a specific client or campus.

const institutions = await sdk.getInstitutions() const institution = institutions[0]

Search places by user input

const results = await sdk.getPlacesByInput( "coffee", institution.mapvxId, "<OPTIONAL_PARENT_PLACE_ID>" ) results.forEach((place) => { console.log(place.mapvxId, place.title) })

To bias results with a coordinate and floor:

const nearbyResults = await sdk.getPlacesByInput( "restroom", institution.mapvxId, "<PARENT_PLACE_ID>", [], "search-panel", "4.666918", "-74.053065", "<FLOOR_ID>" )

Search places by tags

searchPlacesByTags matches places against one or more tags (combined with OR semantics on the server) instead of free text. It’s the right fit for category filters — e.g. “show every place tagged coffee or restaurant”.

const tagResults = await sdk.searchPlacesByTags(institution.mapvxId, ["coffee", "restaurant"])

Sort the results alphabetically instead of by relevance:

const alphabetical = await sdk.searchPlacesByTags(institution.mapvxId, ["restroom"], { sort: "alphabetical", })

To sort by distance, provide either a reference origin place id or the combination of lat + lng + floor + parentPlacessearchPlacesByTags throws if neither is present:

// From a known reference place (e.g. a totem) const nearestFromTotem = await sdk.searchPlacesByTags(institution.mapvxId, ["restroom"], { sort: "distance", origin: "<TOTEM_PLACE_ID>", }) // From an explicit coordinate + floor const nearestFromCoordinate = await sdk.searchPlacesByTags(institution.mapvxId, ["restroom"], { sort: "distance", lat: "4.666918", lng: "-74.053065", floor: "<FLOOR_ID>", parentPlaces: ["<PARENT_PLACE_ID>"], })

Highlight polygons

Places highlighted with teal polygon fill, no borders

map.setPlacesAsSelected(["<PLACE_ID>"]) map.setPlacesAsSelected(["<PLACE_A>", "<PLACE_B>"], "#0F766E")

Clear the color layer when needed:

map.clearColoredPlaces()

Add borders to the same polygons

Places with dark borders only, no fill color

map.addBorderToPlaces(["<PLACE_ID>"]) map.addBorderToPlaces(["<PLACE_A>", "<PLACE_B>"], "#134E4A", 2)

Clear borders independently:

map.clearBorderedPlaces()

Click real places on the map

Single place clicked with highlight color, border, and marker

Place click demo: selecting different places with detail panel

The click listener returns the MapVX ID of the clicked polygon on the active floor.

map.startClickListener(async (placeId: string) => { const place = await sdk.getPlaceDetail(placeId) map.setPlacesAsSelected([placeId], "#C2410C") map.addBorderToPlaces([placeId], "#7C2D12", 2) console.log("Clicked place", { id: place.mapvxId, title: place.title, floor: place.inFloors?.[0] ?? "outdoor", }) })

Stop listening when the flow ends:

map.stopClickListener()

Indoor and outdoor behavior

Indoor

  • prefer parentPlaceId in createMap
  • use place.inFloors?.[0] to understand the visible floor
  • combine search, polygon styling, and floor changes

Outdoor

  • no parentPlaceId is required
  • getCurrentFloor() stays empty
  • polygon clicks and isInsideBounds still work as expected

Combined search and highlight flow

Search and highlight demo: searching places and coloring results

async function searchAndHighlight(query: string): Promise<void> { const results = await sdk.getPlacesByInput(query, institution.mapvxId) if (results.length === 0) { map.clearColoredPlaces() map.clearBorderedPlaces() return } // Limit visible results to avoid visual clutter const topResults = results.slice(0, 5) const ids = topResults.map((place) => place.mapvxId) map.setPlacesAsSelected(ids, "#0F766E") map.addBorderToPlaces(ids, "#134E4A", 2) // Fit the map to show all highlighted places const coords = topResults.filter((p) => p.position).map((p) => p.position) if (coords.length > 0) { map.fitCoordinates(coords, { padding: { top: 60, right: 60, bottom: 100, left: 60 }, maxZoom: 19, }) } }

If the next step in the user flow is to drop markers or build a route from the selected place, use Places, Markers, and Routes.

Last updated on