1

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

    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
4

2 回答 2

2

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

  1. 将您的 map.mbtiles 文件放入/assets文件夹,而不是 res/raw/
  2. 在首次应用程序启动期间复制文件。我只是在你的onCreate()方法中调用copyAssets() 。请参阅下面的代码,这会将资产下的所有内容复制到应用程序私有文件夹。请注意,您可能希望在此处添加对典型文件写入问题案例的处理: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);
    }
}
于 2014-05-26T07:22:45.753 回答
0

我也遇到了同样的问题。以下链接肯定会对您有所帮助:

https://github.com/nutiteq/hellomap3d/wiki/Offline-map-tiles

如何在 android 中使用 nutiteq 处理离线 3D 地图

请让我知道它是否有效。

于 2014-05-26T05:56:09.657 回答