导入.mbfiles扩展文件为Android与Nutiteq [英] Importing .mbfiles extension files for Android with Nutiteq

查看:356
本文介绍了导入.mbfiles扩展文件为Android与Nutiteq的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您的评论JaakL后,我做了一些工作,这是据我得到了。
不幸的是,它不工作呢。
我也一步一步你告诉我但我每次加载应用程序时我只想找到一个白色的屏幕,而不是美丽的地图,我试图加载的。

  super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);    MapView类MapView类;
    图形页面=(图形页面)findViewById(R.id.mapView);    //可选的,但非常有用的:装置在旋转过程中恢复状态的地图,
    //(下)它保存在onRetainNonConfigurationInstance
    组件retainObject =(组件)getLastNonConfigurationInstance();
    如果(retainObject!= NULL){
        //刚恢复的配置和更新监听器,跳过其他初始化        mapView.setComponents(retainObject);        返回;
    }其他{
        // 2.创建和设置图形页面组件 - 强制        mapView.setComponents(新组件());
    }        copyAssets();        尝试{
            MBTilesRasterDataSource数据源=新MBTilesRasterDataSource(
                    新EPSG3857(),0,19,
                    (空).getAbsolutePath()+/braga.mbtiles
                    假的,这一点);
            RasterLayer mbLaye​​r =新RasterLayer(数据源,0);
            。mapView.getLayers()addLayer(mbLaye​​r);
        }赶上(IOException异常五){
            Log.error(e.getMessage());
        }

前三行我的调试器:

  27337-27337 / com.exaple.myapplication5.app E /跟踪:错误打开跟踪文件:没有这样的文件或目录(2)
        27337-27337 / com.exaple.myapplication5.app W / ActivityThread:应用com.exaple.myapplication5.app正在等待调试器端口8100 ...
        27337-27337 / com.exaple.myapplication5.app I / System.out的:发送WAIT块


解决方案

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


  1. 把你的map.mbtiles文件为 /资产文件夹,而不是RES /生/

  2. 第一个应用程序启动时将文件复制。我只是打电话的 copyAssets()的在你的的onCreate()的方法。请参见下面code,根据资产这份一切APP的私有文件夹。请注意,您可能需要添加典型的文件写入的问题的情况下处理有:SD卡无法使用,没有写权限(您的应用程序必须有WRITE_EXTERNAL_STORAG​​E许可),没有足够的空间,也许更多的东西

  3. 创建数据源和层正道:

样code:

  @覆盖
公共无效的onCreate(捆绑savedInstanceState){
  //创建图形页面,设置...    copyAssets();
    尝试{
        MBTilesRasterDataSource数据源=新MBTilesRasterDataSource(
            新EPSG3857(),0,19,
            getExternalFilesDir(空).getAbsolutePath()+/ map.mbtiles
            假的,这一点);
        RasterLayer mbLaye​​r =新RasterLayer(数据源,0);
        //使用setBaseLayer()如果这是主层,addLayer(),如果它是覆盖层
        。mapView.getLayers()setBaseLayer(mbLaye​​r);        // recenter地图覆盖
        HashMap的<字符串,字符串> dbMetaData = dataSource.getDatabase()的getMetaData()。        中锋= dbMetaData.get(中心);
        字符串边界= dbMetaData.get(边界);
        如果(中心!= NULL){
            //格式:长,纬度,放大
            串[] 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(中心指向+ Arrays.toString(centerParams));
        }否则如果(界限!= NULL){
            //格式:隆民,latMin,longMax,latMax
            串[] 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(中心到边界+ bottomLeft.x +,+ topRight.y +,+ topRight.x +,+ bottomLeft.y);
            mapView.setBoundingBox(新边界(bottomLeft.x,topRight.y,topRight.x,bottomLeft.y),FALSE);            //检查变焦是给定范围内
            INT [] = zoomRange dataSource.getDatabase()getZoomRange()。
            如果(mapView.getZoom()&下; zoomRange [0]){
                mapView.setZoom(zoomRange [0] +1);
            }
            如果(mapView.getZoom()> zoomRange [1]){
                mapView.setZoom(zoomRange [1] -1);
            }        }其他{
            //保加利亚
            mapView.setFocusPoint(mapView.getLayers().getBaseLayer().getProjection().fromWgs84(26.483230800000037, 42.550218000000044));
            //变焦 - 0 =世界,就像大多数Web地图
            mapView.setZoom(5.0F);
            Log.debug(中央默认);
        }
    }赶上(IOException异常五){
        Log.error(e.getMessage());
    }
  // ...
 }私人无效copyAssets(){
    AssetManager assetManager = getAssets();
    的String []文件= NULL;
    尝试{
        文件= assetManager.list();
    }赶上(IOException异常五){
        Log.error(无法获取资产的文件列表。+ e.getLocalizedMessage());
    }
    对于(字符串文件名:文件){
        在的InputStream = NULL;
        出的OutputStream = NULL;
        尝试{
          在= assetManager.open(文件名);
          文件不过outFile =新的文件(getExternalFilesDir(空),文件名);          如果(!outFile.exists()){
              OUT =新的FileOutputStream(不过outFile);
              copyFile(IN,OUT);
              了out.flush();
              out.close();
              出= NULL;
          }          附寄();
          在= NULL;        }赶上(IOException异常五){
            Log.error(无法复制资源文件:+文件名+\\ n+ e.getLocalizedMessage());
        }
    }
}
私人无效copyFile(在的InputStream,OutputStream的了)抛出IOException
    字节[]缓冲区=新的字节[32 * 1024];
    INT读;
    而((读= in.read(缓冲))!= -1){
      out.write(缓冲,0,读);
    }
}

After your comment JaakL I did a bit of work and this is as far as I got. Unfortunately, it's not working yet. I did step by step what you told me but every time I load the app I just get a white screen instead of the beautiful map I'm trying to load.

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

First three lines of my debugger :

        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

解决方案

The trick is that you need to copy the file from application package to device storage, otherwise you cannot open the MBtiles file.

  1. Put your map.mbtiles file to /assets folder, not to res/raw/
  2. Copy the file during first application start. I'd just call copyAssets() in your onCreate() method. See code below, this copies everything under assets to app private folder. Note that you may want to add handling of typical file write issue cases there: SD card not available, no permission to write (your app must have WRITE_EXTERNAL_STORAGE permission), not enough space, maybe something more.
  3. Create datasource and layer with right path:

Sample code:

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

这篇关于导入.mbfiles扩展文件为Android与Nutiteq的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆