DB tile source for offline maps

605 views
Skip to first unread message

Frank Schröder

unread,
Jun 28, 2009, 6:23:59 AM6/28/09
to route-...@googlegroups.com
Hi route-me developers and contributors,

first and foremost I would like to thank you for a great piece of
software. We are a small software company based in Frankfurt, Germany
named SharpMind (www.sharpmind.de) and have tried to build something
similar for an offline map application for the iPhone but without the
route-me code it would have taken us much much longer to complete the
app. Thank you guys. :)

Here is what we have done:

In order to build the offline map application we are storing the map
tiles in an sqlite database and index the tiles using the RMTileKey()
function. The map meta data like the supported zoom levels, the
coverage area and the attribution information is stored as name/value
pairs in a separate table. The database layout is very simple and the
application is still zippy on the iPhone and iPod touch.

For best performance it makes sense to disable the internal route-me
database cache as all tiles are already stored in a database. I have
accomplished this using a routeme.plist file.

The code consists of a custom tile source (RMDBTileSource) and a new
tile image (RMDBTileImage). I've attached a patch to the current 0.5
stable release but also have a working patch for the current trunk
available if there is a need. The RMDBTileSource.m file contains the
documentation of the database layout and the name/value pairs for the
meta data.

To get started you need to create an sqlite db with the two tables
(preferences and tiles) and store the tile images as blobs in the
tiles table and index them with the RMTileKey() function. Then add the
minimun and maximum zoom level as well as the tile size to the
preference table and you're done.

Then take the SimpleMap example and change the viewDidLoad method as
follows

- (void)viewDidLoad {
[super viewDidLoad];

...

RMDBMapSource* dbTilesource = [[[RMDBMapSource alloc]
initWithPath:@"path-to-sqlite-file"] autorelease];
[[[RMMapContents alloc] initWithView:mapView tilesource:dbTilesource]
autorelease];

...
}

That's it!

I hope our code is as useful to you as yours was to us. :)

In addition we're open for development projects and paid work for the
iPhone, Android and Symbian and if you would like to know more about
us you can visit our website at www.sharpmind.de.

Frank Schröder

route-me-0.5-db-tilesource-2009-06-28.patch
Message has been deleted

Frank Schröder

unread,
Jun 28, 2009, 9:42:12 AM6/28/09
to route-...@googlegroups.com
Hi Crispin,

I've attached the routeme.plist file which you can add to your project
to disable the db caching. Then only the memory cache is active.

The reason I went for an sqlite approach is that we have something
like 70.000 tiles in the database which - at least to me - seem to
many to keep in the file system. There is overhead with each file so
keeping them all in a single sqlite file reduces the size on the disk
dramatically. I have reductions between 30% (310MB vs. 215MB) and 50%
(673MB vs. 275MB). The DB approach also allows for a simple update of
the entire map. Just update the file and you're done. So its mostly
for packaging and management reasons. At the same time it allows us to
store other information in that same database at the same time.

I hope that answers your question.
Frank

routeme.plist

Hal Mueller

unread,
Jun 28, 2009, 12:47:27 PM6/28/09
to route-...@googlegroups.com
Frank: please post or send the patch for the trunk too.

Hal

Sent from iPhone, please pardon terseness.


On Jun 28, 2009, at 3:23, Frank Schröder <frank.s...@gmail.com>
wrote:

Frank Schröder

unread,
Jun 28, 2009, 3:20:25 PM6/28/09
to route-...@googlegroups.com
Hi Hal,

I've uploaded the patch into the "Files" section under the name route-
me-trunk-db-tilesource-2009-06-28.patch. It is based on the trunk code
from 22 Jun 2009.

Frank

On 28.06.2009, at 17:47, Hal Mueller wrote:

>
> Frank: please post or send the patch for the trunk too.
>
> Hal
>

--
Frank Schröder
frank.s...@gmail.com

Louis St-Amour

unread,
Jul 18, 2009, 8:04:51 PM7/18/09
to route-me
Hi Frank,

Thanks so much for your work on this, as getting the data/tiles in a
workable form is already so much of a hassle, I really appreciate the
code you've made to display them in route-me.

I'm curious about your app's tiles, which as you mention below are
over 200MB. How big an area are we talking about here? Did you render
the areas of interest in more detail, like http://weait.com/content/map-tiles-and-bounding-boxes
? I'm curious because I'm trying to figure out how to handle zooming
in and out, as well as how much detail I should include for the less-
interesting surrounding area, or if I should just stop people from
zooming out farther instead.

To be more specific, the area I'm referring to is York University, and
perhaps Toronto as a whole (sigh), along with general highways in
Ontario (the 401) and then if I let them zoom out farther, all they
would really see is the Earth. For visualization, you can see the
current York University map at http://www.yorku.ca/yorkweb/maps/index.htm
-- it's unfortunately flash-based and hand-drawn in Illustrator,
neither of which would work well in iPhone when people want to zoom in
and see interactively what things are where.

Although I'm working for York U. on this iPhone app, I do intend on
releasing the code as open source, since so much of what I've built so
far relies on open source tools, and I feel the need to give back
despite the closed SDK environment.

Anyway, I'm trying now to figure out how much I should render as
images and how much I should project on to the map instead. Would you
try to layer transparent images for labels on top of the map tiles, or
draw with the SDK, or something? I guess I'm wondering how multiple
layers of information would fit within RMDBTileSource.

Of course, I could just be asking these questions prematurely, as I
haven't yet attempted to render my map, which will be based off of (I
guess) an OSM file made with JOSM and contributed (if possible) back
to OpenStreetMap. Since there are currently buildings missing, but it
does have part of a newly constructed busway to be open this Sept.,
I'm surprised that people don't contribute more to OSM, especially
Universities and Corporations, who could use it to display their
campuses.

Life would be so much simpler if the world were flat,


Louis.

Timothy Bowen

unread,
Jul 18, 2009, 8:52:29 PM7/18/09
to route-...@googlegroups.com
Hey Louis,

You should be able to add labels and images using the RMMarkerManager
fairly easily.

-Tim Bowen
Co-founder, TrailBehind.com

Louis St-Amour

unread,
Jul 19, 2009, 11:13:19 AM7/19/09
to route-me
Hmm. Seeing the class now, it's fairly basic, and I'd have to write
something to handle groups of markers, then, although I suppose if I
wanted to just keep them in memory, something like "hideAllMarkers"
and "unhideAllMarkers" could work.

However, as JOSM (to make OSM files) seems so much easier to use to
make the map, and as I'd have to then figure out Mapnik's rendering
anyway, a part of me was thinking of just showing *everything* in the
map tiles if you zoom in far enough. The point here is not to search
and find a dynamic place, though I think I'd want to do that too, but
to also show selected details in groups, like parking, libraries,
information, or perhaps even floorplans at some point (to show where
ground-floor washrooms are, roughly).

Either way, I'd still want to parse the OSM XML using AQXMLParser
(it's fantastic, git is at http://github.com/AlanQuatermain/aqtoolkit/tree/master
...) and store that in Core Data and related data in Core Data or
something. So I suppose it just comes down to performance, or to how
fancy I can/want to get in the iPhone's rendering. And certainly it
would provide a better experience to, for instance, see bus stops when
zoomed out entirely, but be able to hide said bus stops and show
parking lot differences instead, if wanting to come by car.

But at that point, I've gone from points to polygon outlines of
parking lots, and that's where I have to wonder if drawing manually
every time on an iPhone's GPU is better than pre-rendering images at
the right zoom levels and somehow layering the image tiles on top of
the existing ones. And either way, I have to write stuff, whether it's
for Mapnik or polygon coordinate extraction in Objective-C; I just
have a feeling (without using it yet) that Mapnik may prove easier to
configure.

Any thoughts, anyone? How many annotations have you drawn with route-
me, or at what point might it make more sense to render in advance?
After all, we don't render XML to make the maps on the device, so
there should be *some* reason for preferring image data, even though
it takes longer to download than text. I've heard from a few books
that the iPhone is super-optimized for PNG's ... could that be a
reason?


Louis.

On Jul 18, 8:52 pm, Timothy Bowen <timfbo...@gmail.com> wrote:
> Hey Louis,
>
> You should be able to add labels and images using the RMMarkerManager  
> fairly easily.
>
> -Tim Bowen
> Co-founder, TrailBehind.com
>
> On Jul 18, 2009, at 5:04 PM, Louis St-Amour wrote:
>
>
>
> > Hi Frank,
>
> > Thanks so much for your work on this, as getting the data/tiles in a
> > workable form is already so much of a hassle, I really appreciate the
> > code you've made to display them in route-me.
>
> > I'm curious about your app's tiles, which as you mention below are
> > over 200MB. How big an area are we talking about here? Did you render
> > the areas of interest in more detail, likehttp://weait.com/content/map-tiles-and-bounding-boxes
> > ? I'm curious because I'm trying to figure out how to handle zooming
> > in and out, as well as how much detail I should include for the less-
> > interesting surrounding area, or if I should just stop people from
> > zooming out farther instead.
>
> > To be more specific, the area I'm referring to is York University, and
> > perhaps Toronto as a whole (sigh), along with general highways in
> > Ontario (the 401) and then if I let them zoom out farther, all they
> > would really see is the Earth. For visualization, you can see the
> > current York University map athttp://www.yorku.ca/yorkweb/maps/index.htm

Frank Schröder

unread,
Jul 20, 2009, 6:58:49 AM7/20/09
to route-...@googlegroups.com
Hi Louis,

I've done sample databases using OSM tiles which cover the cities of
Frankfurt and Munich for zoom levels 12-18. The code currently only
works as an offline tile storage.

In terms of what you should render dynamically and what in static
images I can only give you my general opinion. Other people probably
have a better understanding on the performance issues. As the
application is fluid with the map tiles in several zoom layers I would
render as much as possible statically. However, you have to balance
that with the effort to write or enhance the rendering code.
Everything which is dynamic like markers and route overlays have to be
done dynamic anyway.

I don't know how powerful the graphics engine on the iPhone is but I
can imagine that if you overdo it with layering transparent images you
might run into performance issues. But keep in mind that I have no
practical experience in that area. This is just my gut feel. I'm sure
that you can add some transparent image layers to the map to see how
it performs.

As for adding several layers to the RMDBTileSource the underlying data
model should be fairly simple but again I also don't know enough of
the route-me code in order to make a good recommendation. You might be
able to use multiple tile sources or enhance the existing tile source
to understand about layers.

Greetings from Afric en miniature :)
Frank

P.S.: Life would be so much more boring if the world was flat :)

Here are the stats for Frankfurt

009-07-20 11:30:47.880 map2sqlite[7088:10b] Map statistics
2009-07-20 11:30:47.881 map2sqlite[7088:10b] --------------
2009-07-20 11:30:47.881 map2sqlite[7088:10b] map db: fra.db
2009-07-20 11:30:47.881 map2sqlite[7088:10b] file size:
264668160 bytes
2009-07-20 11:30:47.881 map2sqlite[7088:10b] tile directory: fra-osm
2009-07-20 11:30:47.882 map2sqlite[7088:10b] number of tiles: 67784
2009-07-20 11:30:47.882 map2sqlite[7088:10b] zoom levels: 12 - 18
2009-07-20 11:30:48.360 map2sqlite[7088:10b] zoom level 12: 16
tiles, ( 1385, 2144)x( 1388, 2147),
{x=8.437500,y=50.233154}x{x=8.789062,y=50.007740}
2009-07-20 11:30:48.360 map2sqlite[7088:10b] zoom level 13: 64
tiles, ( 2770, 4288)x( 2777, 4295),
{x=8.437500,y=50.233154}x{x=8.789062,y=50.007740}
2009-07-20 11:30:48.361 map2sqlite[7088:10b] zoom level 14: 225
tiles, ( 5541, 8577)x( 5555, 8591),
{x=8.459473,y=50.219097}x{x=8.789062,y=50.007740}
2009-07-20 11:30:48.362 map2sqlite[7088:10b] zoom level 15: 841
tiles, ( 11082, 17155)x( 11110, 17183),
{x=8.470459,y=50.219097}x{x=8.789062,y=50.014797}
2009-07-20 11:30:48.365 map2sqlite[7088:10b] zoom level 16: 3249
tiles, ( 22164, 34311)x( 22220, 34367),
{x=8.475952,y=50.219097}x{x=8.789062,y=50.018330}
2009-07-20 11:30:48.376 map2sqlite[7088:10b] zoom level 17: 12768
tiles, ( 44328, 68623)x( 44441, 68734),
{x=8.478699,y=50.219097}x{x=8.786316,y=50.018330}
2009-07-20 11:30:48.413 map2sqlite[7088:10b] zoom level 18: 50621
tiles, ( 88656,137246)x( 88882,137468),
{x=8.478699,y=50.219097}x{x=8.784943,y=50.019211}

And the stats for Munich

2009-07-20 11:39:24.846 map2sqlite[7140:10b] Map statistics
2009-07-20 11:39:24.847 map2sqlite[7140:10b] --------------
2009-07-20 11:39:24.847 map2sqlite[7140:10b] map db: muc.db
2009-07-20 11:39:24.847 map2sqlite[7140:10b] file size:
287255552 bytes
2009-07-20 11:39:24.847 map2sqlite[7140:10b] tile directory: muc-osm
2009-07-20 11:39:24.848 map2sqlite[7140:10b] number of tiles: 64813
2009-07-20 11:39:24.848 map2sqlite[7140:10b] zoom levels: 12 - 18
2009-07-20 11:39:25.311 map2sqlite[7140:10b] zoom level 12: 20
tiles, ( 1419, 2177)x( 1422, 2181),
{x=11.337891,y=48.283192}x{x=11.777344,y=48.048710}
2009-07-20 11:39:25.311 map2sqlite[7140:10b] zoom level 13: 63
tiles, ( 2839, 4354)x( 2845, 4362),
{x=11.337891,y=48.253941}x{x=11.733398,y=48.048710}
2009-07-20 11:39:25.312 map2sqlite[7140:10b] zoom level 14: 221
tiles, ( 5679, 8709)x( 5691, 8725),
{x=11.359863,y=48.239307}x{x=11.733398,y=48.048710}
2009-07-20 11:39:25.313 map2sqlite[7140:10b] zoom level 15: 825
tiles, ( 11358, 17418)x( 11382, 17450),
{x=11.359863,y=48.239307}x{x=11.722412,y=48.056053}
2009-07-20 11:39:25.316 map2sqlite[7140:10b] zoom level 16: 3136
tiles, ( 22716, 34837)x( 22764, 34900),
{x=11.365356,y=48.239307}x{x=11.716919,y=48.059727}
2009-07-20 11:39:25.327 map2sqlite[7140:10b] zoom level 17: 12288
tiles, ( 45433, 69674)x( 45528, 69801),
{x=11.365356,y=48.237480}x{x=11.716919,y=48.061562}
2009-07-20 11:39:25.363 map2sqlite[7140:10b] zoom level 18: 48260
tiles, ( 90867,139349)x( 91056,139602),
{x=11.366730,y=48.236565}x{x=11.715546,y=48.062477}
--
Frank Schröder
frank.s...@gmail.com

Timothy Bowen

unread,
Jul 20, 2009, 4:32:43 PM7/20/09
to route-...@googlegroups.com
I guess conceptually things that aren't going to change very often
should be rendered statically for best performance, such as the
locations of bathrooms and classrooms. You could overlay events with
the marker manager such as freshman orientation, free concert here
etc. For TrailBehind we hit the server for a list of markers to
manage every time the app loads which allows us to change the data on
the fly without waiting for an apple update. This seems ideally
suited for things like events on campus.

Just my 2c, good luck!

-Tim Bowen
Co-founder, TrailBehind.com

Tanuj Jagoori

unread,
Jan 6, 2014, 6:59:34 AM1/6/14
to route-...@googlegroups.com

working on iPhone osm maps app (Route me).well initialising and downloading online maps was easy but real problem lies in saving the tiles through the code while u are online and reuse them while you are offline.i checked blogs regarding the same but everyone is saving the images externally and importing it in project and then showing them,which is not my requirement.please help me to save the tile image route me picks from online source

 here is how i am using online route me maps



 -(void) viewDidLoad

 {

    [RMMapView class];

     mapView.contents.tileSource = [[RMOpenStreetMapSource alloc] init];


    currentMarker = [[RMMarker alloc]initWithUIImage:[UIImage             imageNamed:@"radarLocatorLite.png"] anchorPoint:CGPointMake(0.5, 0.5)];

     markerManager   = [mapView markerManager];



     locationManager.delegate=self;

     locationManager.desiredAccuracy = kCLLocationAccuracyBest ;

     locationManager.distanceFilter =0;


    [mapView.contents  setZoom:17.0f];

    [markerManager addMarker:currentMarker AtLatLong:currentLocation.coordinate];

    [self initCompassView];

     [locationManager startUpdatingLocation];

     [locationManager startUpdatingHeading];


 }


-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

{

    currentLocation =newLocation;


        [mapView moveToLatLong:newLocation.coordinate];

    [markerManager moveMarker:currentMarker AtLatLon: newLocation.coordinate];

[currentRoutePath addLineToLatLong:newLocation.coordinate];

        [[mapView.contents overlay] addSublayer:currentRoutePath];

       //  NSLog(@"i reached  inside location update%f",currentRoutePath.lineWidth);

Vladimir Vyskocil

unread,
Jan 6, 2014, 7:50:47 AM1/6/14
to route-...@googlegroups.com
On 6 janv. 2014, at 12:59, Tanuj Jagoori <offici...@gmail.com> wrote:

working on iPhone osm maps app (Route me).well initialising and downloading online maps was easy but real problem lies in saving the tiles through the code while u are online and reuse them while you are offline.i checked blogs regarding the same but everyone is saving the images externally and importing it in project and then showing them,which is not my requirement.please help me to save the tile image route me picks from online source

A solution is to use a unlimited size for the db cache that already store downloaded tiles, when you go offline the tiles that have been put in the cache are still ready to be displayed ! You may also pre-fill the cache when you are online for a given location and zoom levels, I used to do it and it was working great.
you may have to clean the cache manually when the tiles are not needed anymore.

Regards,
Vlad.

-- 
You received this message because you are subscribed to the Google Groups "route-me" group.
To unsubscribe from this group and stop receiving emails from it, send an email to route-me-map...@googlegroups.com.
To post to this group, send email to route-...@googlegroups.com.
Visit this group at http://groups.google.com/group/route-me-map.
For more options, visit https://groups.google.com/groups/opt_out.

Justin R. Miller

unread,
Jan 6, 2014, 12:35:00 PM1/6/14
to route-...@googlegroups.com
You may want to look at these API, which exists in the Mapbox iOS SDK (based on Alpstein, which is based on original Route-Me):

https://www.mapbox.com/mapbox-ios-sdk/api/#//api/name/beginBackgroundCacheForTileSource:southWest:northEast:minZoom:maxZoom:
https://www.mapbox.com/mapbox-ios-sdk/api/#RMTileCacheBackgroundDelegate-protocol

JM

On Jan 6, 2014, at 3:59 AM, Tanuj Jagoori <offici...@gmail.com> wrote:

> working on iPhone osm maps app (Route me).well initialising and downloading online maps was easy but real problem lies in saving the tiles through the code while u are online and reuse them while you are offline.i checked blogs regarding the same but everyone is saving the images externally and importing it in project and then showing them,which is not my requirement.please help me to save the tile image route me picks from online source
>
>


--
Justin R. Miller
jus...@mapbox.com
@incanus77

Reply all
Reply to author
Forward
0 new messages