Situm provides indoor&outdoor positioning, with the ability to detect automatically the building where the user is and also the floor. In this section, we provide an in-depth explanation of all the Positioning configurations available.
Before you start #
Get familiar with our Quick Start guides #
We provide several Quickstart Guides (Android, iOS, Cordova, Capacitor, React Native, Flutter) to get your app with Situm up & running quickly. Please make sure you’ve been able to execute your favorite one and that you understand how it works.
Configure Situm positioning using the Remote Configuration #
This section provides a thorough explanation of all positioning options that Situm provides. However, for simplicity, we recommend that you play around with our Remote Configuration feature, that allows you to configure positioning easily through Situm Dashboard.
Positioning example explanation #
In our Quickstart Guides (Android, iOS, Cordova, Capacitor, React Native, Flutter), you’ll notice that we use the following entities / methods.
Entity | Explanation | Documentation |
---|---|---|
LocationManager | Handles all positioning tasks. Implements methods “requestLocationUpdates” and “removeUpdates”, which start & stop positioning. | Android iOS Cordova/Capacitor (start, stop) React Native (start, stop) Flutter (start, stop) |
LocationRequest | Allows to configure the positioning parameters: Building vs Global, whether or not to use WiFi or BLE, etc. | Android iOS Cordova/Capacitor React Native Flutter |
LocationListener | Interface allows you to receive and respond to all the generated geolocations, as well as to other useful information (status and errors). | Android iOS Cordova/Capacitor (location, status, error) React Native (location, status, error) Flutter (location, status, error) |
If you build & execute the Quickstart Guide, your application will produce a log similar to the following one (for the Android example, iOS will be similar).
2021-02-06 00:49:14.441 2592-2592/com.example.androidtestapp I/MainActivity: onStatusChanged() called with: status = [CALCULATING] 2021-02-06 00:49:15.535 2592-2592/com.example.androidtestapp I/MainActivity: onStatusChanged() called with: status = [STARTING]
At first, the onStatusChanged method is called to inform that the Situm SDK is in status “CALCULATING”. Then, it is called again to inform that is in status “STARTING”.
After a few moments, the positioning will start producing a few first outdoor geolocations. If you open the RealTime Panel, you should see your geolocation on the world! Then, behind the scenes, Situm will try to detect if you are within a building that has been configured with Situm technology. If you are in one and open the RealTime Panel, after a few seconds you will see your indoor geolocation within the building.


If you inspect the log lines, you will see very interesting information.
2021-02-06 00:49:16.567 2592-2592/com.example.androidtestapp I/MainActivity: onLocationChanged() called with: location = [Location{provider='SITUM_PROVIDER', deviceId=356655406358, timestamp=1612568956544, position=Point{buildingIdentifier='-1', floorIdentifier='-1', cartesianCoordinate=CartesianCoordinate{x=0,00, y=0,00}, coordinate=Coordinate{latitude=43,356441, longitude=-8,413430}, isOutdoor=true}, quality=HIGH, accuracy=20.287, cartesianBearing=Angle{radians=0.00, degrees=0.00}, bearing=Angle{radians=0.51, degrees=29.44}, bearingQuality=HIGH, customFields={}}]
2021-02-06 01:14:47.319 2592-2592/com.example.androidtestapp I/MainActivity: onLocationChanged() called with: location = [Location{provider='SITUM_PROVIDER', deviceId=356655406358, timestamp=1612570486718, position=Point{buildingIdentifier='6541', floorIdentifier='13483', cartesianCoordinate=CartesianCoordinate{x=17,50, y=10,20}, coordinate=Coordinate{latitude=43,356433, longitude=-8,413040}, isOutdoor=false}, quality=HIGH, accuracy=0.70591295, cartesianBearing=Angle{radians=1.66, degrees=95.19}, bearing=Angle{radians=6.19, degrees=354.81}, bearingQuality=HIGH, customFields={}}]
Location data: detailed overview #
The location data received in the previous example has the following fields:
Field | Description |
---|---|
provider | Always set to SITUM_PROVIDER. Internal parameter. |
deviceId | The identifier of the device that is running the application. |
timestamp | Current Unix Timestamp, in milliseconds since Jan 01 1970 (UTC). |
position.buildingIdentifier | Identifier of the venue where the user is. If “-1”, the user is outdoors (outdoor location). |
position.floorIdentifier | Identifier of the floor where the user is. If “-1”, the user is outdoors (outdoor location). |
position.cartesianCoordinate | Cartesian (XY) location within a building’s floorplan. If we’re dealing with an outdoor location, it will be {x=0.00, y=0.00} (default value) |
position.coordinate | Latitude and longitude in WSG 84 format. If location is an indoor location, this is just a conversion from the cartesianCoordinate to lat/lng. |
position.isOutdoor | This indicates that if are dealing with an outdoor location. |
quality | Indicates whether Situm has a good (HIGH) or bad (LOW) estimation of the position. Usually, it will be LOW when it starts, and it will converge to HIGH as the user walks. It only applies to indoor locations, outdoor locations will always be set to HIGH. |
accuracy | Estimated accuracy of the location, in meters. It can be thought as the approximate error radius around the estimated location that probably encloses the location of the user. It will be high at first and decrease as the user walks. |
cartesianBearing | Cartesian orientation with respect to the bulding’s axis. Only applies to indoor locations. For historical compatibility, in Situm SDK the angles between North and East go between 360º and 450º. |
bearing | Orientation with respect to the Earth North: 0 degrees is North, 90 degrees is East, etc. For historical compatibility, in Situm SDK the angles between North and East go between 360º and 450º. |
bearingQuality | Indicates whether Situm has a good (HIGH) or bad (LOW) estimation of the orientation. Usually, it will be LOW when it starts, and it will converge to HIGH as the user walks. It only applies to indoor locations, outdoor locations will always be set to HIGH. |
customFields | JSON dictionary that may contain key-value tuples. Usually empty. |
Indoor Geolocation modes #
Situm is able to provide Indoor and Outdoor Positions. Regarding Indoor Positions (within building where Situm technology has been configured), Situm provides three methods (mutually exclusive): Situm Indoor, Calibrated Indoor GPS, Uncalibrated Indoor GPS.
Indoor geolocation mode | Description | How to use it |
---|---|---|
Situm Indoor | Determines the user’s position in the calibrated areas of a building by matching WiFi/BLE signals received with the calibrations. More info. | Set to false LocationRequest.useGPS (Android, iOS, Cordova / Capacitor, React Native, Flutter). |
Calibrated Indoor GPS | Mixes the WiFi/BLE + the GPS signals within all the calibrated areas. Recommended in buildings with indoor/outdoor areas with good GPS coverage. More info. | Set to true LocationRequest.useGPS (Android, iOS, Cordova / Capacitor, React Native, Flutter). |
Uncalibrated Indoor GPS | Works just as the Calibrated GPS Indoor mode, but can also use the GPS signal within outdoor uncalibrated areas of your building. This can help you avoid the effort of calibrating big outdoor areas while still having the benefits of using the GPS signal in them. | Set to true LocationRequest.useGPS (Android, iOS, Cordova / Capacitor, React Native, Flutter). Create geofences with a specific configuration in all the outdoor areas where you want Situm to use the GPS information. |
In any of these methods, there may be times when Situm will not be able to provide a valid Indoor Location, usually because the signals do not match with what is expected in a given building. In this case, Situm will inform that the user is not in any known building.
You may try each of these modes using our Situm Mapping Tool application: this will help you get a better understanding on how they work and what you can expect from them.
Building vs Global Mode #
Situm SDK allows you to choose between two positioning modes: Building and Global Mode.
Mode | Building detector | Description | How to use it |
---|---|---|---|
Building | None | Locates the user within a specific building. If user is in the building, generates Indoor Positions. Otherwise, informs that the user is not in the building. | Set the LocationRequest.buildingIdentifier (Android, iOS, Cordova / Capacitor, React Native, Flutter). |
Global | Detects automatically the building where the user is and provides his Indoor Position. | ||
GPS based | Default detector but unrecommended. User will be geolocated in the nearest building from those within a certain maximum distance. More info. | Set the OutdoorLocationOptions.Builder() .buildingDetector to GPS_PROXIMITY (Android) or SITOutdoorLocationOptions.buildingDetector to kSITGpsProximity (iOS). On Cordova/Capacitor, React Native and Flutter this option is only available through Remote Configuration. | |
WiFi/BLE based | Recommended. The user user will be geolocated inside the building whose calibration signals match better with those perceived by the user smartphone. More info. For fast building transitions, enable the “Always on mode” (Android only). More info. | In Android, set the OutdoorLocationOptions.Builder() .buildingDetector to WIFI, BLE or WIFI_AND_BLE, depending on the sensor you want to use to match the signals. In iOS, set the SITOutdoorLocationOptions.buildingDetector to kSITBLE. Always on Mode (Android only). Set the OutdoorLocationOptions.Builder().scansBasedDetectorAlwaysOn method to true. On Cordova/Capacitor, React Native and Flutter this option is only available through Remote Configuration. | |
GPS + WiFi/BLE based | Only available when using the Uncalibrated GPS Indoor positioning mode. User will be geolocated inside the building where: 1) calibration signals match better with those perceived by the user smartphone, and/or 2) GPS signal falls within one of the GPS-configured geofences of the building. | In Android, set the OutdoorLocationOptions.Builder() .buildingDetector to WIFI, BLE or WIFI_AND_BLE, depending on the sensor you want to use to match the signals. Also, set to true LocationRequest.Builder().useGps and the OutdoorLocationOptions.Builder.useGeofencesInBuildingSelector. In iOS, set the SITOutdoorLocationOptions.buildingDetector to kSITBLE and set to true SITLocationRequest.useGPS and the SITOutdoorLocationOptions.useGeofencesInBuildingSelector. This mode also requires to configure special geofences in the building. This mode supports the Always on Mode, like the WiFi/BLE mode (Android only). Set the OutdoorLocationOptions.Builder().scansBasedDetectorAlwaysOn method to true. On Cordova/Capacitor, React Native and Flutter this option is only available through Remote Configuration. |
Indoor Positioning Sensor Management #
As explained in this article, in order to compute the most accurate geolocation, Situm can use many of the sensor information that modern smartphones provide. Situm SDK allows you to activate/deactivate most of these sensors when computing indoor geolocations. This can come in handy to activate special features by enable a certain sensor, saving battery by disabling another, etc.
Sensor | Sub-Mode | Description | How to use it |
---|---|---|---|
WiFi (Android only) | Scan WiFi for indoor positioning and building detection. | Enabled by default. Configured by LocationRequest.useWiFi (Android, Cordova / Capacitor, React Native, Flutter). Not available in iOS. | |
Ignore WiFi throttling (Android only) | In Android 10, you may ignore the WiFi Throttling limitation and scan WiFi at full speed. Also, in Android 11 with SitumSDK v2.69.1 and inferior. Android 5,6,7,8 are not affected by WiFi Throttling. Android 9 doesn’t allow to disable WiFi Throttling. Android 11 + Situm SDK v>2.69.1 scans at full speed if WiFi Throttling is disabled. So, this parameter has no effect on them. | Set to true LocationRequets.Builder().ignoreWiFiThrottling to scan at full speed. False by default (assumes WiFi Throttling is enabled in the device). Make sure you have turned off WiFi Throttling in your device before. On Cordova/Capacitor, React Native and Flutter this option is only available through Remote Configuration. Not available in iOS. | |
BLE | Scan BLE for indoor positioning and building detection. | Enabled by default. Configured by LocationRequest.useBLE (Android, iOS, Cordova / Capacitor, React Native, Flutter). | |
Beacon filters | By default, Situm only detects beacons with Situm’s UUID (73697475-6D73-6974-756D-736974756D15) and Kontakt’s UUID f7826da6-4fa2-4e98-8024-bc5b71e0893e). Nevertheless, you may use any other iBeacon with a different UUID. | Use LocationRequest.beaconFilters (Android, iOS, Cordova / Capacitor, React Native). Not available in Flutter. | |
Auto-enable BLE (Android only) | User may disable Bluetooth on the smartphone, preventing Situm SDK to scan BLE signals. SitumSDK re-enables Bluetooth automatically if LocationRequest.Builder().useBLE is true. | Use LocationRequest.beaconFilters (Android, iOS, Cordova / Capacitor, React Native). Not available in Flutter nor in iOS. To disable this automatic, set LocationRequest.Builder().autoEnableBleDuringPositioning to false. WARNING: This option is not compatible with Android >= 13 or Huawei devices. If you start positioning on those devices using this option, location status to will change to AUTO_ENABLE_BLE_FORBIDDEN. In this case, ask the user to enable the bluetooth sensor by: 1. In Android >= 13 devices: throwing the BluetoothAdapter.ACTION_REQUEST_ENABLE intent. 2. In Huawei devices: just call BluetoothAdapter.enable() (Huawei already implements this dialog). | |
GPS | Use GPS for indoor positioning (useful in buildings with outdoor areas with good GPS coverage). Using GPS implies that Calibrated or Uncalibrated GPS Indoor modes will be used. Do not mistake using GPS with Global Mode: GPS can be used both in Building and Global modes. | Disabled by default. Enable it by setting LocationRequest.useGPS (Android, iOS, Cordova / Capacitor, React Native, Flutter). | |
Gyroscope | Gyroscope measures the angular velocity (rate at which the smartphone turns). Combined with compass, Situm provides an accurate orientation. | Enabled by default. You may disable it with LocationRequest.useGyro (Android). On iOS, Cordova/Capacitor, React Native and Flutter this option is only available through Remote Configuration. | |
Compass | Compass measures the absolute smartphone orientation with respect to the Earth’s North. | Enabled by default. You may disable it (not recommended) with LocationRequest.useCompass (Android, iOS). On Cordova/Capacitor, React Native and Flutter this option is only available through Remote Configuration. | |
Barometer | It is the instrument that measures the pressure of the air in the atmosphere against everything it touches, as gravity pulls it towards the Earth. | Enabled by default. You may disable it (not recommended) with LocationRequest.useBarometer (Android, iOS, Cordova / Capacitor, React Native). From OS 17.4 you should request NSMotionUsageDescription permission to use the barometer (you can find more information here). On Flutter this option is only available through Remote Configuration. |


Detail on how Auto-enable BLE works

Configuration of positioning in navigation #
This positioning feature allows for the adjustment of the user’s current position and orientation to align with a selected navigation route. This feature is governed by three key parameters: Route adjustment, distance threshold and angle difference threshold.
Configuration | Description | How to use it |
---|---|---|
Route adjustment | Enabled by default, it determines whether the positioning should adapt to the chosen path. When activated, it aligns the user’s position and orientation with the selected navigation route (based on the following parameters). | Set the parameter LocationRequest.useRouteAdjustment (Android, iOS) On Cordova/Capacitor, React Native and Flutter this option is only available through Remote Configuration. |
Distance threshold | Defines a “Distance Threshold” in meters to determine when a user’s position is adjusted to the navigation route. If the user is within this threshold, their position is aligned with the route; if they are farther away, their actual position remains unchanged. | Set the parameter LocationRequest.distanceThreshold (Android, iOS) On Cordova/Capacitor, React Native and Flutter this option is only available through Remote Configuration. |
Angle difference threshold | Measured in radians, controls the user’s alignment with a navigation route based on their orientation. If the user’s orientation is within the specified angle difference from the route’s direction, they align with the route; if the difference is larger, their orientation stays unaltered. | Set the parameter LocationRequest.angleDifferenceThreshold (Android, iOS) On Cordova/Capacitor, React Native and Flutter this option is only available through Remote Configuration. |
You can also adjust this navigation parameter in the Situm SDK for both Android and iOS through our Remote Configuration feature.
Motion Mode #
Specifies how the user moves with the smartphone. Situm adapts positioning accordingly based either on inertial sensor or camera visual tracking. To set it, use the LocationRequest.motionMode method (Android, iOS, React Native, Flutter).
Configuration | Description |
---|---|
BY_FOOT | Detects walking movement using inertial sensors (accelerometer, gyroscope, and magnetometer). Situm estimates displacement based on step detection and device orientation. |
BY_CAR (native Android only) | Detects movement in vehicles like cars or forklifts using inertial sensors. Situm adapts calculations to avoid incorrect positioning behaviors designed for pedestrian movement. Top speed = 10 km/h |
BY_FOOT_VISUAL_ODOMETRY | Tracks walking using visual odometry, leveraging the device’s camera to enhance positioning. This mode is primarily used in AR applications to improve movement estimation. |
RADIOMAX (Deprecated, Android only) | Uses WiFi and BLE signals to determine location without modeling the user’s movement. This method is less precise and is no longer recommended for accurate positioning. |
VEHICLE_VISUAL_ODOMETRY (Deprecated, Android only) | An experimental mode for vehicle movement tracking using visual odometry. It is no longer supported and should not be used. |
You can also adjust this navigation parameter in the Situm SDK for both Android and iOS through our Remote Configuration feature.
Location Updates Configuration #
By default, Situm SDK computes one geolocation estimate per second, uploads it to the Situm cloud, and gets stored.
This is fine for more apps, but sometimes you may want to tweak this behaviour (or even disable positioning at all). For example, in a wayfinding app the user may turn around in an instant. Waiting one second to show the turn (default behaviour) does not account for a good navigation UX: faster orientation updates will be handy.
Indoor Positioning #
Configuration | Description | How to use it |
---|---|---|
Realtime updates interval | Sets the interval for uploading real-time locations. More info. | Set the parameter LocationRequest.realtimeUpdateInteral (Android, iOS, Cordova/Capacitor, ReactNative, Flutter) |
Location updates interval | Interval between consecutive Indoor Location updates (minimum and default value = 1 second) provided via the LocationListener.onLocationChanged callback. This does not change how many locations the SDK computes (it always computes one location per second) but how often it informs the app. | Set the parameter LocationRequest.interval (Android, iOS, Cordova/Capacitor, ReactNative). On Flutter this option is only available through Remote Configuration. |
Location updates displacement | Configures the minimum movement that the user has to perform to produce a new location via the LocationListener.onLocationChanged callback. More info. | Set the parameter LocationRequest.smallestDisplacement (Android, iOS, Cordova/Capacitor, ReactNative). On Flutter this option is only available through Remote Configuration. |
Dead reckoning (faster orientation changes) (NOT RECOMMENDED) | Computes fast orientation changes between every two locations and provides several location updates per second (only orientation changes, approx 1 per 150ms) via the LocationListener.onLocationChanged callback. Our Map Viewer will ignore this parameter. | Deactivated by default. Set the parameter LocationRequest.useDeadReckoning (Android, iOS, Cordova/Capacitor, ReactNative, Flutter). |
None of the above configurations change: 1) the frequency with which Situm computes it’s geolocations, 2) the frequency and number of geolocations that Situm uploads to Situm Cloud.
Regarding the update intervals, we only recommend adjusting the Realtime updates interval.
Outdoor Positioning (Global Mode only) #
Configuration | Description | How to use it |
---|---|---|
Disable outdoor positioning | You may want to do this to make sure that users are not tracked outside of the building(s). If you disable it, the GPS based building detector will not work. Therefore, you should set a different building detector (e.g. WiFi/BLE based). | Set the relevant parameters for Android and iOS. Our recommendation is that for both Android and iOS, as well as for Cordova/Capacitor, React Native and Flutter you use the Remote Configuration. |
Compute interval | Frequency with which outdoor locations are computed. Helps reducing battery consumption. | Set the relevant parameters for Android and iOS. Our recommendation is that for both Android and iOS, as well as for Cordova/Capacitor, React Native and Flutter you use the Remote Configuration. |
Update Interval | Frequency with which outdoor locations are delivered to the application. Does not change the frequency with which Situm computes geolocations (it just discards some of them). Useful to reduce the amount of data stored in Situm Cloud to perform geospatial with less data. | Set the relevant parameters for Android and iOS. Our recommendation is that for both Android and iOS, as well as for Cordova/Capacitor, React Native and Flutter you use the Remote Configuration. |
Minimum outdoor accuracy | Filters out outdoor positioning that do not meet a certain accuracy. | Set the relevant parameters for Android and iOS. Our recommendation is that for both Android and iOS, as well as for Cordova/Capacitor, React Native and Flutter you use the Remote Configuration. |