android - 使用 Nutiteq 为 Android 导入 .mbfiles 扩展文件

标签 android nutiteq mbtiles

在你发表评论后,JaakL 我做了一些工作,这是我所能得到的。 不幸的是,它还没有工作。 我按照你告诉我的一步一步地做了,但每次我加载应用程序时,我只会看到一个白色的屏幕,而不是我试图加载的漂亮 map 。

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    MapView mapView;
    mapView=(MapView)findViewById(R.id.mapView);



    // Optional, but very useful: restore map state during device rotation,
    // it is saved in onRetainNonConfigurationInstance() below
    Components retainObject = (Components) getLastNonConfigurationInstance();
    if (retainObject != null) {
        // just restore configuration and update listener, skip other initializations

        mapView.setComponents(retainObject);

        return;
    } else {
        // 2. create and set MapView components - mandatory

        mapView.setComponents(new Components());
    }

        copyAssets();

        try {
            MBTilesRasterDataSource dataSource = new MBTilesRasterDataSource(
                    new EPSG3857(), 0, 19,
                    (null).getAbsolutePath() + "/braga.mbtiles",
                    false, this);
            RasterLayer mbLayer = new RasterLayer(dataSource, 0);
            mapView.getLayers().addLayer(mbLayer);
        } catch (IOException e) {
            Log.error(e.getMessage());
        }

我的调试器的前三行:

        27337-27337/com.exaple.myapplication5.app E/Trace﹕ error opening trace file: No such file or directory (2)
        27337-27337/com.exaple.myapplication5.app W/ActivityThread﹕ Application    com.exaple.myapplication5.app is waiting for the debugger on port 8100...
        27337-27337/com.exaple.myapplication5.app I/System.out﹕ Sending WAIT chunk

最佳答案

技巧是您需要将文件从应用程序包复制到设备存储,否则您无法打开 MBtiles 文件。

  1. 将您的 map.mbtiles 文件放入 /assets 文件夹,而不是 res/raw/
  2. 在第一次启动应用程序时复制文件。我只是在您的 onCreate() 方法中调用 copyAssets()。请参阅下面的代码,这会将 Assets 下的所有内容复制到应用程序私有(private)文件夹。请注意,您可能希望在此处添加对典型文件写入问题案例的处理:SD 卡不可用、无写入权限(您的应用必须具有 WRITE_EXTERNAL_STORAGE 权限)、空间不足,可能还有其他问题。
  3. 使用正确的路径创建数据源和图层:

示例代码:

@Override
public void onCreate(Bundle savedInstanceState) {
  // create mapview, settings...

    copyAssets();
    try {
        MBTilesRasterDataSource dataSource = new MBTilesRasterDataSource(
            new EPSG3857(), 0, 19, 
            getExternalFilesDir(null).getAbsolutePath()+"/map.mbtiles",
            false, this);
        RasterLayer mbLayer = new RasterLayer(dataSource, 0);
        // use setBaseLayer() if this is main layer, addLayer() if it is overlay layer
        mapView.getLayers().setBaseLayer(mbLayer);

        // recenter map to coverage
        HashMap<String, String> dbMetaData = dataSource.getDatabase().getMetadata();

        String center = dbMetaData.get("center");
        String bounds = dbMetaData.get("bounds");
        if(center != null){
            // format: long,lat,zoom
            String[] centerParams = center.split(",");
            mapView.setFocusPoint(mapView.getLayers().getBaseLayer().getProjection().fromWgs84(Double.parseDouble(centerParams[0]), Double.parseDouble(centerParams[1])));
            mapView.setZoom(Float.parseFloat(centerParams[2]));
            Log.debug ("center to point "+Arrays.toString(centerParams));
        }else if(bounds != null){
            // format: longMin,latMin,longMax,latMax
            String[] boundsParams = bounds.split(",");
            MapPos bottomLeft = mapView.getLayers().getBaseProjection().fromWgs84(Double.parseDouble(boundsParams[0]), Double.parseDouble(boundsParams[1]));
            MapPos topRight = mapView.getLayers().getBaseProjection().fromWgs84(Double.parseDouble(boundsParams[2]), Double.parseDouble(boundsParams[3]));
            Log.debug ("center to bounds "+bottomLeft.x+","+topRight.y+","+topRight.x+","+bottomLeft.y);
            mapView.setBoundingBox(new Bounds(bottomLeft.x,topRight.y,topRight.x,bottomLeft.y), false);

            // check that zoom is within given range
            int[] zoomRange = dataSource.getDatabase().getZoomRange();
            if(mapView.getZoom() < zoomRange[0]){
                mapView.setZoom(zoomRange[0]+1);
            }
            if(mapView.getZoom() > zoomRange[1]){
                mapView.setZoom(zoomRange[1]-1);
            }

        }else{
            // bulgaria
            mapView.setFocusPoint(mapView.getLayers().getBaseLayer().getProjection().fromWgs84(26.483230800000037, 42.550218000000044));
            // zoom - 0 = world, like on most web maps
            mapView.setZoom(5.0f);
            Log.debug("center to default");
        }
    } catch (IOException e) {
        Log.error(e.getMessage());
    }


  // ...
 }

private void copyAssets() {
    AssetManager assetManager = getAssets();
    String[] files = null;
    try {
        files = assetManager.list("");
    } catch (IOException e) {
        Log.error("Failed to get asset file list." + e.getLocalizedMessage());
    }
    for(String filename : files) {
        InputStream in = null;
        OutputStream out = null;
        try {
          in = assetManager.open(filename);
          File outFile = new File(getExternalFilesDir(null), filename);

          if(!outFile.exists()){
              out = new FileOutputStream(outFile);
              copyFile(in, out);
              out.flush();
              out.close();
              out = null;
          }

          in.close();
          in = null;

        } catch(IOException e) {
            Log.error("Failed to copy asset file: " + filename + "\n" + e.getLocalizedMessage());
        }       
    }
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[32 * 1024];
    int read;
    while((read = in.read(buffer)) != -1){
      out.write(buffer, 0, read);
    }
}

关于android - 使用 Nutiteq 为 Android 导入 .mbfiles 扩展文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23861670/

相关文章:

java - 从 Nutiteq map 中删除标记的正确方法

ios - 在 iOS 中使用导航的私有(private)属性(property)离线 map

android - 渐变仅到达屏幕边缘 - 而不是 html(手机上的 html/css)

android - 在菜单项的右侧显示抽屉菜单图标

android ListView 可点击问题

php - 用 PHP 读取 openstreetmap PBF 文件?

android - 在 Google Map V2 上加载 MBtiles

java - Android 错误 : DateFormat() sometimes shows 12hr format, 当它应该显示 24 小时制时

java - LineStyleBuilder 等无法解析 setColor() 等函数

android - nutiteq map 上的折线 onLocattionChanged