Skip to content

Commit 4c0da74

Browse files
authored
Merge pull request #210 from Esri/tschie/statistical-query-sample
statistical query sample
2 parents 9c14dd0 + 78c8b30 commit 4c0da74

File tree

3 files changed

+214
-0
lines changed

3 files changed

+214
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<h1>Statistical Query</h1>
2+
3+
<p>Demonstrates how to query a feature table to get aggregated statistics for a specified field.</p>
4+
5+
<p><img src="StatisticalQuery.png"/></p>
6+
7+
<h2>How to use the sample</h2>
8+
9+
<p>Check the boxes for the filters you want to use in the query (a spatial filter and an attribute filter). Click
10+
the "Get Statistics" button to execute the query. A dialog will open with the statistics result.</p>
11+
12+
<h2>How it works</h2>
13+
14+
<p>To query statistics on a <code>FeatureTable</code> field:</p>
15+
16+
<ol>
17+
<li>Create a <code>ServiceFeatureTable</code> from a URL.</li>
18+
<li>Create a list of <code>StatisticDefinition</code>s specifying which field to query against, the aggregate
19+
type, and an optional alias.</li>
20+
<li>Create <code>StatisticsQueryParameters</code> passing in the definitions. You can also use the setters to
21+
specify an area for the query (geometry) or a custom where clause.</li>
22+
<li>Call <code>featureTable.queryStatisticsAsync(queryParameters)</code> to make the query.</li>
23+
<li>Get the <code>StatisticsQueryResult</code> from the <code>ListenableFuture</code>. To see the stastics,
24+
iterate through <code>statisticsQueryResult.iterator()</code> to get the <code>StatisticRecord</code>s.</li>
25+
<li>The map of statistics can be retreived with <code>record.getStatistics()</code> for printing or showing in
26+
a list view.</li>
27+
</ol>
28+
29+
<h2>Features</h2>
30+
31+
<ul>
32+
<li>ArcGISMap</li>
33+
<li>FeatureLayer</li>
34+
<li>QueryParameters</li>
35+
<li>ServiceFeatureTable</li>
36+
<li>StatisticDefinition</li>
37+
<li>StatisticRecord</li>
38+
<li>StatisticType</li>
39+
<li>StatisticsQueryParameters</li>
40+
<li>StatisticsQueryResult</li>
41+
</ul>
213 KB
Loading
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/*
2+
* Copyright 2018 Esri.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
17+
package com.esri.samples.featurelayers.statistical_query;
18+
19+
import java.util.Iterator;
20+
import java.util.List;
21+
import java.util.concurrent.ExecutionException;
22+
import java.util.stream.Collectors;
23+
import java.util.stream.Stream;
24+
25+
import javafx.application.Application;
26+
import javafx.geometry.Insets;
27+
import javafx.geometry.Pos;
28+
import javafx.scene.Scene;
29+
import javafx.scene.control.Alert;
30+
import javafx.scene.control.Button;
31+
import javafx.scene.control.CheckBox;
32+
import javafx.scene.layout.StackPane;
33+
import javafx.scene.layout.VBox;
34+
import javafx.stage.Stage;
35+
36+
import com.esri.arcgisruntime.concurrent.ListenableFuture;
37+
import com.esri.arcgisruntime.data.QueryParameters;
38+
import com.esri.arcgisruntime.data.ServiceFeatureTable;
39+
import com.esri.arcgisruntime.data.StatisticDefinition;
40+
import com.esri.arcgisruntime.data.StatisticRecord;
41+
import com.esri.arcgisruntime.data.StatisticType;
42+
import com.esri.arcgisruntime.data.StatisticsQueryParameters;
43+
import com.esri.arcgisruntime.data.StatisticsQueryResult;
44+
import com.esri.arcgisruntime.layers.FeatureLayer;
45+
import com.esri.arcgisruntime.mapping.ArcGISMap;
46+
import com.esri.arcgisruntime.mapping.Basemap;
47+
import com.esri.arcgisruntime.mapping.view.MapView;
48+
49+
public class StatisticalQuerySample extends Application {
50+
51+
private MapView mapView;
52+
53+
@Override
54+
public void start(Stage stage) throws Exception {
55+
56+
try {
57+
// create stack pane and application scene
58+
StackPane stackPane = new StackPane();
59+
Scene scene = new Scene(stackPane);
60+
scene.getStylesheets().add(getClass().getResource("/css/style.css").toExternalForm());
61+
62+
// set title, size, and add scene to stage
63+
stage.setTitle("Statistical Query Sample");
64+
stage.setWidth(800);
65+
stage.setHeight(700);
66+
stage.setScene(scene);
67+
stage.show();
68+
69+
// create and set a map with the streets vector basemap
70+
final ArcGISMap map = new ArcGISMap(Basemap.createStreetsVector());
71+
mapView = new MapView();
72+
mapView.setMap(map);
73+
74+
// create a service feature table using the URL
75+
String featureServiceURL = "https://sampleserver6.arcgisonline" +
76+
".com/arcgis/rest/services/SampleWorldCities/MapServer/0";
77+
final ServiceFeatureTable featureTable = new ServiceFeatureTable(featureServiceURL);
78+
79+
// create a feature layer from the service feature table and add it to the map
80+
FeatureLayer featureLayer = new FeatureLayer(featureTable);
81+
map.getOperationalLayers().add(featureLayer);
82+
83+
// create toggle buttons for the query filters
84+
CheckBox currentExtentFilterToggle = new CheckBox("Only cities in current extent");
85+
CheckBox populationFilterToggle = new CheckBox("Only cities greater than 5M");
86+
87+
// create static definitions for all the statistics we want to query on
88+
// here we specify all statistic types for the "POP" (population) field
89+
List<StatisticDefinition> statisticDefinitions = Stream.of(StatisticType.values())
90+
.map(type -> new StatisticDefinition("POP", type, null))
91+
.collect(Collectors.toList());
92+
93+
// create a button to perform the statistical query
94+
Button queryButton = new Button("Get Statistics");
95+
queryButton.setOnAction(e -> {
96+
// create statistics query parameters with the definitions
97+
StatisticsQueryParameters statisticsQueryParameters = new StatisticsQueryParameters(statisticDefinitions);
98+
99+
if (currentExtentFilterToggle.isSelected()) {
100+
// set the query geometry to the current visible area
101+
statisticsQueryParameters.setGeometry(mapView.getVisibleArea());
102+
// set the spatial relationship to intersects (the default)
103+
statisticsQueryParameters.setSpatialRelationship(QueryParameters.SpatialRelationship.INTERSECTS);
104+
}
105+
106+
if (populationFilterToggle.isSelected()) {
107+
// set an attribute filter to only retrieve large cities (rank = 1)
108+
statisticsQueryParameters.setWhereClause("POP_RANK = 1");
109+
}
110+
111+
// execute the query
112+
ListenableFuture<StatisticsQueryResult> query = featureTable.queryStatisticsAsync(statisticsQueryParameters);
113+
query.addDoneListener(() -> {
114+
try {
115+
StatisticsQueryResult result = query.get();
116+
StringBuilder statistics = new StringBuilder();
117+
for (Iterator<StatisticRecord> it = result.iterator(); it.hasNext();) {
118+
StatisticRecord record = it.next();
119+
record.getStatistics().forEach((key, value) -> statistics.append("\n").append(key).append(": ").append(value));
120+
}
121+
Alert alert = new Alert(Alert.AlertType.INFORMATION, statistics.toString());
122+
alert.setHeaderText("Statistics");
123+
alert.show();
124+
} catch (ExecutionException | InterruptedException ex) {
125+
Alert alert = new Alert(Alert.AlertType.ERROR, ex.getMessage());
126+
alert.show();
127+
}
128+
});
129+
});
130+
131+
// layout the controls
132+
VBox controlsBox = new VBox(6);
133+
controlsBox.setAlignment(Pos.CENTER);
134+
controlsBox.setMaxSize(220, Double.MIN_VALUE);
135+
controlsBox.getStyleClass().add("panel-region");
136+
currentExtentFilterToggle.setMaxWidth(Double.MAX_VALUE);
137+
populationFilterToggle.setMaxWidth(Double.MAX_VALUE);
138+
queryButton.setMaxWidth(Double.MAX_VALUE);
139+
controlsBox.getChildren().addAll(currentExtentFilterToggle, populationFilterToggle, queryButton);
140+
141+
// add the map view and control panel to stack pane
142+
stackPane.getChildren().addAll(mapView, controlsBox);
143+
StackPane.setAlignment(controlsBox, Pos.TOP_LEFT);
144+
StackPane.setMargin(controlsBox, new Insets(10, 0, 0, 10));
145+
146+
} catch (Exception e) {
147+
// on any error, display the stack trace
148+
e.printStackTrace();
149+
}
150+
}
151+
152+
/**
153+
* Stops and releases all resources used in application.
154+
*/
155+
@Override
156+
public void stop() {
157+
158+
if (mapView != null) {
159+
mapView.dispose();
160+
}
161+
}
162+
163+
/**
164+
* Opens and runs application.
165+
*
166+
* @param args arguments passed to this application
167+
*/
168+
public static void main(String[] args) {
169+
170+
Application.launch(args);
171+
}
172+
173+
}

0 commit comments

Comments
 (0)