ArcGIS for Android 100 系列(六)、离线地图数据加载

1,455 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

ArcGIS 学习笔记系列

1、Arcgis for Android 100 系列(一)、环境配置和地图加载

2、ArcGIS for Android 100 系列(二)、地图基本操作,放大缩小,加载点线面,标注

3、ArcGIS for Android 100 系列(三)、点、线、面等图斑的常见的空间操作

前文介绍了在线图层的加载,但地图应用中离线加载图层的场景还是挺常见的,这时就需要学习如何加载离线地图数据包了。

ArcGIS 离线地图格式有多种:

  • shape 文件
  • mmpk(Mobile Map Package) 格式
  • geodatabase 可编辑
  • TPK / TPKX 格式
  • mspk (Mobile Scene Package) 三维场景地图数据包

Shape 文件加载

Shape 文件是比较老的格式了,它并不单纯的是一个文件,而是多个,如果文件数量不对,文件格式不完整,有可能会加载不出来

ArcGIS 100 加载 Shape 文件需要购买授权,免费版的授权不支持这个功能,或者你可以忍受有水印。

// path 为文件路径,这里只能用绝对路径
ShapefileFeatureTable shapefileFeatureTable = new ShapefileFeatureTable(path);
shapefileFeatureTable.loadAsync();
shapefileFeatureTable.addDoneLoadingListener(() -> {
    if (shapefileFeatureTable.getLoadStatus() == LoadStatus.LOADED) {
        // 加载成功,用 FeatureLayer 来展示
        FeatureLayer featureLayer = new FeatureLayer(featureTable);
        featureLayer.setId(path);
        SimpleRenderer renderer = null;
        SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.RED, 1);
        SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.argb(70, 252, 241, 144), lineSymbol);
        // shape 文件通常不包含图斑色彩信息,这里可以自己设置
        renderer = new SimpleRenderer(fillSymbol);
        featureLayer.setRenderer(renderer);
        mapView.getMap().getOperationalLayers().add(featureLayer);
    } else {
        // 加载失败
        // shapefileFeatureTable.getLoadError() 可以查看报错信息
    }
});

MMPK 格式加载

MMPK(Mobile Map Package)格式文件是一种用于在移动设备上离线使用地图的文件格式。它是 ArcGIS Runtime SDK for Android、iOS 和 .NET 中的一种支持离线使用的地图数据包,可以包含地图、图层、样式、标记、地图范围、交通数据、指南针等相关内容。

try {

// path 为文件路径
    MobileMapPackage mobileMapPackage = new MobileMapPackage(path);
    mobileMapPackage.loadAsync();
    mobileMapPackage.addDoneLoadingListener(() -> {
        if (mobileMapPackage.getLoadStatus().equals(LoadStatus.LOADED)) {

                if (mobileMapPackage.getMaps().isEmpty()) {
                    // 没有图层数据
                }
                int size = mapPackage.getMaps().size();
                for (int i = 0; i < size; i++) {
                    ArcGISMap gisMap = mapPackage.getMaps().get(i);
                    // 这里的 ArcGISMap 可以直接设置为 mapView 的底图
                    // mapView.setMap(gisMap);
                    // 也可以把其中的图层拿出来加载到其他 ArcGISMap 上去
                    LayerList operationalLayers = gisMap.getOperationalLayers();
                    mapView.getMap().getOperationalLayers().addAll(operationalLayers);
                    // 单独加载原来的 ArcGISMap 必须清除活动图层,因为图层的 ArcGISMap 只能有一个,就和 View 的 ParentView 一样
                    gisMap.getOperationalLayers().clear();
                }
        } else {
            // 加载失败
            // mobileMapPackage.getLoadError() 查看错误信息
        }
    });
} catch (Exception e) {
    e.printStackTrace();
}

Geodatabase

Geodatabase(地理数据库)格式是一种基于文件的数据库格式,用于存储和管理地理空间数据和属性数据。Geodatabase 支持多种数据类型和数据集,包括点、线、面、注记、图层、拓扑、网络、地理编码等。它提供了强大的数据管理和查询功能,以及高效的数据加载和渲染功能。

String geodatabasePath = "/path/to/geodatabase.gdb"; 
Geodatabase geodatabase = new Geodatabase(geodatabasePath); 
geodatabase.addDoneLoadingListener(() -> { 
    if (geodatabase.getLoadStatus() == LoadStatus.LOADED) { 
        // 获取 FeatureTable 对象并添加到 Map 中显示 
        FeatureTable featureTable = geodatabase.getGeodatabaseFeatureTable("table_name"); 
        if (featureTable != null) { 
            ArcGISMap map = new ArcGISMap();
            map.getOperationalLayers().add(new FeatureLayer(featureTable)); 
            mMapView.setMap(map); 
        } 
    } 
}); 
geodatabase.loadAsync();

TPK / TPKX 格式

TPK(Tile Package)是 ArcGIS 10.1 版本的一种压缩格式,用于存储地图图块。TPK 文件可以包含多个缩放级别(zoom level)的地图图块,并可以支持多种底图切片方案。

TPKX 同样是一种压缩格式,它可以包含地图服务的全部功能,包括地图图块、要素、标注、样式等数据。TPKX 文件同样可以包含多个缩放级别,并支持多种底图切片方案。

TileCache mainTileCache = new TileCache(path);
ArcGISTiledLayer baselayer = new ArcGISTiledLayer(mainTileCache);
mapView.getMap().getOperationalLayers().add(baselayer);

MSPK 格式

MSPK 是三维场景数据包,是在三维地图中使用的一种离线格式。

MobileScenePackage mobileScenePackage = new MobileScenePackage(mspkPath);

mobileScenePackage.loadAsync();

mobileScenePackage.addDoneLoadingListener(() -> {

  if (mobileScenePackage.getLoadStatus() == LoadStatus.LOADED && !mobileScenePackage.getScenes().isEmpty()) {
    sceneView.setArcGISScene(mobileScenePackage.getScenes().get(0));
  }
  else { 
      // mobileScenePackage.getLoadError() 查看错误信息
  }
});