ArcGIS IPS is an indoor positioning system An indoor positioning system is a system based on a network of devices (usually BLE or Wi-Fi) used to locate people or objects indoors, where other localization sources such as GPS lack precision or fail entirely. Learn more that allows you to locate yourself and others inside a building in real time. Similar to GPS, it puts a blue dot on indoor maps and uses location services to help you navigate to any point of interest or destination. In addition, ArcGIS IPS ArcGIS IPS is an indoor positioning system that allows you to locate yourself and others inside a building in real time. Learn more supports:

  • Wayfinding
  • Location tracking and sharing
  • Location data collection
  • Analytics

IPS-aware maps An IPS aware map is a map that allows you to locate yourself indoors by displaying your current position on a map. Learn more allow you to build apps that work with ArcGIS IPS ArcGIS IPS is an indoor positioning system that allows you to locate yourself and others inside a building in real time. Learn more to locate yourself inside a building.

Indoor positioning in a mobile app

IPS-aware maps

To create an IPS-aware map An IPS aware map is a map that allows you to locate yourself indoors by displaying your current position on a map. Learn more , see Get started with ArcGIS IPS. Here, you will find information about making a map IPS-aware, configuring, and sharing IPS-aware maps with ArcGIS Pro ArcGIS Pro is a professional desktop GIS application that can explore, visualize, analyze, and manage 2D and 3D data. Learn more .

All IPS-aware maps An IPS aware map is a map that allows you to locate yourself indoors by displaying your current position on a map. Learn more must conform to the ArcGIS IPS Information Model that specify components such as the:

  • ArcGIS IPS Data Model - Tables and feature classes that enable indoor positioning and maintain up-to-date information about the beacon infrastructure.
  • IPS quality dataset - Point feature classes used to assess the performance of the ArcGIS IPS deployment.
  • Beacons - Bluetooth Low Energy (BLE) beacons.
  • Floor plan - Sites, facilities, levels, and other details.
  • Transitions - Exits and entrances.
  • Pathways - Line features that the device location can snap to.

Once the map is IPS-aware, you can then use ArcGIS IPS Setup The ArcGIS IPS Setup mobile app allows you to survey the spatial distribution of radio signals from Bluetooth Low Energy (BLE) beacons or WiFi access points inside your building(s) to create reference positioning data; it can also test positioning accuracy once ArcGIS IPS is deployed. Learn more apps to plan and perform survey recordings inside facilities where you want to enable ArcGIS IPS. You can collect radio signals from Bluetooth Low Energy (BLE) beacons inside your buildings. For details, see ArcGIS IPS Setup for use with Android or ArcGIS IPS Setup for use with iOS. When using an IPS-aware map you should also consider the following device limitations:

  • This API supports both Wi-Fi and BLE for indoor positioning on Android devices. When using ArcGIS IPS ArcGIS IPS is an indoor positioning system that allows you to locate yourself and others inside a building in real time. Learn more , we recommend that you only employ one of these systems in a facility.

  • Android 9 introduced Wi-Fi scan throttling to limit the number of Wi-Fi scans. To use Wi-Fi IPS, Android devices (9 or higher) must enable developer mode and disable Wi-Fi scan throttling (Developer Options > Networking > Wi-Fi scan throttling).

Add indoor positioning to your app

Each IPS-aware map An IPS aware map is a map that allows you to locate yourself indoors by displaying your current position on a map. Learn more contains map layers to visualize indoor space and has access to indoor positioning data that determines the device location. To display the device location, create the indoor location data source from the indoor positioning definition of the IPS-aware map An IPS aware map is a map that allows you to locate yourself indoors by displaying your current position on a map. Learn more , as follows:

  1. Load the IPS-aware map and add it into the map view. This is a web map created with ArcGIS Pro that is hosted as a portal item in ArcGIS Online or in ArcGIS Enterprise.

  2. Obtain an indoor positioning definition from the loaded ArcGISMap.indoorPositioningDefinition. If this value is null, the map isn’t IPS-aware An IPS aware map is a map that allows you to locate yourself indoors by displaying your current position on a map. Learn more and can’t be used for indoor positioning.

  3. Load the indoor positioning definition to avoid any delay when the IndoorsLocationDataSource is started.

  4. Create an IndoorsLocationDataSource using the IndoorPositioningDefinition.

  5. Pass the IndoorsLocationDataSource to the MapView composable.
  6. Start the location display’s data source and set the LocationDisplayAutoPanMode. The device location will appear on the display as a blue dot and update as the user moves throughout the space.

val map = ArcGISMap(portalItem)
val locationDisplay = rememberLocationDisplay()
val coroutineScope = rememberCoroutineScope()
LaunchedEffect(Unit) {
map.load().onFailure {
return@LaunchedEffect showError("Map failed to load.")
}
val indoorPositioningDefinition = map.indoorPositioningDefinition
?: return@LaunchedEffect showError("Map does not contain an IndoorPositioningDefinition")
indoorPositioningDefinition.load().onFailure { error ->
return@LaunchedEffect showError("Failed to load the indoorPositioningDefinition")
}
val indoorsLocationDataSource = IndoorsLocationDataSource(indoorPositioningDefinition)
locationDisplay.apply{
dataSource = indoorsLocationDataSource
setAutoPanMode(LocationDisplayAutoPanMode.Navigation)
}
// Start the location display, which will trigger IndoorsLocationDataSource to start receiving IPS updates.
locationDisplay.dataSource.start().onFailure {
showError("Error when starting location display")
}
}
// Pass this location display to the Composable MapView.
MapView(
arcGISMap = map,
locationDisplay = locationDisplay
)

Handle location changes

You can handle a status changed event so that the IndoorsLocationDataSource is notified when the location data source starts, stops, or fails to start.

An IPS location populates additional properties with the current floor and the transmitter (beacon) count. When the floor changes, you can update the map to filter the display of features for the current floor. The floor value returned with the location is an integer that represents the vertical offset, where 0 is the ground floor. This value increases by one for each floor above the ground floor and decreases by one for each floor below.

Use code like the following to read additional properties for the location when it changes.

coroutineScope.launch {
// Handle location changes emitted by the IndoorsLocationDataSource.
locationDisplay.dataSource.locationChanged.first { location ->
val locationProperties = location.additionalSourceProperties
if (locationProperties.isEmpty()) {
showError("Indoor positioning data source does not have any property fields.")
return@first false
}
// Retrieve information about the location of the device.
val positionSource = locationProperties["positionSource"]?.toString() ?: ""
val transmitterCount = locationProperties["transmitterCount"]?.toString() ?: ""
val satelliteCount = locationProperties["satelliteCount"]?.toString() ?: ""
// Get current floor of the device location.
val floor = locationProperties["floor"]?.toString() ?: ""
setupLayers(map, floor.toInt())
true
}
}

In addition to getting the floor, you can get the position source, which will be BLE (Bluetooth Low Energy) when using IPS and GNSS (Global Navigation Satellite Systems) when using GPS. You can also get the count of transmitters (beacons) or satellites used to determine the location.

You can use a definition expression to filter layers in the map to only show features for the current floor. For efficiency, you should only filter features when the floor changes rather than with each location update. Depending on the schema for your floor-aware data, you may need to map the vertical offset value to a level ID in order to filter features by floor (level).

private fun setupLayers(map: ArcGISMap, floor: Int) {
map.operationalLayers.forEach { layer ->
val name = layer.name
// filter applicable layers to show features for the current floor (level)
if (layer is FeatureLayer && (name == "Details" || name == "Units" || name == "Levels")) {
layer.definitionExpression = "VERTICAL_ORDER = $floor"
}
}
}

App permissions

If your app is using Bluetooth on the device to scan for beacon signals or GPS, make sure to add the appropriate permissions.

Add these permissions to your AndroidManifest.xml file.

android.permission.BLUETOOTH_ADMIN
android.permission.BLUETOOTH
android.permission.ACCESS_FINE_LOCATION
<!-- Needed if your app targets Android 12 or higher -->
android.permission.BLUETOOTH_SCAN
android.permission.ACCESS_COARSE_LOCATION