Display Ski Slopes on the Map


This example demonstrates how to create custom map and display it on the mobile phone using MapTiler Cloud and OpenStreetMap (OSM) data. You will learn the following:

  • How to generate your own vector tiles and host them in the MapTiler Cloud.
  • How to create your own map style and use your vector tiles along with predefined MapTiler tiles.
  • How to display your custom map in iOS app.

Slopes Data

We will use ski slopes (small sample in Austria) for this example downloaded from OpenStreetMap (OSM) database. The OSM data is extracted and converted to geopackage. There are many ways how to download OSM data and convert them into geopackage - you can use QGIS, OpenMapTiles project, GDAL ogr2ogr etc. However we have prepared the data for you.

Create vector tiles

We will create vector tiles using MapTiler Desktop - the application which allows you to load your image or geodata and get a tiled map. You can download MapTiler Desktop from MapTiler web site. Launch MapTiler Desktop and open the geo package.


Click “Export” to initiate export wizard and select “mbtiles” format.


Configure zoom levels and attributes. Attributes specified here will be used when working on the map style.


Keep output format gzip and launch rendering.


When done, MapTiler Desktop will show you rendered data.


Lastly, upload the mbtiles file you’ve created to your cloud account.

MapTilerDesktop MapTilerDesktop

Create custom map

In the next step, we will create custom map and we will add slopes as a new layer.

You should first check if you have your vector tiles under Tiles section in your cloud account.


Create new map

In your cloud account, under Maps click New Map button. On the next screen, choose a map which you would like to use as your template. We will choose Outdoor basemaps and click the Customize button.


On the next screen, click the Save button and save the map. You might want to rename the map first.


Click the Advanced editing button and convert the map.


Now you can start editing your map style.


Add slope data source to the map

In the next step we will add your slopes to the map as a new source so that we can use vector tiles from this source in new layers.


From the list of available sources, choose slopes.


Add slope layers

In the next step we will add slopes to the map. We will add 3 layers - blue, red, and black slopes.

In the top left corner, choose Add Layer button.


Select the source (slopes) and source layer (we have only one - slopes)


You can now start configuring the layer. Rename the layer to slopes-easy, add the filter piste_difficulty == easy to include only easy slopes in this layer and set color and opacity.


Create copies of the layer - intermediate and advanced slopes, set filters to piste_difficulty == intermediate and piste_difficulty == advanced and set colors.

Alter map style

You can change other layers as well, for example make landcover_grass and landcover_wood layers and change the color from green to white to set winter theme.

Publish the map

When you are done, you have to publish the map so that you can use it in your application. Click the close button to exit the advanced editor. Then click Publish button.

Scroll down until the Use vector style section. You should now see the url of your map which you can use in the application.


Mobile App - Setup the MapView

  1. In order to use your custom style with ski slopes source, you will need the url which you generated in the previous step amd you need to pass it to the MapboxMap.setStyle method.

     private fun loadStyle(map: MapboxMap) {
         val mapTilerKey = Helper.getMapTilerKey(context!!)
         // Use your custom style url
         // replace the map identifier (f3c7b19d-7f5b-42a2-8b98-90ed51ca373a) with your own identifier
         // see https://docs.maptiler.com/maplibre-gl-native-android/android-custom-map/#publish-the-map
         val styleUrl = "https://api.maptiler.com/maps/f3c7b19d-7f5b-42a2-8b98-90ed51ca373a/style.json?key=${mapTilerKey}";
         // Set the style after mapView was loaded
         map.setStyle(styleUrl) {
             map.uiSettings.setAttributionMargins(15, 0, 0, 15)
  2. And after the map has been initialized, you cam pan and zoom to your slopes

     private fun panToSlopes(map: MapboxMap) {
         val latLngBounds = LatLngBounds.Builder()
             .include(LatLng(46.91076825, 10.91279724))
             .include(LatLng(46.98484291, 11.02306368))
         map.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 10))
  3. The full example looks as follows:

     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
         // Create map view
         mapView = view.findViewById(R.id.simpleMapView)
         mapView?.getMapAsync {map -> loadStyle(map)}