Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents

Map view

Creating the Map View

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

Code Block
languagexml
<com.navmii.sdk.map.MapView
    android:id="@+id/map_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Then start the SDK with the Sdk.initSdkAsync static method and after successful initialization pass the map view to it using the setActiveMapView method. After MapView is no longer active you must call setActiveMapView(null).

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);
	}
}

GPS Coordinates – Screen Position Transformation

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 = mapView.getProjection().mapCoordinatesFromScreenPosition(point);

The reverse operation can be performed by MapProjection.screenPositionFromMapCoordinates:

Code Block
languagejava
Point point = mapView.getProjection().screenPositionFromMapCoordinates(coordinates);

For example, to retrieve current GPS position relative to the screen, you can use 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.

Working with Camera

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:

  • Setting map rotation via setHeading method

  • Setting map center via setTargetLocation method

  • Setting map zoom via setZoom method

  • Setting map tilt via setTilt method

The CameraPosition is instantiated with a builder:

Code Block
languagejava
CameraPosition cameraPosition =
        new CameraPosition.Builder(cameraController.getCameraPosition())
                .setTilt(tilt)
                .setHeading(heading)
                .setZoom(zoom)
                .build();

To move the camera to a position without animation use the CameraController.moveCamera method:

Code Block
languagejava
mapView.getCameraController().moveCamera(cameraPosition);

Alternatively, you can set the desired camera position with animation, using one of the three overloaded animateCamera methods. The first one only takes the position. The second one allows you to provide a listener implementing the CameraAnimationListener interface, which will be notified when the animation ends. The last method additionally takes the duration parameter, allowing you to specify the duration of the animation. The default duration is 0.3 seconds.

Code Block
languagejava
// Sets the map camera's position with duration of 1.5 seconds
// and logs the result when animation finishes or is canceled
cameraController.animateCamera(cameraPosition, 1.5f, new MapView.CameraAnimationListener() {
    @Override
    public void onAnimationEnded(boolean isCompleted, boolean isCanceled) {
        Log.i("CameraAnimationListener", "onAnimationEnded");
    }
});

To stop current animation use the MapView.stopAnimation method:

Code Block
languagejava
mapView.stopAnimation();

Handling Camera Events

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.

There can be three possible reasons for camera movement, defined in the CameraMovementReason enum:

  • gesture;

  • internal animation performed by the SDK (for example, during auto zoom);

  • animation requested by user (see Working with Camera for details).

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.

Map gestures

Gestures with Predefined Behaviour

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.

  • Pan gesture. To drag the map, touch the screen with one finger and hold. Move the finger in the desired direction.

  • Swipe gesture. To move the map with inertia, swipe the screen with one finger. The map will proceed to move in the same direction for a period of time depending on the velocity of the gesture.

  • Pinch gesture. Touch the screen with two fingers and hold. Increase and decrease the distance between them to zoom in and zoom out respectively. Depending on the velocity of the gesture the map can have zoom inertia.

  • Rotation gesture. Touch the screen with two fingers and hold. Rotate the fingers relative to the screen. This gesture also has inertia behaviour.

  • Tilt gesture. Touch the screen with two fingers and move them simultaneously up or down to change the camera tilt.

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

Gestures without Predefined Behaviour

MapView recognizes the following gestures without a predefined behaviour. 

  • Single Tap Gesture. Tap the map with one finger once.

  • Double Tap Gesture. Tap the map with one finger twice.

  • Long Press Gesture. Touch the screen with one finger and hold for a period of time.

To process these gesture events make one your classes implement the MapTapListener interface and add it to MapView map tap listeners using the following code:

Code Block
languagejava
mapView.addMapTapListener(listener);

You can add multiple map tap listeners to a MapView instance.

This way your object or objects will be notified on these gesture events via the following methods:

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
}

Geo Items

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.

Creating Markers on the Map

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);

Drawing Polylines

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);

Working with Polylines

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
// Adds a vertex to the polyline's end
polyline.addVertex(coordinates);
// Inserts a vertex into the polyline at index 3
if (polyline.getVertexCount() >= 3) {
    polyline.addVertex(3, coordinates);
}
// Removes last vertex from the polyline
polyline.removeLastVertex();
// Removes the vertex at index 3 from the polyline 
if (polyline.getVertexCount() >= 3) {
    polyline.removeVertex(3);
}
// Removes all vertices from the polyline
polyline.removeAllVertices(); 

The way the polyline is rendered on the map is also customizable. You can change the polyline's color and width using GeoPolyline's setColor and setWidth methods. The width property is a float value representing polyline's width in density-independent pixels (dp units).

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

Drawing Polygons on the Map

Polygons are defined using the GeoPolygon class, which is initialized in the same manner as a polyline, with a list of points:

Code Block
languagejava
GeoPolygon polygon = new GeoPolygon(coordinates);
mapView.addGeoObject(polygon);

In addition to methods for vertex manipulation, which are identical to those for polylines, there are also methods that allow changing the fill color, stroke color, and stroke width:

Code Block
languagejava
polygon.setFillColor(Color.RED);
polygon.setStrokeColor(Color.BLUE);
public void setStrokeWidth(4);

Drawing Circles on the Map

To draw a circle on the map, initialize an instance of the GeoCircle object with the following parameters:
- Center of the circle (MapCoordinates)
- Radius in meters
- Circle fill color
- Stroke color and stroke width in pixels.

Then add it to the map:

Code Block
languagejava
long radius = 100;
int fillColor = Color.LTGRAY;
int strokeColor = Color.BLACK;
float strokeWidth = 1.0f;

GeoCircle geoCircle = new GeoCircle(
	mapCoordinates, radius, fillColor, strokeColor, strokeWidth);
            
mapView.addGeoObject(geoCircle);

Interacting with Geo Objects

Editing geo objects

Circles and polygons can be made editable using setEditable(boolean) method. An editable object will be displayed with handles, which can be dragged in order to edit the object:

Screenshot_20231222-150030.png
Screenshot_20231222-151814.png

Listening to geo object events

There are four 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

  • modifying an editable geo object by dragging the handles displayed on it by the SDK

The first three events will only be called for clickable geo objects (markers, circles and polygons, for which setClickable(true) method has been called).

The last event will only be called for editable geo objects (circles and polygon, for which setEditable(true) method has been called). This event is called once when a user stops interacting with the object.

To be able to handle these events make one of your classes implement the GeoObjectListener interface and add an instance of this class to the map view's geo object listeners. Methods onGeoObjectClickonGeoObjectPressonGeoObjectRelease, onGeoObjectLongPress and onGeoObjectChanged will be called on these events:

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
}
			
@Override
public void onGeoObjectChanged(GeoObject geoObject) {
    // handle the event (for example, update a corresponding geofence)
}

Offline maps

Please check out the How to get offline maps article to find out how to obtain offline maps.

On how to make the SDK working with offline maps please refer to SDK setup (v2.1.x - Android) | SDKConfigurationSettings.