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
      • Location Types
      • Categories
      • 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
        • Categories
      • 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
    • Map Design
      • Map Design System
      • Using a Custom Mapbox MapStyle
      • 2D Models
    • 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
  • Implementing a Position Provider​
  • Integrating with MapsIndoors SDK​
  • Styling the Blue Dot​

Was this helpful?

Export as PDF
  1. SDKS & Frameworks
  2. Android
  3. User Positioning

Show User's Location aka. Blue Dot

Last updated 1 year ago

Was this helpful?

In this tutorial we will cover how you can implement a positioning system with the MapsIndoors SDK, and use it to have a position indicator for the user (blue dot) shown on the map. We will be creating a PositionProvider (implementing the MPPositionProvider interface), which for the purpose of this tutorial will produce random positions, and attach it to the MapsIndoors SDK which will render the blue dot. We also cover how the blue dot can be styled by modifying its Display Rule.

We will start by creating our implementation of the MPPositionProvider interface.

Implementing a Position Provider

Start by creating the class PositionProvider that implements MPPositionProvider:

class PositionProvider : MPPositionProvider

Add these member variables to PositionProvider:

  • mUpdateListeners: A list for holding listeners

  • mLatestPosition: The latest derived position result

  • mPositionProducer: A timer we will use to execute our positioning code periodically

  • mWhiteHouseBounds: Latitude/longitude coordinate bounds for a part of the White House building

private val mUpdateListeners = ArrayList<OnPositionUpdateListener>()
private var mLatestPosition: MPPositionResultInterface? = null
private var mPositionProducer : Timer? = null
private val mWhiteHouseBounds = MPLatLngBounds(MPLatLng(38.897545509875954, -77.03687635385639), MPLatLng(38.89779861672662, -77.03623597646553))

Next, implement the addOnPositionUpdateListener and removeOnPositionUpdateListener, which adds and removes an entry in our list mUpdateListeners.

override fun addOnPositionUpdateListener(updateListener: OnPositionUpdateListener) {
    mUpdateListeners.add(updateListener)
}

override fun removeOnPositionUpdateListener(updateListener: OnPositionUpdateListener) {
    mUpdateListeners.remove(updateListener)
}

Next, implement getLatestPosition, returning mLatestPosition:

override fun getLatestPosition(): MPPositionResultInterface? {
    return mLatestPosition
}

These three methods require an implementation as the MapsIndoors SDK needs to attach a listener to be notified of positioning changes, as well as get the latest positioning. As long as these three methods are implemented in this manner, you are free to implement the rest of your position provider class as you see fit.

Next, we need to set up some code to generate random positioning results. We define two methods start() and stop() on our class PositionProvider. In the body of start() we start a fixed schedule timer task to execute every second - until our stop() method is called.

fun start(){
    mPositionProducer = Timer(true)
    mPositionProducer?.scheduleAtFixedRate(object: TimerTask() {
        override fun run() {

        }
    }, 0, 1000L)
}

fun stop(){
    mPositionProducer?.cancel()
}

In the timer task's run() method, we compute a random latitude/longitude position within some defined bounds. We create a new MPPoint for the derived position. We also randomize accuracy (meters) and bearing (degrees) values, and create a new MPPositionResult. The position result can optionally have a bearing. Some positioning systems support this, some don't. Refer to the documentation of your chosen positioning provider for this information.

override fun run() {
    // Produce a random positioning inside The White House bounds
    val randomLat = Random.nextDouble(mWhiteHouseBounds.southWest.lat, mWhiteHouseBounds.northEast.lat)
    val randomLng = Random.nextDouble(mWhiteHouseBounds.southWest.lng, mWhiteHouseBounds.northEast.lng)

    val floorIndex = 10.0
    val accuracy = (3..10).random().toFloat() // In meters
    val bearing = (0..360).random().toFloat() // In degrees

    val position = MPPoint(randomLat, randomLng, floorIndex)

    // Randomize whether or not the position result has a bearing
    if(Random.nextInt() % 2 == 0)
        mLatestPosition = MPPositionResult(position, accuracy, bearing)
    else
        mLatestPosition = MPPositionResult(position, accuracy)

    // Report the updated positioning to attached listeners
    for(listener in mUpdateListeners){
        listener.onPositionUpdate(mLatestPosition as MPPositionResult)
    }
}

When we have derived a new position and assigned it to mLatestPosition, we invoke onPositionUpdate() on each attached update listener.

We have now completed the implementation of PositionProvider - we will now cover how this is integrated with the MapsIndoors SDK so the produced positioning is reflected on the map, as well as how we can configure the blue dot styling.

In order for your PositionProvider's produced positions to be rendered on the map, you need to attach it to the MapsIndoors SDK. Use MapsIndoors.setPositionProvider() to set the position provider on the SDK.

// Create a position provider
mPositionProvider = PositionProvider()

MapsIndoors.load(requireActivity().applicationContext, "your mapsindoors api key") {
    // Attach the position provider to the SDK
    MapsIndoors.setPositionProvider(mPositionProvider)
}

Start your PositionProvider instance with start(), so it begins producing positioning results.

mPositionProvider?.start()

The MapsIndoors SDK only supports having a single position provider attached at a time. If you wish to have multiple positioning providers, remove your old provider before setting a new one - or incoorporate multiple positioning systems into a single MPPositionProvider imlpementation.

In order for the MapsIndoors SDK to render the positioning on the map, invoke showUserPosition(true) on your MapControl instance.

// Enable showing the position indicator (aka. the blue dot)
mMapControl?.showUserPosition(true)

You should now have a position indicator on the map, jumping around inside The White House.

The default blue dot styling is basic, and likely needs to be styled to fit your application and make sense to users.

Like with most other things in the MapsIndoors SDK, the styling of the blue dot is dictated by a Display Rule.

A good approach is to attach an OnPositionUpdateListener on your PositionProvider instance.

mPositionProvider?.addOnPositionUpdateListener(object: OnPositionUpdateListener {
    override fun onPositioningStarted(provider: MPPositionProvider) {}

    override fun onPositionFailed(provider: MPPositionProvider) {}

    override fun onPositionUpdate(position: MPPositionResultInterface) {}
})

In the onPositionUpdate() method, we can fetch the Display Rule reserved for the blue dot via MapsIndoors.getDisplayRule() with MPSolutionDisplayRule.POSITION_INDICATOR enum as argument. We can now modify the blue dot styling directly on the Display Rule bluedot. In this case, we want the blue dot to have different icons depending on whether or not the position is directional (has a bearing value) or not. If the position has a bearing, the icon should be a blue circle with a white arrow pointing in the bearing direction. If there is no bearing, the icon should just be a blue circle.

override fun onPositionUpdate(position: MPPositionResultInterface) {
    // Adjust the Display Rule style
    val bluedot = MapsIndoors.getDisplayRule(MPSolutionDisplayRule.POSITION_INDICATOR)
    bluedot.let {
        if(position.hasBearing())
            it?.setIcon(R.drawable.ic_bluedot_bearing)
        else
            it?.setIcon(R.drawable.ic_bluedot)
    }

    // Move the camera to the updated position
    activity?.runOnUiThread {
        mMap?.animateCamera(CameraUpdateFactory
            .newLatLngZoom(LatLngConverter.toLatLng(position.point!!.latLng), 20f))
    }
}

This is also a good place to animate the camera to the new position, if this is the desired use case.

Integrating with MapsIndoors SDK

Styling the Blue Dot

​
See the full implementation of PositionProvider in our samples repository
​
​
See the full implementation in our samples repository