LogoLogo
CMSGitHubSupportBook a demo
  • Documentation
  • Academy
  • Help Center
  • Welcome
  • SDKS & Frameworks
    • Web
      • Getting Started
        • Prerequisites
          • MapsIndoors
          • Map Engine Provider
            • Option 1: Get your Mapbox Access Token
            • Option 2: Get your Google Maps API Keys​
          • Map Engine Setup
        • Getting Started: MapsIndoors
      • Map Visualization
        • Highlight, Hover and Select
        • Remove Labels from Buildings and Venues
        • Change Building Outline
        • Managing Collisions Based on Zoom Level
        • 3D Maps
          • Managing your 3D Maps
        • Base Map Styling - Google Maps
        • Managing feature visibility for Mapbox
      • Wayfinding
        • Directions
        • Directions Service
          • Tailoring the directions to your specific needs
        • Directions Renderer
          • Customizing the Route Animation
        • Multi-stop navigation
          • Custom Icons
        • User's Location as Point of Origin
      • Search
        • Search Operations
        • Searching
        • Using External ID, Geospatial Joins
        • Utilizing MapsIndoors Web Components and Other Searches
      • Map Management
      • Data Visualization
        • Display Heatmap Overlay
      • Other guides
        • Authentication
          • Single Sign-On
            • SSO Configuration
            • SSO Authorisation
          • 2-Factor Authentication
          • Password Reset
        • Application User Roles
        • Custom Properties
        • Display Language
        • Language
        • User Positioning
          • Show User's Location aka. Blue Dot
          • Using Cisco DNA Spaces
        • Working with Events
        • Turn Off Collisions Based on Zoom Level
        • Remove Labels from Buildings and Venues for Web
        • Synchronizing data for a subset of venues
        • Custom Floor Selector
      • Display Rules in Practice
      • Offline Data
      • Managing map visibility
    • Android
      • Getting Started
        • Prerequisites
        • Create a New Project
        • Show a Map
        • Create a Search Experience
        • Getting Directions
        • Enable Live Data
        • Integrating MapsIndoors into your own App
        • Migrating from V3 to V4
          • Migrating to Mapbox V11
      • Directions
        • Directions Service
        • Directions Renderer
          • User's Location as Point of Origin
        • Wayfinding Instructions
          • See Route Element Details
        • Using multi-stop navigation
      • Searching
        • Searching on a Map
        • Creating a Search Experience
      • Switching Solutions
      • Caching & Offline Data
      • Display Language
      • Displaying Objects
        • Application User Roles
        • Getting a Polygon from a Location
        • Location Clustering
        • Location Data Sources
        • Location Details
        • Turn Off Collisions Based on Zoom Level
        • Enabling and Disabling features on the map
      • Change Building Outline Color
      • Event Logging
      • Configuring a menu with AppConfig
      • Display Heatmap Overlay
      • Custom Properties
      • Custom Floor Selector
      • External IDs
      • User Positioning
        • Show User's Location aka. Blue Dot
        • Using Cisco DNA Spaces
        • Using Google Fused Location Provider
        • Using Indoor Atlas
      • Authentication
        • Single Sign-On
          • SSO Configuration
          • SSO Authorisation
        • 2-Factor Authentication
        • Password Reset
      • Display Rules in Practice
        • Label styling through Display Rules
      • Highlight and Select
    • iOS
      • Getting Started
        • Prerequisites
        • Set Up Your Environment
        • Display a Map
        • Search
        • Getting Directions
        • Migrating from v3 to v4
      • Directions
        • Directions Renderer
          • User's Location as Point of Origin
        • Wayfinding Instructions
          • See Route Element Details
        • Directions Service
        • Using multi-stop navigation
      • Searching
        • Searching on a Map
        • Creating a Search Experience
      • Caching & Offline Data
      • Displaying Objects
        • Application User Roles
        • Getting a Polygon from a Location
        • Location Details
        • Turn Off Collisions Based on Zoom Level
        • Enabling and Disabling features on the map
      • Custom Floor Selector
      • Change Building Outline Color
      • Custom Map Padding
      • Custom Properties
      • Display Rules in Practice
        • Label styling through Display Rules
      • Switching Solutions
      • Show User's Location aka. Blue Dot
        • Using Indoor Atlas
        • Using Cisco DNA Spaces
      • Highlight and Select
      • Display Language
    • React Native
      • Getting Started
        • Prerequisites
        • Project Setup
        • Displaying a Map
        • Creating a Search Experience
        • Getting Directions
        • Enabling Live Data
      • Showing Blue Dot
    • Flutter
      • Getting Started
        • Prerequisites
        • Create a New Project
        • Show a Map
        • Create a Search Experience
        • Getting Directions
      • Migration Guide
    • Integration API
      • Integration API Access
        • Access with Swagger
        • Access with Postman
        • Access with Python
        • Client credentials flow
      • Data Description
      • Reverse Geocoding
      • Route Access
      • OpenAPI Specification
    • Built-In Map Edits
      • Getting started
      • Authentication
      • Release notes
      • Reference docs
  • Products
    • Product Overview
    • CMS
      • Interface Overview
      • Display Rules
      • Media Library
        • 2D Models and Icons
        • 3D Models
      • Editing Data
      • Solution Settings
      • Settings
      • Data Concepts
      • User Roles
      • Route Network
        • Barrier Route Element
        • Door Route Element
      • Additional Location Details
    • Map Template
      • Getting Started
        • Web Component
        • React Component
      • Configuration
        • Query Parameters
      • Customization
      • Deploying Map Template to a cloud storage provider
      • 2D/3D Visibility Switch
      • External customization of the Map Template
      • Location Details configuration
      • Kiosk
        • QR code configuration
  • Other
    • Design
      • Standard MapsIndoors Map Style
      • Using a Custom Mapbox MapStyle
    • Changelog
      • Web SDK
        • V4
        • V3
      • Android SDK
        • V4
        • V3
      • iOS SDK
        • V4
        • V3
      • React Native SDK
      • Flutter SDK
      • MI Components
      • Map Template
    • Glossary
  • Legacy Docs
    • Android SDK V3
      • Getting Started
        • Prerequisites
        • Create a New Project
        • Show a Map
        • Create a Search Experience
        • Getting Directions
        • Enable Live Data
        • Integrating MapsIndoors into your own App
    • iOS SDK V3
      • Getting Started
        • Prerequisites
        • Set Up Your Environment
        • Display a Map
        • Search
        • Directions
        • Live Data
        • Integrating MapsIndoors into your own App
      • Inspect Route Element for iOS v3
      • Using Cisco DNA Spaces
      • Using Indoor Atlas
      • Switching Solutions
      • Show User's Location aka. Blue Dot
      • Application User Roles
      • Getting a Polygon from a Location
      • Location Details
  • MapsIndoors SDK Firewall
  • Google Analytics & Logging
  • Reference Docs
    • Web SDK
    • Android SDK
    • iOS SDK
    • React Native SDK
    • Flutter SDK
Powered by GitBook
On this page
  • Retrieve Specific Location: getLocation(id)
  • Use-Case 1: Center the Map to the Location
  • Use-Case 2: Utilizing MapsIndoors SDK Highlighting and Filtering
  • Use-Case 3: Modify Display Rule
  • Use-Case 4: Add a Popup / Info Window
  • Retrieve Queried Locations: getLocations(args opt)
  • Example of Creating a Search Query​
  • Display Search Results on the Map​
  • Clearing the Map of Your Filter​
  • Display Locations as List​

Was this helpful?

Export as PDF
  1. SDKS & Frameworks
  2. Web
  3. Search

Searching

Searching through your MapsIndoors data is an key part of a great user experience with your maps. Users can look for places to go, or filter what is shown on the map.

Searches work on all MapsIndoors geodata. It is up to you to create a search experience that fits your use case.

Retrieve Specific Location: getLocation(id)

Use-Case 1: Center the Map to the Location

Example 1: Using MapsIndoors Location ID on the Card

This example assumes that you've stored the MapsIndoors Location ID directly on the card, accessible via a custom attribute or some other mechanism. When the card is clicked, getLocation(id) retrieves the corresponding location, centers the map on it, and sets the zoom level.

card.addEventListener('click', () => {
  const locationId = card.getAttribute('data-location-id'); // Assume the MapsIndoors ID is stored in a data attribute
  mapsindoors.services.LocationsService.getLocation(locationId).then(location => {
    mapsIndoorsInstance.setFloor(location.properties.floor);
    mapInstance.setCenter({
      lat: location.properties.anchor.coordinates[1],
      lng: location.properties.anchor.coordinates[0]
    });
    mapInstance.setZoom(18);
  });
});

Example 2: Using an External Custom ID on the Card

In this example, an external (custom) ID is stored on the card. The getLocationsByExternalId method is used to fetch locations, taking into account that multiple locations could be returned.

card.addEventListener('click', () => {
  const externalId = card.getAttribute('data-external-id'); // Assume the external ID is stored in a data attribute
  
  // Use getLocationsByExternalId to fetch locations by their external IDs
  mapsindoors.services.LocationsService.getLocationsByExternalId(externalId).then(locations => {
    if (locations.length > 0) {
      const location = locations[0]; // Take the first location if multiple are returned
      
      // Set the floor and center the map
      mapsIndoorsInstance.setFloor(location.properties.floor);
      mapInstance.setCenter({
        lat: location.properties.anchor.coordinates[1],
        lng: location.properties.anchor.coordinates[0]
      });
      
      mapInstance.setZoom(18);
    } else {
      // Handle the case where no locations are returned for the given external ID
      console.warn(`No locations found for external ID ${externalId}`);
    }
  });
});

Both examples work off a click event attached to a card element. The key difference lies in the method used to query MapsIndoors for the location information. Example 1 uses the native MapsIndoors ID, while Example 2 uses an external ID. Both methods then focus the map on the retrieved location.

Use-Case 2: Utilizing MapsIndoors SDK Highlighting and Filtering

Take advantage of using MapsIndoors native filtering and highlighting functionality via the SDK without needing to implement your own custom display logic.

Use-Case 3: Modify Display Rule

Example 1: Customizing Display Rule on Click Event with MapsIndoors Location ID

// Define the rule outside the listener for better readability and reusability
const rule = { 
  visible: true,
  polygonVisible: true,
  polygonFillColor: "#FF0000",
  polygonFillOpacity: 1,
  iconSize: { width: 30, height: 30 },
  labelVisible: true,
};

let previousLocationId = null;  // Keep track of previously filtered location

card.addEventListener('click', () => {
  const locationId = card.getAttribute('data-location-id');
  mapsindoors.services.LocationsService.getLocation(locationId).then(location => {
    // Optionally set the floor and center the map
    mapsIndoorsInstance.setFloor(location.properties.floor);
    mapInstance.setCenter({
      lat: location.properties.anchor.coordinates[1],
      lng: location.properties.anchor.coordinates[0]
    });

    // Reset display rule for previously filtered location, if any
    if (previousLocationId) {
      mapsIndoorsInstance.setDisplayRule(previousLocationId, null);
    }

    // Apply the new display rule to the clicked location
    mapsIndoorsInstance.setDisplayRule(location.id, rule);

    // Update the previous location ID
    previousLocationId = location.id;
  });
});

Example 2: Using an External Custom ID

// Define the display rule
const rule = { 
  visible: true,
  polygonVisible: true,
  polygonFillColor: "#FF0000",
  polygonFillOpacity: 1,
  iconSize: { width: 30, height: 30 },
  labelVisible: true,
};

let previousLocationId = null;  // Keep track of the previously filtered location

card.addEventListener('click', () => {
  const externalId = card.getAttribute('data-external-id');
  
  // Use getLocationsByExternalId() to fetch locations by their external IDs
  mapsindoors.services.LocationsService.getLocationsByExternalId(externalId).then(locations => {
    if (locations.length > 0) {
      const location = locations[0];  // Assume the first location is the one to display

      // Optionally set the floor and center the map
      mapsIndoorsInstance.setFloor(location.properties.floor);
      mapInstance.setCenter({
        lat: location.properties.anchor.coordinates[1],
        lng: location.properties.anchor.coordinates[0]
      });

      // Reset display rule for the previously filtered location, if any
      if (previousLocationId) {
        mapsIndoorsInstance.setDisplayRule(previousLocationId, null);
      }

      // Apply the new display rule to the location
      mapsIndoorsInstance.setDisplayRule(location.id, rule);

      // Update the ID of the previously filtered location
      previousLocationId = location.id;

    } else {
      console.warn(`No locations found for external ID ${externalId}`);
    }
  });
});

This code assumes that if multiple locations are returned from getLocationByExternalId(), the first one is the relevant location for display. The remainder of the code remains largely similar to the previous example, but we're fetching the locations based on an external ID instead of a MapsIndoors Location ID.

Use-Case 4: Add a Popup / Info Window

Mapbox Implementation

In the Mapbox example, we add an event listener to the MapsIndoors instance that listens for 'click' events. When a location is clicked, we display a Mapbox popup at the location's coordinates. Any previously displayed popup will be removed to avoid clutter.

let currentPopup = null;

export const handleLocationClickForMapbox = (location, mapsIndoorsInstance, mapInstance) => {
  if (currentPopup) {
    currentPopup.remove();
  }

  const coords = location.properties.anchor.coordinates;
  const popupContent = `
    <img src="${'Your_custom_image_url_here'}" alt="${location.properties.description}" width="100" height="100" />
    <h2><a href="${'Your_custom_link_here'}" target="_blank">${location.properties.name}</a></h2>
  `;

  currentPopup = new mapboxgl.Popup({ closeOnClick: true, closeButton: true })
    .setLngLat(coords)
    .setHTML(popupContent)
    .addTo(mapInstance);
};

mapsIndoorsInstance.addListener('click', location => {
  handleLocationClickForMapbox(location, mapsIndoorsInstance, mapInstance);
});

Google Maps Implementation

In the Google Maps example, we add an event listener to the MapsIndoors instance to listen for location clicks. When a location is clicked, an info window appears at the coordinates of that location. Similar to the Mapbox example, any previously displayed info window will be closed.

let previousInfoWindow = null;

mapsIndoorsInstance.addListener('click', location => {
  if (previousInfoWindow) {
    previousInfoWindow.close();
  }

  const coords = location.properties.anchor.coordinates;
  const infoWindowContent = `
    <img src="${'Your_custom_image_url_here'}" alt="${location.properties.description}" width="100" height="100" />
    <h2><a href="${'Your_custom_link_here'}" target="_blank">${location.properties.name}</a></h2>
  `;

  const infoWindowOptions = {
    content: infoWindowContent,
    position: {
      lat: coords[1],
      lng: coords[0]
    }
  };

  const infoWindow = new google.maps.InfoWindow(infoWindowOptions);
  infoWindow.open(googleMapsInstance);
  previousInfoWindow = infoWindow;
});

Both implementations ensure that only one popup or info window is open at a given time, closing any previous ones when a new location is clicked. This keeps the map clean and focuses the user's attention on the most recently clicked location.

Retrieve Queried Locations: getLocations(args opt)

To help you in this, there is a range of filters you can apply to the search queries to get the best results. E.g. you can filter by Categories, search only a specific part of the map or search near a Location.

All three return a list of Locations from your solution matching the parameters they are given. The results are ranked upon the three following factors:

  • If a "near" parameter is set, how close is the origin point to the result?

  • How well does the search input text match the text of the result?

  • Which kind of geodata is the result (e.g. Buildings are ranked over POIs)?

This means that the first item in the search result list will be the one best matching the three factors. You always have the ability to reorder your array of locations based on your preference before rendering them in your user interface, if you choose to handle that via some client-side code.

Feel free to refer to this table for a comprehensive understanding of each parameter's type, optional/required status, and functionality.

Parameter
Type
Optional/Required
Description
Default / Example
Code Example

q

string

Optional

Use a text query to search for one or more locations.

fields

string

Optional

Fields to search in when using the search string parameter 'q'. Options: "name,description,aliases,categories"

types

Array.

Optional

Filter by types in a comma-separated list. A location only has one type.

mapsindoors.services.LocationsService.getLocations({ lr: 'en', types: ['meetingroom'] }).then(locations => { ... });

categories

Array.

Optional

Filter by categories in a comma-separated list. A location can be in multiple categories.

mapsindoors.services.LocationsService.getLocations({ categories: categoryKey, lr: 'en' }).then(locations => { ... });

bbox

Object

Optional

Limits the result to inside the bounding box. Must include bbox.east, bbox.north, bbox.south, bbox.west

bbox.east

number

Required if bbox

Max longitude of the bounds in degrees.

bbox.north

number

Required if bbox

Max latitude of the bounds in degrees.

bbox.south

number

Required if bbox

Min latitude of the bounds in degrees.

bbox.west

number

Required if bbox

Min longitude of the bounds in degrees.

take

number

Optional

Max number of locations to get.

await mapsindoors.services.LocationsService.getLocations({ near: 'location:9897fd93fcb14bd39ec8110d', take: 5, ... });

skip

number

Optional

Skip the first number of entries.

near

LatLngLiteral | string

Optional

Can either be a coordinate {lat: number, lng: number} or a string in the format "type:id".

await mapsindoors.services.LocationsService.getLocations({ near: 'location:9897fd93fcb14bd39ec8110d', radius: 50, ... });

radius

number

Optional

A radius in meters. Must be supplied when using near with a point.

await mapsindoors.services.LocationsService.getLocations({ near: 'location:9897fd93fcb14bd39ec8110d', radius: 50, ... });

floor

integer

Optional

Filter locations to a specific floor.

await mapsindoors.services.LocationsService.getLocations({ near: 'location:9897fd93fcb14bd39ec8110d', floor: 50, ... });

orderBy

string

Optional

Which property the result should be sorted by.

sortOrder

string

Optional

Specifies in which order the results are sorted, either "ASC" or "DESC"

"ASC"

building

string

Optional

Limit the search for locations to a building.

venue

string

Optional

Limit the search for locations to a venue (id or name).

const searchParameters = {
  q: 'Office',
  near: { lat: 38.897579747054046, lng: -77.03658652944773 }, // // Blue Room, The White House
  take: 1
}

mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
  console.log(locations);
});

When displaying the search results, it is helpful to filter the map to only show matching Locations. Matching Buildings and Venues will still be shown on the map, as they give context to the user, even if they aren't selectable on the map.

Example of Filtering the Map to Display Searched Locations on the Map

const searchParameters = {
  q: 'Office',
  near: { lat: 38.897579747054046, lng: -77.03658652944773 }, // // Blue Room, The White House
  take: 1
}

mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
  mapsIndoorsInstance.filter(locations.map(location => location.id), false);
});

After displaying the search results on your map you can then clear the filter so that all Locations show up on the map again.

Example of Clearing Your Map Filter to Show All Locations Again

mapsIndoorsInstance.filter(null);

You can also search for Locations, and have them presented to you as a list, instead of just displaying them on the map.

The full code example is shown in the JSFiddle below which will be examined below.

The mapsindoors.services.LocationsService class exposes the getLocations function that enables you to search for Locations.

It will return a promise that gets resolved when the query has executed.

searchElement.addEventListener('input', debounce((e) => {
    const value = e.target.value;
    if (value > '') {
        mapsindoors.services.LocationsService.getLocations({ q: value, includeOutsidePOI: true })
            .then(displayResults)
            .then(filterMap);
    } else {
        clearResults();
        clearFilter();
    }
}, 500));

The debounce method is there to ensure that the service is not being called in rapid succession. This method delays the execution of the function by 500ms, unless debounce is called again within 500ms, in which case the timer is reset.

When the function executes, we check whether the input is empty or not. A request object is created if the input is not empty.

The getLocations function expects either no input, in which case it returns all Locations, or an Object (please refer to the official documentation for an exhaustive list of properties). In this case, the constant value is passed to the q property and the includeOutsidePOI property is set to true. When the Promise resolves, the response is passed to the displayResults helper function.

If the input is empty, we clear the result list and reset the map filter by calling the helper functions clearResults and clearFilter.

We need to clear the previous results, and check if any Locations were returned. If so, we loop through them and add them to the result list.

function displayResults(locations) {
    clearResults();

    if (locations.length > 0) {
        for (const location of locations) {
            searchResults.innerHTML += `<li>${location.properties.name}</li>`;
        }
    } else {
        searchResults.innerHTML = '<li class="no-results">No results matched the query.</li>';
    }

    return locations;
}

If no Locations are returned, a message is shown to the user stating "No results matched the query.". Otherwise, we pass the Locations on to the next helper function called filterMap.

function filterMap(locations) {
    mapsIndoors.filter(locations.map(location => location.id), false);
    return locations;
}

The purpose of the filterMap function is to create a list of location ids used to filter the Locations on the map.

The second parameter tells MapsIndoors not to change the viewport of the map.

Last updated 11 months ago

Was this helpful?

For this use-case, we're focusing on how to display an information popup or info window when a MapsIndoors location is clicked. Both Mapbox and Google Maps implementations are provided. These popups will show a custom image and a link, allowing developers the flexibility to populate it with any content. Let's assume you're getting back your location object from one of the approaches in .

(Our base algorithm for searching is using the "" algorithm)

Example of Creating a Search Query

See the full list of parameters in the :

Display Search Results on the Map

Clearing the Map of Your Filter

Display Locations as List

Search example

See for more information.

See this article for a more detailed description of the debounce concept.

Checking for Results

For more information, see MapsIndoors.filter in the .

Levenshtein distance
​
reference guide
​
​
​
​
mapsindoors.services.LocationsService
"What is debouncing" by Jamis Charles
​
reference documentation
Use-Case 1