Skip to content

Commit 0f5c1f1

Browse files
authored
Merge pull request #529 from Esri/ncastle/qfce
Query feature count and extent - cartography and readme updates
2 parents 3165f80 + 09f3f6b commit 0f5c1f1

File tree

17 files changed

+332
-168
lines changed

17 files changed

+332
-168
lines changed

src/Android/Xamarin.Android/Samples/Analysis/QueryFeatureCountAndExtent/QueryFeatureCountAndExtent.cs

Lines changed: 46 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -24,131 +24,124 @@ namespace ArcGISRuntime.Samples.QueryFeatureCountAndExtent
2424
[ArcGISRuntime.Samples.Shared.Attributes.Sample(
2525
"Query feature count and extent",
2626
"Analysis",
27-
"This sample demonstrates how to query a feature table, in this case returning a count, for features that are within the visible extent or that meet specified criteria.",
27+
"Zoom to features matching a query and count features in the visible extent.",
2828
"Use the button to zoom to the extent of the state specified (by abbreviation) in the textbox or use the button to count the features in the current extent.")]
2929
public class QueryFeatureCountAndExtent : Activity
3030
{
31-
// Search box for state entry
31+
// UI controls.
3232
private EditText _myStateEntry;
33-
34-
// Label for results
3533
private TextView _myResultsLabel;
36-
37-
// Button for querying cities by state
3834
private Button _myQueryStateButton;
39-
40-
// Button for querying cities within the current extent
4135
private Button _myQueryExtentButton;
42-
43-
// Create and hold reference to the used MapView
4436
private readonly MapView _myMapView = new MapView();
4537

46-
// URL to the feature service
47-
private readonly Uri _usaCitiesSource = new Uri("https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0");
38+
// URL to the feature service.
39+
private readonly Uri _medicareHospitalSpendLayer =
40+
new Uri("https://services1.arcgis.com/4yjifSiIG17X0gW4/arcgis/rest/services/Medicare_Hospital_Spending_per_Patient/FeatureServer/0");
4841

49-
// Feature table to query
50-
private ServiceFeatureTable _myFeatureTable;
42+
// Feature table to query.
43+
private ServiceFeatureTable _featureTable;
5144

5245
protected override void OnCreate(Bundle bundle)
5346
{
5447
base.OnCreate(bundle);
5548

5649
Title = "Query feature count and extent";
5750

58-
// Create the UI, setup the control references and execute initialization
5951
CreateLayout();
6052
Initialize();
6153
}
6254

6355
private async void Initialize()
6456
{
65-
// Create the map with a vector street basemap
66-
Map myMap = new Map(Basemap.CreateStreetsVector());
57+
// Create the map with a basemap.
58+
Map myMap = new Map(Basemap.CreateDarkGrayCanvasVector());
6759

68-
// Create the feature table from the service URL
69-
_myFeatureTable = new ServiceFeatureTable(_usaCitiesSource);
60+
// Create the feature table from the service URL.
61+
_featureTable = new ServiceFeatureTable(_medicareHospitalSpendLayer);
7062

71-
// Create the feature layer from the table
72-
FeatureLayer myFeatureLayer = new FeatureLayer(_myFeatureTable);
63+
// Create the feature layer from the table.
64+
FeatureLayer myFeatureLayer = new FeatureLayer(_featureTable);
7365

74-
// Add the feature layer to the map
66+
// Add the feature layer to the map.
7567
myMap.OperationalLayers.Add(myFeatureLayer);
7668

77-
// Wait for the feature layer to load
69+
// Wait for the feature layer to load.
7870
await myFeatureLayer.LoadAsync();
7971

80-
// Add the map to the MapView
81-
_myMapView.Map = myMap;
72+
// Set the map initial extent to the extent of the feature layer.
73+
myMap.InitialViewpoint = new Viewpoint(myFeatureLayer.FullExtent);
8274

83-
// Set the map initial extent to the extent of the feature layer
84-
await _myMapView.SetViewpointGeometryAsync(myFeatureLayer.FullExtent, 50);
75+
// Add the map to the MapView.
76+
_myMapView.Map = myMap;
8577
}
8678

8779
private async void BtnZoomToFeatures_Click(object sender, EventArgs e)
8880
{
89-
// Create the query parameters
90-
QueryParameters queryStates = new QueryParameters { WhereClause = $"upper(ST) LIKE '%{_myStateEntry.Text.ToUpper()}%'" };
81+
// Create the query parameters.
82+
QueryParameters queryStates = new QueryParameters { WhereClause = $"upper(State) LIKE '%{_myStateEntry.Text.ToUpper()}%'" };
9183

92-
// Get the extent from the query
93-
Envelope resultExtent = await _myFeatureTable.QueryExtentAsync(queryStates);
84+
// Get the extent from the query.
85+
Envelope resultExtent = await _featureTable.QueryExtentAsync(queryStates);
9486

95-
// Return if there is no result (might happen if query is invalid)
87+
// Return if there is no result (might happen if query is invalid).
9688
if (resultExtent?.SpatialReference == null)
9789
{
9890
_myResultsLabel.Text = $"Couldn't zoom to features in {_myStateEntry.Text}.";
9991
return;
10092
}
10193

102-
// Create a viewpoint from the extent
94+
// Create a viewpoint from the extent.
10395
Viewpoint resultViewpoint = new Viewpoint(resultExtent);
10496

105-
// Zoom to the viewpoint
97+
// Zoom to the viewpoint.
10698
await _myMapView.SetViewpointAsync(resultViewpoint);
10799

108-
// Update label
100+
// Update label.
109101
_myResultsLabel.Text = $"Zoomed to features in {_myStateEntry.Text}.";
110102
}
111103

112104
private async void BtnCountFeatures_Click(object sender, EventArgs e)
113105
{
114106
try
115107
{
116-
// Create the query parameters
108+
// Get the current visible extent.
109+
Geometry currentExtent = _myMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry;
110+
111+
// Create the query parameters.
117112
QueryParameters queryCityCount = new QueryParameters
118113
{
119-
// Get the current view extent and use that as a query parameters
120-
Geometry = _myMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry,
121-
122-
// Specify the interpretation of the Geometry query parameters
114+
Geometry = currentExtent,
115+
// Specify the interpretation of the Geometry query parameters.
123116
SpatialRelationship = SpatialRelationship.Intersects
124117
};
125118

126-
// Get the count of matching features
127-
long count = await _myFeatureTable.QueryFeatureCountAsync(queryCityCount);
119+
// Get the count of matching features.
120+
long count = await _featureTable.QueryFeatureCountAsync(queryCityCount);
128121

129-
// Update the UI
122+
// Update the UI.
130123
_myResultsLabel.Text = $"{count} features in extent";
131124
}
132125
catch (NullReferenceException exception)
133126
{
134-
// Sample wasn't ready
127+
// Sample wasn't ready.
135128
System.Diagnostics.Debug.WriteLine(exception);
136129
}
137130
catch (Exception)
138131
{
139-
// Uncaught exception in async void will crash application
132+
// Uncaught exception in async void will crash application.
140133
}
141134
}
142135

143136
private void CreateLayout()
144137
{
145-
// Create a new vertical layout for the app
138+
// Create a new vertical layout for the app.
146139
LinearLayout layout = new LinearLayout(this) { Orientation = Orientation.Vertical };
147140

148-
// Create the entry
141+
// Create the entry.
149142
_myStateEntry = new EditText(this) { Hint = "State abbreviation (e.g. NY)" };
150143

151-
// Hide the keyboard on enter
144+
// Hide the keyboard on enter.
152145
_myStateEntry.KeyPress += (sender, args) =>
153146
{
154147
if (args.Event.Action == KeyEventActions.Down && args.KeyCode == Keycode.Enter)
@@ -163,25 +156,25 @@ private void CreateLayout()
163156
}
164157
};
165158

166-
// Create the results label
159+
// Create the results label.
167160
_myResultsLabel = new TextView(this);
168161

169-
// Create the two buttons
162+
// Create the two buttons.
170163
_myQueryStateButton = new Button(this) { Text = "Zoom to matching features" };
171164
_myQueryExtentButton = new Button(this) { Text = "Count features in extent" };
172165

173-
// Subscribe to button events
166+
// Subscribe to button events.
174167
_myQueryExtentButton.Click += BtnCountFeatures_Click;
175168
_myQueryStateButton.Click += BtnZoomToFeatures_Click;
176169

177-
// Add the views to the layout
170+
// Add the views to the layout.
178171
layout.AddView(_myStateEntry);
179172
layout.AddView(_myQueryStateButton);
180173
layout.AddView(_myQueryExtentButton);
181174
layout.AddView(_myResultsLabel);
182175
layout.AddView(_myMapView);
183176

184-
// Show the layout in the app
177+
// Show the layout in the app.
185178
SetContentView(layout);
186179
}
187180
}
-56.4 KB
Loading
Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,43 @@
11
# Query feature count and extent
22

3-
This sample demonstrates how to query a feature table, in this case returning a count, for features that are within the visible extent or that meet specified criteria.
3+
Zoom to features matching a query and count the features in the current visible extent.
44

5-
<img src="QueryFeatureCountAndExtent.jpg" width="350"/>
5+
![](QueryFeatureCountAndExtent.jpg)
66

7-
## Instructions
7+
## How to use the sample
88

99
Use the button to zoom to the extent of the state specified (by abbreviation) in the textbox or use the button to count the features in the current extent.
10+
11+
## How it works
12+
13+
Querying by state abbreviation:
14+
15+
1. A `QueryParameters` object is created with a `WhereClause`.
16+
2. `FeatureTable.QueryExtentAsync` is called with the `QueryParameters` object to obtain the extent that contains all matching features.
17+
3. The extent is converted to a `Viewpoint`, which is passed to `MapView.SetViewpointAsync`.
18+
19+
Counting features in the current extent:
20+
21+
1. The current visible extent is obtained from a call to `MapView.GetCurrentViewpoint(ViewpointType)`.
22+
2. A `QueryParameters` object is created with the visible extent and a defined `SpatialRelationship` (in this case 'intersects').
23+
3. The count of matching features is obtained from a call to `FeatureTable.QueryFeatureCountAsync`.
24+
25+
## Relevant API
26+
27+
* `QueryParameters`
28+
* `QueryParameters.WhereClause`
29+
* `QueryParameters.Geometry`
30+
* `QueryParameters.SpatialRelationship`
31+
* `FeatureTable.QueryExtentAsync`
32+
* `FeatureTable.QueryFeatureCountAsync`
33+
* `MapView.GetCurrentViewpoint(ViewpointType)`
34+
35+
## About the data
36+
37+
[See the layer on ArcGIS Online](https://www.arcgis.com/home/item.html?id=c8810b20c01b4e8ba5cd848966a66d7b)
38+
39+
This map shows hospital spending per-patient for common incidents. Hospitals in blue/turquoise spend less than the national average. Red/salmon indicates higher spending relative to other hospitals, while gray is average.
40+
41+
## Tags
42+
43+
Feature layer, Feature table, Query, Medicare
-7.02 KB
Loading

src/Forms/Shared/Samples/Analysis/QueryFeatureCountAndExtent/QueryFeatureCountAndExtent.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
<ColumnDefinition Width="*" />
1616
</Grid.ColumnDefinitions>
1717
<Entry Grid.Row="0" Grid.ColumnSpan="2" x:Name="txtStateEntry" Text="NH" />
18-
<Button Text="Zoom to matching features" Grid.Row="1" Grid.Column="0" Clicked="BtnZoomToFeatures_Click" />
19-
<Button Text="Count features in extent" Grid.Row="1" Grid.Column="1" Clicked="BtnCountFeatures_Click" />
18+
<Button Text="Zoom to matching" Grid.Row="1" Grid.Column="0" Clicked="BtnZoomToFeatures_Click" />
19+
<Button Text="Count in extent" Grid.Row="1" Grid.Column="1" Clicked="BtnCountFeatures_Click" />
2020
<Label Grid.Row="2" Grid.ColumnSpan="2" x:Name="txtResults" />
2121
<esriUI:MapView x:Name="MyMapView" Grid.Row="3" Grid.ColumnSpan="2" />
2222
</Grid>

src/Forms/Shared/Samples/Analysis/QueryFeatureCountAndExtent/QueryFeatureCountAndExtent.xaml.cs

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,89 +18,90 @@ namespace ArcGISRuntime.Samples.QueryFeatureCountAndExtent
1818
[ArcGISRuntime.Samples.Shared.Attributes.Sample(
1919
"Query feature count and extent",
2020
"Analysis",
21-
"This sample demonstrates how to query a feature table, in this case returning a count, for features that are within the visible extent or that meet specified criteria.",
21+
"Zoom to features matching a query and count features in the visible extent.",
2222
"Use the button to zoom to the extent of the state specified (by abbreviation) in the textbox or use the button to count the features in the current extent.")]
2323
public partial class QueryFeatureCountAndExtent : ContentPage
2424
{
25-
// URL to the feature service
26-
private readonly Uri _usaCitiesSource = new Uri("https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0");
25+
// URL to the feature service.
26+
private readonly Uri _medicareHospitalSpendLayer =
27+
new Uri("https://services1.arcgis.com/4yjifSiIG17X0gW4/arcgis/rest/services/Medicare_Hospital_Spending_per_Patient/FeatureServer/0");
2728

28-
// Feature table to query
29-
private ServiceFeatureTable _myFeatureTable;
29+
// Feature table to query.
30+
private ServiceFeatureTable _featureTable;
3031

3132
public QueryFeatureCountAndExtent()
3233
{
3334
InitializeComponent();
3435

3536
Title = "Query feature count and extent";
36-
37-
// Create the UI, setup the control references and execute initialization
3837
Initialize();
3938
}
4039

4140
private async void Initialize()
4241
{
43-
// Create the map with a vector street basemap
44-
Map myMap = new Map(Basemap.CreateStreetsVector());
42+
// Create the map with a basemap.
43+
Map myMap = new Map(Basemap.CreateDarkGrayCanvasVector());
4544

46-
// Create the feature table from the service URL
47-
_myFeatureTable = new ServiceFeatureTable(_usaCitiesSource);
45+
// Create the feature table from the service URL.
46+
_featureTable = new ServiceFeatureTable(_medicareHospitalSpendLayer);
4847

49-
// Create the feature layer from the table
50-
FeatureLayer myFeatureLayer = new FeatureLayer(_myFeatureTable);
48+
// Create the feature layer from the table.
49+
FeatureLayer myFeatureLayer = new FeatureLayer(_featureTable);
5150

52-
// Add the feature layer to the map
51+
// Add the feature layer to the map.
5352
myMap.OperationalLayers.Add(myFeatureLayer);
5453

55-
// Wait for the feature layer to load
54+
// Wait for the feature layer to load.
5655
await myFeatureLayer.LoadAsync();
5756

58-
// Set the map initial extent to the extent of the feature layer
57+
// Set the map initial extent to the extent of the feature layer.
5958
myMap.InitialViewpoint = new Viewpoint(myFeatureLayer.FullExtent);
6059

61-
// Add the map to the MapView
60+
// Add the map to the MapView.
6261
MyMapView.Map = myMap;
6362
}
6463

6564
private async void BtnZoomToFeatures_Click(object sender, EventArgs e)
6665
{
67-
// Create the query parameters
68-
QueryParameters queryStates = new QueryParameters { WhereClause = $"upper(ST) LIKE '%{txtStateEntry.Text.ToUpper()}%'" };
66+
// Create the query parameters.
67+
QueryParameters queryStates = new QueryParameters { WhereClause = $"upper(State) LIKE '%{txtStateEntry.Text.ToUpper()}%'" };
6968

70-
// Get the extent from the query
71-
Envelope resultExtent = await _myFeatureTable.QueryExtentAsync(queryStates);
69+
// Get the extent from the query.
70+
Envelope resultExtent = await _featureTable.QueryExtentAsync(queryStates);
7271

73-
// Return if there is no result (might happen if query is invalid)
72+
// Return if there is no result (might happen if query is invalid).
7473
if (resultExtent?.SpatialReference == null)
7574
{
7675
return;
7776
}
7877

79-
// Create a viewpoint from the extent
78+
// Create a viewpoint from the extent.
8079
Viewpoint resultViewpoint = new Viewpoint(resultExtent);
8180

82-
// Zoom to the viewpoint
81+
// Zoom to the viewpoint.
8382
await MyMapView.SetViewpointAsync(resultViewpoint);
8483

85-
// Update the UI
84+
// Update the UI.
8685
txtResults.Text = $"Zoomed to features in {txtStateEntry.Text}";
8786
}
8887

8988
private async void BtnCountFeatures_Click(object sender, EventArgs e)
9089
{
91-
// Create the query parameters
90+
// Get the current visible extent.
91+
Geometry currentExtent = MyMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry;
92+
93+
// Create the query parameters.
9294
QueryParameters queryCityCount = new QueryParameters
9395
{
94-
// Get the current view extent and use that as a query parameters
95-
Geometry = MyMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry,
96-
// Specify the interpretation of the Geometry query parameters
96+
Geometry = currentExtent,
97+
// Specify the interpretation of the Geometry query parameters.
9798
SpatialRelationship = SpatialRelationship.Intersects
9899
};
99100

100-
// Get the count of matching features
101-
long count = await _myFeatureTable.QueryFeatureCountAsync(queryCityCount);
101+
// Get the count of matching features.
102+
long count = await _featureTable.QueryFeatureCountAsync(queryCityCount);
102103

103-
// Update the UI
104+
// Update the UI.
104105
txtResults.Text = $"{count} features in extent";
105106
}
106107
}

0 commit comments

Comments
 (0)