How to Integrate or Work with Open Street Map (OSM) in an Android App (Kotlin)

Anil Kr Mourya
3 min readJun 28, 2023

--

What is OSM?

OpenStreetMap is a free, open geographic database updated and maintained by a community of volunteers via open collaboration. Contributors collect data from surveys, trace it from aerial imagery, and also from other freely licensed geodata sources.

OpenStreetMap (OSM) is a collaborative mapping project that aims to create a free and editable map of the world. It is built by a community of contributors who collect, verify, and update geographic data using GPS devices, aerial imagery, and local knowledge. Here’s an explanation of how OpenStreetMap works, with an example:

Data Collection: OpenStreetMap relies on volunteers to collect data. Contributors can use GPS devices to record tracks while walking, cycling, or driving, or they can trace features from satellite or aerial imagery. They can also add attributes such as street names, points of interest, and other relevant information.

Editing: Once the data is collected, contributors can edit the map using the OpenStreetMap editor. There are various editing tools available, including web-based editors like iD and JOSM (Java OpenStreetMap Editor). These editors allow users to add, modify, or delete map features such as roads, buildings, parks, rivers, and more.

Tags and Attributes: OpenStreetMap uses a tagging system to describe and classify map features. Each feature has one or more tags associated with it, providing information about its characteristics. For example, a road might have tags indicating its name, surface type, maximum speed, and so on. Tags are key-value pairs, allowing flexibility and customization.

Quality Assurance: OpenStreetMap has built-in quality assurance measures to maintain data accuracy. Contributors can review and validate each other’s edits, ensuring the correctness of the map. There are also automated validation tools that help identify potential errors or inconsistencies in the data.

Rendering and APIs: OpenStreetMap data is available for rendering maps and for developers to build applications through APIs (Application Programming Interfaces). The data can be rendered into different map styles, including street maps, topographic maps, cycling maps, and more. The APIs allow developers to access and utilize the map data for their own projects.

To implement OpenStreetMap on Android, you can use the following steps:

  • Add the OpenStreetMap library to your project’s dependencies. You can do this by adding the following line to your project’s build.gradle file:
implementation 'org.osmdroid:osmdroid-android:6.1.14'
  • Add the required permissions to your app’s AndroidManifest.xml file:
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
  • Create a layout file for the map view. You can use a RelativeLayout or a FrameLayout to contain the map view. Here’s an example layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity.MainActivity">

<org.osmdroid.views.MapView
android:id="@+id/osmmap"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

</RelativeLayout>

Create Activity and In your activity, initialize the map view and set its properties.

import android.app.ProgressDialog
import android.graphics.Rect
import android.location.GpsStatus
import android.location.Location
import android.os.Bundle
import android.util.Log

import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.*
import com.nic.supperapp.R
import com.nic.supperapp.databinding.ActivityMainBinding
import org.osmdroid.api.IMapController
import org.osmdroid.config.Configuration
import org.osmdroid.events.MapListener
import org.osmdroid.events.ScrollEvent
import org.osmdroid.events.ZoomEvent
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay

class MainActivity : AppCompatActivity(), MapListener, GpsStatus.Listener {





lateinit var mMap: MapView
lateinit var controller: IMapController;
lateinit var mMyLocationOverlay: MyLocationNewOverlay;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
Configuration.getInstance().load(
applicationContext,
getSharedPreferences(getString(R.string.app_name), MODE_PRIVATE)
)
mMap = binding.osmmap
mMap.setTileSource(TileSourceFactory.MAPNIK)
mMap.mapCenter
mMap.setMultiTouchControls(true)
mMap.getLocalVisibleRect(Rect())


mMyLocationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), mMap)
controller = mMap.controller

mMyLocationOverlay.enableMyLocation()
mMyLocationOverlay.enableFollowLocation()
mMyLocationOverlay.isDrawAccuracyEnabled = true
mMyLocationOverlay.runOnFirstFix {
runOnUiThread {
controller.setCenter(mMyLocationOverlay.myLocation);
controller.animateTo(mMyLocationOverlay.myLocation)
}
}
// val mapPoint = GeoPoint(latitude, longitude)

controller.setZoom(6.0)

Log.e("TAG", "onCreate:in ${controller.zoomIn()}")
Log.e("TAG", "onCreate: out ${controller.zoomOut()}")

// controller.animateTo(mapPoint)
mMap.overlays.add(mMyLocationOverlay)

mMap.addMapListener(this)


}

override fun onScroll(event: ScrollEvent?): Boolean {
// event?.source?.getMapCenter()
Log.e("TAG", "onCreate:la ${event?.source?.getMapCenter()?.latitude}")
Log.e("TAG", "onCreate:lo ${event?.source?.getMapCenter()?.longitude}")
// Log.e("TAG", "onScroll x: ${event?.x} y: ${event?.y}", )
return true
}

override fun onZoom(event: ZoomEvent?): Boolean {
// event?.zoomLevel?.let { controller.setZoom(it) }


Log.e("TAG", "onZoom zoom level: ${event?.zoomLevel} source: ${event?.source}")
return false;
}

override fun onGpsStatusChanged(event: Int) {


TODO("Not yet implemented")
}


}

Run your application, and enjoy.

  • Connect your Android device or start an emulator.
  • Build and run your application.

Conclusion: OpenStreetMap provides a versatile mapping solution for Android applications. By integrating OpenStreetMap in your app, you can display interactive maps, add overlays and markers, and utilize various features offered by the osmdroid library. With OpenStreetMap, you have access to a free and editable map data source, allowing you to create location-based applications, navigation systems, and more, all powered by the collaborative efforts of the OpenStreetMap community.

Thank You

--

--