Find features in a feature table which match an SQL 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 click “Search”, a query is performed and the matching features are highlighted or an error is returned.
How it works
- Create a
ServiceFeatureTableusing the URL of a feature service. - Create a
QueryParameterswith a where clause specified usingsetWhereClause(). - Perform the query using
queryFeaturesAsync(query)on the service feature table. - When complete, the query will return a
FeatureQueryResultwhich 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
Sample Code
/* * Copyright 2022 Esri. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
module com.esri.samples.feature_layer_query { // require ArcGIS Maps SDK for Java module requires com.esri.arcgisruntime;
// handle SLF4J http://www.slf4j.org/codes.html#StaticLoggerBinder requires org.slf4j.nop;
// require JavaFX modules that the application uses requires javafx.graphics; requires javafx.controls;
exports com.esri.samples.feature_layer_query;}/* * Copyright 2017 Esri. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */
package com.esri.samples.feature_layer_query;
import javafx.application.Application;import javafx.application.Platform;import javafx.geometry.Insets;import javafx.geometry.Pos;import javafx.scene.Scene;import javafx.scene.control.Alert;import javafx.scene.control.Alert.AlertType;import javafx.scene.control.Button;import javafx.scene.control.Label;import javafx.scene.control.TextField;import javafx.scene.layout.Background;import javafx.scene.layout.BackgroundFill;import javafx.scene.layout.CornerRadii;import javafx.scene.layout.HBox;import javafx.scene.layout.StackPane;import javafx.scene.layout.VBox;import javafx.scene.paint.Color;import javafx.scene.paint.Paint;import javafx.stage.Stage;
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.loadable.LoadStatus;import com.esri.arcgisruntime.mapping.ArcGISMap;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 FeatureLayerQuerySample extends Application {
private Alert dialog;
private MapView mapView; private FeatureLayer featureLayer; private ServiceFeatureTable featureTable; private Point startPoint; private ListenableFuture<FeatureQueryResult> tableQueryResult;
private final int SCALE = 100000000;
@Override public void start(Stage stage) {
try { // create stack pane and application scene StackPane stackPane = new StackPane(); Scene scene = new Scene(stackPane); scene.getStylesheets().add(getClass().getResource("/feature_layer_query/style.css").toExternalForm());
// set title, size, and add scene to stage stage.setTitle("Feature Layer Query Sample"); stage.setWidth(800); stage.setHeight(700); stage.setScene(scene); stage.show();
// authentication with an API key or named user is required to access basemaps and other location services String yourAPIKey = System.getProperty("apiKey"); ArcGISRuntimeEnvironment.setApiKey(yourAPIKey);
// create a control panel VBox controlsVBox = new VBox(6); controlsVBox.setBackground(new Background(new BackgroundFill(Paint.valueOf("rgba(0,0,0,0.3)"), CornerRadii.EMPTY, Insets.EMPTY))); controlsVBox.setPadding(new Insets(10.0)); controlsVBox.setMaxSize(250, 80); controlsVBox.getStyleClass().add("panel-region");
// create area for searching Label searchLabel = new Label("Search for a State:"); searchLabel.getStyleClass().add("panel-label"); TextField searchField = new TextField(); searchField.setMaxWidth(150); Button searchButton = new Button("Search"); HBox searchBox = new HBox(5); searchBox.getChildren().addAll(searchField, searchButton); searchBox.setDisable(true);
// create dialog to display alert information dialog = new Alert(AlertType.WARNING);
// search for the state that was entered searchButton.setOnAction(e -> { // clear the selection of the feature featureLayer.clearSelection(); String stateText = searchField.getText();
if (stateText.trim().length() > 0) { searchForState(stateText); } else { dialog.setContentText("State Not Found! Add a valid state name."); dialog.showAndWait(); mapView.setViewpointCenterAsync(startPoint, SCALE); } });
// add search label and box to the control panel controlsVBox.getChildren().addAll(searchLabel, searchBox);
// create a starting point for the view startPoint = new Point(-11000000, 5000000, SpatialReferences.getWebMercator());
// set fill to golden color for the US states with a black color outline SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLACK, 1); SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.DARKGOLDENROD, lineSymbol);
// create a service feature table featureTable = new ServiceFeatureTable("https://services.arcgis.com/jIL9msH9OI208GCb/arcgis/rest/services/USA_Daytime_Population_2016/FeatureServer/0");
// create a feature layer from table featureLayer = new FeatureLayer(featureTable); featureLayer.setOpacity(0.8f); featureLayer.setMaxScale(10000);
// enable search once the feature layer is loaded featureLayer.addDoneLoadingListener(() -> { if (featureLayer.getLoadStatus() == LoadStatus.LOADED) { searchBox.setDisable(false); } else { Alert alert = new Alert(Alert.AlertType.ERROR, "Feature Layer Failed to Load!"); alert.show(); } });
// set renderer for feature layer featureLayer.setRenderer(new SimpleRenderer(fillSymbol));
// create a map with the topographic basemap style final ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
// create a map view and set the map to it mapView = new MapView(); mapView.setMap(map);
// add the feature layer to the map's operational layers map.getOperationalLayers().add(featureLayer);
// set viewpoint to the start point mapView.setViewpointCenterAsync(startPoint, SCALE);
// add the map view and control panel to stack pane stackPane.getChildren().addAll(mapView, controlsVBox); StackPane.setAlignment(controlsVBox, Pos.TOP_LEFT); StackPane.setMargin(controlsVBox, new Insets(10, 0, 0, 10)); } catch (Exception e) { // on any error, display the stack trace e.printStackTrace(); } }
/** * Searches for a US state inside the current ServiceFeatureTable. * * @param state a US state that is being searched */ private void searchForState(String state) {
// create a query for the state that was entered QueryParameters query = new QueryParameters(); query.setWhereClause("upper(STATE_NAME) LIKE '" + state.toUpperCase() + "'");
// search for the state feature in the feature table tableQueryResult = featureTable.queryFeaturesAsync(query);
tableQueryResult.addDoneListener(() -> { try { // get the result from the query FeatureQueryResult result = tableQueryResult.get(); // if a state feature was found if (result.iterator().hasNext()) { // get state feature and zoom to it Feature feature = result.iterator().next(); Envelope envelope = feature.getGeometry().getExtent(); mapView.setViewpointGeometryAsync(envelope, 200);
// set the state feature to be selected featureLayer.selectFeature(feature); } else { Platform.runLater(() -> { dialog.setContentText("State Not Found! Add a valid state name."); dialog.showAndWait(); mapView.setViewpointCenterAsync(startPoint, SCALE); }); } } catch (Exception e) { // on any error, display the stack trace e.printStackTrace(); } }); }
/** * Stops and releases all resources used in application. */ @Override public void stop() {
if (mapView != null) { mapView.dispose(); } }
/** * Opens and runs application. * * @param args arguments passed to this application */ public static void main(String[] args) {
Application.launch(args); }
}