anhtuanmai / osmdroid

Automatically exported from code.google.com/p/osmdroid
0 stars 0 forks source link

Loading tiles from the assets directory. #169

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Help request.

I am trying to load map tiles from the assets directory.

I see the I need to write a custom TileProvider, but am unsure where to go next:

The existing tile loaders make assumptions that the tile is coming from a URL 
or File, and the themselves translate into an InputStream. Unfortunately, the 
android.content.res.AssetManager can only give FileDescriptors and InputStreams.

This makes me think I need to write my own MapTileModuleProviderBase? 

Is this something likely to be supported in future?

** Design Critique; please ignore. ** 
** Likely due to lack of clarity in my own head. **
It's a shame that all the translating from Tile to InputStream can't be done in 
a single method on TileSource, then all Executors/ThreadPool etc can be done in 
a more generic TileLoader and MapTileProvider
** End of Design Critique **

Thanks. 

Original issue reported on code.google.com by gullcatc...@gmail.com on 26 Feb 2011 at 11:58

GoogleCodeExporter commented 8 years ago
The TileSource classes are designed to mostly encapsulate meta-data about the 
tile source and the MapTileModule classes are designed to do the work of 
pulling the data described by the TileSource. Your situation does probably call 
for creating a MapTileModule that does the work of pulling the data from the 
assets. You should probably extend BitmapTileSourceBase. It would likely ignore 
calls to setTileSource (unless the assets contains different tile sets). If you 
have recommendations for changes to the API to make this more generic without 
losing any current functionality, then we'd be happy to take a look!

Original comment by kurtzm...@gmail.com on 27 Feb 2011 at 4:27

GoogleCodeExporter commented 8 years ago
It should be possible to read zip and gemf files from the assets directory.

Original comment by neilboyd on 17 Mar 2011 at 3:32

GoogleCodeExporter commented 8 years ago
Attached is a patch that implements this.
It only works for GEMF files because that's the only type of archive where I 
can influence the reading from file to also be able to handle reading from 
assets.

I'd appreciate any feedback, especially from the people that implemented GEMF 
and the tile provider.

Also attached is the GEMF that should be placed in assets.

Original comment by neilboyd on 29 Mar 2011 at 10:01

Attachments:

GoogleCodeExporter commented 8 years ago
Has this issue been integrated into the code? Or should I download and apply it 
by myself?

Original comment by zetxek on 13 Jun 2011 at 10:22

GoogleCodeExporter commented 8 years ago
No it hasn't been integrated. I asked for feedback and didn't get any.

Original comment by neilboyd on 14 Jun 2011 at 4:58

GoogleCodeExporter commented 8 years ago
I really find this a quite interesting feature to have, as this way you don't 
need to have the maps on the SD card... I will surely download osmdroid source 
code and try your patch and give some feedback!

Original comment by zetxek on 14 Jun 2011 at 8:08

GoogleCodeExporter commented 8 years ago
Greetings,

Not sure if this thread is still alive. I came upon it when looking for 
information about using the assets folder to store tiles in.
Upon reading here, I downloaded and applied issue169.patch. Successfully 
testing it with haarlem.gemf, I converted the Osmdroid.zip file to gemf and put 
them into my assets folder. When launching the app, it failed to load the map 
with following error:

D/szipinf ( 1827): Initializing inflate state
E/o*.o*.t*.m*.ArchiveFil*( 1827): Error opening GEMF file
E/o*.o*.t*.m*.ArchiveFil*( 1827): java.io.FileNotFoundException: This file can 
not be opened as a file descriptor; it is probably compressed

I then put my gemf file in the original /sdcard/osmdroid folder and read it 
from there, with positive result. I could successfully view and zoom the map.
Since I have zoom levels down to 18, I recreated the map file(gemf) with lowest 
zoom level only and added it back to the assets folder. The map loaded nicely. 
I kept recreating the gemf with added zoom levels. Once reaching level 14, it 
crashed again with above exception. I removed zoom level 14 and added 15, 
causing the crash again. This happened for all zoom levels between 14-18. 
For above tests, I was using the CloudMade map source, but I also tested it 
using Mapnik, with same results, although I only had zoom levels to 16 there. 
The map always started failing for zoom level 14 and above.

Not sure why it kept crashing on high zooms, I tested creating a new gemf file 
from a random different area, and here it would work just fine all the way up 
to 18.

Was wondering if anyone have ideas of what may cause this problem? Perhaps I am 
using an incorrect method of creating the gemf files, though it seems to work 
for some places. 
Worst case, I can always go back to using the osmdroid folder, but I think 
being able to load maps from assets is a nice feature.

Some info in no particular order:
* patch issue169.patch added to checkout of 
http://osmdroid.googlecode.com/svn/trunk
    Revision: 1082
* Tried with CloudMade Default Style and Mapnik from mobac(no errors reported 
during download/creation), zoom levels 10 - 18. Map fails to load from zoom 
level 14 with both formats
* Atlas format used: Osmdroid ZIP
* gemf file conversion: unzip archive and run generate_efficient_map_file.py 
(kept getting a java.lang.NoClassDefFoundError: Could not initialize class 
org.osmdroid.tileprovider.util.StreamUtils when trying osmdroid-packager).

Here is the full trace:

D/GEMFFileArchive( 1827): constructor
D/GEMFFileArchive( 1827): constructor
D/GEMFFileArchive( 1827): constructor
D/szipinf ( 1827): Initializing inflate state
E/o*.o*.t*.m*.ArchiveFil*( 1827): Error opening GEMF file
E/o*.o*.t*.m*.ArchiveFil*( 1827): java.io.FileNotFoundException: This file can 
not be opened as a file descriptor; it is probably compressed
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
android.content.res.AssetManager.openAssetFd(Native Method)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
android.content.res.AssetManager.openFd(AssetManager.java:330)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
org.osmdroid.util.GEMFFile.getLength(GEMFFile.java:521)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
org.osmdroid.util.GEMFFile.readHeader(GEMFFile.java:465)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
org.osmdroid.util.GEMFFile.<init>(GEMFFile.java:96)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
org.osmdroid.util.GEMFFile.<init>(GEMFFile.java:83)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
org.osmdroid.tileprovider.modules.GEMFFileArchive.<init>(GEMFFileArchive.java:27
)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
org.osmdroid.tileprovider.modules.GEMFFileArchive.getGEMFFileArchive(GEMFFileArc
hive.java:31)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
org.osmdroid.tileprovider.modules.ArchiveFileFactory.getArchiveFile(ArchiveFileF
actory.java:54)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
org.osmdroid.tileprovider.modules.MapTileAssetsArchiveProvider.findArchiveFiles(
MapTileAssetsArchiveProvider.java:86)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
org.osmdroid.tileprovider.modules.MapTileAssetsArchiveProvider.<init>(MapTileAss
etsArchiveProvider.java:35)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
org.osmdroid.samples.SampleWithTilesInAssets.onCreate(SampleWithTilesInAssets.ja
va:27)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
android.app.ActivityThread.access$1500(ActivityThread.java:117)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
android.os.Handler.dispatchMessage(Handler.java:99)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at android.os.Looper.loop(Looper.java:123)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
android.app.ActivityThread.main(ActivityThread.java:3683)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
java.lang.reflect.Method.invokeNative(Native Method)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
java.lang.reflect.Method.invoke(Method.java:507)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
E/o*.o*.t*.m*.ArchiveFil*( 1827):   at dalvik.system.NativeStart.main(Native 
Method)

Thanks

Original comment by hja...@gmail.com on 29 Mar 2012 at 5:45

GoogleCodeExporter commented 8 years ago
It has been a year with no activity, any updates on this issue?

Original comment by madfi...@gmail.com on 4 Nov 2012 at 11:36

GoogleCodeExporter commented 8 years ago
I'm unlikely to work any more on this since it can only work for GEMF files and 
I don't use them and according to comment 7 even that isn't working.

Original comment by neilboyd on 5 Nov 2012 at 6:20

GoogleCodeExporter commented 8 years ago
Apparently the compression issue is because Android SDK under 2.3 cannot read 
compressed files larger than 1MB.

You can skip compression by renaming the file to *.mp3.

http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-a
pps/

Original comment by dzei...@gmail.com on 22 Nov 2012 at 1:26

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
I wrote a small tile source and a provider to read png from the assets folder 
using the "z/x/y" structure and it seems to work.

Original comment by dzei...@gmail.com on 26 Nov 2012 at 2:17

GoogleCodeExporter commented 8 years ago
I'm not actively working on this any more, but it looks hopeful that it would 
work like this.
@dzeikei perhaps you could post the patch here.

Original comment by neilboyd on 26 Nov 2012 at 5:55

GoogleCodeExporter commented 8 years ago
This if for a special use case where you only ever need to show a small part 
the world and need offline access from the start.
Here is a simple tilesource and a tileprovider to read tile pngs from 
"assets/map/z/x/y" assets folder structure.

Use like this:
public static final AssetsTileSource ASSETS_TILE_SOURCE = new 
AssetsTileSource(getActivity().getAssets(), "Map", 
ResourceProxy.string.offline_mode, 14, 17, 256, ".png"); // This will load from 
/Map/14/12345/12345.png

MapTileModuleProviderBase moduleProvider = new 
MapTileFileAssetsProvider(ASSETS_TILE_SOURCE);
SimpleRegisterReceiver simpleReceiver = new 
SimpleRegisterReceiver(this.getActivity());
MapTileProviderArray tileProviderArray = new 
MapTileProviderArray(ASSETS_TILE_SOURCE, simpleReceiver, new 
MapTileModuleProviderBase[] { moduleProvider });

Original comment by dzei...@gmail.com on 4 Dec 2012 at 10:38

Attachments:

GoogleCodeExporter commented 8 years ago
I'm trying to use your classes to load a map from the assets.
I am able to show the map, but it doesn't load very well: the map is shown only 
if I touch the screen to scroll or to zoom. Then, when I zoom in or out, the 
map disappear again (There no map, just the gray grid).

I workarounded this problem by calling "mapView.invalidate()" just after the 
creation and each time I zoom, but it's not very effective, we always see the 
map disappearing and re appearing again...

Can you help me with this?

Original comment by cilia.r...@gmail.com on 12 Apr 2013 at 12:59

GoogleCodeExporter commented 8 years ago
My code only works if you actually have tiles for the particular zoom level.
I had to limit the mapview's panning and zoom levels to match the included 
tiles.

Original comment by dzei...@gmail.com on 12 Apr 2013 at 1:31

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
I have the tiles in the assets, for all zoom levels.
The problem is just about refreshing after a zoom. If I scroll a little bit the 
map, the tiles appear.

Edit: here is a screencast of my problem: 
http://nyphel.com/~neoz/screencast_osmdroid.webm
As you can see, I have to touch the screen to update the map. 
Do you see what could be the problem?

Original comment by cilia.r...@gmail.com on 12 Apr 2013 at 2:49

GoogleCodeExporter commented 8 years ago
Weird because I never had that kind of issue.
I'm guessing for some reason, AssetsTileSource is not being set before the map 
is first shown.

Original comment by dzei...@gmail.com on 15 Apr 2013 at 1:11

GoogleCodeExporter commented 8 years ago
Ok, I don't really understand, I tried to initialize "ASSETS_TILE_SOURCE" in 
different places (in the mapview, in the activity...) but my problem is still 
there.
Anyway, I workarrouned by calling "invalidate()" in the "dispatchDraw" method 
of the mapview.
Thanks for your help!

Original comment by cilia.r...@gmail.com on 15 Apr 2013 at 2:47

GoogleCodeExporter commented 8 years ago
Hi dzei,

I couldn't get your code to work, not sure where I'm going wrong. It looks like 
it's working, but the map images aren't loading. Do you have an example of 
really simple Activity class that I could just plug in and try out? It would be 
great if you could provide a simple starting point which people like me could 
work from.

Original comment by p...@wscreative.co.uk on 19 Apr 2013 at 4:08

GoogleCodeExporter commented 8 years ago
Hi,
I tried to do load map tiles from assets but I can't understand what is 
"ASSETS_TILE_SOURCE" how can i initialize it ? 

can any one tell me please ?

Original comment by Rania....@gmail.com on 14 Aug 2013 at 12:13

GoogleCodeExporter commented 8 years ago
hi
why there is not a good sample for offline map? anybody can help me? 

Original comment by arashsam...@gmail.com on 7 Nov 2014 at 9:03