OSMDroid has built in support for offline maps.
You can download the tiles for any area, transfer them to the cache folder used by OSMDroid on a device's external memory and view that area without using a data connection.
If a data connection is available and enabled and the user pans the map to an area where there are no offline tiles, then OSMDroid will try and download the required tiles.
If a data connection is NOT available or has been disabled then the map will display a plain background for areas where no offline tiles are available.
Downloading tiles has been made very easy!
All you need is
Mobile Atlas Creator.
That link contains the instructions needed, Mobile Atlas Creator will download the tiles you require and package them into a ZIP file ready to be transferred to your device's external memory.
It looks like you can even create a SQLite database to store your offline tiles - i have not tried this yet.
I've used Mobile Atlas Creator to download the tiles which cover my hometown of King's Lynn, Norfolk, UK.
It gave me the option to select an area and then select which zoom levels i wanted to download tiles for.
To keep the offline tile archive file small so i could upload it to the forum i selected just zoom levels 0 to 12.
I've also selected OSM Mapnik as the map tile source.
Downloading tiles for all zoom levels for a large area will create a (very) large offline tile archive file.
In Mobile Atlas Creator, click the
Settings button (near
Create atlas button) and select the
Tile update tab.
Tiles have an expiry date, if your offline tiles pass their expiry date then they should not be used and OSMDroid should download fresh tiles.
I've not tested this yet so it may be that if no data connection is available then expired tiles will be displayed.
I shall experiment and post my findings.
Anyway lets leave the Tile update Settings tab as it is by default.
The
Directories tab let you select whereabouts your offline tile archive will be saved.
So having selected a map tile source, an area of the map and finally the zoom levels for which you want to download tiles you just click
Create atlas and wait for it to produce your offline tile archive.
My offline tile archive is just 316KBs in size.
If the created offline tile cache has a filename that uses one or more uppercase letters then rename it - we will include this file in the project assets and only all lowercase filenames are allowed.
Transfer your offline file cache to your project's
Files folder, remember to add it to your project using the Files tab
Add files button so that it is included in the APK.
Now before i go any further consider what tiles are
already cached on your device's external storage...
I've got many Mapnik tiles cached on my SD card - for this example i want to be sure that my offline tiles are used and not previously cached tiles.
OSMDroid caches tiles to folder on your device's external storage named
osmdroid.
It's shared by all (installed) applications that use an OSMDroid based map - whether using this library or the native Android library.
Inside the cache folder is a folder named
tiles and inside that are folders named after the
tilesource (Mapnik for example).
Each tilesource folder contains all cached tiles for that tilesource named and structured according to the
Slippy map tile naming convention.
So i've used a file manager to rename my Mapnik tilecache from Mapnik to
Mapnikbak.
Now i can test my offline files:
Code:
Sub Process_Globals
Dim MapCenter As GeoPoint
Dim ZoomLevel As Int
End Sub
Sub Globals
Dim MapView1 As MapView
End Sub
Sub Activity_Create(FirstTime As Boolean)
If FirstTime Then
Dim OfflineTileCacheFilename, TileCacheDir As String
OfflineTileCacheFilename="offline_tile_cache_mapnik.zip"
TileCacheDir=File.DirRootExternal&"/osmdroid"
' check if the offline tile cache has already been copied to the OSMDroid cache folder
If File.Exists(TileCacheDir, OfflineTileCacheFilename)=False Then
' create the 'osmdroid' cache folder if it does not exist
If File.Exists(TileCacheDir&"/", "")=False Then
File.MakeDir(File.DirRootExternal, "osmdroid")
End If
' copy the offline tile cache to the OSMDroid cache folder
File.Copy(File.DirAssets, OfflineTileCacheFilename, TileCacheDir, OfflineTileCacheFilename)
End If
End If
MapView1.Initialize("MapView1")
Activity.AddView(MapView1, 0, 0, 100%x, 100%y)
MapView1.SetMultiTouchEnabled(True)
MapView1.SetZoomEnabled(True)
' ensure that the map displays the Mapnik tiles
MapView1.SetTileSource("Mapnik")
' disable the data connection
MapView1.SetDataConnectionEnabled(False)
If FirstTime Then
' center the map within the area covered by the offline tiles
MapCenter.Initialize(52.75192, 0.40505)
' choose a zoom level for which offline tiles exist
ZoomLevel=10
End If
MapView1.Zoom=ZoomLevel
MapView1.SetCenter3(MapCenter)
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
MapCenter=MapView1.GetCenter
ZoomLevel=MapView1.Zoom
End Sub
Sub MapView1_ZoomChanged
If MapView1.Zoom>12 Then
' i could have set the map zoom to 12 if it was more than 12 but this way you can see the level 12 tiles stretched to display where zoom level 13+ does not exist
ToastMessageShow("Tiles are cached for zoom levels 0 to 12 only, current zoom level is: "&MapView1.Zoom, False)
End If
End Sub
Everything works as desired.
The offline tile cache file is copied to the osmdroid cache folder if it has not already been copied.
And the MapView displays just my offline tiles - where there are no offline tiles the MapView displays just it's background grid.
At zoom levels of 13 and higher the MapView stretches the tiles from zoom level 12 to fit the higher zoom levels.
The
MapView1_ZoomChanged event listener could just have easily set the MapView zoom to 12 if it was higher.
There's a few things to watch for with offline tiles:
- Mobile Atlas Creator does not support downloading of all the TileSources that the MapView supports.
I see no option to download CycleMap tiles for example.
- In the MapView the Mapnik tiles cover at least zoom level 18.
Mobile Atlas Creator offers to download only up to zoom level 16!
- If offline tiles expire and the MapView will no longer use them then watch that you don't have a massive offline tile archive wasting SD card space.
As well as offline map tiles, we can use a MapView to display any other image tiles.
That makes a MapView an ideal panorama viewer - cut your hi-res panorama image into tiles and view them in glorious hi-res in a MapView.
Circuit diagrams and floorplans are other large images that could be displayed in a MapView without having to worry about the memory overhead that dealing with large bitmaps causes.
Martin.
[edit]Example code updated it now checks if the
osmdroid cache folder exists, and creates it if necessary.[/edit]