osmdroid and mapsforge

5,713 views
Skip to first unread message

Azimuth

unread,
Jun 20, 2012, 3:21:02 PM6/20/12
to osmd...@googlegroups.com
hi,

i use the osmdroid MapViewer, Overlays, etc in my application. The tileprovider is the offline mapnik tileprovider
is there a way to integrate mapsforge as a source-provider in osmdroid? Has anybody already experience with that? I found a wrapper in the osmdroid-library, but how should i use that ?

thanks in advance!



Neil

unread,
Jun 21, 2012, 1:17:03 AM6/21/12
to osmd...@googlegroups.com
Firstly, mapsforge are discontinuing to support the offline tiles, so osmdroid is actually an alternative to mapsforge in that area. To see how to use the mapsforge wrapper, have a look at the Google wrapper example.
 
Neil

Jez

unread,
Jun 21, 2012, 4:36:57 AM6/21/12
to osmd...@googlegroups.com
Hi Neil,

I've been meaning to email about mapsforge/osmdroid integration for a while.  I use osmdroid in the CycleStreets Android app, and recently integrated it with the Mapsforge renderer.  I started out your mapsforge wrapper code, but had an existing stack of overlays and user interaction that I wanted to lay on top of it.  Also switching between mapsforge rendering and osmdroid tile rendering was awkward.  I pushed the mapsforge stuff down into a tile overlay, and then had a bit of a revelation and wrapping Mapsforge as an OSMDroid TileSource and TileProvider.  This turns out to be a fantastic way to hook the two together - the coupling is very low, you don't need to change anything you've already built on top of OSMDroid. I use it to provide offline vector maps, not tiles, for the CycleStreets app. 

The source for the TileSource and TileProvider is at
   https://github.com/jezhiggins/android/tree/master/src/org/mapsforge/android/maps

This MapView
   https://github.com/jezhiggins/android/blob/master/src/net/cyclestreets/views/CycleMapView.java
can switch between normal OSDDroid online tile provider and an offline MapsForge tile provider.

It's possible that my code relies on some small patches to MapsForge - I haven't fully unpicked that yet as I made several changes while I thrashed around before hitting on the tilesource thing. The binary jar and the source are up there on GitHub too, though.  OSMDroid does not need patching for this to work. 

I'm happy to look at pulling this out of the CycleStreets source and packaging separately, providing it for the osmdroid-third-party jar or whatever.

Jez

Neil

unread,
Jun 21, 2012, 7:20:05 AM6/21/12
to osmd...@googlegroups.com
Nice idea!
As I mentioned, mapsforge is deprecating tile download functionality - see this link: https://groups.google.com/d/topic/mapsforge-dev/0xn8vqilcpI/discussion - so it probably doesn't make sense to incorporate it.  Since your code is also open source, it probably makes more sense to leave it at that, and not integrate into osmdroid.

Neil

Azimuth

unread,
Jun 21, 2012, 4:12:14 PM6/21/12
to osmd...@googlegroups.com
thanks for the replies!

@jeff
The idea is that mapsforge will be used for tile-rendering for osmdroid, right?
that means, that your tileprovider creates PNG / Bitmap tiles and give it to the osmdroid-MapView?
that is a very good solution for offline use, because the mapsforge maps-packages are very small ...

azimuth


On Thursday, June 21, 2012 10:36:57 AM UTC+2, Jez Higgins wrote:

manimaul

unread,
Oct 23, 2012, 9:08:27 AM10/23/12
to osmd...@googlegroups.com
Jez,

Thank you very much for the example.  Having mapsforge as an osmdroid TileProvider is exactly what I'm looking for... this should be part of Osmdroid IMO.

Will

Petar Petrov

unread,
Oct 24, 2012, 6:08:45 AM10/24/12
to osmd...@googlegroups.com
Hi Jez,
are you creating rasters on the fly (on the mobile), to feed as tile provider?

I was considering working with vector SVG for map overlays!
since, I realized that I need different raster size for each
particular zoom level my app supports.
the alternative is to stock all the png version of a merker overlay
with your app, making it harder to support and of-curse bigger.
--
All the best,
Petar Petrov
http://ppetrov.net

Jez Higgins

unread,
Oct 24, 2012, 7:53:50 AM10/24/12
to osmd...@googlegroups.com


On Wednesday, 24 October 2012 11:08:46 UTC+1, ppetrovdotnet wrote:
are you creating rasters on the fly (on the mobile), to feed as tile provider?   

Yes, I'm using MapsForge as a tile provider for OsmDroid, generating tiles images from the vector data on demand.  Because (I assume) they are both working off the same dataset, MapsForge and OsmDroid both use the same projections, zoom levels, and so on.  When OsmDroid requests a particular tile at a particular zoom level, I just hand it off to the MapsForge renderer and then pass the image back out to OsmDroid.

Coming back to my earlier email, the CycleStreets code I pointed to works with OsmDroid and Mapsforge as is, so it's a pretty easy way to hook the two together.

Jez

Martin

unread,
Oct 26, 2012, 3:45:18 AM10/26/12
to osmd...@googlegroups.com
Hi there Jez.

I've more or less got your code to work and now have a mapforge vector tile layer in OSMDroid - thanks a lot.

Do these vector tiles get cached?
I see no cache folder in the default 'osmdroid' folder and nothing cached in the default mapsforge '/Android/data/
org.mapsforge.android.maps/cache/' folder either.

Martin.

Jez Higgins

unread,
Oct 27, 2012, 4:20:21 PM10/27/12
to osmd...@googlegroups.com

I've more or less got your code to work and now have a mapforge vector tile layer in OSMDroid - thanks a lot.
 
Cool.
 
Do these vector tiles get cached?
I see no cache folder in the default 'osmdroid' folder and nothing cached in the default mapsforge '/Android/data/
org.mapsforge.android.maps/cache/' folder either.

They're cached in memory, but not written out to disk.  It should be difficult to add if you wanted to, but I didn't bother as the rendering is generally so fast that there's no observable benefit in writing the images out to storage.

Jez
 

Martin

unread,
Oct 28, 2012, 3:22:20 AM10/28/12
to osmd...@googlegroups.com
Could you give me some hints as to how i'd enable a tile cache on external memory?
If it's straightforward to implement i'd like to do so.

Thanks.

Martin.

Jez Higgins

unread,
Oct 29, 2012, 6:07:02 AM10/29/12
to osmd...@googlegroups.com


On Sunday, 28 October 2012 07:22:21 UTC, Martin wrote:
Could you give me some hints as to how i'd enable a tile cache on external memory?
If it's straightforward to implement i'd like to do so.

In MapsforgeOSMDroidTileProvider.TileLoader.loadTile we have

    @Override
    public Drawable loadTile(final MapTileRequestState aState) throws CantContinueException
    {
      Drawable tile = drawMapsforgeTile(aState);
      if(tile == null)
        tile = downloadTile(aState);
      return tile;
    }

So, had off to Mapsforge to render the tile.  If Mapsforge failed - no data, out of bounds, etc - we go to the fallback tilesource and download a tile. 

You could extend this to something like

    @Override
    public Drawable loadTile(final MapTileRequestState aState) throws CantContinueException
    {
      Drawable tile = checkCache(aState);
      if(tile != null)
        return tile;

      tile = drawMapsforgeTile(aState);
      if(tile == null)
        tile = downloadTile(aState);

      if(tile != null)
         cacheTile(aState, tile);

      return tile;
    }

The OSMDroid FileWriter class can handle most of the mechanics of managing the cache, so you just need a bit of glue between the two.

Jez

manimaul

unread,
Nov 4, 2012, 12:55:13 PM11/4/12
to osmd...@googlegroups.com
I've been playing around with this for a bit.  Here is a very simple example utilizing Jez' code to overlay a mapsforge map on top of osmdoid.  I thought I'd share if anyone else is interested in this.

Will

---

import org.mapsforge.android.maps.MapsforgeOSMDroidTileProvider;
import org.mapsforge.android.maps.MapsforgeOSMTileSource;
import org.osmdroid.tileprovider.MapTileProviderArray;
import org.osmdroid.tileprovider.modules.MapTileModuleProviderBase;
import org.osmdroid.tileprovider.modules.NetworkAvailabliltyCheck;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.TilesOverlay;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;

public class MapActivity extends Activity {
    private final static String MAPSFORGE = "Mapsforge";
    private MapView mapView;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);
       
        mapView = (MapView) this.findViewById(R.id.mapview);
       
        //
        //mapsforge tile provider setup
        //
       
        final MapsforgeOSMTileSource mapsforgeTileSource = new MapsforgeOSMTileSource(MAPSFORGE);
        mapsforgeTileSource.setMapFile(Environment.getExternalStorageDirectory()+"/washington.map");
       
        final  NetworkAvailabliltyCheck networkCheck = new  NetworkAvailabliltyCheck(this);
       
        final MapsforgeOSMDroidTileProvider mapsforgeProvider =
                new MapsforgeOSMDroidTileProvider(TileSourceFactory.DEFAULT_TILE_SOURCE, networkCheck);
       
        mapsforgeProvider.setTileSource(mapsforgeTileSource);
       
        final MapTileModuleProviderBase[] myProviders = new MapTileModuleProviderBase[1];
        myProviders[0] = mapsforgeProvider;
        final MapTileProviderArray myMapTileProviderArray = new MapTileProviderArray(mapsforgeTileSource, null, myProviders);
        final TilesOverlay myOverlay = new TilesOverlay(myMapTileProviderArray, this);
        mapView.getOverlays().add(myOverlay);
       
        final MyHandler mHandler = new MyHandler(this);
       
        myMapTileProviderArray.setTileRequestCompleteHandler(mHandler);
       
        //
        //end mapsforge tile provider setup
        //
       
        mapView.setMultiTouchControls(true);
       
        final MapController mapController = mapView.getController();
        mapController.setZoom(10);
       
        final GeoPoint startPoint = new GeoPoint(47329981,-122456359);
        mapController.setCenter(startPoint);
       
    }
   
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_map, menu);
        return true;
    }
   
    private static class MyHandler extends Handler {
        private MapActivity mapActivity;
       
        public MyHandler(final MapActivity mapActivity) {
            this.mapActivity = mapActivity;
        }
       
        public void handleMessage(Message msg) {
            mapActivity.mapView.invalidate();
        }
    }
   
}

Ifor

unread,
Jan 4, 2013, 6:13:39 PM1/4/13
to osmd...@googlegroups.com
I have managed to get Jez's code modified to go though the tile cache system which I think is nessasary on an older phone.  I really think the code should get into the main development stream it's a very nice addition being able to have a local .map file for a big area localy as an alternative to haveing tile based files localy.
 
Basicaly I have had to modify the FileWriter class to make things protected so I can extend it to add in a new save() method taking the bitmap that MapsForge has generated and writing it to the cache.  There are modifications to Jez's tile source so it will work with the cache and then a variation on the Basic tile provider to use the new tile writer and add the new mapsforge provider into the chain.

Martin

unread,
Jan 5, 2013, 4:37:07 AM1/5/13
to osmd...@googlegroups.com
That sounds very interesting - do you plan to share your code?

Thanks.

Martin.

Ifor

unread,
Jan 5, 2013, 5:15:58 AM1/5/13
to osmd...@googlegroups.com
I would like to share my code by getting it into the project properly but don’t know how to go about this.  The fact I have had to change the TileWriter so I can extend it means you need more than just my new files...
 
I have the code checked out as a read only setup from 5 or 6 weeks back and at the moment am not at all keen on updating it as issues 388 will affect me.
 
Ifor
From: Martin
Sent: Saturday, January 05, 2013 9:37 AM
Subject: Re: osmdroid and mapsforge
 

Martin

unread,
Jan 7, 2013, 5:01:43 AM1/7/13
to osmd...@googlegroups.com
OK.

I'll continue to watch this thread and hopefully you'll post if and when your code is available?

Thanks.

Martin.

Sergey Yakovlev

unread,
Mar 8, 2013, 12:41:59 PM3/8/13
to osmd...@googlegroups.com
One more interested man here. Don`t abandon it please :)

суббота, 5 января 2013 г., 14:15:58 UTC+4 пользователь Ifor написал:

emux

unread,
Apr 28, 2013, 12:01:22 PM4/28/13
to osmd...@googlegroups.com
Mapsforge 0.4.0 (rewrite branch):
With the new layer architecture (currently under development in the Git rewrite branch) tile downloading is added again.
https://groups.google.com/forum/?fromgroups=#!topic/mapsforge-dev/cXQDkTQL00Y

MKergall

unread,
Sep 28, 2013, 2:34:16 PM9/28/13
to osmd...@googlegroups.com
+10 !

In my opinion, having mapsforge vector maps fully integrated as one of the standard tile providers is the main improvement to bring to osmdroid.

And on mapsforge side, having an automatic downloading of mapsforge maps (tiles) is a must have. Reasonably small areas, and a caching mechanism just like osmdroid one.

Ultimately, why not thinking about merging both projects, instead of having each one reinventing the wheel (GeoPoint, overlays, sample apps,...)?

emux

unread,
Nov 28, 2013, 2:50:30 PM11/28/13
to osmd...@googlegroups.com
Hi,

I've been experimenting lately with using Mapsforge as tile provider to Osmdroid
and indeed the result is interesting.

Though the rendering speed is quite slow..
I wonder what are your experiences about this?

I suspect the "synchronized" production of each tile bitmap is the cause,
but again without it the MapDatabase read gets corrupted.
Any ideas?

Best regards, Emux
https://play.google.com/store/apps/details?id=gr.talent.cruiser

Martin

unread,
Nov 29, 2013, 7:09:29 AM11/29/13
to osmd...@googlegroups.com
Yes Jez's code give us only a single rendering thread.

I recently ported Jez's code to work with the GoogleMaps TileProvider class and had hoped to modify it so that it could render tiles on multiple threads.
But it was above my skill levels so i gave up!

If anyone is interested in seeing the TileProvider implementation then let me know.

Martin.

Tony Montana

unread,
Apr 22, 2014, 9:46:11 AM4/22/14
to osmd...@googlegroups.com
welcome all!
Please share the results of your labors, really need to solution of this problem.
Thanks.

emux

unread,
Apr 22, 2014, 11:06:33 AM4/22/14
to osmd...@googlegroups.com
I have not invested more time at this idea.
But for completeness it's worth mentioning (if not already)
that another example of this approach exists here.

--
Emux
Cruiser - Atlas

MKergall

unread,
Apr 24, 2014, 5:31:14 PM4/24/14
to osmd...@googlegroups.com
I just integrated the solution from Salida Software in OSMBonusPack.
It works.

Unfortunately, this method doesn't allow to simply change the tile provider on an existing map.
I added some code in a GenericMapView, to keep as much MapView attributes as possible. But it's not ideal.

I will have a look on Jez method.

Reply all
Reply to author
Forward
0 new messages