Selection mode

Download Sample Viewer

Description

This sample demonstrates how to programmatically select a group of features in an ArcGISFeatureLayer in SELECTION_ONLY mode. The blue points in the map are the unselected features that represent census block points.

Right-click on the map to select a new group of features: a query will be performed a set distance from the clicked point to retrieve features. Hold Ctrl and right-click to add a group of features to the already selected ones. Hold Shift and right-click to remove a group of features from the already selected ones. Left-click a selected feature to view attributes of that feature. Note that panning or zooming (changing the map extent) does not change the selected features.

Code snippet


    // create ArcGISFeatureLayer from service URL
    final ArcGISFeatureLayer featureLayer = new ArcGISFeatureLayer(URL_BLOCK_POINTS);
    // SELECTION_ONLY mode will activate only those features selected through the feature layer.
    featureLayer.setOperationMode(QueryMode.SELECTION_ONLY);
    // select the attributes of a feature that are retrieved when the feature layer is queried
    featureLayer.setOutFields(new String[] {"FIPS", "POP2000"});
    // define a renderer to symbolize active features
    featureLayer.setRenderer(new SimpleRenderer(SYM_CITY));
  

Sample Code

/* Copyright 2014 Esri

All rights reserved under the copyright laws of the United States
and applicable international laws, treaties, and conventions.

You may freely redistribute and use this sample code, with or
without modification, provided you include the original copyright
notice and use restrictions.

See the use restrictions.*/
package com.esri.client.samples.featurelayers;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

import com.esri.toolkit.overlays.InfoPopupOverlay;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Geometry;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.Point;
import com.esri.core.map.CallbackListener;
import com.esri.core.map.FeatureSet;
import com.esri.core.tasks.ags.query.Query;
import com.esri.map.ArcGISDynamicMapServiceLayer;
import com.esri.map.ArcGISFeatureLayer;
import com.esri.map.ArcGISFeatureLayer.SELECTION_METHOD;
import com.esri.map.JMap;
import com.esri.map.LayerInitializeCompleteEvent;
import com.esri.map.LayerInitializeCompleteListener;
import com.esri.map.LayerList;
import com.esri.map.MapOptions;
import com.esri.map.MapOptions.MapType;
import com.esri.map.MapOverlay;
import com.esri.map.QueryMode;

/***
 * This sample demonstrates how to programmatically select a group of features in an 
 * ArcGISFeatureLayer in SELECTION_ONLY mode. The blue points in the map are the 
 * unselected features that represent census block points.
 *<ul>
 * <li>Right-click on the map to select a new group of features: a query will be performed a set
 * distance from the clicked point to retrieve features.</li>
 * <li>Hold Ctrl and right-click to add a group of features to the already selected ones.</li>
 * <li>Hold Shift and right-click to remove a group of features from the already selected ones.</li>
 * <li>Left-click a selected feature to view attributes of that feature.</li>
 * <li>Note that panning or zooming (changing the map extent) does not change the selected features.</li>
 * </ul>
 *
 */
public class SelectionApp {

  // resources
  private final String URL_CENSUS =
      "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer";
  private final String URL_BLOCK_POINTS =
      "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/0";

  // JMap
  private JMap map;

  // the width and length of the envelope used to select features,
  // centered around the clicked point (in decimal degrees, the feature
  // layer's units)
  private final static double ENVELOPE_SIZE = 0.01;

  // ------------------------------------------------------------------------
  // Constructors
  // ------------------------------------------------------------------------
  public SelectionApp() {
  }

  // ------------------------------------------------------------------------
  // Core functionality
  // ------------------------------------------------------------------------
  /**
   * Creates a feature layer in SelectionOnly mode.
   */
  private ArcGISFeatureLayer createFeatureLayerInSelectionOnlyMode() {
    final ArcGISFeatureLayer featureLayer = new ArcGISFeatureLayer(URL_BLOCK_POINTS);

    // SelectionOnly mode will activate only those features selected through the feature layer.
    featureLayer.setOperationMode(QueryMode.SELECTION_ONLY);
    featureLayer.setSelectionColor(Color.RED);

    // select the attributes of a feature that are retrieved when the feature layer is queried.
    featureLayer.setOutFields(new String[] {"FIPS", "POP2000"});

    return featureLayer;
  }

  /**
   * A custom map overlay to handle mouse-click events.
   */
  class UserCommandOverlay extends MapOverlay {

    private static final long serialVersionUID = 1L;
    JMap jMap;
    ArcGISFeatureLayer featureLayer;

    /**
     * CTOR.
     * @param jMap JMap to which this overlay belongs.
     * @param featureLayer feature layer that has the river features.
     */
    UserCommandOverlay(JMap jMap, ArcGISFeatureLayer featureLayer) {
      this.jMap = jMap;
      this.featureLayer = featureLayer;
    }

    /**
     * Handle mouse-clicks.
     */
    @Override
    public void onMouseClicked(MouseEvent event) {

      // handle right-clicks, ignore others
      if (event.getButton() == MouseEvent.BUTTON3) {

        // create a spatial query that selects features near the point of mouse-click.
        // this query will be passed to the feature layer that will activate the
        // features and display them on the map.

        Query query = new Query();

        // set the out fields to include the object id as this is needed
        // by the selection code to determine which features we already
        // have when the selection method is Subtract
        featureLayer.setOutFields(new String[] {
            featureLayer.getObjectIdField(), "FIPS", "POP2000" });

        // convert screen coordinates to map coordinates.
        Point clickPointOnBaseLayer = jMap.toMapPoint(event.getX(), event.getY());

        // In this sample, the coordinate system of the feature layer is different from
        // that of the base layer. Since the query will be performed on the feature
        // layer, perform necessary projection
        Point clickPointOnFeatureLayer = (Point) GeometryEngine.project(
            clickPointOnBaseLayer,
            jMap.getSpatialReference(),
            featureLayer.getDefaultSpatialReference());

        // limit the query to an area around the clicked point.
        Geometry queryExtent = new Envelope(clickPointOnFeatureLayer, ENVELOPE_SIZE, ENVELOPE_SIZE);
        query.setGeometry(queryExtent);

        // Selection Method:
        // to add to existing group of selected features - on ctrl + right-click
        // to remove from existing group - on shift + right-click
        // to create a new group - otherwise.
        SELECTION_METHOD featureSelectionMethod = SELECTION_METHOD.NEW;
        if (event.isControlDown()) {
          featureSelectionMethod = SELECTION_METHOD.ADD;
        } else if (event.isShiftDown()) {
          featureSelectionMethod = SELECTION_METHOD.SUBTRACT;
        }

        // let the feature layer handle the query, activate and display appropriate features.
        try {
          featureLayer.selectFeatures(
              query,
              featureSelectionMethod,
              new CallbackListener<FeatureSet>() {

                @Override
                public void onError(Throwable e) {
                  e.printStackTrace();
                }

                @Override
                public void onCallback(FeatureSet objs) {
                  System.out.println("Total selected features : " +
                      featureLayer.getSelectedFeatures().length);
                }

              }
              );
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
  }

  // ------------------------------------------------------------------------
  // Static methods
  // ------------------------------------------------------------------------
  /**
   * Starting point of this application.
   * @param args arguments to this application.
   */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          // instance of this application
          SelectionApp selectionApp = new SelectionApp();

          // create the UI, including the map, for the application.
          JFrame appWindow = selectionApp.createWindow();
          appWindow.add(selectionApp.createUI());
          appWindow.setVisible(true);
        } catch (Exception e) {
          // on any error, display the stack trace.
          e.printStackTrace();
        }
      }
    });
  }

  // ------------------------------------------------------------------------
  // Public methods
  // ------------------------------------------------------------------------
  /**
   * Creates and displays the UI, including the map, for this application.
   */
  public JComponent createUI() throws Exception {
    // application content
    JComponent contentPane = createContentPane();

    // description
    JPanel description = createDescription();
    contentPane.add(description);

    // map
    map = createMap();
    contentPane.add(map);

    return contentPane;
  }

  // ------------------------------------------------------------------------
  // Private methods
  // ------------------------------------------------------------------------
  /**
   * Creates a map.
   * @return a map.
   */
  private JMap createMap() throws Exception {
    // focus on Redlands, California
    MapOptions mapOptions = new MapOptions(MapType.TOPO, 34.0515888762, -117.190346717, 14);
    final JMap jMap = new JMap(mapOptions);
    LayerList layers = jMap.getLayers();

    // -----------------------------------------------------------------------------------------
    // Base Layer - this has the census data
    // -----------------------------------------------------------------------------------------
    ArcGISDynamicMapServiceLayer censusLayer = new ArcGISDynamicMapServiceLayer(URL_CENSUS);
    layers.add(censusLayer);

    // -----------------------------------------------------------------------------------------
    // Feature Layer - demographics by block points
    // -----------------------------------------------------------------------------------------
    ArcGISFeatureLayer blockPointsLayer = createFeatureLayerInSelectionOnlyMode();
    layers.add(blockPointsLayer);

    // -----------------------------------------------------------------------------------------
    // Map overlay - to handle mouse events, and render results on to the feature layer
    // -----------------------------------------------------------------------------------------
    jMap.addMapOverlay(new UserCommandOverlay(jMap, blockPointsLayer));

    // -----------------------------------------------------------------------------------------
    // InfoPopupOverlay - another map overlay to display attributes of a selected feature
    // -----------------------------------------------------------------------------------------
    final InfoPopupOverlay infoPopupOverlay = new InfoPopupOverlay();
    infoPopupOverlay.setPopupTitle("Census Block Point");
    infoPopupOverlay.setItemTitle("Object ID: {ObjectID}");
    jMap.addMapOverlay(infoPopupOverlay);

    blockPointsLayer.addLayerInitializeCompleteListener(new LayerInitializeCompleteListener()
    {
      @Override
      public void layerInitializeComplete(LayerInitializeCompleteEvent event)
      {
        //when the feature layer is initialized, let the InfoPopupOverlay know
        //so that the InfoPopupOverlay can show attributes of the locations found
        infoPopupOverlay.addLayer(event.getLayer());
      }
    });

    return jMap;
  }

  /**
   * Creates a window.
   * @return a window.
   */
  private JFrame createWindow() {
    JFrame window = new JFrame("ArcGISFeatureLayer - Selection Mode");
    window.setBounds(100, 100, 1000, 700);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setLayout(new BorderLayout(0, 0));
    window.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent windowEvent) {
        super.windowClosing(windowEvent);
        map.dispose();
      }
    });
    return window;
  }

  /**
   * Creates a content pane.
   * @return a content pane.
   */
  private static JLayeredPane createContentPane() {
    JLayeredPane contentPane = new JLayeredPane();
    contentPane.setLayout(new BorderLayout(0, 0));
    contentPane.setVisible(true);
    return contentPane;
  }

  /**
   * Creates a description for this application.
   * @return a JPanel that has the description text.
   */
  private JPanel createDescription() {
    JPanel descriptionContainer = new JPanel();
    descriptionContainer.setLayout(new BoxLayout(descriptionContainer, 0));
    descriptionContainer.setSize(360, 250);
    descriptionContainer.setLocation(10, 10);
    JTextArea description = new JTextArea(
        "The feature layer is in SelectionOnly mode. The blue points in the map are the unselected features that " +
            "represent census block points.\n\n" +
            "- Right-click on the map to select a new group of features: a query will be performed a set distance from the clicked point to retrieve features.\n" +
            "- Hold Ctrl and right-click to add a group of features to the already selected ones.\n" +
            "- Hold Shift and right-click to remove a group of features from the already selected ones.\n" +
            "- Left-click on a selected feature to view the attributes of that feature.\n" +
            "- Note that panning or zooming does not change the selected features."
        );
    description.setFont(new Font("Verdana", Font.PLAIN, 11));
    description.setForeground(Color.WHITE);
    description.setBackground(new Color(0, 0, 0, 180));
    description.setEditable(false);
    description.setLineWrap(true);
    description.setWrapStyleWord(true);
    description.setBorder(BorderFactory.createEmptyBorder(5,10,5,5));
    descriptionContainer.add(description);
    descriptionContainer.setBackground(new Color(0, 0, 0, 0));
    descriptionContainer.setBorder(new LineBorder(Color.BLACK, 3, false));
    return descriptionContainer;
  }
}
Feedback on this topic?