situm-capacitor-plugin-wayfinding v0.11.3
situm-capacitor-plugin-wayfinding
Situm Wayfinding Plugin for Capacitor has been designed to create indoor location applications in the simplest way. It has been built in the top of the Situm SDK.
Submitting Contributions
You will need to sign a Contributor License Agreement (CLA) before making a submission. Learn more here.
Configuration
First of all, you must configure your Capacitor project. This has been already done for you in the sample application, but nonetheless you can read the official Capacitor documentation.
Dont forget to add the platforms of your choice:
your/project/path$ npx cap add <platform>
Remember that this module implements the Android and iOS native interfaces but not the web interface as it is intended for use in mobile applications.
To install situm-capacitor-plugin-wayfinding
, add the next line to your package.json
file:
"dependencies": {
"situm-capacitor-plugin-wayfinding": "latest"
Then run npm install
and npx cap sync
to install packages, copy the web app build and Capacitor configuration file into the native platform project and update the native plugins and dependencies previously referenced:
your/project/path$ npm install && npx cap sync
In your project, add the HTMLElement that will hold the Situm Wayfinding Module (the map div):
<div id="situm-map"></div>
The size of this div
will be the size of the native module. That size must be greater than 0.
Note that right now it is not possible to modify the size or position of the native element, which affects both scrollable elements and screen rotations.
The native map will be drawn behind your HTML. Make sure the background of the parent HTML elements is transparent. For example, in ionic:
ion-content {
--background: none;
}
And finally in your Typescript layer, initialize the module:
const librarySettings = {
user: "YOUR_SITUM_USER",
apiKey: "YOUR_SITUM_APIKEY",
iosGoogleMapsApiKey: "YOUR_IOS_GOOGLE_MAPS_APIKEY",
buildingId: "YOUR_BUILDING_ID",
dashboardUrl: "https://dashboard.situm.com",
hasSearchView: true,
searchViewPlaceholder: "Capacitor WYF",
useDashboardTheme: false,
captureTouchEvents: true,
useRemoteConfig: false
};
await SitumWayfinding.load(element, librarySettings);
A common use case is to integrate this plugin in the lifecycle of a framework like Angular, React or Vue. I such cases, the framework may destroy and recreate the page on which the map div is defined (for example, after navigating). You must call load(HTMLElement element, ...)
as many times as you need to tell the plugin that the map div has changed (for example, at every call to ionViewDidEnter
if you are using Ionic's lifecycle callbacks). More information in the section Frameworks navigation.
Requirements:
Setup your Situm Account
You must set up an account in our Dashboard, retrieve your API KEY and configure your first building:
- Go to the sign in form and enter your username and password to sign in.
- Go to the account section and on the bottom, click on “generate one” to generate your API KEY.
- Go to the buildings section and create your first building.
- Download Situm Mapping Tool in Play Store (Only Android devices) and calibrate your building. Check out our user guide for detailed information.
Google Maps API KEY:
A Google Maps API KEY is required for this plugin to work. More info is available in the official Google Documentation. Make sure to enable your API KEY for the platforms of your choice.
- iOS: put your API KEY in the
LibrarySettings
object of this example app.
const librarySettings = {
...
iosGoogleMapsApiKey: "YOUR_IOS_GOOGLE_MAPS_APIKEY",
...
};
- Android: the Google Maps API KEY must be set in the
AndroidManifest.xml
file (that you will find in theandroid/src/main
folder) of your project.
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="YOUR_ANDROID_GOOGLE_MAPS_APIKEY"/>
Dependencies:
At this moment this module uses Capacitor Google Maps. Add this dependency to your package.json
to let Capacitor add the corresponding native project modules (a fork of the original repository):
"dependencies": {
"situm-capacitor-googlemaps-native": "0.0.3"
Android
This module depends on the Situm Wayfinding for Android visual component. You must add the Situm Repository to your project level build.gradle
file (again, in the android
folder of your project):
allprojects {
repositories {
maven { url "https://repo.situm.com/artifactory/libs-release-local" }
...
The location permission is required in your app level AndroidManifest.xml
:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
If you are targeting Android Pie devices (or above), add Apache Http Legacy to your AndroidManifest.xml
:
<uses-library
android:name="org.apache.http.legacy"
android:required="false"/>
Customization:
Colors
Use the parameter useDashboardTheme
of LibrarySettings
to decorate the whole WYF UI with your organization theme.
Positioning icons
Use the fields userPositionIcon
and userPositionArrowIcon
in LibrarySettings
to set the icons representing the user position (without and with orientation respectively).
The path is relative to the native android assets folder and iOS App folder. It was inspired in the results of npx cap sync
as you will see bellow. For example, for the following tree:
android/app/src/main/assets/
| ...
├── public/
| ...
| ├── images
| │ ├── dot_icon.png
| │ └── arrow_icon.png
...
ios/App/App/
| ...
├── public/
| ...
| ├── images
| │ ├── dot_icon.png
| │ └── arrow_icon.png
Will apply the following path:
// LibrarySettings:
const librarySettings = {
user: "YOUR_SITUM_USER",
...
userPositionIcon: "public/images/dot_icon.png",
userPositionArrowIcon: "public/images/arrow_icon.png"
};
You can manually copy the icons in your native projects, or manage them in the web side. For the latter, your assets folder will vary depending on the UI framework of your choice, for example:
- Angular: see the assets property for your build options in the documentation.
- Vue: see the public folder.
In both cases the execution of npx cap sync
will copy your assets to a predefined public
folder, as you can see in the following output:
$ npx cap sync
...
✔ Copying web assets from dist to android/app/src/main/assets/public
...
✔ Copying web assets from dist to ios/App/App/public
...
Check that folders after executing npx cap sync
to ensure you are setting the correct path to your icons.
Using or not a UI framework is up to you, the rule is to set a path relative to the native assets folders.
How does this plugin work?
The map div:
This plugin generates a native map view, and puts it under the browser (the map view is not an HTML element). You can specify the size and position of the map view using its containing <div>
(the map div).
The plugin changes the background of the map div to transparent in your application. If any other HTML element is displayed over or behind the map div, then it will cover the native map. For example, it is known that Ionic ion-content
will set a solid background to your contents, so if you put the map div inside an ion-content
element you will probably need to force its brackground to transparent:
...
<ion-content>
<div id="situm-map"></div>
...
</ion-content>
ion-content {
--background: none;
}
Touch events dispatching:
This plugin adds a native transparent layer over the map that will capture and handle every touch event of your app. Once the map is loaded:
- Every touch event inside the map bounds will be dispathed to the native map.
- Any HTML element inside the map div will also receive the same touch events:
<div id="situm-map">
<!-- The function onOverlayClick() will be called. -->
<div id="mapOverlay" (click)="onOverlayClick();"><p>HTML element</p></div>
</div>
- Any HTML element outside the map bounds will also receive the touch events.
- The plugin will not dispatch touch events to any HTML element defined outside the map div but inside the map bounds. You can use the method
setCaptureTouchEvents(false)
to prevent this and handle every touch event in your app. CallsetCaptureTouchEvents(true)
to return the control to the map.
Frameworks navigation
Common applications will probably use the navigation pattern established by some framework like Angular, React or Vue. It is possible for the framework to recreate the page on which the map div is defined (for example, when the page is removed from the stack). In such cases, the map div HTMLElement reference gets obsolete. As a consecuence, event delegation stops working properly when interacting with HTML elements displayed over the native map.
To solve this inconvenience you can call load(HTMLElement element, ...)
as many times as you need to refresh the underlying reference and make the plugin work as expected.
API
load(...)
unload()
onPoiSelected(...)
onPoiDeselected(...)
onFloorChange(...)
onNavigationRequested(...)
onNavigationFinished(...)
onNavigationError(...)
setCaptureTouchEvents(...)
selectBuilding(...)
selectPoi(...)
navigateToPoi(...)
navigateToLocation(...)
stopNavigation(...)
stopPositioning()
- Interfaces
load
load(settings: WayfindingSettings) => Promise<WayfindingResult>
Param | Type |
---|---|
settings | WayfindingSettings |
Returns: Promise<WayfindingResult>
unload
unload() => any
Returns: any
onPoiSelected
Get notified every time a Poi is selected.
onPoiSelected(callback: (data: OnPoiSelectedResult) => void)
// Example:
SitumWayfinding.onPoiSelected((result: OnPoiSelectedResult) => {
console.log(`Selected ${result.poiName} at ${result.buildingName}`);
});
Returns: void
onPoiDeselected
Get notified every time a Poi is deselected.
onPoiDeselected(callback: (data: OnPoiDeselectedResult) => void)
// Example:
SitumWayfinding.onPoiDeselected((result: OnPoiDeselectedResult) => {
console.log(`Deselected poi at ${result.buildingName}`);
});
Returns: void
onFloorChange
Get notified when the floor displayed in the map is changed.
onFloorChange(callback: (data: OnFloorChangeResult) => void)
// Example:
SitumWayfinding.onFloorChange((result: OnFloorChangeResult) => {
console.log(`Floor changed from ${result.fromFloorName} to ${result.toFloorName}`);
});
Returns: void
onNavigationRequested
Get notified when the navigation to a Poi
or Location
is requested.
onNavigationRequested(callback: (data: OnNavigationResult) => void)
// Example:
SitumWayfinding.onNavigationRequested((result: OnNavigationResult) => {
console.log(`Navigation requested to ${result.navigation.destination}.`);
});
Returns: void
onNavigationFinished
Get notified when the navigation to a Poi
or Location
finishes. Query NavigationResult.Navigation.status
to check if the route was canceled or the user reached the destination.
onNavigationFinished(callback: (data: OnNavigationResult) => void)
// Example:
SitumWayfinding.onNavigationFinished((result: OnNavigationResult) => {
console.log(`Navigation to ${result.navigation.destination} finished with status ${result.navigation.status}.`);
});
Returns: void
onNavigationError
Get notified when the floor displayed in the map is changed.
onNavigationError(callback: (data: OnNavigationResult) => void)
// Example:
SitumWayfinding.onNavigationError((result: OnNavigationResult) => {
console.log(`Navigation to ${result.navigation.destination} failed with error ${result.error}`);
});
Returns: void
setCaptureTouchEvents
Use this method to disable the capture of touch events. This is useful to enable events on HTML elements defined outside the map div.
setCaptureTouchEvents(options: CaptureTouchEvents)
Returns: void
selectBuilding
Use this method to select a building by identifier.
selectBuilding(building: Building)
Returns: Promise<void>
selectPoi
Use this method to select a POI using both building and POI identifiers.
selectPoi(poi: Poi)
Returns: Promise<void>
navigateToPoi
Use this method to request navigation to the given POI.
navigateToPoi(poi: Poi)
Returns: Promise<void>
navigateToLocation
Use this method to request navigation to a given location, in a given floor.
navigateToLocation(location: Point)
Returns: Promise<void>
stopNavigation
Use this method to stop navigation (if it was started).
stopNavigation()
Returns: Promise<void>
stopPositioning
Use this method to stop positioning. This method also stops navigation if it was started.
stopPositioning()
Returns: Promise<void>
Interfaces
WayfindingSettings
Prop | Type |
---|---|
mapId | any |
librarySettings | LibrarySettings |
screenInfo | ScreenInfo |
LibrarySettings
Prop | Type | Default |
---|---|---|
user | String | |
apiKey | String | |
iosGoogleMapsApiKey | String | |
buildingId | String | |
dashboardUrl? | String | |
hasSearchView | Boolean | true |
searchViewPlaceholder | String | |
useDashboardTheme? | Boolean | true |
userPositionIcon? | String | |
userPositionArrowIcon? | String | |
showPositioningButton? | Boolean | true |
captureTouchEvents? | Boolean | true |
useRemoteConfig? | Boolean | true |
showPoiNames? | Boolean | true |
lockCameraToBuilding? | Boolean | false |
enablePoiClustering? | Boolean | true |
maxZoom? | Number | 21 |
minZoom? | Number | 0 |
initialZoom? | Number | 18 |
ScreenInfo
Prop | Type |
---|---|
devicePixelRatio | Number |
x | Number |
y | Number |
width | Number |
height | Number |
OnPoiSelectedResult
Prop | Type |
---|---|
buildingId | String |
buildingName | String |
floorId | String |
floorName | String |
poiId | String |
poiName | String |
OnPoiDeselectedResult
Prop | Type |
---|---|
buildingId | String |
buildingName | String |
OnFloorChangeResult
Prop | Type |
---|---|
buildingId | String |
buildingName | String |
fromFloorId | String |
fromFloorName | String |
toFloorId | String |
toFloorName | String |
OnNavigationResult
Prop | Type |
---|---|
navigation | Navigation |
error? | Error |
Building
Prop | Type |
---|---|
id | String |
Point
Prop | Type |
---|---|
buildingId | String |
floorId | String |
latitude | String |
longitude | String |
Poi
Prop | Type |
---|---|
id | String |
buildingId | String |
Navigation
Prop | Type | Values |
---|---|---|
status | String | REQUESTED , ERROR , DESTINATION_REACHED , CANCELED |
destination | Destination |
Destination
Prop | Type | Values |
---|---|---|
category | String | POI , LOCATION |
identifier? | String | |
name? | String | |
point | Point |
Error
Prop | Type |
---|---|
code | String |
message | String |
CaptureTouchEvents
Prop | Type |
---|---|
captureEvents | Boolean |
SitumMapOverlays
Prop | Type |
---|---|
overlays | any |
SitumMapOverlay
Prop | Type |
---|---|
x | Number |
y | Number |
width | Number |
height | Number |
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago