使用地图

使用Web地图URL

ArcGISMap map = new ArcGISMap("URL/to/webmap");

使用Web地图门户项目

  1. 通过向门户网站提供URL字符串来创建门户网站对象。在下面的示例中,可以从ArcGIS Online(www.arcgis.com)访问公共地图。
Portal portal = new Portal("http://www.arcgis.com");
  1. 通过提供门户网站和地图的项目ID字符串来构造门户网站项目对象。
PortalItem mapPortalItem = new PortalItem(portal, "e229d715f7ca4fa980308549fb288165");
  1. 将门户项目传递给地图构造函数。
ArcGISMap map = new ArcGISMap(mapPortalItem);

从移动地图包创建地图对象

移动地图包是在ArcGIS Pro中创建的文件对象(.mmpk)。它是地图,其图层,数据,网络和定位器的传输机制。

每个移动地图包都可以包含一个或多个可以在地图视图中显示的地图。

  1. 获取移动地图包的文件路径。
File mmpkFile = new File(Environment.getExternalStorageDirectory(), dataPath + "CaliforniaNevada.mmpk");
String mmpkPath = mmpkFile.getAbsolutePath();
  1. 使用文件路径构造移动地图包对象。
final MobileMapPackage mobileMapPackage = new MobileMapPackage("path/to/file/.mmpk");
  1. 必须先将移动地图包加载到应用程序中,然后才能访问地图本身。加载移动地图包后,可以将其任何地图分配给要显示的地图视图。
mobileMapPackage.addDoneLoadingListener(() -> {
  if (mobileMapPackage.getLoadStatus() == LoadStatus.LOADED) {
    System.out.println("Number of maps = " + mobileMapPackage.getMaps().size());
    // In this case the first map in the array is obtained
    ArcGISMap mobileMap = mobileMapPackage.getMaps().get(0);
  } else {
    // If loading failed, deal with failure depending on the cause...
  }
});
mobileMapPackage.loadAsync();

在地图视图中显示地图

mapView.setMap(map);

监控图层加载

mapView.addLayerViewStateChangedListener(new LayerViewStateChangedListener() {
  @Override
  public void layerViewStateChanged(LayerViewStateChangedEvent layerViewStateChangedEvent) {
    
    StringBuilder layerStatuses = new StringBuilder();
    for (LayerViewStatus status : layerViewStateChangedEvent.getLayerViewStatus()) {
      if (layerStatuses.length() > 0) {
        layerStatuses.append(",");
      }
      layerStatuses.append(status.name());
    }
// 显示所有图层的加载状态
    showMessage(String.format("Layer '%s' status=%s", layerViewStateChangedEvent.getLayer().getName(),
        layerStatuses.toString()));
  }
});

监控地图绘制

mMapView.addDrawStatusChangedListener(new DrawStatusChangedListener() {
    @Override
    public void drawStatusChanged(DrawStatusChangedEvent drawStatusChangedEvent) {
        if(drawStatusChangedEvent.getDrawStatus() == DrawStatus.IN_PROGRESS){
            progressBar.setVisibility(View.VISIBLE);
            Log.d("drawStatusChanged", "spinner visible");
        }else if (drawStatusChangedEvent.getDrawStatus() == DrawStatus.COMPLETED){
            progressBar.setVisibility(View.INVISIBLE);
        }
    }
});

导航地图

Polygon polygon = mapView.getVisibleArea();

通过 setPointView方法,可以

  • 将地图旋转到指定的角度。
  • 将地图缩放到指定的比例。
  • 缩放或平移地图,以使给定的几何体适合地图视图的可见区域。
  • 将地图缩放或平移到指定位置。
  • 将地图缩放或平移到特定视点。您可以使用以下命令定义视点:
    • 中心和规模
    • 中心,比例和旋转
    • 纬度,经度和比例
    • 目标范围
    • 目标范围和轮换
      设备位置
LocationDisplay locationDisplay = mapView.getLocationDisplay();
locationDisplay.addDataSourceStatusChangedListener(new LocationDisplay.DataSourceStatusChangedListener() {
  @Override
  public void onStatusChanged(LocationDisplay.DataSourceStatusChangedEvent dataSourceStatusChangedEvent) {
    if (dataSourceStatusChangedEvent.getSource().getLocationDataSource().getError() == null) {
      showMessage("Location Display Started=" + dataSourceStatusChangedEvent.isStarted());
    } else {
      // Deal with problems starting the LocationDisplay...
    }
  }
});
locationDisplay.startAsync();

启用环绕

mapView.setWrapAroundMode(WrapAroundMode.ENABLE_WHEN_SUPPORTED);

旋转地图

// 旋转90度
final ListenableFuture<Boolean> viewpointSetFuture = mapView.setViewpointRotationAsync(90);
viewpointSetFuture.addDoneListener(new Runnable() {
  @Override
  public void run() {
    try {
      boolean completed = viewpointSetFuture.get();
      if (completed)
        showMessage("Rotation completed successfully");
    } catch (InterruptedException e) {
      showMessage("Rotation interrupted");
    } catch (ExecutionException e) {
      // Deal with exception during animation...
    }
  }
});

触摸监听

  1. 创建 DefaultMapViewOnTouchListener的子类
class MapSingleTapListener extends DefaultMapViewOnTouchListener {
···
}
  1. 处理回掉方法
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
  Point mapPoint = mapView.screenToLocation(new android.graphics.Point((int)e.getX(), (int)e.getY()));
  showMessage(String.format("User tapped on the map at (%.3f,%.3f)", mapPoint.getX(), mapPoint.getY()));
  return true;
}
  1. 添加监听
mapView.setOnTouchListener(new MapSingleTapListener(context, mapView));

拍摄地图的快照(屏幕截图)

final ListenableFuture<Bitmap> exportImageFuture = mapView.exportImageAsync();
exportImageFuture.addDoneListener(new Runnable() {
  @Override
  public void run() {
    try {
      // Get the resulting Bitmap from the future
      Bitmap bitmap = exportImageFuture.get();

      if (bitmap != null) {
        // Create a File to write the Bitmap into
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "map.png");
        FileOutputStream fileOutputStream;
        try {
          // Write the Bitmap into the file and close the file stream.
          fileOutputStream = new FileOutputStream(file);
          bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
          fileOutputStream.close();
        } catch (IOException e) {
          // Deal with exception writing file...
        }
      }

    } catch (InterruptedException | ExecutionException e) {
      // Deal with exception during export...
    }
  }
});

设置在线底图

ArcGISTiledLayer tiledLayer = new ArcGISTiledLayer("http://services.arcgisonline.com/arcgis/rest/services/Canvas/World_Dark_Gray_Base/MapServer");
Basemap basemap = new Basemap(tiledLayer);

map = new ArcGISMap();
map.setBasemap(basemap);

将图层组合到一个底图中

ArcGISTiledLayer tiledLayer = new ArcGISTiledLayer("http://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer");
ArcGISMapImageLayer censusLayer = new ArcGISMapImageLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer");

map = new ArcGISMap();
map.getBasemap().getBaseLayers().add(tiledLayer);
map.getBasemap().getBaseLayers().add(censusLayer);

添加操作图层

ArcGISMapImageLayer censusLayer = new ArcGISMapImageLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer");
// Add layer to the map (by default, added as top layer)
map.getOperationalLayers().add(censusLayer);

插入指定层图层

ArcGISMapImageLayer usaLayer = new ArcGISMapImageLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer");
// Insert layer at position 0 (added as bottom layer of the map)
map.getOperationalLayers().add(0, usaLayer);

加载地图及其图层

map.loadAsync();
map.addDoneLoadingListener(new Runnable() {

    @Override
    public void run() {
        //code here to check for error status
        if (map.getLoadStatus() == LoadStatus.FAILED_TO_LOAD) {
            showMessage("map failed to load : " + map.getLoadError().getMessage());

        }
    }});

或者在地图中设置

mapView = new MapView(context);
mapView.setMap(map);

保存到门户网站(略)

环绕地图

启用或禁用环绕

默认情况下,当用户向东和向西平移地图时,地图视图会尝试包裹地图以获得连续体验。要禁用地图视图的环绕行为(或重新启用它),可以将环绕模式设置为适当的值。如果满足以下要求,则环绕只能应用于地图视图。

  • 地图的全部范围涵盖了整个世界。
  • 地图的空间参考是WGS 84(WKID = 4326)或Web墨卡托(WKID = 102113,102100或3857)。这意味着地图中的所有平铺图层都必须属于这些空间参考之一。但是,动态图层可以位于任何空间参考中,因为它们能够重新投影其数据。
  • 地图中的动态图层基于ArcGIS Server 10.0或更高版本的服务。早期版本的REST API不支持用于空间参考的已知文本(WKT)值,这是使动态地图服务支持环绕所必需的。

如果不满足上面的要求,则启动环绕会失败,并且不会报错。
使用用例:如果启用环绕,则关闭;如果关闭,设为启用

if (mapView.getWrapAroundMode() == WrapAroundMode.DISABLED) {
  // 启用环绕
  mapView.setWrapAroundMode(WrapAroundMode.ENABLE_WHEN_SUPPORTED);
  if (!mapView.isWrapAroundEnabled()) {

  }
} else {
  // 禁用环绕
  mapView.setWrapAroundMode(WrapAroundMode.DISABLED);
}

添加图层

图层有两个常见角色:

  • 底图图层 - 为您的数据提供上下文(背景)
  • 操作层 - 正在使用的地图数据

操作层

地图和场景公开了一个可操作的图层属性,它是一个图层集合。您可以在地图的操作层中添加和删除图层。

ArcGISMap map = new ArcGISMap();
map.getOperationalLayers().add(someLayer);
map.getOperationalLayers().remove(someLayer);

底图图层

底图显示“基础图层”属性,该属性包含底图中的所有图层。该getBaseLayers方法可以通过地图和场景的底图进行访问。请注意,如果有合适的地图,建议您使用所有地图的底图。可以使用静态工厂方法创建的底图的一些示例是:

  • 世界意象
  • 世界街头
  • 国家地理
  • 世界导航(矢量)
  • 世界街头(矢量)
ArcGISMap map = new ArcGISMap(Basemap.createNavigationVector());
// or
map.setBasemap(Basemap.createNavigationVector());
// or
map.getBasemap().getBaseLayers().add(someBasemapLayer);

推荐阅读更多精彩内容