Skip to content

Commit

Permalink
Merge pull request #529 from Esri/ncastle/qfce
Browse files Browse the repository at this point in the history
Query feature count and extent - cartography and readme updates
  • Loading branch information
nCastle1 authored Oct 16, 2018
2 parents 3165f80 + 09f3f6b commit 0f5c1f1
Show file tree
Hide file tree
Showing 17 changed files with 332 additions and 168 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,131 +24,124 @@ namespace ArcGISRuntime.Samples.QueryFeatureCountAndExtent
[ArcGISRuntime.Samples.Shared.Attributes.Sample(
"Query feature count and extent",
"Analysis",
"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.",
"Zoom to features matching a query and count features in the visible extent.",
"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.")]
public class QueryFeatureCountAndExtent : Activity
{
// Search box for state entry
// UI controls.
private EditText _myStateEntry;

// Label for results
private TextView _myResultsLabel;

// Button for querying cities by state
private Button _myQueryStateButton;

// Button for querying cities within the current extent
private Button _myQueryExtentButton;

// Create and hold reference to the used MapView
private readonly MapView _myMapView = new MapView();

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

// Feature table to query
private ServiceFeatureTable _myFeatureTable;
// Feature table to query.
private ServiceFeatureTable _featureTable;

protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);

Title = "Query feature count and extent";

// Create the UI, setup the control references and execute initialization
CreateLayout();
Initialize();
}

private async void Initialize()
{
// Create the map with a vector street basemap
Map myMap = new Map(Basemap.CreateStreetsVector());
// Create the map with a basemap.
Map myMap = new Map(Basemap.CreateDarkGrayCanvasVector());

// Create the feature table from the service URL
_myFeatureTable = new ServiceFeatureTable(_usaCitiesSource);
// Create the feature table from the service URL.
_featureTable = new ServiceFeatureTable(_medicareHospitalSpendLayer);

// Create the feature layer from the table
FeatureLayer myFeatureLayer = new FeatureLayer(_myFeatureTable);
// Create the feature layer from the table.
FeatureLayer myFeatureLayer = new FeatureLayer(_featureTable);

// Add the feature layer to the map
// Add the feature layer to the map.
myMap.OperationalLayers.Add(myFeatureLayer);

// Wait for the feature layer to load
// Wait for the feature layer to load.
await myFeatureLayer.LoadAsync();

// Add the map to the MapView
_myMapView.Map = myMap;
// Set the map initial extent to the extent of the feature layer.
myMap.InitialViewpoint = new Viewpoint(myFeatureLayer.FullExtent);

// Set the map initial extent to the extent of the feature layer
await _myMapView.SetViewpointGeometryAsync(myFeatureLayer.FullExtent, 50);
// Add the map to the MapView.
_myMapView.Map = myMap;
}

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

// Get the extent from the query
Envelope resultExtent = await _myFeatureTable.QueryExtentAsync(queryStates);
// Get the extent from the query.
Envelope resultExtent = await _featureTable.QueryExtentAsync(queryStates);

// Return if there is no result (might happen if query is invalid)
// Return if there is no result (might happen if query is invalid).
if (resultExtent?.SpatialReference == null)
{
_myResultsLabel.Text = $"Couldn't zoom to features in {_myStateEntry.Text}.";
return;
}

// Create a viewpoint from the extent
// Create a viewpoint from the extent.
Viewpoint resultViewpoint = new Viewpoint(resultExtent);

// Zoom to the viewpoint
// Zoom to the viewpoint.
await _myMapView.SetViewpointAsync(resultViewpoint);

// Update label
// Update label.
_myResultsLabel.Text = $"Zoomed to features in {_myStateEntry.Text}.";
}

private async void BtnCountFeatures_Click(object sender, EventArgs e)
{
try
{
// Create the query parameters
// Get the current visible extent.
Geometry currentExtent = _myMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry;

// Create the query parameters.
QueryParameters queryCityCount = new QueryParameters
{
// Get the current view extent and use that as a query parameters
Geometry = _myMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry,

// Specify the interpretation of the Geometry query parameters
Geometry = currentExtent,
// Specify the interpretation of the Geometry query parameters.
SpatialRelationship = SpatialRelationship.Intersects
};

// Get the count of matching features
long count = await _myFeatureTable.QueryFeatureCountAsync(queryCityCount);
// Get the count of matching features.
long count = await _featureTable.QueryFeatureCountAsync(queryCityCount);

// Update the UI
// Update the UI.
_myResultsLabel.Text = $"{count} features in extent";
}
catch (NullReferenceException exception)
{
// Sample wasn't ready
// Sample wasn't ready.
System.Diagnostics.Debug.WriteLine(exception);
}
catch (Exception)
{
// Uncaught exception in async void will crash application
// Uncaught exception in async void will crash application.
}
}

private void CreateLayout()
{
// Create a new vertical layout for the app
// Create a new vertical layout for the app.
LinearLayout layout = new LinearLayout(this) { Orientation = Orientation.Vertical };

// Create the entry
// Create the entry.
_myStateEntry = new EditText(this) { Hint = "State abbreviation (e.g. NY)" };

// Hide the keyboard on enter
// Hide the keyboard on enter.
_myStateEntry.KeyPress += (sender, args) =>
{
if (args.Event.Action == KeyEventActions.Down && args.KeyCode == Keycode.Enter)
Expand All @@ -163,25 +156,25 @@ private void CreateLayout()
}
};

// Create the results label
// Create the results label.
_myResultsLabel = new TextView(this);

// Create the two buttons
// Create the two buttons.
_myQueryStateButton = new Button(this) { Text = "Zoom to matching features" };
_myQueryExtentButton = new Button(this) { Text = "Count features in extent" };

// Subscribe to button events
// Subscribe to button events.
_myQueryExtentButton.Click += BtnCountFeatures_Click;
_myQueryStateButton.Click += BtnZoomToFeatures_Click;

// Add the views to the layout
// Add the views to the layout.
layout.AddView(_myStateEntry);
layout.AddView(_myQueryStateButton);
layout.AddView(_myQueryExtentButton);
layout.AddView(_myResultsLabel);
layout.AddView(_myMapView);

// Show the layout in the app
// Show the layout in the app.
SetContentView(layout);
}
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,9 +1,43 @@
# Query feature count and extent

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.
Zoom to features matching a query and count the features in the current visible extent.

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

## Instructions
## How to use the sample

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.

## How it works

Querying by state abbreviation:

1. A `QueryParameters` object is created with a `WhereClause`.
2. `FeatureTable.QueryExtentAsync` is called with the `QueryParameters` object to obtain the extent that contains all matching features.
3. The extent is converted to a `Viewpoint`, which is passed to `MapView.SetViewpointAsync`.

Counting features in the current extent:

1. The current visible extent is obtained from a call to `MapView.GetCurrentViewpoint(ViewpointType)`.
2. A `QueryParameters` object is created with the visible extent and a defined `SpatialRelationship` (in this case 'intersects').
3. The count of matching features is obtained from a call to `FeatureTable.QueryFeatureCountAsync`.

## Relevant API

* `QueryParameters`
* `QueryParameters.WhereClause`
* `QueryParameters.Geometry`
* `QueryParameters.SpatialRelationship`
* `FeatureTable.QueryExtentAsync`
* `FeatureTable.QueryFeatureCountAsync`
* `MapView.GetCurrentViewpoint(ViewpointType)`

## About the data

[See the layer on ArcGIS Online](https://www.arcgis.com/home/item.html?id=c8810b20c01b4e8ba5cd848966a66d7b)

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.

## Tags

Feature layer, Feature table, Query, Medicare
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Entry Grid.Row="0" Grid.ColumnSpan="2" x:Name="txtStateEntry" Text="NH" />
<Button Text="Zoom to matching features" Grid.Row="1" Grid.Column="0" Clicked="BtnZoomToFeatures_Click" />
<Button Text="Count features in extent" Grid.Row="1" Grid.Column="1" Clicked="BtnCountFeatures_Click" />
<Button Text="Zoom to matching" Grid.Row="1" Grid.Column="0" Clicked="BtnZoomToFeatures_Click" />
<Button Text="Count in extent" Grid.Row="1" Grid.Column="1" Clicked="BtnCountFeatures_Click" />
<Label Grid.Row="2" Grid.ColumnSpan="2" x:Name="txtResults" />
<esriUI:MapView x:Name="MyMapView" Grid.Row="3" Grid.ColumnSpan="2" />
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,89 +18,90 @@ namespace ArcGISRuntime.Samples.QueryFeatureCountAndExtent
[ArcGISRuntime.Samples.Shared.Attributes.Sample(
"Query feature count and extent",
"Analysis",
"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.",
"Zoom to features matching a query and count features in the visible extent.",
"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.")]
public partial class QueryFeatureCountAndExtent : ContentPage
{
// URL to the feature service
private readonly Uri _usaCitiesSource = new Uri("https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0");
// URL to the feature service.
private readonly Uri _medicareHospitalSpendLayer =
new Uri("https://services1.arcgis.com/4yjifSiIG17X0gW4/arcgis/rest/services/Medicare_Hospital_Spending_per_Patient/FeatureServer/0");

// Feature table to query
private ServiceFeatureTable _myFeatureTable;
// Feature table to query.
private ServiceFeatureTable _featureTable;

public QueryFeatureCountAndExtent()
{
InitializeComponent();

Title = "Query feature count and extent";

// Create the UI, setup the control references and execute initialization
Initialize();
}

private async void Initialize()
{
// Create the map with a vector street basemap
Map myMap = new Map(Basemap.CreateStreetsVector());
// Create the map with a basemap.
Map myMap = new Map(Basemap.CreateDarkGrayCanvasVector());

// Create the feature table from the service URL
_myFeatureTable = new ServiceFeatureTable(_usaCitiesSource);
// Create the feature table from the service URL.
_featureTable = new ServiceFeatureTable(_medicareHospitalSpendLayer);

// Create the feature layer from the table
FeatureLayer myFeatureLayer = new FeatureLayer(_myFeatureTable);
// Create the feature layer from the table.
FeatureLayer myFeatureLayer = new FeatureLayer(_featureTable);

// Add the feature layer to the map
// Add the feature layer to the map.
myMap.OperationalLayers.Add(myFeatureLayer);

// Wait for the feature layer to load
// Wait for the feature layer to load.
await myFeatureLayer.LoadAsync();

// Set the map initial extent to the extent of the feature layer
// Set the map initial extent to the extent of the feature layer.
myMap.InitialViewpoint = new Viewpoint(myFeatureLayer.FullExtent);

// Add the map to the MapView
// Add the map to the MapView.
MyMapView.Map = myMap;
}

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

// Get the extent from the query
Envelope resultExtent = await _myFeatureTable.QueryExtentAsync(queryStates);
// Get the extent from the query.
Envelope resultExtent = await _featureTable.QueryExtentAsync(queryStates);

// Return if there is no result (might happen if query is invalid)
// Return if there is no result (might happen if query is invalid).
if (resultExtent?.SpatialReference == null)
{
return;
}

// Create a viewpoint from the extent
// Create a viewpoint from the extent.
Viewpoint resultViewpoint = new Viewpoint(resultExtent);

// Zoom to the viewpoint
// Zoom to the viewpoint.
await MyMapView.SetViewpointAsync(resultViewpoint);

// Update the UI
// Update the UI.
txtResults.Text = $"Zoomed to features in {txtStateEntry.Text}";
}

private async void BtnCountFeatures_Click(object sender, EventArgs e)
{
// Create the query parameters
// Get the current visible extent.
Geometry currentExtent = MyMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry;

// Create the query parameters.
QueryParameters queryCityCount = new QueryParameters
{
// Get the current view extent and use that as a query parameters
Geometry = MyMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry,
// Specify the interpretation of the Geometry query parameters
Geometry = currentExtent,
// Specify the interpretation of the Geometry query parameters.
SpatialRelationship = SpatialRelationship.Intersects
};

// Get the count of matching features
long count = await _myFeatureTable.QueryFeatureCountAsync(queryCityCount);
// Get the count of matching features.
long count = await _featureTable.QueryFeatureCountAsync(queryCityCount);

// Update the UI
// Update the UI.
txtResults.Text = $"{count} features in extent";
}
}
Expand Down
Loading

0 comments on commit 0f5c1f1

Please sign in to comment.