0
votes

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.

3
File f = new File("file:///android_asset/" + "myfile.map");. That does not work as the File class cannot handle files from assets. Google for how to read a file from assets. - greenapps
if (f.exists()) { File[] list = f.listFiles();. If f is your .map file then how can you think you could list files? You are not trying to load that file as you stated but treating it as a directory instead. - greenapps
i tried reading from assets with InputStream but here i need it to be File not inputStream, should i convert inputStream to File after reading it? - MJakhongir
You cannot convert an InputStream to a FIle object. And you did not react on what i said about file opening and directory listing. And you have not told why you need a File object. It is pretty unclear what you want with your code. Please write a decent post first. - greenapps
i need to open a single .map file downloaded from mapsforge in a map view, if you do not know how to do it, there is no point judging my post - MJakhongir

3 Answers

2
votes

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);
1
votes

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;
    

    }

0
votes

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.