OSMDROID - 加载从 mapsforge 下载的 .map 文件

Posted

技术标签:

【中文标题】OSMDROID - 加载从 mapsforge 下载的 .map 文件【英文标题】:OSMDROID - loading .map file downloaded from mapsforge 【发布时间】:2017-08-11 19:55:00 【问题描述】:

我正在尝试加载 .map 文件,该文件位于 android studio 的 /assets 文件夹中。 .map 文件是从 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();
    

未找到错误“myfileDirectory”。

【问题讨论】:

File f = new File("file:///android_asset/" + "myfile.map");。这不起作用,因为 File 类无法处理资产中的文件。谷歌了解如何从资产中读取文件。 if (f.exists()) File[] list = f.listFiles();。如果f 是您的 .map 文件,那么您怎么能认为您可以列出文件?您并没有像您所说的那样尝试加载该文件,而是将其视为目录。 我尝试使用 InputStream 从资产中读取,但在这里我需要它是 File 而不是 inputStream,我应该在读取后将 inputStream 转换为 File 吗? 您不能将 InputStream 转换为 FIle 对象。你没有对我所说的文件打开和目录列表做出反应。而且您还没有告诉您为什么需要 File 对象。很不清楚你想要你的代码是什么。请先写一篇像样的文章。 我需要在地图视图中打开从mapsforge下载的单个.map文件,如果你不知道怎么做,那么判断我的帖子没有意义 【参考方案1】:

自从我编写了您发布的代码以来,我认为我可以加入。

    您发布的代码实际上是用于加载 osmdroid 使用默认切片提供程序链(sqlite、mbtile、zip 等)支持的离线切片数据库集合。 Mapsforge 不在该列表中,因为它是一种特殊情况。 要在 osmdroid 中使用 maps forge 提供的图块,您可能应该遵循此示例 https://github.com/osmdroid/osmdroid/blob/master/OpenStreetMapViewer/src/main/java/org/osmdroid/samplefragments/tileproviders/MapsforgeTileProviderSample.java 我相信您会在此处提供各种其他有用的示例。 在资产文件夹中捆绑地图文件或任何其他数据库(尽管可以这样做)在 osmdroid 中加载此图块是不可能的,除非将原始 jpg/png 存储在资产中。因此,如果捆绑资产是您选择的路径,您需要将数据库复制到设备存储,然后告诉 osmdroid 加载它。我不知道为什么,但这可能与权限有关。

为了节省您一些时间,这里是相关的 sn-p 代码,其中 mapsFile[]

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

【讨论】:

非常感谢,我会检查【参考方案2】:

回答我自己的问题, *.map文件需要放在/sdcard/osmdroid/下

感谢http://programtalk.com/java-api-usage-examples/org.osmdroid.mapsforge.MapsForgeTileProvider/

在 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);

获取.map文件的方法

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;

【讨论】:

【参考方案3】:

如果OfflineTileProvider 无法从InputStream 读取,但需要File 对象到.map 文件,那么您应该首先关注真实文件。

因此,首先将资产中的所有“文件”复制到文件系统上的文件中。

之后你就可以使用这些文件了。

将文件从资产复制到文件存储的代码已在此处发布了一百次。

【讨论】:

只有一个 .map 文件 答案对一个文件也有效。你想说什么?

以上是关于OSMDROID - 加载从 mapsforge 下载的 .map 文件的主要内容,如果未能解决你的问题,请参考以下文章

Osmdroid:如何从我自己的位图(图块)创建和加载地图?

OSMDroid 从资产文件夹加载自定义离线图块

osmdroid:加载自定义tilesource时显示的乱码

osmdroid离线地图不加载瓷砖

在android中使用mapsforge的离线地图

Osmdroid 和 Mapnik 磁贴提供程序不再工作