Overview

You will learn: how to add feature layers to a 3D map.

With ArcGIS Runtime SDK for Android, it's easy to create a mapping app that displays a basemap and one or more layers. ArcGIS Online hosts several tile and vector tile basemaps that you can use in your map (2D) or scene (3D). Feature layers allow you to add datasets hosted online (with ArcGIS Online or other ArcGIS servers) or stored locally (in a runtime geodatabase, for example). By default, feature layers will draw with pre-set symbols to fill the extent of map, but you can customize this by setting your own styles with a renderer or using a SQL expression to limit the data retrieved.

In this lab you will create a new scene with an imagery basemap, add a feature layer that represents trails near the Santa Monica Mountains, and display the scene in your app.

Before you begin

Make sure you have installed the latest version of Android Studio.

Reuse the starter project

In a new or empty project folder, make a copy of the Create a starter app or download and unzip the project solution.

  • Open the new Android project in Android Studio.

  • Run the project and verify the project builds and the map displays in the device simulator.

  • You may be required to sync the project dependencies.

Steps

Modify the project to display a scene (3D) instead of a map (2D)

  1. Open the layout file app > res > layout > activity_main.xml in Text view. Change the MapView element to SceneView.

       <com.esri.arcgisruntime.mapping.view.SceneView
         android:id="@+id/sceneView"
         android:layout_width="match_parent"
         android:layout_height="match_parent" >
       </com.esri.arcgisruntime.mapping.view.SceneView>
    
  2. Open the file app > java > {your.package.name} > MainActivity.java and change the MapView private member variable type to SceneView and rename it to mSceneView. Change all occurrences of mMapView to mSceneView.

    public class MainActivity extends AppCompatActivity {
    
       // *** CHANGE ***
       private MapView mMapView;
       // *** CHANGE TO ***
       private SceneView mSceneView;
    

    Be sure to update the onCreate, onPause, onResume, and onDestroy methods.

  3. Completely remove the setupMap method. Create a new method named setupScene.

     private void setupScene() {
         if (mSceneView != null) {
         }
     }
    

Create a new scene with an imagery basemap

  1. In setupScene(), set the SceneView with a new ArcGISScene created with a basemap type Basemap.Type.IMAGERY_WITH_LABELS.

    private void setupScene() {
      if (mSceneView != null) {
        // *** ADD ***
        Basemap.Type basemapType = Basemap.Type.IMAGERY_WITH_LABELS;
        ArcGISScene scene = new ArcGISScene(basemapType);
        mSceneView.setScene(scene);
      }
    }
    

Add a new feature layer

  1. Add a new method named addTrailheadsLayer(). This method adds a new FeatureLayer to the scene. Create an ServiceFeatureTable to access the trails data and a FeatureLayer to view it. For the layer data source, provide a URL to the Trailsheads layer.

     private void addTrailheadsLayer() {
         String url = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0";
         final ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable(url);
         FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable);
     }
    
  2. Add the layer to the map's collection of operational layers, after you create the FeatureLayer.

        mSceneView.getScene().getOperationalLayers().add(featureLayer);
    
  3. Set the initial display area (Viewpoint) of the map to the location of features in the trails layer. Use the Camera to provide a specific perspective.

        Camera camera = new Camera(
                33.950896,
                -118.525341,
                16000.0,
                0.0,
                50.0,
                0);
        mSceneView.setViewpointCamera(camera);
    
  4. Call the addTrailheadsLayer() method from the setupScene() method after the scene is set on the scene view.

            mSceneView.setScene(scene);
            // *** ADD ***
            addTrailsLayer();
    

Set the elevation source for the scene

  1. Use an elevation service provided by Esri and add it to the scene. Create a separate method to add the elevation service.

    private void setElevationSource(ArcGISScene scene) {
        ArcGISTiledElevationSource elevationSource = new ArcGISTiledElevationSource(
            "http://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer");
        scene.getBaseSurface().getElevationSources().add(elevationSource);
    }
    
  2. Call setElevationSource() from the setupScene() method. Add this method call after the trails layer is added.

    addTrailsLayer();
    // *** ADD ***
    setElevationSource(scene);
    
  3. Update onCreate() to locate your SceneView and map it to the new mSceneView variable. Update the view ID to sceneView. Also change the setupMap() method call to the new setupScene() method.

     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         mSceneView = findViewById(R.id.sceneView);
         setupScene();
     }
    

Display the new scene in your app

  1. Run your app to test your code. When the app opens, you should see imagery appear with trail lines displayed on top. The map is rendered in 3D with the elevation data that gives accurate detail to the terrain.

Congratulations, you're done!

Compare your solution with our completed solution project.

Challenge

Customize your viewpoint with the camera

You can obtain the viewpoint camera from the scene. Using a ViewpointChangedListener observe how camera settings change as you move around in the map. Modify your code to display a different viewpoint with your own custom camera settings.

Add additional feature layers

Visit ArcGIS Online and find additional interesting park datasets to load into the app. Here are a couple suggestions:

  • Trailheads (points): https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0
  • Parks (polygons): https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Parks_and_Open_Space/FeatureServer/0

Filter features in the trails layer

Sometimes you want your layer to show a subset of the data from a service. A definition expression lets you define attribute criteria that restrict the features for a layer. Consult the service info for the Trailheads data source and construct an expression for the layer's DefinitionExpression property that will show only those trailheads without parking.