MJakhongir
MJakhongir

Reputation: 3018

OSMDROID - loading .map file downloaded from mapsforge

I'm trying to load .map file which is placed in /assets folder in android studio. The .map file was downloaded from mapsforge @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

    map = (MapView) findViewById(R.id.map);
    map.setBuiltInZoomControls(true);
    map.setTileSource(TileSourceFactory.MAPNIK);
    IMapController controller = map.getController();
    GeoPoint point = new GeoPoint(41.2585, 69.2097);
    controller.animateTo(point);
    controller.setZoom(10);

    File f = new File("file:///android_asset/" + "myfile.map");
    if (f.exists()) {
        File[] list = f.listFiles();
        if (list != null) {
            for (int i = 0; i < list.length; i++) {
                if (list[i].isDirectory()) {
                    continue;
                }
                String name = list[i].getName().toLowerCase();
                if (!name.contains(".")) {
                    continue; //skip files without an extension
                }
                name = name.substring(name.lastIndexOf(".") + 1);
                if (name.length() == 0) {
                    continue;
                }
                if (ArchiveFileFactory.isFileExtensionRegistered(name)) {
                    try {
                        OfflineTileProvider tileProvider = new OfflineTileProvider(new SimpleRegisterReceiver(this),
                                new File[]{list[i]});
                        map.setTileProvider(tileProvider);
                        String source = "";
                        IArchiveFile[] archives = tileProvider.getArchives();
                        if (archives.length > 0) {
                            Set<String> tileSources = archives[0].getTileSources();
                            if (!tileSources.isEmpty()) {
                                source = tileSources.iterator().next();
                                map.setTileSource(FileBasedTileSource.getSource(source));
                            } else map.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);

                        } else map.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
                        map.invalidate();
                        return;
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
        Toast.makeText(this, f.getAbsolutePath() + " did not have any files I can open! Try using MOBAC", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(this, f.getAbsolutePath() + " dir not found!", Toast.LENGTH_SHORT).show();
    }
}

Getting error "myfileDirectory" did not found.

Upvotes: 0

Views: 2758

Answers (3)

MJakhongir
MJakhongir

Reputation: 3018

answering my own question, *.map file needs to be placed under /sdcard/osmdroid/

credits to http://programtalk.com/java-api-usage-examples/org.osmdroid.mapsforge.MapsForgeTileProvider/

inside OnCreate ...

    mMap = (MapView) findViewById(R.id.map);
    Set<File> mapfiles = findMapFiles();
    File[] maps = new File[mapfiles.size()];
    maps = mapfiles.toArray(maps);
    if (maps.length==0)Log.d(TAG, "No Mapsforge files found");
    else Toast.makeText(this, "Loaded " + maps.length + " map files",
   Toast.LENGTH_LONG).show(); 
    XmlRenderTheme theme = null;
    try {
        theme = new AssetsRenderTheme(getApplicationContext(), 
     "renderthemes/","rendertheme-v4.xml");
    }catch (Exception ex){
        ex.printStackTrace();
    }
    MapsForgeTileProvider forge = new MapsForgeTileProvider(new   
    SimpleRegisterReceiver(this), MapsForgeTileSource.createFromFiles(maps,  
    theme, "rendertheme-v4"), null);
    mMap.setTileProvider(forge);
    mMap.setUseDataConnection(false);
    mMap.setMultiTouchControls(true);
    mMap.setBuiltInZoomControls(true);
  • methods to get .map file

    protected static Set<File> findMapFiles() {
    Set<File> maps = new HashSet<>();
    List<StorageUtils.StorageInfo> storageList =   
    StorageUtils.getStorageList();
    for (int i = 0; i < storageList.size(); i++) {
        File f = new File(storageList.get(i).path + File.separator +  
    "osmdroid" + File.separator);
        if (f.exists()) {
            maps.addAll(scan(f));
        }
    }
    return maps;
    }
    
    static private Collection<? extends File> scan(File f) {
    List<File> ret = new ArrayList<>();
    File[] files = f.listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            if (pathname.getName().toLowerCase().endsWith(".map"))
                return true;
            return false;
        }
    });
    if (files != null) {
        for (int i = 0; i < files.length; i++) {
            ret.add(files[i]);
        }
    }
    return ret;
    

    }

Upvotes: 1

spy
spy

Reputation: 3258

Since I wrote the code you posted, I figured I'm chime in.

  1. The code you posted is really for loading a collection of offline tile databases that osmdroid supports with the default tile provider chain (sqlite, mbtile, zip, etc). Mapsforge is not in that list since it's a special case scenario.
  2. To use maps forge provided tiles with osmdroid, you should probably follow this example https://github.com/osmdroid/osmdroid/blob/master/OpenStreetMapViewer/src/main/java/org/osmdroid/samplefragments/tileproviders/MapsforgeTileProviderSample.java I'm sure you'll kind all kinds of other useful examples there.
  3. Bundling map files or any other database within the assets folder (although it's possible to do) loading this tiles in osmdroid isn't possible except for storing raw jpg/pngs in assets. So if bundling in assets is your chosen path, you'll want to copy the database to device storage, then tell osmdroid to load it. I'm not sure why but it may have to do with permissions.

To save you some time, here's the relevant snippet of code where by maps is a File[].

XmlRenderTheme theme = null;
        try {
            theme = new AssetsRenderTheme(getContext().getApplicationContext(), "renderthemes/", "rendertheme-v4.xml");
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        fromFiles = MapsForgeTileSource.createFromFiles(maps, theme, "rendertheme-v4");
        forge = new MapsForgeTileProvider(
            new SimpleRegisterReceiver(getContext()),
            fromFiles, null);


        mMapView.setTileProvider(forge);

Upvotes: 2

greenapps
greenapps

Reputation: 11224

If OfflineTileProvider cannot read from an InputStream but needs a File object to a .map file then you should care for real files first.

So copy all 'files' from assets to files on the file system first.

After that you can use those files.

Code to copy files from assets to file storage has been published a hundred times here.

Upvotes: 0

Related Questions