Overview

You will learn: how to create a new feature collection with a point feature collection table. The feature collection is then displayed on a map as a layer.

With the ArcGIS Runtime SDK for Java it's easy to create and add features to feature collections and display them on a map. A feature collection is a type of feature layer that holds static collections of features stored as JSON inside a map or portal item. Any feature collection can be saved as part of the map and edited like other feature layers. Feature collections are useful for adding and storing features, including their geometry and attributes, directly within a web map (no URL is used with feature collections.) Feature collections contain one or more feature collection tables and originate from shapefiles, CSVs, GPX files, or programatically as you will do in this lab.

In this lab, you will build an app that creates 3 point features, adds them to a Feature Collection Table, and then displays them in a Feature Layer on the map. The features will be created directly from latitude and longitude coordinates.

Before you begin

You must have previously installed the ArcGIS Runtime SDK for Java and set up your development environment. Please review the install and set up instructions if you have not done this.

Reuse the starter project

If you have not done the starter project lab, be sure to review it first so you are familiar with running the app.

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

Steps

Update the project

  1. Open the settings.gradle file in an editor of your choice and change the rootProject.name value to create-a-feature-collection.

Update imports

  1. Open the App.java file in src/main/java/com/arcgis/developers/labs. Then add the following after the existing imports.

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import com.esri.arcgisruntime.data.Feature;
    import com.esri.arcgisruntime.data.FeatureCollection;
    import com.esri.arcgisruntime.data.FeatureCollectionTable;
    import com.esri.arcgisruntime.data.Field;
    import com.esri.arcgisruntime.geometry.GeometryType;
    import com.esri.arcgisruntime.geometry.Point;
    import com.esri.arcgisruntime.geometry.SpatialReferences;
    import com.esri.arcgisruntime.layers.FeatureCollectionLayer;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.symbology.SimpleRenderer;
    

Add a FeatureCollectionLayer to the map view

  1. Find the existing setupMap method. After the existing code, create a FeatureCollection and a FeatureCollectionLayer. Add the FeatureCollectionLayer to the map view.

    private void setupMap() {
        if (mMapView != null) {
            // ...
            mMapView.setMap(map);
    
            // *** ADD ***
            FeatureCollection featureCollection = new FeatureCollection();
            FeatureCollectionLayer featureCollectionLayer = new FeatureCollectionLayer(featureCollection);
            map.getOperationalLayers().add(featureCollectionLayer);
    
  2. Add a new private method createPointTable. Define it so that it takes a FeatureCollection as a parameter. This method will create the FeatureCollectionTable and add features to it. Each feature must have a symbol assigned in order to be visible on the map. Also create an ArrayList variable to hold the list of features in the collection.

    private void createPointTable(FeatureCollection featureCollection) {
         List<Feature> features = new ArrayList<>();
    }
    
  3. Define the schema for the feature collection table by adding field definitions to an ArrayList, as follows:

         List<Feature> features = new ArrayList<>();
         // *** ADD ***
         List<Field> pointFields = new ArrayList<>();
         pointFields.add(Field.createString("Place", "Place Name", 50));
    
  4. Create a FeatureCollectionTable object using the schema created in the previous step:

         pointFields.add(Field.createString("Place", "Place Name", 50));
         // *** ADD ***
         FeatureCollectionTable pointsTable = new FeatureCollectionTable(pointFields, GeometryType.POINT, SpatialReferences.getWgs84());
    
  5. Create the symbol and renderer that will be used to visualize the features on the map:

         FeatureCollectionTable pointsTable = new FeatureCollectionTable(pointFields, GeometryType.POINT, SpatialReferences.getWgs84());
         // *** ADD ***
         SimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.TRIANGLE, 0xFF0000FF, 18);
         SimpleRenderer renderer = new SimpleRenderer(simpleMarkerSymbol);
         pointsTable.setRenderer(renderer);
    
  6. Add the table to the featureCollection object:

         pointsTable.setRenderer(renderer);
         // *** ADD ***
         featureCollection.getTables().add(pointsTable);
    
  7. Create a feature for each of the 3 sporting venues that will be added to the pointTable:

         featureCollection.getTables().add(pointsTable);
         // *** ADD ***
         // Dodger Stadium
         Map<String, Object> attributes1 = new HashMap<>();
         attributes1.put(pointFields.get(0).getName(), "Dodger Stadium");
         Point point1 = new Point(-118.2406294, 34.0736221, SpatialReferences.getWgs84());
         features.add(pointsTable.createFeature(attributes1, point1));
    
         // Los Angeles Memorial Coliseum
         Map<String, Object> attributes2 = new HashMap<>();
         attributes2.put(pointFields.get(0).getName(), "LA Coliseum");
         Point point2 = new Point(-118.287767, 34.013999, SpatialReferences.getWgs84());
         features.add(pointsTable.createFeature(attributes2, point2));
    
         // Staples Center
         Map<String, Object> attributes3 = new HashMap<>();
         attributes3.put(pointFields.get(0).getName(), "Staples Center");
         Point point3 = new Point(-118.267028, 34.043145, SpatialReferences.getWgs84());
         features.add(pointsTable.createFeature(attributes3, point3));
    
  8. Add the features asynchronously to the pointTable. This completes the createPointTable method.

        features.add(pointsTable.createFeature(attributes3, point3));
        // *** ADD ***
        pointsTable.addFeaturesAsync(features);
    
  9. Inside the setupMap() method, after adding the FeatureCollectionLayer to the map, make a call to the method you just created.

            map.getOperationalLayers().add(featureCollectionLayer);
            // *** ADD ***
            createPointTable(featureCollection);
    
  10. Run the app and you should see 3 blue triangles positioned in the Los Angeles area.

Congratulations, you're done!

Your map should show a vector tiled basemap with the locations for Dodger Stadium, Staples Center, and the LA Coliseum, prominent sports venues in the Los Angeles area.

Challenge

Add features with different symbols and styles

  1. Use a UniqueValueRenderer instead of the SimpleRenderer to display the features: UniqueValueRenderers are used to symbolize groups of features or graphics (see GeoElement) that have matching attributes. This is most common with nominal, or string, data.
  2. Add a text symbol: TextSymbols are used to display text for graphics and features. Add text symbols for the point features used in the lab.
  3. Change the marker symbol: Use a different shape (for example a square) for the SimpleMarkerSymbol used in the lab using the available styles.