Phisma
Phisma

Reputation: 51

Create a map using openstreetmap with jetpack compose in Kotlin programming language for Android

I want to develop an Android app using Kotlin and jetpack compose. I want to show a map on the display. For this I want to use openstreetmap. I need a composable function which can show me a map on the display.

All the codes I could find are based on xml UI design and the codes are outdated and do not work if you want to use jetpack compose. I tried to use osmdroid.

Upvotes: 1

Views: 4909

Answers (2)

Marsroverr
Marsroverr

Reputation: 746

You can use AndroidView to use the OSMDroid library's provided views.

For more specifics you can check out Using Views in Compose but here's some example code:

var geoPoint by mutableStateOf(GeoPoint(0.0,0.0))

AndroidView(
    modifier = Modifier.fillMaxSize(),
    factory = { context ->
        // Creates the view
        MapView(context).apply {
            // Do anything that needs to happen on the view init here
            // For example set the tile source or add a click listener
            setTileSource(TileSourceFactory.USGS_TOPO)
            setOnClickListener {
                TODO("Handle click here")
            }
        }
    },
    update = { view ->
        // Code to update or recompose the view goes here
        // Since geoPoint is read here, the view will recompose whenever it is updated
        view.controller.setCenter(geoPoint)
    }
)

Upvotes: 1

Phisma
Phisma

Reputation: 51

I could solve my problem. This is my code.

package com.example.mapapp

import android.content.pm.PackageManager
import android.os.Bundle
import android.preference.PreferenceManager
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.mapapp.ui.theme.MapAppTheme
import org.osmdroid.config.Configuration
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.views.MapView
import android.Manifest

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.INTERNET), 0)
        }
        super.onCreate(savedInstanceState)
        setContent {
            MapAppTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {

                    OsmdroidMapView()
                }
            }
        }
        val ctx = applicationContext
        Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx))
        Configuration.getInstance().userAgentValue = "MapApp"

    }
}

@Composable
fun OsmdroidMapView() {
    val context = LocalContext.current
    AndroidView(
        modifier = Modifier.fillMaxSize(),
        factory = { context ->
            val mapView = MapView(context)
            mapView.setTileSource(TileSourceFactory.MAPNIK)
            mapView.setBuiltInZoomControls(true)
            mapView.setMultiTouchControls(true)
            mapView
        }
    )
}

Upvotes: 0

Related Questions