Custom Map Styles
The HERE SDK for Android provides a flexible solution to customize the map by loading custom map schemes.
If you are looking for predefined map styles, see the Quick Start guide for an introduction. The HERE SDK already includes a set of pre-configured map styles such as MapStyle.NORMAL_DAY
or MapStyle.SATELLITE
.
Create and Load Custom Map Styles
The most flexible solution to customize the map is to create your own map styles using a configuration file generated with the WYSIWYG HERE Style Editor.
Note
To access the HERE Style Editor, please contact your HERE representative - as the editor is not yet publicly available. Please note that the resulting map styles are not compatible with the web editor, so only the HERE Style Editor can be used with the HERE SDK.
This HERE SDK release is compatible with the HERE Style Editor 0.60. It is recommended to use the latest style editor and to update existing styles in case of unexpected behavior or errors.
Usually, the HERE Style Editor is updated for each new release. In practice, consider to re-export existing custom map styles with the matching version of the HERE Style Editor. This should be checked whenever you integrate a newer HERE SDK version. Note that some map features like 3D landmarks are only available for specific versions. As a rule of thumb, we recommend to get in touch with your HERE representative to discuss potential style updates for each new release.
Screenshot: The HERE Style Editor showing a custom map configuration.
As soon as you are satisfied with your custom map style, export it via File -> Export -> Here Rendering Engine Configuration. Please unzip the resulting file. You will find a few JSON files.
Copy all JSON files into the "assets" directory of your project. If not already added, you can add that folder via Android Studio (Right-click on the project: New -> Folder -> Assets folder). You can also manually generate the folder.
The main style file always ends with *.scene.json
.
Load the style into a map scene as follows:
private void loadMapStyle() {
String fileName = "omv/omv-traffic-traffic-normal-night.scene.json";
AssetManager assetManager = context.getAssets();
try {
assetManager.open(fileName);
} catch (IOException e) {
Log.e("CustomMapStylesExample", "Error: Map style not found!");
return;
}
mapView.getMapScene().loadScene("" + fileName, new MapScene.LoadSceneCallback() {
@Override
public void onLoadScene(@Nullable MapError mapError) {
if (mapError == null) {
} else {
Log.d("CustomMapStylesExample", "onLoadScene failed: " + mapError.toString());
}
}
});
}
In the above snippet, we use Android's AssetManager
to verify that the *.scene.json
file exists at the expected location. You only have to load this file. From there, the HERE SDK will find the other files - as exported from the editor. Make sure that all style files are kept together at the same folder level. *.scene.json
is the main file that includes references to the other files.
Screenshot: Another example for a custom map style configuration.
Using custom map styles can be very effective to differentiate your app from other map applications. In addition, it is possible to change map styles on-the-fly, for example, to shift the user's attention to certain map elements based on the current state of your app.
Note
You can find a CustomMapStyles
example app on GitHub.
Load Custom Raster Layers
Another alternative to customize the map's look is to add your own raster tile service on top of the HERE map styles. This can be your own server where you host tiles that you want to show as an overlay on top of selected areas of the world - or a public tile server such as OpenStreetMap. Fully opaque and transparent map tile overlays are supported. It is also possible to add more than one raster layer to the map at the same time.
Note
Note that this is a beta release of this feature, so there could be a few bugs and unexpected behaviors. Related APIs may change for new releases without a deprecation process.
To add custom raster layers, you need to create a RasterDataSource
. A RasterDataSource
represents the source of raster tile data to display. It also allows changing its configuration. With a RasterDataSourceConfiguration
you can specify a configuration for the data source, including URL, tiling scheme, storage levels and caching parameters.
Finally, with the MapLayerBuilder
you can create a MapLayer
to add a renderable map overlay to the map.
- Use
MapLayerVisibilityRange
to specify at which zoom levels the map layer should become visible. - Use the
MapLayerPriority
to specify the draw order of the MapLayer
. - Use the
MapContentType
to specify the type of data to be shown by the MapLayer
.
In case of raster tile images, use MapContentType.RASTER_IMAGE
.
Default map gesture actions such as pinch, rotate and zoom behave in the same way for raster tiles as for HERE vector maps - except for a few differences: For example, raster tiles are loaded as bitmaps and therefore a rotated raster map tile rotates all labels and street names contained together with the tile.
Note
When loading a map scene with a custom map style or the default map style, the map will be rendered using vector tiles where the map information is represented as vector data consisting of vertices and paths for better scalability and performance. By contrast, raster tiles are regularly-spaced and square, and consist of bitmap images that represent only pixel information. Note that the satellite map style is also raster based.
Create a RasterDataSource
as follows:
private RasterDataSource createRasterDataSource(String dataSourceName) {
String templateUrl = "https://stamen-tiles.a.ssl.fastly.net/toner/{z}/{x}/{y}.png";
List<Integer> storageLevels = Arrays.asList(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
RasterDataSourceConfiguration.Provider rasterProviderConfig = new RasterDataSourceConfiguration.Provider(
templateUrl,
TilingScheme.QUAD_TREE_MERCATOR,
storageLevels);
String path = "cache/raster/toner";
long maxDiskSizeInBytes = 1024 * 1024 * 32;
RasterDataSourceConfiguration.Cache cacheConfig = new RasterDataSourceConfiguration.Cache(path, maxDiskSizeInBytes);
return RasterDataSource(mapView.getMapContext(),
new RasterDataSourceConfiguration(dataSourceName, rasterProviderConfig, cacheConfig));
}
This code uses a tile source from Stamen Design, which can be used under the CC BY 3.0 license. The data itself comes from OpenStreetMap. For more information visit http://maps.stamen.com/#watercolor/12/37.7706/-122.3782.
Note that you can also use other tile sources that follow the OSM standard style format /zoom/x/y.png
. The templateURL
should look like this:
https://YourRasterTileService.com/{zoom}/{xTile}/{yTile}.png
Here, the zoom
value represents the map's current zoom level, and xTile
and yTile
defines the horizontal and vertical tile numbers.
Once the tile source is created, a MapLayer
can be built:
private MapLayer createMapLayer(String dataSourceName) {
MapLayerPriority priority = new MapLayerPriorityBuilder().renderedLast().build();
MapLayerVisibilityRange range = new MapLayerVisibilityRange(0, 22 + 1);
try {
MapLayer mapLayer = new MapLayerBuilder()
.forMap(mapView.getHereMap())
.withName(dataSourceName + "Layer")
.withDataSource(dataSourceName, MapContentType.RASTER_IMAGE)
.withPriority(priority)
.withVisibilityRange(range)
.build();
return mapLayer;
} catch (MapLayerBuilder.InstantiationException e) {
throw new RuntimeException(e.getMessage());
}
}
And finally, the MapTile
's visibility can be controlled by enabling or disabling the layer. Note that we also need to provide a unique name. Each RasterDataSource
can be created only once:
String dataSourceName = "myRasterDataSourceTonerStyle";
rasterDataSourceTonerStyle = createRasterDataSource(dataSourceName);
rasterMapLayerTonerStyle = createMapLayer(dataSourceName);
rasterMapLayerTonerStyle.setEnabled(true);
The resulting layer looks like this:
Screenshot: A b/w toner style map layer from Stamen Design shown on top of a map view.
The above screenshot shows that you can easily combine custom raster tiles with other HERE SDK features. For example, you can render several MapMarker
instances on top of the tile data from a tile server.
Note
One of the main advantages of custom raster layers is that you can easily enhance the HERE map styles with a transparent custom tile source on top, for example, to show weather data or any other data you want to see on top of the map. When using an opaque raster tile source, it is recommended to combine this with an empty base map style.
If you do not use an empty base map style, then the underlying map scheme will "shine" through until the raster layer tiles are loaded. The accompanying example app shows how this looks like.
There are certain other parameters that you can adjust: For example, if your app uses multiple raster layers, you can define a load priority when building a layer with the MapLayerBuilder
. This allows to specify an integer value: Higher values will lead to load the layer before layers with lower values.
Another option to reduce the loading time while panning the map can be to adjust the feature configuration.