DEV Community

Mubarak Basha
Mubarak Basha

Posted on • Originally published at mubaraknative.Medium on

Getting Started with MapLibre on Android

All you need to know about MapLibre
All you need to know about MapLibre

In this article, we are going to learn what MapLibre Native is for rendering vector maps in Android. We will also explore the benefits of using MapLibre over other map rendering SDKs, some customization options, and more. Let’s begin!

What is MapLibre Native ??

MapLibre Native is an open-source vector map rendering library for Android. It is part of the MapLibre Organization, which provides open-source mapping solutions for various platforms, including Android, iOS, and Web.

Originally, it was a community-led fork of Mapbox GL Native for Android before Mapbox closed-sourced their implementation. Since then, the project has replaced the closed-source components with fully open-source alternatives.

Why MapLibre Native ??

You might wonder why we need to use MapLibre Native when we already have Google Maps, Mapbox, Here SDKs, and other mapping providers.

Yes, many software SDKs and libraries exist to integrate maps into products, but they often come with vendor lock-in.

For example, if you want to set up your own map server to reduce the cost of monthly/annual billing , you can’t do that with proprietary SDKs. Additionally, they offer limited customization options.

In short, MapLibre Native allows you to swap out implementations easily , offering greater flexibility and control.

How to work with MapLibre Native??

Before diving into integration, let’s discuss how MapLibre Native handles map data.

MapLibre Native is a map renderer  — to display a map, we need map data. In my previous article, I explained the types of map tiles.

MapLibre Native renders vector tile data , which can be self-hosted using a tile server (e.g., TileServer GL with a simple S3 CDN ). Alternatively, multiple vector tile providers are available.

For a high-level understanding, we need to display data in Mapbox Vector Tile (MVT) format, such as this example:

https://demotiles.maplibre.org/style.json

More details: https://maplibre.org/maplibre-style-spec/

What do we build ??

In this demo, we will build a views (XML) based simple app that uses OpenFreeMap tile data to display a world map.

Sample app uses Maplibre to render global map from openfreemap

For production apps, you can self-host your data using Protomaps or TileServer GL.

Note: There is a community folk for MapLibre Native for Jetpack Compose checkout here.

build.gradle.kts(Module:app)

You can find the latest version of this maplibre native SDK at Maven Central here .

    dependencies {
       // ...
    implementation ("org.maplibre.gl:android-sdk:11.8.2")
       // ...
    }
Enter fullscreen mode Exit fullscreen mode

Don’t forget to add internet permission to your app for fetching map tiles from the server.

AndroidManifest.xml


<!-- ... -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- ... -->
Enter fullscreen mode Exit fullscreen mode

Step 1:

Let’s start by adding MapViewin your XML layout on your Activity/fragment .

<org.maplibre.android.maps.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />
Enter fullscreen mode Exit fullscreen mode

Step 2: Initialize this MapView in your fragment or Activity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import org.maplibre.android.MapLibre
import org.maplibre.android.camera.CameraPosition
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    // Declare a variable for MapView
    private lateinit var mapView: MapView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Get an instance of MapLibre.
        MapLibre.getInstance(this)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // Init the MapView
        mapView = binding.mapView
        mapView.getMapAsync { map ->
            map.setStyle("https://tiles.openfreemap.org/styles/liberty")
            // Shows full world view
            map.cameraPosition = CameraPosition.Builder().target(LatLng(0.0,0.0)).zoom(1.0).build()
        }
    }

    override fun onStart() {
        super.onStart()
        mapView.onStart()
    }

    override fun onResume() {
        super.onResume()
        mapView.onResume()
    }

    override fun onPause() {
        super.onPause()
        mapView.onPause()
    }

    override fun onStop() {
        super.onStop()
        mapView.onStop()
    }

    override fun onLowMemory() {
        super.onLowMemory()
        mapView.onLowMemory()
    }

    override fun onDestroy() {
        super.onDestroy()
        mapView.onDestroy()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mapView.onSaveInstanceState(outState)
    }
}
Enter fullscreen mode Exit fullscreen mode

When we run the app, it successfully shows the world map from OpenFreeMap data for other data sources checkout TestStyles from MapLibreAndroidTestApp.

Conclusion

That’s it we learned What is MapLibre Native , why we use MapLibre and also learned its benefits over other sdk for complete source code with a additional map features, checkout the repository down below.

GitHub - MubarakNative/MBCompass: A fully functional jetpack compose compass app that uses device magnetometer to find cardinal direction

If you found this article helpful and learned something new, please consider ❤️ and sharing it with your friends. This is a niche topic, and very few articles cover it in detail. Creating content like this takes hours of effort — from designing a thumbnail to structuring the information in an easy-to-understand way.

Your support motivates me to keep writing more valuable articles. See you in the next one! 🚀

Top comments (0)