The Mapwize Android SDK allows you to add indoor maps and way finding in your Android apps. After your map has been created in Mapwize Studio, you can use this SDK to display the map in your app and let the user interact with it.
This SDK only comes with the core MapView and API and is intended for the advanced Mapwize integrations. For a first integration of Mapwize in your project, please consider Mapwize UI and Mapwize UI Documentation.
If you are looking for a fully featured and ready to use Fragment to add Mapwize Indoor Maps and Navigation in your Android app, have a look at Mapwize UI and Mapwize UI Documentation. This open-source project enriches the core SDK with interfaces for search and directions, that you can use as is or modify to your taste.
We ourselves are using Mapwize UI to build the Mapwize app available on Google Play store.
Using external IDs is the best way to reference objects in your code. External IDs can be defined in Mapwize Studio for Venues and Places. With external IDs, you can easily change map content on the Studio side while avoiding any change in your code, for example promoting a beta venue to production. You can also specify multiple external IDs for a single object.
All methods that use an "ID" can take either an external ID or a Mapwize ID. But please note that Mapwize IDs are randomly generated and that the IDs will change in case of object copy or clone.
External IDs can be used in centerOnVenue
, centerOnPlace
, restrictContentToVenueId
, restrictContentToOrganization
options.
// Restrict content to organization
FrameLayout container = findViewById(R.id.container);
MapOptions options = new MapOptions.Builder()
.restrictContentToOrganization("MyOrganization")
.build();
mapwizeView = new MapwizeView(getApplicationContext(),
new MapwizeConfiguration.Builder(getApplicationContext(), "apiKey").build(),
options);
mapwizeView.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
));
container.addView(mapwizeView);
// Restrict content to multiple venues and center on a Venue
FrameLayout container = findViewById(R.id.container);
MapOptions options = new MapOptions.Builder()
.restrictContentToVenueIds(Arrays.asList("MyOrganization>>MyVenue","MyOrganization>>MyOtherVenue"))
.centerOnVenue("MyOrganization>>MyVenue")
.build();
mapwizeView = new MapwizeView(getApplicationContext(),
new MapwizeConfiguration.Builder(getApplicationContext(), "apiKey").build(),
options);
mapwizeView.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
));
container.addView(mapwizeView);
// Restrict content to one Venue and center on a Place
FrameLayout container = findViewById(R.id.container);
MapOptions options = new MapOptions.Builder()
.restrictContentToVenueIds(Arrays.asList("MyOrganization>>MyVenue","MyOrganization>>MyOtherVenue"))
.centerOnPlace("MyOrganization>>MyVenue>>MyPlace")
.build();
mapwizeView = new MapwizeView(getApplicationContext(),
new MapwizeConfiguration.Builder(getApplicationContext(), "apiKey").build(),
options);
mapwizeView.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
));
container.addView(mapwizeView);
The MapwizeApi methods getPlaceDetails
and getVenueDetails
can take an external ID as parameter. It allows you to retrieve information about Venues and Places
void getPlaceDetails(@NonNull String id,
@NonNull ApiCallback<PlaceDetails> callback);
void getVenueDetails(@NonNull String id,
@NonNull ApiCallback<VenueDetails> callback);
The method setPlaceStylesWithId
can take external IDs as key.
void setPlaceStylesWithId(@NonNull Map<String, Style> styleByPlace);
MapwizeSDK is compatible with Android api 21 and above.
In your root build.gradle
file, add the following maven repositories
repositories {
repositories {
...
maven { url "https://jitpack.io" }
maven { url "https://maven.mapwize.io"}
}
}
In the build.gradle
file of your app, add the Mapwize dependency.
dependencies {
implementation ("io.mapwize.sdk:mapwize-sdk:{lib-version}") {
transitive = true
}
}
As Mapbox is now compatible with java 8
, you have to add those lines to the build.gradle
in order to avoid errors at start.
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
You'll need a Mapwize API key to load the map and allow API requests. To get your own Mapwize API key, sign up for a free account at mapwize.io. Then within the Mapwize Studio, navigate to "API Keys" on the side menu.
In your MyApplication
class, you need to initialize the MapwizeConfiguration in the onCreate
method.
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
MapwizeConfiguration config = new MapwizeConfiguration.Builder(this, "YOUR_API_KEY").build();
MapwizeConfiguration.start(config);
}
}
Please make sure that your MyApplication
class is defined in your AndroidManifest.xml
<application
...
android:name=".MyApplication">
...
</application>
Mapwize is using Mapbox SDK to render the outdoor map. There are 2 options regarding the outdoor:
Mapbox
to create your own outdoor map style and customize it the way you want. This requires you to have a Mapbox subscription and set your Mapbox access token. In order to use this option, you need set your Mapbox styleUrl using the MapwizeConfiguration styleUrl
builder method.You can either inflate MapwizeView using an XML layout or instantiate it programmatically.
activity_create_map_using_xml.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CreateMapUsingXmlActivity">
<io.mapwize.mapwizesdk.map.MapwizeView
android:id="@+id/mapwizeView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
MapwizeApplication.java
public class MapwizeApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Mapwize globale initialization
MapwizeConfiguration config = new MapwizeConfiguration.Builder(this, "YOUR_API_KEY").build();
MapwizeConfiguration.start(config);
}
}
CreateMapUsingXmlActivity.java
public class CreateMapUsingXmlActivity extends AppCompatActivity {
MapwizeView mapwizeView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_map_using_xml);
mapwizeView = findViewById(R.id.mapwizeView);
mapwizeView.onCreate(savedInstanceState);
mapwizeView.getMapAsync((mapwizeMap) -> {
// Mapwize is fully loaded.
});
}
@Override
public void onStart() {
super.onStart();
mapwizeView.onStart();
}
@Override
public void onResume() {
super.onResume();
mapwizeView.onResume();
}
@Override
public void onPause() {
mapwizeView.onPause();
super.onPause();
}
@Override
public void onStop() {
mapwizeView.onStop();
super.onStop();
}
@Override
public void onSaveInstanceState(@NonNull Bundle saveInstanceState) {
super.onSaveInstanceState(saveInstanceState);
mapwizeView.onSaveInstanceState(saveInstanceState);
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapwizeView.onLowMemory();
}
@Override
public void onDestroy() {
mapwizeView.onDestroy();
super.onDestroy();
}
}
activity_create_map_programmatically.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CreateMapProgrammaticallyActivity">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
MapwizeApplication.java
public class MapwizeApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Mapwize globale initialization
MapwizeConfiguration config = new MapwizeConfiguration.Builder(this, "YOUR_API_KEY").build();
MapwizeConfiguration.start(config);
}
}
CreateMapProgrammaticallyActivity.java
public class CreateMapProgrammaticallyActivity extends AppCompatActivity {
MapwizeView mapwizeView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_map_programmatically);
FrameLayout container = findViewById(R.id.container);
MapwizeMapOptions options = new MapwizeMapOptions.Builder()
.build();
mapwizeView = new MapwizeView(getApplicationContext(), options);
mapwizeView.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
));
container.addView(mapwizeView);
mapwizeView.onCreate(savedInstanceState);
mapwizeView.getMapAsync((mapwizeMap) -> {
// Mapwize is fully loaded.
});
}
@Override
public void onStart() {
super.onStart();
mapwizeView.onStart();
}
@Override
public void onResume() {
super.onResume();
mapwizeView.onResume();
}
@Override
public void onPause() {
mapwizeView.onPause();
super.onPause();
}
@Override
public void onStop() {
mapwizeView.onStop();
super.onStop();
}
@Override
public void onSaveInstanceState(@NonNull Bundle saveInstanceState) {
super.onSaveInstanceState(saveInstanceState);
mapwizeView.onSaveInstanceState(saveInstanceState);
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapwizeView.onLowMemory();
}
@Override
public void onDestroy() {
mapwizeView.onDestroy();
super.onDestroy();
}
}
In order to work properly, the MapwizeView
needs to know about the life cycle of the related activity. Make sure to implement all life cycle methods : onStart, onResume, onPause, onStop, onSaveInstanceState, onLowMemory, onDestroy.
As the loading of the map can take some time, especially when large venues need to be loaded, it is advised to keep the map active when the screen is rotating or resizing instead of destroying and recreating it. To do so, the attribute android:configChanges="orientation|sreenSize"
can be added to the Activity definition in the AndroidManifest.xml
.
<activity
android:name=".MapActivity"
android:configChanges="orientation|screenSize">
...
</activity>
The map can be loaded with the following options available in the MapOptions class:
floor
to set the default floor when entering a venue. Floors are Double and can be decimal values.language
to set the default language for venues. language
is a string with 2 letters ISO 639-1 code like "en", "fr", "nl".universeId
to set the default universe for the displayed venue.restrictContentToVenueId
to show only the related venue on the map.restrictContentToVenueIds
to show only the related venues on the map.restrictContentToOrganizationId
to show only the venues of that organization on the map.centerOnPlaceId
to center on a place at start.centerOnVenueId
to center on a venue at start.logoClickable
If true, the Mapwize logo will display legals information on click. Default is true.All options can be used in your XML layout file.
It is also possible to specify a main color to tint all the controls on the map. To do so, add mapwize_main_color
in value/colors
in your app.
In some cases, you may want to display a map using a different API key than the one used at initialization. For example, you have displayed a first map for an organization A and you want to display another map for an organization B.
In these cases, you must use the MapwizeConfiguration#Builder
that returns a MapwizeConfiguration object. Once you have your MapwizeConfiguration
, you can use it in every Mapwize class that needs this object.
Note : If you want to inflate MapwizeView from an xml file, you have to use the MapwizeConfiguratio
singleton.
Listeners are provided for all kinds of events, from map click and venueEnter to FloorChange. Check the javadoc for more details.
In order to react to click events on the map, Mapwize provides an object that helps you know on which object the user clicked. It can be a venue, a place or mapwize coordinates.
It is represented with 3 event types :
public final static int MAP_CLICK = 0; // The user clicked on the map
public final static int PLACE_CLICK = 1;// The user clicked on a place
public final static int VENUE_CLICK = 2;// The user clicked on a venue
The following attributes can be retrieved :
int eventType; // Enum, see above
LatLngFloor latLngFloor; // The latLngFloor at which the click was made. The latitude and longitudes are always set, but the floor can be null. Available for all event types.
PlacePreview placePreview; // Not null if eventType == PLACE_CLICK
VenuePreview venuePreview; // Not null if eventType == VENUE_CLICK
A typical way to handle those event :
mapwizeMap.setOnClickListener(event -> {
switch (event.getEventType()) {
case ClickEvent.MAP_CLICK:
LatLngFloor llf = event.getLatLngFloor()
// Do something with LatLngFloor
break;
case ClickEvent.PLACE_CLICK:
PlacePreview placePreview = event.getPlacePreview()
// Do something with place
break;
case ClickEvent.VENUE_CLICK:
VenuePreview venuePreview = event.getVenuePreview())
// Do something with venue
break;
}
});
Displaying the user's location on the map is done by connecting an IndoorLocationProvider to Mapwize.
There are many IndoorLocation providers freely available as part of the IndoorLocation open-source framework.
If you can't find a corresponding provider to fit your needs, contact us at support@mapwize.io or build your own starting from the base classes.
To set the IndoorLocationProvider on the MapwizeMap:
public void setIndoorLocationProvider(@NonNull IndoorLocationProvider provider);
public void setIndoorLocationProvider(@NonNull IndoorLocationProvider provider, LocationComponentOptions userOnfloorOptions, LocationComponentOptions userOutOfFloorOptions, boolean showUserHeading);
To learn more about the LocationComponentOptions see Mapbox user location customization,
Our default values are :
onFloorLocationComponentOptions = LocationComponentOptions.builder(mapView.getContext())
.elevation(5)
.accuracyAlpha(.0f) // Hide the accuracy
.accuracyColor(Color.parseColor(mainColor)) // Use the main color (useless cause alpha = 0)
.foregroundTintColor(Color.parseColor(mainColor)) // Use the main color for the forground
.bearingTintColor(Color.parseColor(mainColor)) // Use the main color for the heading
.foregroundStaleTintColor(Color.parseColor(mainColor)) // Use the main color if the user location does not change for a while
.trackingGesturesManagement(true) // Allow the override of touch event action
.trackingAnimationDurationMultiplier(0.5f) // Change the animation duration when location change
.trackingInitialMoveThreshold(100) // Allow the user to touch the screen without removing the follow user mode
.trackingMultiFingerMoveThreshold(100) // Allow the user to multiple gesture without removing the follow user mode
.build();
outOfFloorLocationComponentOptions = LocationComponentOptions.builder(mapView.getContext())
.elevation(5)
.accuracyAlpha(.3f)
.accuracyColor(Color.GRAY)
.foregroundTintColor(Color.GRAY)
.bearingTintColor(Color.GRAY)
.foregroundStaleTintColor(Color.GRAY)
.trackingAnimationDurationMultiplier(0.5f)
.trackingInitialMoveThreshold(100)
.trackingMultiFingerMoveThreshold(100)
.build();
If you want to manually set the user location, you can use the ManualIndoorLocationProvider.
You can retrieve the current user position on the map using IndoorLocation getUserPosition()
and the user heading using Double getUserHeading()
methods.
There is no listeners provided for the user's new location changes. Subscribe to the IndoorLocationProvider's listener instead.
The user's heading is also displayed on the map as an arrow from the user position.
You can use the follow user mode feature to automatically move the map as the user location changes.
3 modes are provided by FollowUserMode enum class :
FollowUserMode.NONE
: the map does not move if the location changesFollowUserMode.FOLLOW_USER
: the map moves in order to keep the user position at the center. Zoom and rotation do not change.FollowUserMode.FOLLOW_USER_AND_HEADING
: the map moves and rotates in order to keep the user position in the center and the heading towards the top of the device.You can retrieve the current mode using the FollowUserMode getFollowUserMode()
method and you can set it using
public void setFollowUserMode(FollowUserMode followMode)
The FollowUserMode is automatically set to NONE
when the user manually moves the map or changes the floor.
Indoor maps are defined inside venues. The map will automatically enter in a venue when the zoom is sufficient, and exit the venue when the map is moved away. Only one venue can be open at a time.
The currently displayed venue can be retrieved using the getVenue
method
public Venue getVenue();
The method returns null if no venue is displayed on the map. Listeners are available to listen to enter and exit venues' events.
Venues can have multiple universes. Universes are like views. In Mapwize Studio, it is possible to define which elements are displayed in which universe and define security policies for each of them.
When a venue is displayed, the method Universe getUniverse()
will return the currently displayed universe for the current venue.
You can set and get the universe for each venue using
public void setUniverse(@NonNull Universe universe);
public void setUniverseForVenue(@NonNull Universe universe, @NonNull Venue venue);
public Universe getUniverseForVenue(@NonNull Venue venue);
Venues usually have multiple floors. Floors are identified by a Double and can be decimal.
When a venue is displayed, the method Floor getFloor()
will return the currently displayed floor for that venue and List<Floor> getFloors()
will return the list of active floors for that venue. A floor is considered active if the geometry of one layer of that floor is intersecting with the visible region on the screen.
You can change the floor using
public void setFloorForVenue(@NonNull Double floor, @NonNull Venue venue);
public void setFloor(Double floor);
The OnFloorWillChange
event is fired when the SDK starts loading floor content.
The OnFloorChange
event is fired when the floor data are loaded.
The OnFloorsChange
event is fired when the list of active floors changes, which may or may not happen at venue enter, venue exit or universe change.
The title of the places that are displayed on the map can be translated to multiple languages and you can control what language is used.
Firstly, you can set the preferred language of the user. By default, titles will be displayed in the preferred language if available in the venue. Otherwise, the main language of the venue is used.
public void setPreferredLanguage(@NonNull String language);
public String getPreferredLanguage();
It is also possible to specify what language to use for a specific venue and get the displayed language for the current venue.
public void setLanguageForVenue(@NonNull String language, @NonNull Venue venue);
public String getLanguage();
Markers are a convenient way to add simple pins on the map.
Mapwize Markers are not attached to a specific venue and will be displayed even if the venue is not visible.
If you want to add more complex annotations on the map, you have all the power of Mapbox at your disposal. Have a look at their documentation
By default, the image used for the pin is the standard Mapwize pin. However, you can specify your own using a Mapbox Icon.
Marker addMarker(@NonNull LatLngFloor latLngFloor);
Marker addMarker(@NonNull LatLngFloor latLngFloor, @NonNull String markerIconName);
Marker addMarker(@NonNull Place place);
Marker addMarker(@NonNull Place place, @NonNull String markerIconName);
void addMarkers(@NonNull Placelist placelist, @NonNull OnMarkersAdded callback);
void addMarker(@NonNull Placelist placelist, @NonNull String markerIconName, @NonNull OnMarkersAdded callback);
void removeMarker(@NonNull Marker markerCoordinate);
interface OnMarkersAdded<T> {
void getMarkersAsync(T markers);
}
The title of places are displayed based on the zoom level. The objective is to display as many as possible without having collisions. By default, the order specified in Mapwize Studio is used to define which place is displayed first.
However, there are situations where you would like to dynamically change the order. For example, if the user clicks on a place and you display some information about it, you might want to make sure that the title of that place stay displayed with different zoom levels. Basically, you want to promote that place to the first position.
Promoting places make them be displayed on top of other places on the rendering. Of course, the collision mechanism still apply if two promoted places collide, so only the first place in the promoted places list will be displayed on top. Also, promoted places are only shown on their floor and only when their venue are visible.
void addPromotedPlace(@NonNull Place place);
void addPromotedPlaces(@NonNull List<Place> places);
void addPromotedPlaces(@NonNull Placelist placelist, @NonNull OnPlacesPromoted callback);
void removePromotedPlace(@NonNull Place place);
void removePromotedPlaces(@NonNull List<Place> places);
void removePromotedPlaces(@NonNull Placelist placelist);
void removePromotedPlaces();
interface OnPlacesPromoted {
void getPlacesAsync(@NonNull List<Place> places);
}
Selecting a place allows you to highlight a specific place to make it more visible for the user.
Only one place can be selected at a time. Selecting another place while the first one is still selected will deselect the first one.
A selected place remains visible regardless of the zoom level of the map.
To display directions on the map, the first step is to compute them then you can show them. To compute the direction, you'll need to use the API methods to get a Direction object as described in the API section.
void getDirection(@NonNull DirectionPoint from,
@NonNull DirectionPoint to,
DirectionMode directionMode,
@NonNull final ApiCallback<Direction> callback);
Once you have a Direction object, you can display it on the map using
public void setDirection(@NonNull Direction direction);
public void setDirection(@NonNull Direction direction, @NonNull DirectionOptions options);
The first method will use default DirectionOptions.
Here is the list of options with their default value:
String startMarkerIconName = null;
String endMarkerIconName = "mapwize_default_marker_icon";
boolean displayStartMarker = false;
boolean displayEndMarker = true;
boolean centerOnStart = true;
boolean displayStartingFloor = true;
You can retrieve the displayed direction using
public Direction getDirection();
Please note that the direction will only be available after the navigationDidStart
listener is fired.
And you can remove the direction by setting it to null
or by using
public void removeDirection();
Navigation is used to display a direction between the user location to her destination.
void startNavigation(@NonNull DirectionPoint to, DirectionMode directionMode, @NonNull DirectionOptions options, @NonNull OnNavigationUpdateListener onNavigationUpdateListener) throws NavigationException;
void stopNavigation();
public interface OnNavigationUpdateListener {
boolean shouldRecomputeNavigation(@NonNull NavigationInfo navigationInfo);
void navigationWillStart();
void navigationDidStart();
}
Mapwize can recompute the IndoorLocation whenever the user is too far from the direction path shown on the map.
You can use NavigationInfo
object provided by shouldRecomputeNavigation
to recompute direction if needed.
NavigationInfo
contains 3 parameters :
double duration
: the remaining time until the user reaches the end of the directiondouble distance
: the remaining distance until the user reaches the end of the directiondouble locationDelta
: the difference between the user location reported by your indoorlocation provider and the location displayed on the screen. This property can be used to to recompute the direction if the user moves to far from the direction path shown on the map.Using the NavigationInfo
object in the shouldRecomputeNavagation
method, you can tell the SDK to recompute the Direction
by returning true
.
If you want to show that a meeting room is available, then, dynamic styling of places is what you are looking for.
You can overwrite the style of any place at any time using the setPlaceStyle
function. Set the style to null
to return to the default style.
void setPlaceStyle(@NonNull Place place, @Nullable Style style);
void setPlaceStyleWithId(@NonNull String placeId, @Nullable Style style);
void setPlacesStyleWithIds(@NonNull Map<String, Style> styleByPlaceId);
void setPlacesStyle(@NonNull Map<Place, Style> styleByPlace);
void setPlaceStyle(@NonNull List<Place> places, @Nullable Style style);
void removeAllCustomStyle();
The available attributes for the style are
title
the title displayed for this place (String)iconUrl
the name of the image that will be used to display the place icon (String)fillColor
the color of the inside of the polygon. Only used if the place is a polygon. (String with format "#000000")strokeColor
the color of the border of the polygon. Only used if the place is a polygon. (String with format "#000000")fillOpacity
the opacity of the inside of the polygon. Only used if the place is a polygon. (Double between 0 and 1)strokeOpacity
the opacity of the border of the polygon. Only used if the place is a polygon. (Double between 0 and 1)strokeWidth
the width of the border of the polygon. Only used if the place is a polygon. (Double positive)isMarkerDisplay
defines if the markerCoordinate of the place is displayed or not. (Boolean default true)isShapeDisplay
defines if the shape of the place is displayed or not. (Boolean default true)Maps can be made available offline using the OfflineManager. When offline, the following features are available:
Data is downloaded for specific universes of specific venues.
If a venue/universe has been downloaded offline, all the data for that venue/universe will come from the local database regardless the network availability. Changes made to the venue map on Mapwize Studio will not be available in the app until a new download is done. It is the developer's responsibility to trigger venue re-downloads.
To limit the size of the data downloaded on the device, it is possible to specify a minZoom and a maxZoom. For raster layers, only the tiles in that zoom range will be downloaded. The map can still be seen at any zoom level but graphics might appear pixelated. By default, minZoom = 16
and maxZoom = 21 or 23
depending on the surface of the venue. For raster layers, the size of zoom n+1
is usually about 4x
the size of the zoom n
. When a minZoom
and maxZoom
have been used for a venue/universe, they cannot be changed. The only option is to delete the offlineRegion and download it again with the new parameters.
To download content for a specific universe of a specific venue and make that veenue/univrse available offline, use downloadData
:
public void downloadData(Venue venue, Universe universe, DownloadTaskListener listener)
public void downloadData(Venue venue, Universe universe, int minZoom, int maxZoom, DownloadTaskListener listener)
To update the local data for a venue, the same downloadData
method can be used again.
You can also use the following method to check if an update is available
public void checkForUpdate(@NonNull OfflineRegion offlineRegion, @NonNull CheckForUpdateCallback callback)
then, you can use this method to update it
public void updateData(OfflineRegion offlineRegion, DownloadTaskListener listener)
If a venue/universe does not need to be offline anymore, the removeData
method can be used to delete all the offline data from database and filesystem.
public void removeData(@NonNull OfflineRegion offlineRegion, @NonNull RemoveDataCallback callback)
Note: After removing or downloading data, displayed maps need to be refreshed using MapwizeMap#refresh(Venue venue, Universe universe). Otherwise, the map might not display properly or might be inconsistent.
The following methods allow you to check which venues and universes are available offline.
public boolean hasOfflineRegion(Venue venue, Universe universe)
public OfflineRegion getOfflineRegion(Venue venue, Universe universe)
public List<OfflineRegion> getOfflineRegions()
A complete set of functions are available to query raw Mapwize objects.
Some API functions are available offline if the venue and universe was downloaded using the MapwizeOfflineManager.
The API behavior is as follows:
private final String venueId;
private final String universeId;
private final Boolean isVisible;
private final String alias;
private final String name;
private final Double floor;
private final String organizationId;
private final Double latitudeMin;
private final Double latitudeMax;
private final Double longitudeMin;
private final Double longitudeMax;
private String query;
private String venueId;
private String organizationId;
private String universeId;
private String[] objectClass;
Access requests are not available offline.
Access can be granted at runtime by calling the Api
directly :
public static void getAccess(@NonNull String accessKey, @NonNull final ApiCallback<Boolean> callback);
After using this method, you have to refresh the MapwizeMap manually using MapwizeMap.refresh(OnAsyncTaskReady callback);
You can also call the grantAccess method on the MapwizeMap
. This method handles the Api call as well as the map refresh.
public static void grantAccess(@NonNull String accessKey, @NonNull final ApiCallback<Boolean> callback);
You can also sign in (and sign out) with the following methods. Sign in will give you all the access that you have on your account on the Mapwize studio
public static void signin(@NonNull String token, @NonNull ApiCallback<Boolean> callback)
public static void signout(@NonNull ApiCallback<Boolean> callback)
Once connected, you can get the user information with the following method:
public static void getUserInfo(@NonNull ApiCallback<UserInfo> callback)
public static void getVenue(@NonNull String id, @NonNull ApiCallback<Venue> callback);
public static void getVenueWithAlias(@NonNull String alias, @NonNull ApiCallback<Venue> callback);
public static void getVenueWithName(@NonNull String name, ApiCallback<Venue> callback);
public static void getVenues(@NonNull ApiFilter apiFilter, ApiCallback<List<Venue>> callback);
public static void getPlace(@NonNull String id, @NonNull ApiCallback<Place> callback);
public static void getPlaceWithAlias(@NonNull String alias, @NonNull Venue venue, @NonNull ApiCallback<Place> callback);
public static void getPlaceWithName(@NonNull String name, @NonNull Venue venue, @NonNull ApiCallback<Place> callback);
public static void getPlaces(@NonNull ApiFilter apiFilter, @NonNull ApiCallback<List<Place>> callback);
ConnectorPlaces are not available offline
public static void getConnectorPlaces(@NonNull ApiFilter apiFilter, @NonNull ApiCallback<List<ConnectorPlace>> callback);
public static void getConnectorPlaceWithAlias(@NonNull String alias, @NonNull Venue venue, @NonNull ApiCallback<ConnectorPlace> callback);
public static void getConnectorPlaceWithName(@NonNull String name, @NonNull Venue venue, @NonNull ApiCallback<ConnectorPlace> callback);
public static void getConnectorPlace(@NonNull String id, @NonNull ApiCallback<ConnectorPlace> callback);
public static void getPlaceList(@NonNull String id, @NonNull ApiCallback<Place> callback);
public static void getPlaceListWithAlias(@NonNull String alias, @NonNull Venue venue, @NonNull ApiCallback<Place> callback);
public static void getPlaceListWithName(@NonNull String name, @NonNull Venue venue, @NonNull ApiCallback<Place> callback);
public static void getPlaceLists(@NonNull ApiFilter apiFilter, @NonNull ApiCallback<List<Place>> callback);
public static void getMainFromForVenue(@NonNull String venueId, @NonNull ApiCallback<List<Place>> callback);
public static void getMainSearchesForVenue(@NonNull String venueId, @NonNull ApiCallback<List<MapwizeObject>> callback)
Layers are not available offline.
public static void getLayer(@NonNull String id, @NonNull ApiCallback<Layer> callback);
public static void getLayerWithName(@NonNull String name, @NonNull Venue venue, @NonNull ApiCallback<Layer> callback);
public static void getLayers(@NonNull ApiFilter apiFilter, @NonNull ApiCallback<List<Layer>> callback);
public static void getStyleSheet(@NonNull String id, @NonNull ApiCallback<StyleSheet> callback);
public static void getUniverses(@NonNull ApiFilter apiFilter, @NonNull ApiCallback<List<Universe>> callback);
public static void getUniverse(@NonNull String id, @NonNull ApiCallback<Universe> callback);
public static void getAccessibleUniverseForVenue(@NonNull String venueId, @NonNull ApiCallback<List<Universe>> callback);
interface OnUniverseChangeListener {
void onUniversesChange(@NonNull List<Universe> universes);
void onUniverseWillChange(@NonNull Universe universe);
void onUniverseChange(@Nullable Universe universe);
void onUniverseChangeError(@NonNull Universe universe, @NonNull Throwable error);
}
Directions with waypoints and mutliple "To" parameters are not available offline.
public static void getDirection(@NonNull DirectionPoint from, @NonNull List<? extends DirectionPoint> to, @NonNull List<? extends DirectionPoint> waypoints, boolean isAccessible, boolean waypointOptimize, @NonNull ApiCallback<Direction> callback);
public static void getDirection(@NonNull DirectionPoint from, @NonNull DirectionPoint to, @NonNull List<? extends DirectionPoint> waypoints, boolean isAccessible, boolean waypointOptimize, @NonNull ApiCallback<Direction> callback);
public static void getDirection(@NonNull DirectionPoint from, @NonNull List<? extends DirectionPoint> to, boolean isAccessible, @NonNull ApiCallback<Direction> callback);
public static void getDirection(@NonNull DirectionPoint from, @NonNull DirectionPoint to, boolean isAccessible, @NonNull ApiCallback<Direction> callback);
Distances are not available offline.
You can get a distance list between a 'from' point to a list of 'to' points using :
public static void getDistances(@NonNull DirectionPoint from, @NonNull List<DirectionPoint> to, boolean isAccessible, boolean sortByTraveltime, @NonNull ApiCallback<DistanceResponse> callback)
The offline search does not return the same results as the online search.
public static void search(@NonNull SearchParams params, @NonNull ApiCallback<List<MapwizeObject>> callback)
If you are using a custom instance of Mapwize server you have to set the server URL in your MapwizeConfiguration.
The default parameters are :
serverScheme = "https";
serverHost = "api.mapwize.io";
serverApiPath = "v1/";
Mapwize Telemetry reports some details about the map usage in your application so that you can get usage statistics about your maps. Analytics are stored in an anonymous way according to our Privacy Policy. The user location is NEVER logged as part of the Telemetry logged data.
Telemetry is enable by default but you can deactivate it using the MapwizeConfiguration.Builder().telemetryEnabled(false)
method.
Events are stored in local storage and sent in batch to Mapwize servers. At the moment, the following events are logged :
The SDK provides a View component to help you display a floor selector. To add the floorController to your map, you need to
addOnFloorChangeListener
and addOnFloorsChangeListener
methodsThe floor controller can be created using the method
new FloorControllerView(context);
It then exposes the following methods:
public void onFloorsChange(@NonNull List<Floor> floors, boolean showController, String language);
public void onFloorWillChange(@Nullable Floor floor);
public void onFloorChange(@Nullable Floor floor);
that should be called on the MapwizeMap addOnFloorChangeListener
and addOnFloorsChangeListener
listeners.
You should also listen to when the user selects a floor and bind it with the MapwizeMap.setFloor method:
public void setOnFloorClickListener(OnFloorClickListener listener);
This is a complete example on how to add and bind the floorController:
FloorControllerView floorControllerView = new FloorControllerView(this);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.BOTTOM | Gravity.END;
mapwizeView.addView(floorControllerView, layoutParams);
mapwizeView.getMapAsync(mapwizeMap -> {
mapwizeMap.addOnFloorChangeListener(new MapwizeMap.OnFloorChangeListener() {
@Override
public void onFloorWillChange(@Nullable Floor floor) {
floorControllerView.onFloorWillChange(floor);
}
@Override
public void onFloorChange(@Nullable Floor floor) {
floorControllerView.onFloorChange(floor);
}
@Override
public void onFloorChangeError(@Nullable Floor floor, @NonNull Throwable error) {
//report error
}
});
mapwizeMap.addOnFloorsChangeListener(floors -> floorControllerView.onFloorsChange(floors, floors.size() > 1, mapwizeMap.getLanguage()));
floorControllerView.setOnFloorClickListener(floor -> mapwizeMap.setFloor(floor.getNumber()));
});
Version 3.2.0 brings two main changes for developers. The offline manager now makes use of the new OfflineRegion object and the Direction Api now uses the DirectionMode feature recently added on Mapwize.
The download methods handles the Mapbox
download automatically. The skipMapboxDownload
argument has been removed.
When a download succeeds, it now returns an OfflineRegion object (instead of nothing before). This OfflineRegion object can be retrieved later using the getOfflineRegions methods and it contains information about the downloaded content (venueId, universeId, minZoom and maxZoom).
The OfflineRegion replaces the venue, universe
pair that was used before.
The following methods have been removed:
boolean isVenueUniverseOffline(Venue venue, Universe universe)
List<Venue> getOfflineVenues()
List<Universe> getOfflineUniverses(Venue venue)
The offline manager provides methods to check if an update is available for an OfflineRegion, to update its data or to remove the OfflineRegion. Those operations cannot be done using a venue, universe
pair anymore.
In the previous versions, you could use the isAccessible
parameter in the direction API to search for an accessible direction. IsAccessible
was convenient but limiting. We are now adding a more general concept in order to provide more customizable direction modes in your venue.
DirectionMode
is configured on Mapwize Studio for each venue/universe. Because of that, the SDK does not know what direction modes are available before entering in a venue.
There are two way to retrieve the available direction modes:
When you have your direction modes, you can use one of them to make a direction request.
Direction modes have a type
. The accessible directions you already have configured in the Studio have been automatically migrated to a mode with type ACCESSIBLE
.
For convenience, the old direction api method with the isAccessible
parameter have been kept but we encourage you to make the change as soon as you can. The offline direction engine no longer does support the isAccessible
parameter and the request will always be sent to the server.
For any question or request, please contact us at support@mapwize.io.