Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents
printablefalse


SDK Setup

The SDK supports Android version 2.3.3 ("Gingerbread", API level 10) or higher and the following ABIs:

  • armeabi-v7a
  • arm64-v8a
  • x86
  • x86_64

In order to add the SDK library to your application insert the following code into your app's build.gradle:

...

Code Block
languagegroovy
repositories {
    flatDir {
        dirs '<the_path_to_navmiisdk_aar>'
    }
}

dependencies {
    compile (name: 'navmiisdk:<sdk_version>', ext: 'aar')
}

Add the following lines to the AndroidManifest.xml of your application within the <application></application> block:

Code Block
languagexml
<meta-data android:name="com.navmii.sdk.API_KEY" android:value="YOUR_API_KEY" />

Add the following lines to the AndroidManifest.xml within the <manifest></manifest> block:

...

Code Block
languagexml
<uses-feature android:name="android.hardware.location.gps" />

This version of Navmii SDK doesn't support working with multiple instances of MapView at the same time. The SDK supports only one visible MapView instance at a time. Displaying multiple instances of MapView will result in an undefined behaviour.

The key component of the SDK is a singleton instance of  the Sdk class, which can be received with Sdk.getInstance() static method. To initialize the Sdk and start map rendering use the static Sdk.initSdkAsync method. This method takes ConfigurationSettings as an argument. To deinitialize the SDK use the Sdk.deinitializeSdk method. The Sdk.pause and Sdk.resume methods only start and stop map rendering respectively, without initializing/deinitializing the SDK.

...

Code Block
languagejava
    @Override
    protected void onPause() {
        super.onPause();

        Sdk.getInstance().pause();
    }

    @Override
    protected void onResume() {
        super.onResume();

        Sdk.getInstance().resume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

		if (Sdk.getInstance().getState() == Sdk.State.INITIALIZING ||
                Sdk.getInstance().getState() == Sdk.State.INITIALIZED) {

            Sdk.getInstance().deinitializeSdk();
        }
    }


The ConfigurationSettings class represents the settings with which the SDK can be launched. If you have the resources designated to customize the map, you can specify the path to these resources via the setCustomResourcesPath method.

...

Code Block
languagejava
	        Sdk.ConfigurationSettings configurationSettings =
                new Sdk.ConfigurationSettings.Builder()
                        .setOfflineMapsPath(thePath)
                        .build();

When the SDK is configured to use online map data, it uses stable release maps by default. If you need more up-to-date map data, you can use Sdk.ConfigurationSettings.Builder.setUseOnlineBetaMaps(true) method to switch to beta maps. Please note that beta maps may contain errors which are not present in the release ones, therefore it's not recommended to use them in production.

If the SDK is configured to use offline map data, this method has no effect.

The SDK can have four possible states represented by the Sdk.State enum:

...

Code Block
languagejava
private class SdkStateListener implements Sdk.StateChangeListener {

    // Can only happen between onStart - onStop.
    @Override
    public void onStateChanged(Sdk.State state) {
        switch (state) {
            case UNINITIALIZED:
                break;
            case INITIALIZING:
                break;
            case INITIALIZED:
                break;
            case INITIALIZATION_FAILED:
                break;
        }
    }
}

private final Sdk.StateChangeListener stateChangeListener = new SdkStateListener();

@Override
public void onStart() {
    super.onStart();

    // Check - what if SDK initialization has failed between onStop - onStart.
    if (Sdk.getInstance().getState() == Sdk.State.INITIALIZATION_FAILED) {
        // Show an error message
    }

    Sdk.getInstance().addStateChangeListener(stateChangeListener);

Mapping

In order to add the map view to your activity, insert the following code into the layout file:

...

Code Block
languagejava
@Override
public void onStart() {
    super.onStart();

    MapView mapView = (MapView) findViewById(R.id.map_view);

	if (Sdk.getInstance().getState() == Sdk.State.INITIALIZED) {
	    Sdk.getInstance().setActiveMapView(mapView);
	}
}

@Override
public void onStop() {
	super.onStop();

	if (Sdk.getInstance().getState() == Sdk.State.INITIALIZED) {
	    Sdk.getInstance().setActiveMapView(null);
	}
}

You can transform Point representing a screen position of a point on the map to MapCoordinates object representing corresponding GPS location using MapView.getProjection method, which returns an instance of the MapProjection class, and the following code:

...


Code Block
languagejava
MapCoordinates coordinates = sdk.getNavigationManager().getCurrentPosition();
Point point = mapView.getProjection().screenPositionFromMapCoordinates(coordinates);

Note: south hemisphere latitudes are represented by negative values.

Typically, you want to adjust the area presented on the map on your app's events. You can do it by using MapView.getCameraController method, which returns an instance of the CameraController class, that can be used to move camera to a desired position. The camera position itself is represented in Navmii SDK as CameraPositionCameraPosition and CameraController allow you to perform the following operations:

...


Code Block
languagejava
mapView.stopAnimation();


The SDK can inform you about camera movements, if you have a class implementing the CameraMovementListener interface and have added an instance of this class to CameraController object's listeners.

...


Code Block
languagejava
// Adds ViewController to cameraController's listeners
mapView.getCameraController().addCameraMovementListener(new MapView.CameraMovementListener() {
    @Override
    public void onCameraMoved(CameraMovementReason reason) {
        Log.i("CameraMovementListener", "onCameraMoved, reason: " + reason);
    }
});


You also can add multiple listeners to a CameraController instance. To detach a listener use the removeCameraMovementListener method.

After being created and added to the view hierarchy, MapView is ready to receive the user's touch events. The map reacts to the following gestures as described with no extra code needed.

...

If you want to handle these gestures in your code please refer to Handling Camera Events section.

MapView recognizes the following gestures without a predefined behaviour. 

...

Code Block
languagejava
@Override
void onSingleTap(MapCoordinates coordinates) {
    // handle single tap
}

@Override
void onDoubleTap(MapCoordinates coordinates) {
    // handle double tap
}

@Override
void onLongTap(MapCoordinates coordinates) {
    // handle long tap
}

Navmii SDK provides an easy way to present custom images on the map and to draw polylines. Children classes of GeoObject abstract class represent these custom images (GeoMarker) and polylines (GeoPolyline) in the SDK. MapView instance is responsible for creating and handling this type of objects.

To present a marker on the map at specified coordinates with default image, instantiate it first by specifying its coordinates and the path to the image and then add it to the map using the MapView.addGeoObject method: 


Code Block
languagejava
GeoMarker marker = new GeoMarker(coordinates, imagePath);
mapView.addGeoObject(marker);


To draw a polyline on the map initialize, instantiate it with a list of MapCoordinates representing polyline vertices geo positions and then add it to the map:

Code Block
languagejava
GeoPolyline polyline = new GeoPolyline(coordinates);
mapView.addGeoObject(polyline);

You can insert and remove a point or multiple points into and from a polyline, using GeoPolyline's addVertex, removeVertexremoveLastVertex and removeAllVertices methods. To retrieve overall vertices count use the getVertexCount method. To get a copy of all vertices, use the getVertices method.

...


Code Block
languagejava
// Sets polyline color to red
polyline.setColor(Color.RED);
// Sets polyline width to 3dp
polyline.setWidth(3);


There are three types of user events related to GeoObject recognized by the SDK:

  • single tap on a geo object
  • double tap on a geo object
  • long press on a geo object

...

Code Block
languagejava
@Override
void onGeoObjectClick(GeoObject geoObject) {
    // handle click
}

@Override
void onGeoObjectPress(GeoObject geoObject) {
    // handle press
}

@Override
void onGeoObjectRelease(GeoObject geoObject) {
    // handle release
}

@Override
void onGeoObjectLongPress(GeoObject geoObject) {
    // handle long press
}


Routing

The core component responsible for working with routes and navigation in Navmii SDK is RoutingManager. This class's singleton instance allows you to calculate and apply single and multiple routes and receive all necessary navigation information.

If you have a list of MapCoordinates representing waypoints for a route, you can calculate the route (and alternative routes, if applicable) using a RoutePlan instance and calculateRoute method. Alternatively, use calculateRouteFromCurrentPosition method if you you want the route to be calculated from the user's current GPS position. This way you don't need to pass the current position coordinates as the first element in the list of waypoints.

...


Code Block
languagejava
// Creates a RoutePlan instance with waypoints
RoutePlan routePlan = new RoutePlan();
routePlan.setWaypoints(waypoints);
// Creates a NMRoutingSettings instance with pedestrian routing mode
RoutingSettings routingSettings = new RoutingSettings.Builder()
        .setRoutingMode(RoutingMode.PEDESTRIAN)
        .build();
// Applies the settings and calculates routes starting from the first coordinates in the array
sdk.getRoutingManager().calculateRoute(routePlan, routingSettings);
// Performs the same operation but starting with the user's current position
sdk.getRoutingManager().calculateRouteFromCurrentPosition(routePlan, routingSettings);


There are three possible RouteManager states that can be obtained with the getStatus method:

  • No routes are presented on the map (NO_ROUTE)
  • A route (or routes) is presented on the map, but the navigation hasn't started (CHOOSING)
  • A route is applied and navigation is in process (ROUTE_APPLIED)

The SDK can notify listeners on the following route calculation events:

...

Code Block
languagejava
sdk.getRoutingManager().removeRoutingListener(listener);

By default, the SDK calculates up to 3 routes with a particular route plan if possible and renders them on the map. You can disable this type of behaviour with the setDrawAlternativeRoutes method.

...


// Logs the numbers of routes and the selected route index
RoutingManager routingManager = sdk.getRoutingManager();
Log.i("RoutingManager", String.format("number of routes %s, selected route index %s", routingManager.getRouteCount(), routingManager.getSelectedRouteIndex()));

To select the route at the desired index use selectRouteAtIndex: method. The clearRoutes method removes all the calculated routes from the map. The abort method cancels route calculation that is currently in progress.

Navmii SDK allows you to customize the parameters that will be used for route calculation via RoutingSettings. You can define if the traffic will be taken into consideration and if toll roads and motorways will be avoided on route calculation:

...


Code Block
languagejava
RoutingSettings routingSettings = new RoutingSettings.Builder()
        .setRoutingMode(RoutingMode.VEHICLE)
        .setRoutingOptimization(RoutingOptimization.SHORTEST)
        .setVehicleType(VehicleType.TRUCK)
        .build();

Rerouting

When navigating on the route a better route can be calculated and the currently applied route changed. To enable/disable this option use the RoutingManager.setReroutingEnabled method. There are also two parameters you can specify defining when rerouting is triggered:

  • time difference with possible alternative route
  • length difference with possible alternative route

These parameters can be specified through the RoutingManager.setTimeThresholdForReroutingByTraffic and RoutingManager.setLengthThresholdForReroutingByTraffic methods respectively.


Code Block
languagejava
// Enables rerouting when a route 15 minutes faster or 10% shorter is calculated
sdk.getRoutingManager().setReroutingEnabled(true);
sdk.getRoutingManager().setTimeThresholdForReroutingByTraffic(15);
sdk.getRoutingManager().setLengthThresholdForReroutingByTraffic(10);

If you have added a RoutingListener to the RoutingManager, it will be notified on rerouting through onRouteCalculationSucceeded method. In this case the calculationReason parameter will be either REROUTING or REROUTING_CAUSED_BY_TRAFFIC.

Navigation

The main component responsible for navigation in Navmii SDK is NavigationManager. You can access an instance of this class via Sdk.getNavigationManager method:

...

Code Block
languagejava
@Override
void onWaypointPassed() {
    Log.i("NavigationListener", "onWaypointPassed");
}

@Override
void onArrivalPointReached() {
    Log.i("NavigationListener", "onArrivalPointReached");
}

The NavigationManager has the getGpsStatus method indicating if the SDK accepts GPS signal. GPS status is represented as GpsStatus enum of the following values:

...

Code Block
languagejava
            @Override
            public void onGpsStatusChanged(GpsStatus status) {
                Log.i("NavigationListener", "onGpsStatusChanged " + status);
            }

The user's current position can be retrieved via NavigationManager.getCurrentPosition method. 

...


Code Block
languagejava
            @Override
            public void onCurrentPositionChanged(MapCoordinates coordinates) {
                Log.i("NavigationListener", "onCurrentPositionChanged: " + coordinates);
            }


Navmii SDK allows you to demonstrate the way the real-time traverse of the route will look like on the screen. When the route is calculated, use startDemoRoute and stopDemoRoute methods. Use isDemoRouteActive method to find out if the demo route is still in progress.

...


Code Block
languagejava
    // Logs out messages on demo route start and finish
    @Override
    public void onDemoRouteStarted() {
        Log.i("NavigationListener", "onDemoRouteStarted");
    }

    @Override
    public void onDemoRouteFinished() {
        Log.i("NavigationListener", "onDemoRouteFinished");
    }

Navmii SDK also creates a bitmap image representing traffic on the current route. To be able to receive this image when it updates, make one of you classes implement the TrafficOnRouteImageListener interface and add an instance of this class to NavigationManager's "traffic on route image" listeners:


Code Block
languagejava
navigationManager.addTrafficOnRouteImageListener(listener);

To detach a "traffic on route image" listener use removeTrafficOnRouteImageListener method.


Code Block
languagejava
@Override
void onTrafficOnRouteImageUpdated(Bitmap bitmap) {
    // handle the image
}


When navigating on the route you can get a NavigationInfo instance from NavigationManager. This object will contain the following information:

...

Code Block
languagejava
NavigationInfo navigationInfo = navigationManager.getNavigationInfo();
Log.i("NavigationInfo", String.format("current road name - %s", navigationInfo.getCurrentRoad().getName()));
Log.i("NavigationInfo", String.format("next direction type - %s", navigationInfo.getNextDirection().getDirectionType()));
Log.i("NavigationInfo", String.format("distance to the next direction - %s meters", navigationInfo.getDistanceToDirection()));
Log.i("NavigationInfo", String.format("speed limit - %s kmh", navigationInfo.getSpeedLimit()));
Log.i("NavigationInfo", String.format("current speed - %s kmh", navigationInfo.getCurrentSpeed()));
Log.i("NavigationInfo", String.format("time to destination - %s seconds", navigationInfo.getTimeToDestination()));
Log.i("NavigationInfo", String.format("distance to destination - %s meters", navigationInfo.getDistanceToDestination()));
Log.i("NavigationInfo", String.format("passed distance - %s meters", navigationInfo.getPassedDistance()));
Log.i("NavigationInfo", String.format("country - %s", navigationInfo.getCountry().getName()));
Log.i("NavigationInfo", String.format("distance to speed camera - %s", navigationInfo.getDistanceToSpeedCamera()));


 A RoadInfo instance contains the following information on a road:

...


Code Block
languagejava
RoadInfo roadInfo = navigationInfo.getCurrentRoad();
Log.i("NavigationInfo", String.format("road name - %s", roadInfo.getName()));
Log.i("NavigationInfo", String.format("route number - %s", roadInfo.getRouteNumber()));
Log.i("NavigationInfo", String.format("form of way - %s", roadInfo.getFormOfWay()));
Log.i("NavigationInfo", String.format("functional class - %s", roadInfo.getFunctionalClass()));


Navmii SDK allows you to setup the way the navigation guidance will be provided. It's possible throughout the NavigationManager.getGuidanceSettings method. You can set the guidance output either to text or switch it off. If you pass GuidanceOutput.TEXT to the GuidanceSettings.setGuidanceOutput method, you'll be able to receive String instances with navigation guidance in NavigationListener.onGuidanceTextReady method.

...


Code Block
languagejava
// Sets guidance language to American English
GuidanceSettings settings = navigationManager.getGuidanceSettings();
settings.setLocale("en-US");


Currently supported languages:

  • Czech
  • Danish
  • English (UK)
  • English (US)
  • Finnish
  • French (France)
  • German
  • Italian
  • Korean
  • Norwegian
  • Polish
  • Portugese (Brazil)
  • Portugese (Portugal)
  • Russian
  • Spanish (Spain)
  • Swedish
  • Turkish

Places and coordinates

Geo locations in Navmii SDK are represented as instances of the read-only MapCoordinates class. As expected, it has two methods: getLatitude (returns values in the range [-90, 90]) and getLongitude (returns values in the range [-180, 180)). If the values passed to the constructor of MapCoordinates are out of their ranges, they will be adjusted automatically:

...

Code Block
languagejava
// Creates a MapRectangle by specifying top left and bottom right corners
MapCoordinates topLeft = new MapCoordinates(51.50884, -0.12924);
MapCoordinates bottomRight = new MapCoordinates(51.50754, -0.12699);
MapRectangle rectangle = new MapRectangle(topLeft, bottomRight);

// Creates a MapRectangle around all the coordinates in the array
MapCoordinates first = new MapCoordinates(51.50754, -0.12874);
MapCoordinates second = new MapCoordinates(51.50781, -0.12699);
MapCoordinates third = new MapCoordinates(51.50810, -0.12807);
MapCoordinates fourth = new MapCoordinates(51.50839, -0.12924);
MapCoordinates fifth = new MapCoordinates(51.50884, -0.12721);
MapRectangle boundingBox = MapRectangle.boundingRectangle(
        new MapCoordinates[]{first, second, third, fourth, fifth});


Navmii SDK provides a set of classes responsible for representation of addresses an places of interest (POIs). The most basic classes to represent geographical entities are CityState and CountryCity contains the following information on a city:

...

Code Block
languagejava
Log.i("Country", String.format("country ISO 3 code - %s", country.getIso3Code()));
Log.i("Country", String.format("country name - %s", country.getName()));
Log.i("Country", String.format("country speed units - %s", country.getInfo().getSpeedUnits()));
Log.i("Country", String.format("country distance units - %s", country.getInfo().getDistanceUnits()));
Log.i("Country", String.format("country driving side - %s", country.getInfo().getDrivingSide()));

The CityState and Country classes are aggregated into Address class. The Address also provides:

...

Code Block
languagejava
Log.i("Address", String.format("country name - %s", address.getCountry().getName()));
Log.i("Address", String.format("statename - %s", address.getState().getName()));
Log.i("Address", String.format("county name - %s", address.getCounty()));
Log.i("Address", String.format("city name - %s", address.getCity().getName()));
Log.i("Address", String.format("administrative hierarchy - %s", address.getAdminHierarchy()));
Log.i("Address", String.format("street name - %s", address.getStreet()));
Log.i("Address", String.format("route number - %s", address.getRouteNumber()));
Log.i("Address", String.format("house number - %s", address.getHouseNumber()));

When working with Navmii SDK search services you will also meet Place instances. They represent places of interest (POIs). A Place instance can provide you with the following info:

...

Code Block
languagejava
Log.i("Place", String.format("place name - %s", place.getName()));
Log.i("Place", String.format("place type - %s", place.getType()));
Log.i("Place", String.format("coordinates - %s", place.getCoordinates()));
Log.i("Place", String.format("address - %s, %s", place.getAddress().getStreet(), place.getAddress().getHouseNumber()));
Log.i("Place", String.format("is address approximated - %s", place.isAddressApproximated()));
Log.i("Place", String.format("POI category - %s", place.getPoiData().getPrimaryCategory()));

for (int category : place.getPoiData().getCategories()) {
    Log.i("Place", "POI belongs to category " + category);
}

Search

In Navmii SDK it is possible to search addresses and places. You can get a SearchManager instance via getSearchManager method in the Sdk singleton. SearchManager exposes several builders to create the objects needed to perform all possible lookups in the SDK.

...

Request has method start which takes the CompletionListener as an argument, allowing you to pass a listener, which will handle the search results if the request succeeds, or an error in case of failure. You also can cancel the request with the cancel method.

The fastest and the most lightweight request is CountryAndStateRequest. Use this request instead of the ReverseGeocodingRequest when you want to know only country and state at some coordinates. You can create a builder for this request with the SearchManager.createCountryAndStateRequest method. When you perform this search, a List<Place> containing a single item will be returned to the listener.

Code Block
languagejava
        Request countryStateRequest =
                searchManager.createCountryAndStateRequest(coordinates).build();

        countryStateRequest.start(new Request.CompletionListener() {
            @Override
            public void onRequestCompleted(Request request, List<Place> results) {
                Address countryAndState = results.get(0).getAddress();
                Log.i("CountryAndStateRequest",
                        String.format(
                                "Request completed: %s %s",
                                countryAndState.getCountry(),
                                countryAndState.getState()));
            }

            @Override
            public void onRequestFailed(Request request, RequestError error) {
                Log.i("CountryAndStateRequest", "Request failed: " + error);
            }
        });

If you want to get the address at some coordinates use ReverseGeocodingRequest. To create a builder for this request use the SearchManager.createReverseGeocodingRequest method.


Code Block
languagejava
        Request reverseGeocodingRequest =
                searchManager.createReverseGeocodingRequest(coordinates).build();

        reverseGeocodingRequest.start(new Request.CompletionListener() {
            @Override
            public void onRequestCompleted(Request request, List<Place> results) {
                Log.i("ReverseGeocodingRequest", "Request completed:");

                for (Place place : results) {
                    Log.i("ReverseGeocodingRequest", place.toString());
                }
            }

            @Override
            public void onRequestFailed(Request request, RequestError error) {
                Log.i("ReverseGeocodingRequest", "Request failed: " + error);
            }
        });

Note: if only country and state are relevant for your search please refer to Country and State Search.

You can perform search for Places of Interest (POIs) located within a search radius from some coordinates and containing a specified text string in their names. In order to do this use a PoiRequest instance created via theSearchManager.createPoiRequest. By default, the search is performed within the radius of 100 meters and among all POI categories. You can specify these parameters with setSearchRadius and setPoiCategories methods of the request's builder. Search results in the returned array will be sorted by distance (from closer to farther) from the search location.


Code Block
languagejava
        Request poiRequest = searchManager.createPoiRequest("cafe", coordinates).build();

        poiRequest.start(new Request.CompletionListener() {
            @Override
            public void onRequestCompleted(Request request, List<Place> results) {
                Log.i("PoiRequest", "Request completed:");

                for (Place place : results) {
                    Log.i("PoiRequest", place.toString());
                }
            }

            @Override
            public void onRequestFailed(Request request, RequestError error) {
                Log.i("PoiRequest", "Request failed: " + error);
            }
        });

You also can get coordinates for a String representing a particular address. In order to do this use a GeocodingRequest instance, which can be created using the SearchManager.createGeocodingRequest method.

...