使用Nutiteq导入Android的.mbfiles扩展文件

使用Nutiteq导入Android的.mbfiles扩展文件,android,nutiteq,mbtiles,Android,Nutiteq,Mbtiles,在你评论JaakL之后,我做了一些工作,这就是我所能做的。 不幸的是,它还不起作用。 我一步一步地按照你告诉我的做了,但是每次我加载应用程序时,我都会看到一个白色的屏幕,而不是我正在加载的漂亮地图 super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MapView mapView; mapView=(MapView)findViewById(R.id.mapVie

在你评论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

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


请让我知道它是否有效。

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

  • 将map.mbtiles文件放入/assets文件夹,而不是res/raw/
  • 在第一次应用程序启动期间复制文件。我只需要在onCreate()方法中调用copyAssets()。请参阅下面的代码,这会将资产下的所有内容复制到应用程序专用文件夹。请注意,您可能希望在此处添加对典型文件写入问题的处理:SD卡不可用、没有写入权限(您的应用程序必须具有写入\u外部\u存储权限)、空间不足,可能还有其他问题
  • 创建具有正确路径的数据源和图层:
  • 示例代码:

    @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);
        }
    }
    
    @覆盖
    创建时的公共void(Bundle savedInstanceState){
    //创建地图视图、设置。。。
    复制资产();
    试一试{
    MBTILERStartDataSource=新MBTILERStartDataSource(
    新的EPSG3857(),0,19,
    getExternalFilesDir(null).getAbsolutePath()+“/map.mbtiles”,
    假的,这个);
    RasterLayer mbLayer=新的RasterLayer(数据源,0);
    //如果这是主层,请使用setBaseLayer(),如果是覆盖层,请使用addLayer()
    mapView.getLayers().setBaseLayer(mbLayer);
    //重新居中映射到覆盖范围
    HashMap dbMetaData=dataSource.getDatabase().getMetadata();
    字符串中心=dbMetaData.get(“中心”);
    字符串边界=dbMetaData.get(“边界”);
    如果(中心!=null){
    //格式:长、横向、缩放
    字符串[]centerParams=center.split(“,”);
    mapView.setFocusPoint(来自WGS84的mapView.getLayers().getBaseLayer().getProjection()(Double.parseDouble(centerParams[0])、Double.parseDouble(centerParams[1]);
    setZoom(Float.parseFloat(centerParams[2]);
    Log.debug(“中心到点”+Arrays.toString(centerParams));
    }else if(界限!=null){
    //格式:longMin、latMin、longMax、latMax
    字符串[]boundsParams=bounds.split(“,”);
    MapPos bottomLeft=mapView.getLayers().getBaseProjection().froms84(Double.parseDouble(boundsParams[0])、Double.parseDouble(boundsParams[1]);
    MapPos topRight=mapView.getLayers().getBaseProjection().fromWgs84(Double.parseDouble(boundsParams[2])、Double.parseDouble(boundsParams[3]);
    Log.debug(“中心到边界”+bottomLeft.x+,“+topRight.y+,“+topRight.x+,”+bottomLeft.y+);
    setBoundingBox(新边界(bottomLeft.x,topRight.y,topRight.x,bottomLeft.y),false);
    //检查缩放是否在给定范围内
    int[]zoomRange=dataSource.getDatabase().getZoomRange();
    if(mapView.getZoom()zoomRange[1]){
    设置缩放(缩放范围[1]-1);
    }
    }否则{
    //保加利亚
    mapView.setFocusPoint(来自WGS84的mapView.getLayers().getBaseLayer().getProjection()(26.48323080000037,42.550218000000044));
    //zoom-0=世界,与大多数web地图一样
    mapView.setZoom(5.0f);
    Log.debug(“中心到默认值”);
    }
    }捕获(IOE异常){
    Log.error(例如getMessage());
    }
    // ...
    }
    私人资产(){
    AssetManager AssetManager=getAssets();
    String[]files=null;
    试一试{
    files=assetManager.list(“”);
    }捕获(IOE异常){
    Log.error(“获取资产文件列表失败。”+e.getLocalizedMessage());
    }
    用于(字符串文件名:文件){
    InputStream in=null;
    OutputStream out=null;
    试一试{
    in=assetManager.open(文件名);
    File outFile=新文件(getExternalFilesDir(null),文件名);
    如果(!outFile.exists()){
    out=新文件输出流(输出文件);
    复制文件(输入、输出);
    out.flush();
    out.close();
    out=null;
    }
    in.close();
    in=null;
    }捕获(IOE异常){
    Log.error(“复制资产文件失败:”+filename+“\n”+e.getLocalizedMessage());
    }       
    }
    }
    私有void copyFile(输入流输入,输出流输出)引发IOException{
    字节[]缓冲区=新字节[32*1024];
    int-read;
    while((read=in.read(buffer))!=-1){
    输出。写入(缓冲区,0,读取);
    }
    }
    
    谢谢您的回复。这不是我想要的!:)哦……那你把它复制到你的设备存储器了吗?JaakL已经帮我解决了,不过谢谢你的建议!:)我已经更新了我的帖子。任何帮助都会很棒。谢谢你们有设置baseLayer吗?如果mbtiles本身是基础层,而不是覆盖层,则使用setBaseLayer()而不是addLayer()。我在上面更新了我的样本,我两个都试过了,但仍然不起作用。我已经用调试器的前3行更新了我的原始帖子(其中包含一些错误)。请确保缩放并居中映射到真实内容所覆盖的区域。我添加了示例代码以从元数据自动检测mbtiles区域,但这取决于元数据是否存在。调试器行在这里不是很相关。你好,JaakL。谢谢你给我的所有信息,尽管我有两个小问题,但到目前为止它工作得很好。1.有时整个地图加载得很好,但有时不会加载整个地图。2.当我尝试拖动屏幕以查看地图的某些部分时,整个地图加载