Skip to content

Migrate from Google Maps to MapMetrics

This guide helps you migrate an existing Android app from the Google Maps SDK to the MapMetrics SDK, covering the key API differences and code changes needed.

Prerequisites

  • An existing Android project using com.google.android.gms:play-services-maps
  • A MapMetrics API key from the MapMetrics Portal

Step 1: Update Dependencies

Replace the Google Maps dependency in build.gradle:

gradle
// Remove:
// implementation 'com.google.android.gms:play-services-maps:18.x.x'

// Add:
implementation 'org.mapmetrics.android-sdk:latest-version'

Remove the Google Maps API key from AndroidManifest.xml:

xml
<!-- Remove this: -->
<!-- <meta-data android:name="com.google.android.geo.API_KEY" android:value="..." /> -->

Step 2: Replace the Map View

Layout XML

xml
<!-- Google Maps -->
<!-- <com.google.android.gms.maps.MapView ... /> -->

<!-- MapMetrics -->
<org.maplibre.android.maps.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Activity Code

kotlin
// ========== GOOGLE MAPS ==========
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.MapView
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
import com.google.android.gms.maps.CameraUpdateFactory

class MapActivity : AppCompatActivity(), OnMapReadyCallback {
    private lateinit var mapView: MapView

    override fun onMapReady(googleMap: GoogleMap) {
        googleMap.moveCamera(
            CameraUpdateFactory.newLatLngZoom(LatLng(48.8566, 2.3522), 12f)
        )
        googleMap.addMarker(
            MarkerOptions().position(LatLng(48.8584, 2.2945)).title("Eiffel Tower")
        )
    }
}

// ========== MAPMETRICS ==========
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.MapMetricsMap
import org.maplibre.android.maps.Style
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.annotations.MarkerOptions
import org.maplibre.android.camera.CameraPosition
import org.maplibre.android.camera.CameraUpdateFactory

class MapActivity : AppCompatActivity() {
    private lateinit var mapView: MapView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_map)

        mapView = findViewById(R.id.mapView)
        mapView.onCreate(savedInstanceState)
        mapView.getMapAsync { map ->
            map.setStyle(
                Style.Builder().fromUri(
                    "https://gateway.mapmetrics.org/styles/YOUR_STYLE_ID?token=YOUR_API_KEY"
                )
            )
            map.cameraPosition = CameraPosition.Builder()
                .target(LatLng(48.8566, 2.3522))
                .zoom(12.0)
                .build()
            map.addMarker(
                MarkerOptions()
                    .position(LatLng(48.8584, 2.2945))
                    .title("Eiffel Tower")
            )
        }
    }
}

Step 3: API Mapping Reference

Core Classes

Google MapsMapMetrics
GoogleMapMapMetricsMap
MapView (gms)MapView (maplibre)
SupportMapFragmentSupportMapFragment
OnMapReadyCallbackLambda in getMapAsync {}
com.google.android.gms.maps.model.LatLngorg.maplibre.android.geometry.LatLng

Camera

Google MapsMapMetrics
CameraUpdateFactory.newLatLng()CameraUpdateFactory.newLatLng()
CameraUpdateFactory.newLatLngZoom()CameraUpdateFactory.newLatLngZoom()
CameraUpdateFactory.newLatLngBounds()CameraUpdateFactory.newLatLngBounds()
googleMap.moveCamera()map.moveCamera()
googleMap.animateCamera()map.animateCamera()
map.easeCamera() (constant speed)
CameraPosition.Builder().target().zoom().bearing().tilt()Same pattern, same methods

Markers

Google MapsMapMetrics
googleMap.addMarker(MarkerOptions)map.addMarker(MarkerOptions)
MarkerOptions().position().title().snippet()Same pattern
BitmapDescriptorFactory.fromResource()IconFactory.getInstance(ctx).fromBitmap()
marker.remove()map.removeMarker(marker)
googleMap.clear()map.clear()

Event Listeners

Google MapsMapMetrics
setOnMapClickListeneraddOnMapClickListener
setOnMapLongClickListeneraddOnMapLongClickListener
setOnMarkerClickListenersetOnMarkerClickListener
setOnCameraMoveListeneraddOnCameraMoveListener
setOnCameraIdleListeneraddOnCameraIdleListener

UI Settings

Google MapsMapMetrics
googleMap.uiSettings.isZoomControlsEnabledNo built-in controls (add custom)
googleMap.uiSettings.isCompassEnabledmap.uiSettings.isCompassEnabled
googleMap.uiSettings.isScrollGesturesEnabledmap.uiSettings.isScrollGesturesEnabled
googleMap.uiSettings.isZoomGesturesEnabledmap.uiSettings.isZoomGesturesEnabled
googleMap.uiSettings.isRotateGesturesEnabledmap.uiSettings.isRotateGesturesEnabled
googleMap.uiSettings.isTiltGesturesEnabledmap.uiSettings.isTiltGesturesEnabled

What's Different in MapMetrics

FeatureGoogle MapsMapMetrics
StylingLimited JSON styleFull MapLibre style spec
Data layersLimited overlaysGeoJSON sources + layers (fill, line, circle, symbol, heatmap, fill-extrusion)
ExpressionsNot availableData-driven styling with expressions
Vector tilesNot availableFull MVT support
OfflineLimited cachingFull offline region management
Open sourceProprietaryBuilt on MapLibre GL (open source)
PricingPay per loadMapMetrics pricing model

Step 4: Lifecycle

Both SDKs require forwarding lifecycle events. The pattern is identical:

kotlin
// Same for both Google Maps and MapMetrics
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 onDestroy() { super.onDestroy(); mapView.onDestroy() }
override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    mapView.onSaveInstanceState(outState)
}

Step 5: Key Things to Note

  1. Style URL required — MapMetrics uses vector tile styles, so you must provide a style URL via setStyle(). There's no default map appearance without it.

  2. Marker API is similar — Basic MarkerOptions work almost identically. For advanced markers (100+), switch to symbol layers.

  3. No built-in zoom controls — MapMetrics doesn't have default on-screen zoom buttons. See Navigation Controls to add your own.

  4. Powerful layer system — MapMetrics gives you GeoJSON sources, data-driven expressions, and multiple layer types that far exceed Google Maps' overlay API.

Next Steps


Tip: The migration is mostly mechanical — class names change but patterns stay similar. The biggest win is gaining access to GeoJSON layers, data-driven styling, and vector tile sources that aren't available in Google Maps.