Offline maps in iOS using OpenStreetMap and Route-Me

This tutorial is heavily based on Rupert’s article here. However, the steps in this article are very different on some points. There are some steps that I had to figure out using other sources.

Generating OpenStreetMap tiles database

We’re going to use downloadosmtiles.pl to download OSM tiles for a specific region.

  1. Download, compile, and install GEO-OSM-Tiles 0.04. In Terminal:

    wget http://search.cpan.org/CPAN/authors/id/R/RO/ROTKRAUT/Geo-OSM-Tiles-0.04.tar.gz
    tar -xf Geo-OSM-Tiles-0.04.tar.gz
    cd Geo-OSM-Tiles-0.04
    
    perl Makefile.PL # make sure there are no errors/warnings
    make
    make test
    make install # you might have to use sudo
    

    If you get errors like this on Makefile.PL: “Warning: prerequisite YAML 0 not found.“, install the missing Perl libraries first before continuing.

  2. Determine the region you want to download. You can use OSM: go to http://openstreetmap.org and select Export from the top menu. You should be able to see 4 fields specifying the selected region coordinates. Click on Manually select a different area to define your own region.

  3. Execute downloadosmtiles.pl with the coordinates and your desired zoom levels to download the tiles:

    downloadosmtiles.pl --lat=0.871:1.79 --long=103.342:104.3 --zoom=0:15 --destdir=/your/tiles/folder
    

    When specifying values for lat and long, enter the lowest value first. Call downloadosmtiles.pl help to see more options.

    The destination folder should now contain image files organized like this:

  4. Download and run map2sqlite to convert the tile set to a sqlite database. You can download the source here and compile it in XCode. Or you can download the compiled binary here. We’ll use the compiled binary in this example.

    wget http://shiki.me/blog/downloads/map2sqlite-bin.zip
    tar -xf map2sqlite-bin.zip
    
    ./map2sqlite -db /your/mymap.sqlite -mapdir /your/tiles/folder
    

Using the offline map in Route-Me

For a quick example, we’ll use a sample project included in route-me.

  1. Download and extract the latest route-me library from GitHub: https://github.com/route-me/route-me
  2. Open the sample project at samples/SimpleMap/SimpleMap.xcodeproj. Select the SimpleMap scheme and test to make sure it runs before we do anything to it.
  3. Add the map database you just created to the project’s resources. Make sure that it is also added to the Copy Bundle Resources.

  4. In MapViewViewController.m, add an import for RMDBMapSource.h.

  5. Add this to the bottom of -viewDidLoad of MapViewViewController.m:

    // Use the bundled database as our map source
    RMDBMapSource *mapSrc = [[[RMDBMapSource alloc] initWithPath:@"mymap.sqlite"] autorelease];
    [[[RMMapContents alloc] initWithView:mapView tilesource:mapSrc] autorelease];
    
    // Constrain our map so the user can only browse through our exported map tiles
    [mapView setConstraintsSW:CLLocationCoordinate2DMake(mapSrc.bottomRightOfCoverage.latitude, mapSrc.topLeftOfCoverage.longitude)
                           NE:CLLocationCoordinate2DMake(mapSrc.topLeftOfCoverage.latitude, mapSrc.bottomRightOfCoverage.longitude)];
    // Move to the center of our exported map
    [mapView moveToLatLong:mapSrc.centerOfCoverage];
    

    The first 2 lines instruct the map view (RMMapView) to use the offline map as the map source. The -setConstraintsSW:NE call is not necessary but I think it’s a good idea to only show the map region that we have exported. The user will see empty gray spaces for regions that we don’t have map tiles for without the constraints.

And we’re done!

  • Pingback: Offline maps in iOS using OpenStreetMap and Route-Me « Collectibles

  • hamdan

    i’v got this warning,“Warning: prerequisite YAML 0 not found.“ how do we add other perl libraries?can u please refer me to a link or something?

  • Shiki

    @hamdan, sorry, my knowledge in Perl is very limited. I’m using MacPorts, so I was able to install YAML quite easily through that.

  • hamdan

    @shiki,thanks at lot for the tutorial,it worked pretty well,but im not able to see grey spaces for regions that we don’t have map tiles. i’m jus not allowed to scroll to those areas…?plz do let me know if u have any idea…

  • Shiki

    @hamdan, if you’d look at the Step 5 in the “Using the offline map in Route-Me” section, the code in there constrains the map to just the part where you have tiles. You can remove that code so you’ll see gray spaces.

  • Dasoman

    Ok, never mind, I was setting the coordinates backwards.

  • Dasoman

    Sorry, the other comment I wrote (about not being able to download the tiles) didn’t show. Please ignore these two messages (and thanks for the tutorial!).

  • hamdan

    thanks a lot Shiki.

  • hamdan

    hello shiki,can we do forward and backward geocoding on openstreetmap?i mean offline…if possible can u guide me to a good tutorial or ideas please?

  • Shiki

    @hamdan Sorry, I have no experience with that.

  • http://www.splinelab.de Mirko

    Hi Shiki,

    thanks for the excellent tutorial. The source of map2sqlite is not available at github anymore. Any ideas where to get it?

  • Bach

    Thanks for the detailed tutorial. I’m getting this error though: … Can’t locate Geo/OSM/Tiles.pm … BEGIN failed–compilation aborted at ./downloadosmtiles.pl line 6. …

    any ideas why this might be happening?

  • Shiki
  • Shiki

    @Bach In what step does that happen?

  • Pingback: Offline maps in iOS | Sawtell Software

  • JulienT

    Hi,

    I have to congratulate the author for this great tutorial. I have however a small problem : I’m trying to use map2sqlite on Ubuntu (12.04) but when I execute

    ./map2sqlite -db /your/mymap.sqlite -mapdir /your/tiles/folder

    an error occurs. I replaced the files destination with mine. The error in the terminal shows strange characters.

    If anyone can help me it would be nice.

    Thanks.

  • http://www.signar.se/blog Signar

    @Bach I had the same problem and made it work by copying downloadosmtiles.pl into the lib directory and running it from there.

  • louis de decker

    Hello Shiki the link to the source code of map2sqlite is down (https://github.com/InfiniteDroplets/iOS-OfflineMaps-Example/downloads) Is it available elsewhere ? thanks! Louis

  • Shiki
  • http://www.mobileappvault.com MobileAppVault

    Hello, I think this is a similar project and more up to date! https://github.com/mapbox/mapbox-ios-sdk

  • https://go-left.com/ Frank Schröder

    I am the original author of the map2sqlite tool and I am happy to see that it is still of good use. I will upload the source to github next week so that it is available again.

    Frank

  • https://go-left.com/ Frank Schröder

    Just pushed the source of map2sqlite-1.0 to github

    https://github.com/magiconair/map2sqlite
    

    Have fun Frank

  • Bill

    I would like to thank you for this article. Sadly can’t get past “Warning: prerequisite YAML 0 not found.“ . When trying to install YAML with ‘perl -MCPAN -e ‘install +YAML’ i get: ‘YAML is up to date (0.84). Anyone nows what I miss? Struggling for two days now…

  • http://bicivalenciaApp.es Alex

    You’re the man! I was using 6 month old generated tile databases and apparently they changed the structure of how route-me queries them. Following your tutorial made me understand my mistake. Love your neat style.

    Thank you.

  • Raeds

    @Signar I had the same problem, can you tell me where are you copying the downloadosmtiles.pl ? (folder? way?) thanks a lot.

  • Manju

    Hi Shiko, Excellent tutorial. Any idea on how I can limit the zoom levels (min and max) ??

  • hxming2919

    hi, can u give this example to me? i done it follow you, but it can’t display my map data.

    Thanks my email: 329287241@qq.com

  • Tomas

    All this terminal/Perl bullshit is way too hard for a simple beginning developer. I just can’t get it to work. I don’t understand a thing about Terminal, always giving me errors and whatnot, so frustrating.

    Isn’t there a simpler way to achieve this, without Perl or terminal?

  • Shiki

    @Tomas sorry man. This is the only way I know.

  • hugh

    Great tutorial. Helped loads. Only thing I would add is that instead of wget I had to use ‘curl -o’.

  • http://www.cocoabits.de Dirk

    Great tutorial, works like a charme. The hardest part was to install the YAML module without knowing perl. Thanks!!!

  • kim

    404 Not Found at downloadosmtiles.pl line 227. 408 Request Time-out at downloadosmtiles.pl line 227.

  • kim

    *** WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: Graphics & memory are overly taxed if [contents minZoom] is more than 1.5 smaller than [tileSource minZoom]

  • Wojtek

    You can use this tool to download tiles: http://wiki.openstreetmap.org/wiki/JTileDownloader it’s easy to use

  • http://programsoftware.net/apps/ Lee Chuck

    Can some one post code on how to place a marker on current gsp location on the code snipped above?

  • http://artoonsolutions.com/ sanjay

    Can we add annotation on offline map?

  • http://masbog.com masbog

    how to fix Makefile.PL: “Warning: prerequisite YAML 0 not found.“

    masbogs-MacBook-Pro:$ sudo cpan password: ***** cpan[1]> install Geo::OSM::Tiles

    :)

  • Ali

    THank you for a very good tutorial. i have done all successfully and happy to see my map in simulator. if you can help me with next step… that is routing, i meen how to show the rout on my loaded map between two point.

    i have searched but so far could not find anything useful.

    http://wiki.openstreetmap.org/wiki/OsmSharp/Tutorials/Routing

    but i could not get the osmsharp for native IOS.

    so i you have anything to guide, i will fall in love with you :)

    cheers. Ali

  • Misha

    I wonder why the author used perl ? ZX Spectrum Basic is much older and the procedure to run would be more interesting than f**king with installing perl…

  • zzzS

    How do I download the MapQuest Open layer of the map? Whenever I download the map, it downloads the Standard map only. Is there a way to do it?

  • Pingback: Offline maps in iOS using OpenStreetMap and Route-Me | LAZIOMATICA - Guida allo Sviluppo Software

  • Hippie

    Very cool article. Thanks so much!

  • Jacob Gelman

    A good developer should be comfortable with the terminal.

  • Tiago Pereira

    You can use “mobile atlas creator” – http://mobac.sourceforge.net/ But Jacob is right ;)

  • Pingback: iOS offline maps using Mapbox iOS SDK and OpenStreetMap | timominous

  • Haniel Cintra

    Hello Shiki

    I’m using this project but i had some difficult, in my project before i add the map, and define routes, i can’t use this map offline, It just loading when i’m connected on internet.

    Can you tell me something about this?? some help for loading the map offline??

    Thanks