Situm SDK can be used to build Wayfinding and Tracking applications, and dozens of use cases within those realms. In this document, we provide a step-by-step guide to use and configure the visual component of our SDKs and plugins, the MapViewer.
MapViewer is a web based indoor cartography visualizer with highly detailed maps, that allows you to guide the users of your app through your buildings. This plug-and-play visual component will highly improve your app user experience with the following features:
- 2D and 3D map visualization, compatible with raster floorplans, raster tiles, GeoJSON/IMDF floorplans and decorative 3D models.
- Intuitive Guidance with Dynamic and Static Navigation.
- Advanced POI Display Based on Zoom Level and Density.
- “What’s Nearby” Exploration Made Easy with Category & Subcategory Filtering, and POI search.
- POI information visualization.
- Tailored User Experience with High Configurability.
- Multilingual Interface.
Prepare the MapViewer in your app #
First of all we will need to integrate the MapView component in your project. This step is handled differently in every framework, so you must to follow our Quickstart Guides for Flutter, React Native or Cordova, Android, iOS first to learn how to display our component in these frameworks. Once you have your app up & running you’ll probably have something like this:
... // 1. Import the component import 'package:situm_flutter/wayfinding.dart'; // 2. Implement MapView in your Widget @override Widget build(BuildContext context) { return MapView( key: const Key("situm_map"), configuration: MapViewConfiguration( // WARNING! Remember to authenticate with your credentials. // You might find helpful this guide https://situm.com/docs/03-built-in-wayfinding-ui#prepare-viewer situmApiKey: "YOUR_APIKEY", buildingIdentifier: "YOUR_BUILDING_IDENTIFIER", ), onLoad: (MapViewController controller) => {} ); }
... // 1. Import the component import {MapView, SitumProvider} from '@situm/react-native'; const Screen: React.FC = () => { ... return ( ... {/* 2. Implement MapView in your component */} <SitumProvider> <MapView style={{height: '100%', width: '100%'}} configuration={{ // WARNING! Remember to authenticate with your credentials. // You might find helpful this guide https://situm.com/docs/03-built-in-wayfinding-ui#prepare-viewer situmApiKey: 'YOUR_APIKEY', buildingIdentifier: 'YOUR_BUILDING_IDENTIFIER', }} onLoad={(event: any) => {}} /> </SitumProvider> ... ); }; const App = () => <Screen />; export default App;
// index.html <html> ... <body> <!-- Add this component to your body --> <!-- Retrieve your situm api-key here https://dashboard.situm.com/accounts/profile --> <!-- Follow this guide (https://situm.com/docs/sdk-cartography/#building-identifier) to find out the identifier of the building you want to display --> <map-view viewer-domain="https://map-viewer.situm.com" situm-api-key="YOUR_APIKEY" building-identifier="YOUR_BUILDING_IDENTIFIER" /> <script src="cordova.js"></script> <script type="module" src="js/index.js"></script> </body> </html>
import UIKit import SitumSDK class ViewController: UIViewController, SITMapViewDelegate, SITLocationDelegate{ @IBOutlet weak var mapView: SITMapView! var mapViewController: SITMapViewController? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. initSDK() mapView.delegate = self // Load mapview controller let conf = SITMapViewConfiguration(buildingIdentifier: "", remoteIdentifier: "") mapView.load(with: conf) { controller, error in guard error==nil else{ print("Error loading map \(String(describing: error))") return } print("Map loaded properly") // Store controller // Assign for later updates self.mapViewController = controller } } func initSDK() { SITServices.provideAPIKey("APIKEY", forEmail: "EMAIL") // Check / request permissions SITLocationManager.sharedInstance().addDelegate(self) SITLocationManager.sharedInstance().requestLocationUpdates(nil) } // MARK: SITMapViewDelegate Methods func mapView(_ mapView: SITMapView!, didSelectedPoi poi: SITPOI!) { print("User selected poi: \(poi)") } func mapView(_ mapView: SITMapView!, didUnselectedPoi poi: SITPOI!) { print("User unelected poi: \(poi)") } // MARK: SITLocationDelegate Methods func locationManager(_ locationManager: SITLocationInterface, didUpdate location: SITLocation) { print("location received: \(location)") } func locationManager(_ locationManager: SITLocationInterface, didFailWithError error: Error?) { print("There was an error: \(error)") } func locationManager(_ locationManager: SITLocationInterface, didUpdate state: SITLocationState) { print("Status update received: \(state)") } }
class MapViewActivity : AppCompatActivity() { private lateinit var mapView: MapView private var mapViewController: MapViewController? = null private val buildingId = "BUILDING_IDENTIFIER" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_mapview) initSdk() mapView = findViewById(R.id.exampleMapView) val mapViewConfiguration = MapViewConfiguration.Builder().setBuildingIdentifier(buildingId) .setViewerDomain("https://map-viewer.situm.com").build() mapView.load(mapViewConfiguration, object : MapView.MapViewCallback { override fun onLoad(mapViewController: MapViewController) { this@MapViewActivity.mapViewController = mapViewController } override fun onError(error: Error) { Toast.makeText(baseContext, "Error: ${error.message}", Toast.LENGTH_LONG).show() } }) } private fun initSdk() { SitumSdk.init(this) SitumSdk.configuration().setApiKey( "EMAIL", "APIKEY" ) SitumSdk.locationManager().requestLocationUpdates( LocationRequest.Builder().useDeadReckoning(false).buildingIdentifier(buildingId).build() ) SitumSdk.locationManager().addLocationListener(object : LocationListener { override fun onLocationChanged(loc: Location) { // Do nothing. } override fun onStatusChanged(status: LocationStatus) { // Do nothing. } override fun onError(error: Error) { Toast.makeText(baseContext, "Error: ${error.message}", Toast.LENGTH_LONG).show() } }) } }
The vital part of the previous code snippet is to pass a MapViewConfiguration(Flutter, React Native, Cordova) to our component. This configuration contains the basic information you need to visualize your building inside your app. These are the most commonly used configurations (other configurations are also available, take a look at our API docs for Flutter, React Native and Cordova)
Parameter | Description |
---|---|
situmAPIKey | This parameter allows you to authenticate. You can obtain an API key by creating a new one at your profile. You should create a read-only API key. |
buildingIdentifier | This parameter will select the building that the MapView component will display. Follow this handy guide to find out the identifier. Note: this parameter does not configure the building where you want to retrieve geolocation. To do this, you’ll need to configure positioning as explained in this guide. |
remoteIdentifier | A string identifier that allows you to remotely configure all map settings. Typically, this will be a string such as “configuration_1234”. You can obtain yours by contacting support@situm.com. |
language | Sets the UI and cartography language based on the given ISO 639-1 code. MapViewer UI supports multiple languages like Arabian (ar), French (fr), Hebrew (he) and many other languages that you can find in the Situm docs. If your language is not supported, please write us at support@situm.com. MapViewer content can be translated into any language. See how to do it in this documentation. (Coming Soon) Android and iOS. Use remoteIdentifier instead. |
(Advanced usage only) viewerDomain | This parameter should ONLY be used for on-premise projects or under Situm’s guidance. It allows you to configure the URL domain that the MapViewer will display (by default: https://map-viewer.situm.com). |
Interacting with the visual component #
The previous section shows how to get the MapViewer up & running in your app and configure basic settings such as the building it will display or the language that it will use. For more advanced usages, you may want to interact with the MapViewer. In this regard, you can:
- Send actions to the MapViewer: receive as selecting a POI programmatically, changing the languange of the UI, moving the camera around the building…
- Receive events sent from the MapViewer: the user selecting a POI on the map, the user clicking on a URL link inside a POI description…
Sending actions to the MapViewer #
You can modify the MapViewer behaviour by sending actions to it. To do so, it is necessary to wait until the onLoad() method gets called: at this point, the map will be ready and initialized.
This method should be implemented like this:
... // Implement MapView in your Widget @override Widget build(BuildContext context) { return MapView( key: const Key("situm_map"), configuration: MapViewConfiguration( ... ), onLoad: (MapViewController controller) { // MapView was loaded correctly, // now you can send actions by using the MapViewController, for example: controller.selectPoi("123456"); // controller.navigateToPoi("123456", accessibilityMode: AccessibilityMode.CHOOSE_SHORTEST); // controller.setLanguage("fr"); // controller.followUser(); // ... // Learn how to correctly implement these actions at https://pub.dev/documentation/situm_flutter/latest/wayfinding/MapViewController-class.html }); } ...
// Importing dependencies import React, {useRef} from 'react'; import {SafeAreaView} from 'react-native'; import {MapView, MapViewRef, SitumProvider} from '@situm/react-native'; const Screen: React.FC = () => { const mapViewRef = useRef<MapViewRef>(null); ... return ( <SafeAreaView style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}> <SitumProvider> <MapView ref={mapViewRef} style={{height: '100%', width: '100%'}} configuration={{ ... }} onLoad={(event: any) => { // MapView was loaded correctly, // now you can send actions by using the MapViewController, for example: mapViewRef.current?.selectPoi(123456); // mapViewRef.current?.navigateToPoi({ // identifier: 123456, // accessibilityMode: AccessibilityMode.CHOOSE_SHORTEST, // }); // mapViewRef.current?.setDirectionsOptions({ // includedTags: ['tag_one', 'tag_two'], // excludedTags: ['tag_three'], // }); // ... // Learn how to correctly implement these actions at https://github.com/situmtech/react-native/blob/master/src/wayfinding/types/index.ts#L11 }} /> </SitumProvider> </SafeAreaView> ); }; const App = () => <Screen />; export default App;
// NOTE: Remember to specify your credentials in your <map-view> component of your index.html. // index.js document.addEventListener("deviceready", onDeviceReady, false); // Set the onLoad callback as soon as you can to send actions function onDeviceReady() { cordova.plugins.MapView.onLoad((controller) => { // MapView was loaded correctly, // now you can send actions by using the MapViewController, for example: controller.selectPoi(123456); // controller.navigateToPoi(123456, "CHOOSE_SHORTEST"); // controller.setLanguage("fr"); // ... // Learn how to correctly implement these actions at https://developers.situm.com/sdk_documentation/cordova/jsdoc/latest/mapviewcontroller }); }
@IBAction func optionsButtonPressed(_ sender: Any) { let options = SITMapViewDirectionsOptions(includedTags: ["TAG1", "TAG2"], excludedTags: ["EXCLUDE_TAG1", "EXCLUDE_TAG2"]) self.mapViewController?.setDirectionsOptions(options) }
Coming Soon
After the onLoad() method is called, we can start sending actions to MapViewer using the MapViewController (Flutter, React Native and Cordova). Take a look at all the posible actions available at the frameworks respective API references. The most prominent ones are:
Action | Description | Available in |
---|---|---|
selectPoi() | Allows to select a POI programmatically in your venue. This will cause the MapViewer to center the view on that POI and show its information. (Coming Soon) Android and iOS | Flutter, React Native, Cordova |
navigateToPoi() | Allows to navigate to POI programmatically in your venue. This will cause the MapView to start navigation mode displaying the route between the user’s location and the POI specified by parameters. (Coming Soon) Android and iOS | Flutter, React Native, Cordova |
setLanguage() | Changes the UI and cartography language based on the given ISO 639-1 code. Check the Situm docs to see the list of supported languages. See how to fully internationalize MapViewer content in this documentation. (Coming Soon) Android and iOS | Flutter, React Native, Cordova |
setDirectionsOptions() | Define the options that the routes calculated by the MapViewer will use. These options are includedTags and excludedTags. They are used to include or exclude the links of the path that contain the given tags. Follow this guide to learn how to set tags for your links. | Flutter, React Native, Android, iOS |
Receiving events from the MapViewer #
As mentioned before, you can also listen to events happening inside the MapViewer. Like when sending actions, you’ll need to wait for onLoad() method being called:
... // Implement MapView in your Widget @override Widget build(BuildContext context) { return MapView( key: const Key("situm_map"), configuration: MapViewConfiguration( ... ), onLoad: (MapViewController controller) { // MapView was loaded correctly, // now you can listen to events by using the MapViewController. for example: controller.onPoiSelected((poiSelectedResult) { debugPrint("POI(${poiSelectedResult.poi.identifier}) is selected"); }); controller.onPoiDeselected((poiDeselectedResult) { debugPrint("POI(${poiDeselectedResult.poi.identifier}) was deselected"); }); // Learn how to correctly implement these events at https://pub.dev/documentation/situm_flutter/latest/wayfinding/MapViewController-class.html }); } ...
// Importing Situm dependencies import {SafeAreaView} from 'react-native'; import { MapView, MapViewRef, OnPoiDeselectedResult, OnPoiSelectedResult, SitumProvider, } from '@situm/react-native'; const Screen: React.FC = () => { ... return ( <SafeAreaView style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}> <SitumProvider> <MapView style={{height: '100%', width: '100%'}} configuration={{ ... }} // For React-Native is not needed to wait until onLoad() is called to listen to events. onPoiSelected={(event: OnPoiSelectedResult) => { console.log( `POI(${event.identifier}) is now selected: ${JSON.stringify(event)}`, ); }} onPoiDeselected={(event: OnPoiDeselectedResult) => { console.log( `POI(${event.identifier}) is was deselected: ${JSON.stringify(event)}`, ); }} // Learn how to correctly implement these events at https://github.com/situmtech/react-native/blob/master/src/wayfinding/components/MapView.tsx#L68 /> </SitumProvider> </SafeAreaView> ); }; const App = () => <Screen />; export default App;
// NOTE: Remember to specify your credentials in your <map-view> component of your index.html. // index.js document.addEventListener("deviceready", onDeviceReady, false); // Set the onLoad callback as soon as you can to successfully listen to all events function onDeviceReady() { cordova.plugins.MapView.onLoad((controller) => { // MapView was loaded correctly, // now you can listen to events by using the MapViewController, for example: controller.onPoiSelected((poiSelectedResult) => { console.log( `POI(${poiSelectedResult.poi.identifier}) is now selected: ${poiSelectedResult}` ); }); controller.onPoiDeselected((poiDeselectedResult) => { console.log( `POI(${poiDeselectedResult.poi.identifier}) is was deselected: ${poiDeselectedResult}` ); }); // Learn how to correctly implement these events at https://developers.situm.com/sdk_documentation/cordova/jsdoc/latest/mapviewcontroller }); }
// MARK: SITMapViewDelegate Methods func mapView(_ mapView: SITMapView!, didSelectedPoi poi: SITPOI!) { print("User selected poi: \(poi)") } func mapView(_ mapView: SITMapView!, didUnselectedPoi poi: SITPOI!) { print("User unelected poi: \(poi)") }
Coming Soon
After implementing the onLoad() method, we can start listening to all the events happening inside the visual component using the MapViewController(Flutter, React Native and Cordova). You may take a look at all the posible actions available at the frameworks respective API references. Here we collect the most common ones:
Event | Description | Available in |
---|---|---|
onPoiSelected() | Get notified when a POI is selected. (Coming Soon) Android. | Flutter, React Native, Cordova, iOS |
onPoiDeselected() | Get notified when a previously selected POI is deselected. (Coming Soon) Android. | Flutter, React Native, Cordova, iOS |
onExternalLinkClicked() | Callback invoked when the user clicks on a link in the MapView that leads to a website different from the MapView’s domain. For example some POI description may contain a link to a video or a website, and if this callback is not set, the link will be opened in the system’s default browser by default. (Coming Soon) Android and iOS. | Flutter, React Native |