Skip to main content
Version: Android SDK 2.0

VMSDK User Guide for Android 2.0

Welcome

image of example wayfinding map

Audience

VMSDK documentation is designed for people familiar with basic mobile development for Android. The latest generated docs for the Android SDK can be found here.

Supported Platforms

VMSDK supports Android 5.0+ (API 21). Consult your map provider’s documentation for their own supported platforms.

Install and run the reference app

  1. Make sure you have version Electric Eel (2022.1.1) or later of Android Studio.
  2. Download our sample app here.
  3. In the extracted directory, navigate to vmsdk-sampleapp and open it in Android Studio.
  4. The reference app uses the Google Maps SDK and the MapLibre SDK, so you will need to generate a Google API Key and generate a MapTiler API Key.
  5. Once you’ve generated a Google Maps API key and a MapTiler API Key, open src/main/res/values/strings.xml and update map_tiler_key and google_maps_key values.
  6. Build and run the app on the emulator or device.
caution

Using Google Maps with the VMSDK is not supported in some versions of the Android emulator. You will need to use a physical device for this.

Implement

Add the dependencies to your build.gradle

The vmsdk-core Maven package is required in your build.gradle file to use any features.

implementation 'com.aegirmaps:vmsdk-core:2.0.5'

You also need to include a reference to the Maven Central repository if your build.gradle if you don't already have one:

repositories {
mavenCentral()
}

Load the VMD file and display your map

Now you’re ready to write code to load the venue data info from the VMD file. Consult the example in the SDK demo: MapActivity.java.

To get started, create a VMDZipFileCollection to load the VMD data.

new VMDUrlFileCollection(
"https://your_vmd_endpoint.com",
"VENUE_ID",
cacheFolder,
MapProvider.GOOGLE_MAPS,
fileCollection -> {
//start parsing the VMD after files are downloaded (asynchronously)
Map.load(fileCollection, this, callback);
return null;
}
);

Implement the com.aegir.vmms.vmd.MapDelegate interface to be notified when the VMD isfinished loading.

/**
* Called when the VMD file is done loading SUCCESSFULLY
* @param vmd a Map object with venue object model and wayfinding data
*/
@Override
public void didFinishLoadingMap(Map vmd, CustomMapInfo customMapInfo)
{
// this is a good place to create your MapView and call the onCreate()
// method of that MapView instance.
this.mapView = new VectorMapView(this);
this.mapView.onCreate(this.savedInstanceState, this);
}

At this point, you should have a map display of the world with your map tiles superimposed.

Legacy Support

If you need to add support for parsing legacy venue map data files to your application, include the ‘vmsdk-legacy’ dependency in your project's build.gradle file. The SDK will automatically detect if it’s loading a zip file that contains legacy venue map data or new venue map data and process appropriately.

caution

Vector map tiles and wayfinding is not supported for legacy venue maps.

Customizing your map's look and feel

If you use vector map tiles, as opposed to raster map tiles, you have great flexibility in styling your map. For more information, see Vector Map Tile Style Spec.

Global map styling

The easiest way to style your map is to create a Map Style JSON configuration file that follows the Vector Map Tile Style Spec. For a full example, see style_default.json in the demo project.

//load your custom style from style_default.json configuration file
VMDAssetFile venueStyleConfig = new VMDAssetFile("style_default.json", getAssets());
VenueStyle venueStyle = new VenueStyle(venueStyleConfig,"venue_map_sample" );

//apply the style to your map
this.mapView.setStyle(venueStyle);

Styling individual map elements

You can now add custom styles to individual map elements. This allows you to override the overall map style defined in your map's VMVenueStyle configuration for a single element.

//get the map unit you want to style
MapUnit mapUnit = ... //some map unit
MapView mapView = ... // some mapview

//create your custom style
VenueLayerStyle style = new VenueLayerStyle();
style.setFillColor(Color.GREEN);
style.setOutlineColor(Color.RED);
//... see class documentation for a full list of styleable attributes

//apply the style to the unit. If the map unit is not visible, it will be
//applied the next time it is shown.
mapView.setStyleForMapUnit(style, mapUnit);

Responding to MapView events and callbacks

There are numerous ways to customize the behavior of your map view by responding to the following events:

Map loading will start

Before you can begin configuring your map view with its initial state, you must wait for internal setup to happen first. After that is complete, your app code will be notified in the delegate method below. In this method, you should call MapView.setupMap.

/**
* Called when map view will begin loading. You must NOT call MapView.setupMap
before this method has been called.
* @param map the MapView
*/
@Override
public void willStartLoadingMapView(MapView mapView);

Map loading complete

In some scenarios, you may want to wait until the map view has completed loading before proceeding to the next step. You can wait for the didFinishLoadingMapView callback.

/**
* Called when map view has finished loading so you can do any additional setup
* @param map the MapView
*/
@Override
public void didFinishLoadingMapView(MapView mapView);

Changes in map position

Anytime the map’s position changes, you can act accordingly.

caution

If your map view is overlaid on another provider's map (such as Google Maps), this is a good place to ensure the map positions stay in sync with each other.

/**
* @param newLocation the new map location
* @param newZoom the new map zoom
* @param newBearing the new map bearing
* @param newTilt the new map tilt
*/
@Override
public void didChangeCameraPosition(LatLng newLocation, float newZoom, double
newBearing, double newTilt);

Room selection/highlighting

When the user taps the map on a specific point or room, you can respond to those events appropriately. If you return true to canSelectUnit, the map will also highlight the selected shape using the color defined in your Map Style json for the layer-id of floor_selected_unit_[FLOOR]. See Customizing your map's look and feel above for more information.

/** 
* param mapUnit The map unit to check.
* @return Boolean indicating whether or not a map unit can be selected.
*/
Boolean canSelectUnit(MapUnit mapUnit);

/**
* Called when a map unit is selected on the map.
* @param mapUnit The map unit that was selected.
*/
void didSelectUnit(MapUnit mapUnit);

Adding your own annotations to the map view

You can programmatically add annotations to the map to suit your needs by creating a new PointAnnotation object and adding it to the map:

Bitmap icon = // custom icon;

PointAnnotation marker = new PointAnnotation();
marker.setFloorId(floor.getId()); //set the floor id to the VMMSBaseFloor
// object's uid that this marker belongs on

marker.setTitle(wp.getId()); //give it a title, which you can use to reference
//in additional callbacks

marker.setFloorNumber(floor.getFloorNumber());

marker.setPosition(target.getLocation()); //set the location you want the
//annotation to appear on the map

//If your MapView has usingDefaultMapProvider == true
marker.setIcon(IconFactory.getInstance(this).fromBitmap(icon));
//If your MapView has usingDefaultMapProvider == false
marker.setHtml(<div>Some html</div>);

this.mapView.addMarker(marker);
note

Custom annotations are implemented differently depending on whether your MapView has usingDefaultMapProvider set to true. If it is, then you can create a custom Bitmap to represent your map annotation. Otherwise, you will need to recreate your bitmap using HTML and CSS.

Responding to Errors that occur in the SDK

There are numerous instances where an error could occur within the VMSDK at any of the many steps above. You can be notified of the error by implementing any of the following callbacks:

VMD Parsing errors

If any errors are encountered while parsing your venue map data files, this method will be called within the SDK with more detailed information about the error:

/**
* Callback if the VMD file FAILS to load
* @param e the exception that was raised during load
*/
@Override
public void didFailToLoadMapWithError(Exception e)

Map display errors

If any errors are encountered when your map is loaded and rendered on screen through the MapView object, this method will be called within the SDK with more detailed information about the error:

/**
* Called when the map view fails to load
* @param mapView the MapView that failed to load
* @param ex the error that caused the failure
*/
@Override
public void didFailToLoadMapView(MapView mapView, Exception ex) {

Enable Wayfinding

You can add wayfinding capabilities to your map view to enable your application to provide turn-by-turn paths and directions:

If you want the waypath to be rendered on your map view, you'll have to create a VectorWalkingPathOverlay and add it to your mapview: ::note You have to wait until didFinishLoadingMapView is called to be able to set this!

//Create a new overlay that will display paths and markers for directions
this.walkingPathOverlay = new VectorWalkingPathOverlay(this.mapView);
//Set the delegate so this class can override certain functionality
this.walkingPathOverlay.setDelegate(this);
this.walkingPathOverlay.setMap(this.vmd);
.. and so on

Handle Wayfinding events

Implement the com.aegir.vmms.wayfinding.WayfindingDelegate interface to get notified of any callbacks from the SDK for wayfinding:

/**
* Callback after waypath has been determined
* @param path the Waypath that leads from the starting point to the ending point
*/
@Override
public void didFinishFindingWaypath(Waypath path);
/**
* Called after turn by turn directions are done
* @param turnByTurnDirections the list of directions
*/
@Override
public void didFinishCreatingTurnByTurnDirections(List<MapDirectionStep> turnByTurnDirections);

Override auto-generated wayfinding directions and landmark names

caution

This section is experimental

You can use map information from a JSON file to override the VMD’s auto-generated wayfinding directions and landmark names. See this full example: MapActivity.java.

The data contained in your wayfinding info override file must be in JSON format, according to the following specs:

{
"points": [
{
"id": "node_waypoint_b1_f1_517",
"public-description": "the edge of the Basketball Court"
},
{
"id": "<the ID of the waypoint>",
"public-description": "<the description you want for this
landmark/waypoint>"
}
],
"paths": [
{
"pathID": "node_path_b1_f1_722",
"p1": "node_waypoint_b1_f1_473",
"p2": "node_waypoint_b1_f1_567",
"description-d1": "along the sidewalk",
"description-d2": "along the sidewalk the other direction"
},
{
"pathID": "<the ID of the path>",
"p1": "<the ID of one of the waypoints>",
"p2": "<the ID of the other waypoint>",
"description-d1": "<description for traversing from P1 to P2>, leave
blank to auto-generate",
"description-d2": "<description for traversing from P2 to P1>, leave
blank to auto-generate"
}
]
}

Responding to wayfinding events and callbacks

Changing floors for wayfinding

When you have a waypath that spans multiple floors, the default behavior for MapView is to draw a button on the map that looks like this:

image of wayfinding button

You can provide your own image instead that matches your own branding. Additionally, when the user selects that button, you must implement that behavior as well by specifying what floor to change to, etc. See MapActivity.java for an example of how to appropriately respond to a floor change event.

/// Called to provide a custom image for the floor change annotation button
/// @param annotation the annotation
/// @return the custom image
@Override
public Bitmap imageForFloorChangeAnnotation(FloorChangePointAnnotation annotation);

/**
* Called when a floor annotation is selected. You should use this to
* update the floor that is visible on your mapview
* @param annotation
*/
@Override
public void didSelectFloorChangeAnnotation(FloorChangePointAnnotation annotation)

Responding to errors that occur in wayfinding

Wayfinding errors

Errors may occur during wayfinding, usually if no paths exist between your selected start & end destination. This method will be called within the SDK with more detailed information about the error:

/**
* Callback when wayfinding fails
* @param e the exception that was raised
*/
@Override
public void didFailToFindWaypathWithError(Exception e)
/**
* Callback when turn-by-turn fails
* @param e the exception that was raised
*/
@Override
public void didFailToCreateTurnByTurnDirectionsWithError(Exception e)

Customizing wayfinding look and feel

All styling for wayfinding is now done through new styling properties added in v1.1 to the “wayfinding” section of the Vector map tile spec.

Landmark customization

In the turn-by-turn directions provided by the SDK for wayfinding, there are usually points of interest, or landmarks, that are part of each step and refer to actual places on the map. You can add special icons to the map to further highlight your landmarks:

/**
* Called to provide a custom image for a landmark annotation
* @param annotation the annotation
* @return the custom image
*/
Bitmap imageForLandmarkAnnotation(LandmarkAnnotation annotation)s
caution

Landmark annotations are not currently supported if your MapView instance has usingDefaultMapProvider set to false.

More Information

For assistance with the Aegir VMSDK, related questions, or information about other Aegir products and services, visit https://support.aegirmaps.com/ or contact Aegir Support at [email protected].