situm-cordova-plugin-official

Situm Cordova-based Plugin for hybrid apps.

Usage no npm install needed!

<script type="module">
  import situmCordovaPluginOfficial from 'https://cdn.skypack.dev/situm-cordova-plugin-official';
</script>

README

Situm Cordova Plugin · npm npm npm


Table of contents


Description

Situm Cordova Plugin is a set of utilities that allow any developer to build Cordova location based apps using Situm's indoor positioning system. Among many other capabilities, apps developed with Situm Cordova Plugin will be able to:

  • Obtain information related to buildings where Situm's positioning system is already configured: floorplans, points of interest, geotriggered events, etc.

  • Retrieve the location of the smartphone inside these buildings (position, orientation, and floor where the smartphone is).

  • Compute a route from a point A (e.g. where the smartphone is) to a point B (e.g. any point of interest within the building).

  • Trigger notifications when the user enters a certain area.


Capacitor compatibility

This plugin is compatible with Capacitor 3.0

Issue: In iOS, there is a known issue with capacitor-cli 3.2.5 and static cordova plugins https://github.com/ionic-team/capacitor/issues/5142. To solve it use a different version of capacitor cli.


Setup your account

In this tutorial, we will guide you step by step to set up your first Cordova application using Cordova Situm Plugin. Before starting to write code, we recommend you to set up an account in our Dashboard (https://dashboard.situm.es), retrieve your API KEY and configure your first building.

  1. Go to the sign in form and enter your username and password to sign in.

  2. Go to the account section and on the bottom, click on “generate one” to generate your API KEY.

  3. Go to the buildings section and create your first building.

  4. Download Situm Mapping Tool in Play Store (Only Android devices) and calibrate your building. Check out our user guide for detailed information.

  5. You are ready for building your own Cordova applications. Please check next steps about requirements


Installing pre-requisites

Configure cordova:

Cordova requirements:


Installing the plugin

In this we assume that you have already created an hybrid application with your favorite framework (Ionic, Phonegap, Appcelerator, Telerik...). After that there are some different ways to install the plugin:

1) Manually from npm:

$ cordova plugin add situm-cordova-plugin-official

2) Defined in config.xml for automatic installation:

  <plugin name="situm-cordova-plugin-official" source="npm">

  </plugin>

3) With Cordova CLI utility from master (or another branch):

$ cordova plugin add https://github.com/situmtech/situm-cordova-plugin.git

* Please note that we are using Cocoapods in order to manage iOS dependencies, which means you might need to run pod repo update when trying to compile your app after updating our plugin

4) For Capacitor users:

npm install situm-cordova-plugin-official
npx cap sync

Android platform:

Situm SDK for Android now compiles and targets sdkVersion 31 (Android 12). To work properly on Android 12 devices and above, the host app must:

  • Target android api 31 or above. In your project config.xml file, add <preference name="android-targetSdkVersion" value="31" /> to the Android platform configuration.
  • Request the runtime permissions ACCESS_COARSE_LOCATION, BLUETOOTH_SCAN and BLUETOOTH_CONNECT (plus ACCESS_FINE_LOCATION if you are using Global Mode). Remember to also add them to the Android platform section of your config.xml file:
  <config-file parent="/manifest" target="AndroidManifest.xml">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- In Global mode -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
  </config-file>
  • Add android:exported="true" to all the intent-filtered components of your AndroidManifest.xml file. You can add the following configuration to your config.xml to automate this process:
  <edit-config
      file="app/src/main/AndroidManifest.xml"
      target="/manifest/application/activity[@android:name='MainActivity']"
      mode="merge">
    <activity android:exported="true"/>
  </edit-config>
  • Make sure the widget root element of your config.xml file declares the Android namespace:
  <widget id="..." version="..."
    ...
    xmlns:android="http://schemas.android.com/apk/res/android">
  • If you find problems, also make sure the Gradle JDK points to version 11 in your project configuration (recommended Android Studio embedded JDK).

Using the Plugin

Accessing plugin object

When device ready event is fired, global cordova variable is injected in namespace. Plugins are available in this variable: cordova.plugins. The Situm Cordova Plugin is autowired within this object.

So, all methods are called in the same way, e.g. 'setApiKey':

  cordova.plugins.Situm.setApiKey(email, apiKey);

Methods

- setApiKey

Log in into your Situm Account. This key is generated in Situm Dashboard. Return true if apiKey was set successfully, otherwise false

  setApiKey("your_email@domain.com", "YOUR_API_KEY");

- setUserPass

Provides user's email and password.

  setUserPass("email@domain.com", "ourPassword");

- setCacheMaxAge

Sets the maximum age of a cached response in seconds.

  setCacheMaxAge(200);

- startPositioning

Starts the positioning on the locationRequest, a building should be sent as the first parameter and a locationOptions should be sent as the second one. Returns a set of locationStatus and location through the success callback.

  startPositioning([building, locationOptions], position => {
    // position as location object
  }, (error) => {
    // If errors will come here
  });

- stopPositioning

Stop locationListener on current active listener.

  stopPositioning(() => {
    // Your code here
  }, (error) => {
    // If errors will come here
  });

- fetchBuildings

Download all the buildings for the current user.

  fetchBuildings((buildings) => {
    // Array of buildings
  }, (error) => {
    // If errors will come here
  });

- fetchFloorsFromBuilding

Download all the floors of a building.

  fetchFloorsFromBuilding(building, (floors) => {
    // Array of floors
  }, (error) => {
    // If errors will come here
  });

- fetchIndoorPOIsFromBuilding

Download the indoor POIs of a building.

  fetchIndoorPOIsFromBuilding(building, (pois) => {
    // Array of pois
  }, (error) => {
    // If errors will come here
  });

- fetchOutdoorPOIsFromBuilding

Download the outdoor POIs of a building.

  fetchOutdoorPOIsFromBuilding(building, (pois) => {
    // Array of pois
  }, (error) => {
    // If errors will come here
  });

- fetchEventsFromBuilding

Download the events of a building.

  fetchEventsFromBuilding(building, (events) => {
    // Array of Situm events
  }, (error) => {
    // If errors will come here
  });

- fetchPoiCategories

Get all POI categories, download and cache their icons asynchronously.

  fetchPoiCategories((poiCategories) => {
    // Array of POI cateogires
  }, (error) => {
    // If errors will come here
  });

- fetchMapFromFloor

Download the map image of a floor.

  fetchMapFromFloor (floor, (mapImage) => {
    // Map image as a bitmap
  }, (error) => {
    // If errors will come here
  });

- fetchPoiCategoryIconNormal

Get the normal category icon for a POICategory.

  fetchPoiCategoryIconNormal (poiCategory, (iconNormal) => {
    // Icon as a bitmap
  }, (error) => {
    // If errors will come here
  });

- fetchPoiCategoryIconSelected

Get the selected category icon for a POICategory.

  fetchPoiCategoryIconSelected (poiCategory, (iconSelected) => {
    // Icon as a bitmap
  }, (error) => {
    // If errors will come here
  });

- invalidateCache

Invalidate all the resources in the cache.

  invalidateCache((response) => {});

- requestDirections

Calculates a route between two points.

var directionsOptionsMap = new Object();
directionsOptionsMap["minimizeFloorChanges"] = true;
  requestDirections([building, from, to, directionsOptionsMap], (route) => {
    // Route Situm object
  }, (error) => {
    // If errors will come here
  });

- requestNavigationUpdates

Necessary step to request progress. Alone this method does not provide progress object. You must feed navigation API with location, as indicated on updateNavigationWithLocation section.

  var navigationOptions = new Object();
  navigationOptions["distanceToIgnoreFirstIndication"] = 0.3; // (Optional) meters;
  navigationOptions["outsideRouteThreshold"] = 10; // (Optional) meters;
  navigationOptions["distanceToGoalThreshold"] = 7; // (Optional) meters;
  navigationOptions["distanceToFloorChangeThreshold"] = 10; // (Optional) meters;
  navigationOptions["distanceToChangeIndicationThreshold"] = 5; // (Optional) meters
  navigationOptions["timeToIgnoreUnexpectedFloorChanges"] = 25000; // (Optional) milliseconds
  navigationOptions["indicationsInterval"] = 6000; // (Optional) milliseconds
  navigationOptions["timeToFirstIndication"] = 6000; // (Optional) milliseconds
  navigationOptions["roundIndicationsStep"] = 5; // (Optional) milliseconds

  requestNavigationUpdates([navigationOptions], (res: any) => {
    // Progress and other navigation status messages can be processed here  
  }, (error: any) => {
    // If errors will come here 
  });

- updateNavigationWithLocation

Usually, position variable should be one of the locations provided by the system on the startPositioning function.

  updateNavigationWithLocation([position], (result) => {
    // Result
  }, (error) => {
    // If errors will come here
  });

- removeNavigationUpdates

When you are no longer interested on Navigation Updates you should call this method to remove internal allocated resources.

  removeNavigationUpdates();

Run javascript tests

  1. Install mocha and expect.js:
npm install mocha --save
npm install expect.js --save
```
2. In js tests folder run: 
```javascript 
mocha test 

Dependencies

Use Cases

Here we will include some examples of tipical use cases resolved using this plugin.

Navigation: Guide an user through a route

This funcionality will allow you to draw a route between two points inside a building. You can obtain an static route with all the information you need, but also, Situm SDK provides a way to show the indications while you are going from one point to another. In this example we will show you how to get the indications.

This is a three-steps-functionallity, first we have to request indications so the route is calculated, then request the navigation updates (with the configured options) and then provide the new position every time we move along the route. Next you will find a code example step by step:

  • First is obtainingt the route:

  var directionsOptionsMap = new Object();
  // This defines if you want to take a minimum number of floor changes
  directionsOptionsMap["minimizeFloorChanges"] = true;
  // This chooses if the route needs to be suitable for wheelchairs
  // Possible values: CHOOSE_SHORTEST, ONLY_NOT_ACCESSIBLE_FLOOR_CHANGES, ONLY_ACCESSIBLE
  directionsOptionsMap["accessibilityMode"] = "CHOOSE_SHORTEST";
  // This defines the initial orientation in degrees
  directionsOptionsMap["startingAngle"] = 0.0;
  
  requestDirections([building, from, to, directionsOptionsMap], (route) => {
  
    // Route Situm object
    console.log(route["points"])
    console.log(route["indications"])
    
  }, (error) => {
  
    // If errors will come here
    console.log('An unexpected error has ocurred.')
    
  });
  

It will be received on the onSuccess callback of the requestDirections method. At this point, you will be able to draw the steps to represent the route.


  // This are some of the options for the navigation, check the docs for more
  var navigationOptions = new Object();
  navigationOptions["distanceToIgnoreFirstIndication"] = 0.3; // (Optional) meters;
  navigationOptions["outsideRouteThreshold"] = 10; // (Optional) meters;
  navigationOptions["distanceToGoalThreshold"] = 7; // (Optional) meters;
  navigationOptions["distanceToFloorChangeThreshold"] = 10; // (Optional) meters;
  navigationOptions["distanceToChangeIndicationThreshold"] = 5; // (Optional) meters
  navigationOptions["timeToIgnoreUnexpectedFloorChanges"] = 25000; // (Optional) milliseconds
  navigationOptions["indicationsInterval"] = 6000; // (Optional) milliseconds
  navigationOptions["timeToFirstIndication"] = 6000; // (Optional) milliseconds
  navigationOptions["roundIndicationsStep"] = 5; // (Optional) milliseconds

  requestNavigationUpdates([navigationOptions], (res: any) => {     
  
    if (res["type"] == "progress") {
    
        // Navigation progress can be processed here
        console.log(res["currentIndication"])
        console.log(res["distanceToGoal"])
        
    } else if (res["type"] == "destinationReached") {
    
        // Here you manage the event when the user reaches the goal of the route
        
    } else if (res["type"] == "userOutsideRoute") {
    
        // Here you manage the event when the user is outside of the route
        
    }
  }, (error: any) => {
  
    // If errors will come here 
    console.log('An unexpected error has ocurred.')
    
  });

Please note that in our first callback we are checking the type value in the result. this indicates if the object received is a NavigationProgress or an status update. When type is different from "progress" it means that your user has either reached it's destination or gone outside of the route. In both former cases you must stop the positioning. To recover from this event or start a new route you should call - requestNavigationUpdates again.

  • Then we update the navigation. Each time a new position is received through - startPositioning callback, it should be sent with this method to receive a new NavigationProgress:

  updateNavigationWithLocation([position], (result) => {
  
    // Progress will be managed in the requestNavigationUpdates callback
    
  }, (error) => {
  
    // If errors will come here
    console.log('An unexpected error has ocurred.')
    
  });

License

Situm-Cordova-Plugin is licensed under MIT License

More information

More info is available at our Developers Page.

Keep up to date about important changes in the README.md file of this project, or visit the official documentation to see more details.

Support information

For any question or bug report, please send an email to support@situm.es