Feature layer query

View inJavaKotlin
View on GitHub
Sample viewer app

Find features in a feature table which match an SQL query.

Image of feature layer query

Use case

Query expressions can be used in ArcGIS to select a subset of features from a feature table. This is most useful in large or complicated data sets. A possible use case might be on a feature table marking the location of street furniture through a city. A user may wish to query by a TYPE column to return "benches". In this sample, we query a U.S. state by STATE_NAME from a feature table containing all U.S. states.

How to use the sample

Input the name of a U.S. state into the text field. When you tap "GO", a query is performed and the matching features are highlighted or an error is returned.

How it works

  1. Create a ServiceFeatureTable using the URL of a feature service.
  2. Create a QueryParameters with a where clause specified using setWhereClause().
  3. Perform the query using queryFeaturesAsync(query) on the service feature table.
  4. When complete, the query will return a FeatureQueryResult which can be iterated over to get the matching features.

About the data

This sample uses U.S. State polygon features from the USA 2016 Daytime Population feature service.

Relevant API

  • FeatureLayer
  • FeatureQueryResult
  • QueryParameters
  • ServiceFeatureTable

Tags

Search and Query

Sample Code

MainActivity.java
                                                                                                                                                                     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/* Copyright 2016 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 Sample code usage restrictions document for further information.
 *
 */

package com.esri.arcgisruntime.sample.featurelayerquery;

import java.util.Iterator;

import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.data.Feature;
import com.esri.arcgisruntime.data.FeatureQueryResult;
import com.esri.arcgisruntime.data.QueryParameters;
import com.esri.arcgisruntime.data.ServiceFeatureTable;
import com.esri.arcgisruntime.geometry.Envelope;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.SpatialReferences;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.BasemapStyle;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.symbology.SimpleFillSymbol;
import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
import com.esri.arcgisruntime.symbology.SimpleRenderer;

public class MainActivity extends AppCompatActivity {

  private static final String TAG = MainActivity.class.getSimpleName();

  private MapView mMapView;
  private ServiceFeatureTable mServiceFeatureTable;
  private FeatureLayer mFeatureLayer;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // authentication with an API key or named user is required to access basemaps and other
    // location services
    ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY);

    // get reference to map view
    mMapView = findViewById(R.id.mapView);
    // create a map with the topographic basemap
    final ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    // set the map to the map view
    mMapView.setMap(map);

    // create a service feature table and a feature layer from it
    mServiceFeatureTable = new ServiceFeatureTable(getString(R.string.us_daytime_population_url));
    // create the feature layer using the service feature table
    mFeatureLayer = new FeatureLayer(mServiceFeatureTable);
    mFeatureLayer.setOpacity(0.8f);
    mFeatureLayer.setMaxScale(10000);

    //override the renderer
    SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLACK, 1);
    SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.YELLOW, lineSymbol);
    mFeatureLayer.setRenderer(new SimpleRenderer(fillSymbol));

    // add the layer to the map
    map.getOperationalLayers().add(mFeatureLayer);

    // zoom to a view point of the USA
    mMapView.setViewpointCenterAsync(new Point(-11000000, 5000000, SpatialReferences.getWebMercator()), 100000000);
  }

  /**
   * Handle the search intent from the search widget
   */
  @Override
  protected void onNewIntent(Intent intent) {
    setIntent(intent);
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String searchString = intent.getStringExtra(SearchManager.QUERY);
      searchForState(searchString);
    }
  }

  private void searchForState(final String searchString) {
    // clear any previous selections
    mFeatureLayer.clearSelection();
    // create objects required to do a selection with a query
    QueryParameters query = new QueryParameters();
    // make search case insensitive
    query.setWhereClause("upper(STATE_NAME) LIKE '%" + searchString.toUpperCase() + "%'");
    // call select features
    final ListenableFuture<FeatureQueryResult> future = mServiceFeatureTable.queryFeaturesAsync(query);
    // add done loading listener to fire when the selection returns
    future.addDoneListener(() -> {
      try {
        // call get on the future to get the result
        FeatureQueryResult result = future.get();
        // check there are some results
        Iterator<Feature> resultIterator = result.iterator();
        if (resultIterator.hasNext()) {
          // get the extent of the first feature in the result to zoom to
          Feature feature = resultIterator.next();
          Envelope envelope = feature.getGeometry().getExtent();
          mMapView.setViewpointGeometryAsync(envelope, 10);
          // select the feature
          mFeatureLayer.selectFeature(feature);
        } else {
          Toast.makeText(this, "No states found with name: " + searchString, Toast.LENGTH_LONG).show();
        }
      } catch (Exception e) {
        String error = "Feature search failed for: " + searchString + ". Error: " + e.getMessage();
        Toast.makeText(this, error, Toast.LENGTH_LONG).show();
        Log.e(TAG, error);
      }
    });
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    // get the SearchView and set the searchable configuration
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    // assumes current activity is the searchable activity
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false);
    return true;
  }

  @Override
  protected void onPause() {
    mMapView.pause();
    super.onPause();
  }

  @Override
  protected void onResume() {
    super.onResume();
    mMapView.resume();
  }

  @Override protected void onDestroy() {
    mMapView.dispose();
    super.onDestroy();
  }
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.