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:
- Cast 3 FeatureLayer.FeatureTable to ServiceFeatureTable (suggestions? this is how it was done somewhere on the reference)
- Set the ServiceFeatureTable.Where's
- Call ServiceFeatureTable.Refresh(false) on each table
- Set the MapView extent to the continental US
- Collect features and aggregate them (via ServiceFeatureTable.QueryAsync(queryFilter) and creating a collection)
- Linq out the extent based on the features in the collection, I could also go back to a shape if needed
- Call SetViewAsync(myEnvelope, timeSpan)
- 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.