ArcGIS Runtime SDK for .NET Zoom to Features that are not Selected?

3931
2
Jump to solution
08-10-2015 02:55 PM
MichaelCaruana
New Contributor II

Hello all,

I've spent quite a bit of time now trying to do something that should be relatively simple.  I've been up and down the API reference, I've tried looking here, and at gis.StackExchange, and I still can't seem to find what I'm looking for.

What I want: I have multiple FeatureLayers containing in house data, when a user selects a menu option, I want the map to pan and zoom to their relevant features (which are probably not in the current map extent). This is a WPF app and is using the newer .NET runtime, not the WPF one. (.NET 4.5, Runtime v10.2.5)

Details: I have three FeatureLayers, initially the map extent is set to a specific area, with all layers operating on demand.  I have a menu, with different "regions" we'll call them.  When a user selects their region, I want to pan/zoom to it.  The regions change very often, so instead of trying to set some static extents, I'm instead trying to use the data that is currently available to that region.  I was hoping to simply set the FeatureServiceTable.Where's to their appropriate definition, and magically zoom to the cumulative extent of all three layers.  I know each FeatureServiceTable will have it's extent property, however that is for the entire table; I want the extent of the filtered features to pass to MyMapView.SetViewAsync(filteredFeaturesExtent, new TimeSpan...).  Unless I'm missing something, there's no "pan the map to the only features that should be on it" method.

What I've Tried:

My data are all points, so after lots of googling, I decided to try making my own shape.  I used a MultiPointBuilder to create a MultiPoint shape, and then got the extents from the shape.  This kind of worked, I was having lots of issues with null QueryResults though, and decided to try something else.

I then decided I would try to use Linq on the feature collections returned from the FeatureServiceTable.QueryAsync method.  Again this seemed to work, but with the same issues as before.  I know the features exist, but aren't being returned as results.

I reworked the Linq quite a bit, worked out my own bugs, etc, but nothing was helping.  I then decided that it was probably querying via the current extent.  So, before I try querying for features, I set the MapView extent to a nice wide view of the continental US.  This also didn't help in the right way... I still have to set the layers' definitions, refresh all the feature tables, set the whole USA extent, THEN query for the features, then call SetView to pan the map to them.  Isn't there a better way?

My issue with this is that there seems to be too many redundant calls to the server:

  1. Cast 3 FeatureLayer.FeatureTable to ServiceFeatureTable (suggestions? this is how it was done somewhere on the reference)
  2. Set the ServiceFeatureTable.Where's
  3. Call ServiceFeatureTable.Refresh(false) on each table
  4. Set the MapView extent to the continental US
  5. Collect features and aggregate them (via ServiceFeatureTable.QueryAsync(queryFilter) and creating a collection)
  6. Linq out the extent based on the features in the collection, I could also go back to a shape if needed
  7. Call SetViewAsync(myEnvelope, timeSpan)
  8. Refresh all the FeatureLayers again, because it never seems to grab everything the first time.  I first tried without doing this, thinking the changing extent would cause all the features to be reloaded automatically.  However, maybe 1/3rd of the time, I'll leave it alone, and wait to see if my timer finds anymore features, and it always does.

What is the best way to query for, and find the extent of a group of points which are probably not even in the map extent?  Is this the only way I'll be able to pan the map to features that aren't loaded?  Is there some hidden overload of the QueryAsync method that would allow me to pass in a wider extent than the current view?  Any and all tips and tricks will be greatly appreciated as I feel this is a little cumbersome to simply pan and zoom the map.

0 Kudos
1 Solution

Accepted Solutions
AnttiKajanus1
Regular Contributor II

Hi,

First I would recommend to upgrade binaries to 10.2.6 since it contained several bug fixes.

When you are using FeatureServices, remember that there is a service limit how many results it can return per call. MaxRecordCount is service side configuration that can be changed and defaults to 1000. This might be one of the reasons why you aren't getting all the results at once since we cannot override this from the client side.

FeatureServices are usually run using default configuration ServiceFeatureTable.Mode = OnDemand which queries only features from the visible extent. You can use mode Snapshot that gets all available features from the service. The amount that you get initially might be restricted by the service configuration. In this case, left overs are queried in similar fashion than in OnDemand mode.

If you need to use spatial query when getting features from FeatureService / ServiceFeatureTable you can use SpatialQueryFilter Class instead of QueryFilter.

One when you are aggregating features and finding the full extent, you can create an envelope from the features if layers extent doesn't match what you need.

View solution in original post

0 Kudos
2 Replies
AnttiKajanus1
Regular Contributor II

Hi,

First I would recommend to upgrade binaries to 10.2.6 since it contained several bug fixes.

When you are using FeatureServices, remember that there is a service limit how many results it can return per call. MaxRecordCount is service side configuration that can be changed and defaults to 1000. This might be one of the reasons why you aren't getting all the results at once since we cannot override this from the client side.

FeatureServices are usually run using default configuration ServiceFeatureTable.Mode = OnDemand which queries only features from the visible extent. You can use mode Snapshot that gets all available features from the service. The amount that you get initially might be restricted by the service configuration. In this case, left overs are queried in similar fashion than in OnDemand mode.

If you need to use spatial query when getting features from FeatureService / ServiceFeatureTable you can use SpatialQueryFilter Class instead of QueryFilter.

One when you are aggregating features and finding the full extent, you can create an envelope from the features if layers extent doesn't match what you need.

View solution in original post

0 Kudos
MichaelCaruana
New Contributor II

SpatialQueryFilter was exactly what I needed.  It worked perfectly, and actually helped me in a few other places, thank you so much!

0 Kudos