DEV Community

Cover image for OSM Android Offline Map Library
EGEMEN
EGEMEN

Posted on

OSM Android Offline Map Library

Offline OpenStreet Map Library (No Internet Required) You dont have to even one-time connect!

Offline OpenStreetMap Library

Performance friendly and scalable

Why this project exists

Offline map usage is kind a problem for developers and there are rare documentations. I believe this library will helpful for developers.

Features and Usage

Implementation

Add it in your root build.gradle at the end of repositories
    repositories {
        maven { url 'https://jitpack.io' }
    }
Enter fullscreen mode Exit fullscreen mode
Add the dependency
    implementation 'com.github.AsynctaskCoffee:AndroidOfflineMapLibrary:v1'
    implementation 'com.github.MKergall:osmbonuspack:6.6.0'
    implementation 'org.osmdroid:osmdroid-android:6.1.0'
Enter fullscreen mode Exit fullscreen mode

You need to download offline map-tiles as SQLite format. And you should put it under assets folder. Let me explain how to download offline map-tiles step-by-step;

1. First you need to download Mobile Atlas Creator from HERE
2. Open MOBAC and select Osmdroid SQLite

3. Select map source (selecting osm is better) and zoom-levels (15-14-13-12 are ideal) as you desire from left panel.

4. Draw a area (small areas consume less storage). And press add selection button from left panel.

5. As you can see layers are selected. After selecting layers press Create Atlas button.

6. Select 'Ignore download errors and continue automatically' and continue.

7. After finishing download process rename the SQLite file as 'map.sqlite' and copy it into assets folder.

8. And yes! You completed the hard part. Rest of the steps just coding few lines.

Java

public class MainActivity extends AppCompatActivity implements MapListener, GeoPointListener {

    OfflineMapView offlineMapView;
    MapUtils mapUtils;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        offlineMapView = findViewById(R.id.map);
        offlineMapView.init(this, this);
    }


    @Override
    public void mapLoadSuccess(MapView mapView, MapUtils mapUtils) {

        // GeoPoint belongs to ISTANBUL heart of the world :)
        this.mapUtils = mapUtils;
        offlineMapView.setInitialPositionAndZoom(new GeoPoint(41.025135, 28.974101), 14.5);

        // 41.025135, 28.974101 Galata Tower

        Marker marker = new Marker(mapView);
        marker.setPosition(new GeoPoint(41.025135, 28.974101));
        marker.setIcon(getResources().getDrawable(R.drawable.galata_tower));

        // marker.setImage(drawable);

        marker.setTitle("Hello Istanbul");
        marker.showInfoWindow();
        mapView.getOverlays().add(marker);
        mapView.invalidate();
    }

    @Override
    public void mapLoadFailed(String ex) {
        Log.e("ex:", ex);
    }

    @Override
    public void onGeoPointRecieved(GeoPoint geoPoint) {

        //Selected GeoPoint Returns Here

        Toast.makeText(this, geoPoint.toDoubleString(), Toast.LENGTH_SHORT).show();
    }

    public void activateAnimatePicker(View view) {
        if (mapUtils != null)
            offlineMapView.setAnimatedLocationPicker(true, this, mapUtils);
    }
}
Enter fullscreen mode Exit fullscreen mode

Kotlin

class MainActivityKotlin : AppCompatActivity(), MapListener, GeoPointListener {

    lateinit var offlineMapView: OfflineMapView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main_kotlin)
        offlineMapView = findViewById(R.id.map)
        offlineMapView.init(this, this)
    }

    @SuppressLint("ShowToast")
    override fun onGeoPointRecieved(geoPoint: GeoPoint?) {

        //Selected GeoPoint Returns Here

        Toast.makeText(this, geoPoint?.toDoubleString(), Toast.LENGTH_SHORT).show()
    }

    override fun mapLoadSuccess(mapView: MapView?, mapUtils: MapUtils?) {

        // GeoPoint belongs to ISTANBUL heart of the world :)

        offlineMapView.setInitialPositionAndZoom(GeoPoint(41.011099, 28.996885), 15.5)
        offlineMapView.setAnimatedLocationPicker(true, this, mapUtils)


    }

    override fun mapLoadFailed(ex: String?) {
        Log.e("ex", ex.orEmpty())
    }
}
Enter fullscreen mode Exit fullscreen mode

Or XML

<egolabsapps.basicodemine.offlinemap.Views.OfflineMapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:initialFocusLatitude="41.025818"
        app:initialFocusLongitude="28.973436"
        app:zoomLevel="15" />
Enter fullscreen mode Exit fullscreen mode
Result: Say Hi to ISTANBUL :)

Top comments (6)

Collapse
 
asafeca profile image
A. Safeca • Edited

Hi?
Thanks for sharing, but the map does not load. And the Logcat says permission is denied. I am sending the image with the error reproduced.
And I believe that the problem lives here:
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/osmdroid/");
"osmdroid/" directory does not even exist!

Collapse
 
asynctaskcoffee profile image
EGEMEN

I think you have to give hardware read/write runtime permission. Because library creates this folder.

Collapse
 
mr_bayat_95f221f4d3489ff profile image
Mr. Bayat

this project have this error " Map load failed Asset files cannot copied" for samsung A34 android 13, . but for android 9 it work well.... what's wrong?????? i add all runtime permission but it dont work well.

Collapse
 
adna973 profile image
adna973

hello friend can make more deletes for that project thanks

Collapse
 
mr_bayat_95f221f4d3489ff profile image
Mr. Bayat

maven { url = uri("jitpack.io" ) }

Collapse
 
mr_bayat_95f221f4d3489ff profile image
Mr. Bayat

use this ** maven { url = uri("jitpack.io" ) }**