Is there any way to get all features using layerview.queryFeatures

2909
9
05-29-2019 10:03 AM
JackFairfield
Occasional Contributor II

When running queryFeatures on a FeatureLayerView, only the features that are currently in the extent are returned.  Is there any way to query for all graphics that have been drawn / downloaded from the server? I would like to be able to get statistics on a large area even if the user is zoomed in and only looking at a few features.  I don't want to make any more server / rest endpoint requests, this becomes too slow.

Here is a jsbin that logs the number of features to demonstrate what I am talking about.

https://output.jsbin.com/jojonuhehi

Thanks.

Tags (2)
0 Kudos
9 Replies
Egge-Jan_Pollé
MVP Regular Contributor

Hi Jack Fairfield‌,

From the documentation (ArcGIS API for JavaScript 4.11):

A FeatureLayerView represents the LayerView of a FeatureLayer after it has been added to a Map in either a MapView or SceneView.

Apparently, as you code sample shows, this FeatureLayerView is updated every time you zoom in or out and the queryFeatureCount() only returns the number of features within the view extent.

Solution:

If you want to query more than just the features within the view extent you should not query the FeatureLayerView, but instead the FeatureLayer itself.

See the code snippet (modified from your sample) below: querying the layerView will return a limited number of features (depending on the zoom level) whereas querying the featureLayer will always return 73,642, i.e. the total number of Census Tracts in the Feature Service.

So, accessing the FeatureLayer itself will allow you to query more features than currently present in the view extent.

Does this solve your issue?

Egge-Jan

view.whenLayerView(featureLayer).then(function (layerView) {
    layerView.watch("updating", function (value) {
        if (!value) {
            featureLayer
                .queryFeatureCount()
                .then(function (results) {
                    console.log(results);
                })
            layerView
                .queryFeatureCount()
                .then(function (results) {
                    console.log(results);
                })
                .catch(function (error) {
                    console.error("query failed: ", error);
                });
        }
    });
});
0 Kudos
JackFairfield
Occasional Contributor II

Egge-Jan,

 

Thanks for your response. I understand that I could query the featureLayer to get the correct count, however I would prefer not to make an additional server request if possible.  At least some of the points have been requested and drawn on the map.  It would be nice if there was a way to query and only get the points that haven't been drawn / received already.

Not sure if what I am talking about makes a lot of sense.

Maybe instead, if there was a way to ensure that all points were drawn in the first place.  Why is the api not showing all points?

0 Kudos
Egge-Jan_Pollé
MVP Regular Contributor

Hi Jack,

No, maybe I don't really get what you are after...? In the example you included you are accessing a Feature Service with all Census Tracts for all of the United States, including Puerto Rico, while you are zoomed in to New York. So I can imagine that the FeatureLayerView does not contain all 73,642 Tracts, but only those needed to visualize New York...

You want to query more than is actually visible, you say, so I think you should not query the FeatureLayerView, but something else (the FeatureLayer itself....).

Does this make sense?

0 Kudos
JackFairfield
Occasional Contributor II

Here is another example:

https://jsbin.com/qagezumixa/edit?html,output

I am querying both the layerview and the feature layer itself.  My main question is, why aren't these values the same?  It appears that all of the points aren't actually being drawn for some reason.

Thanks for your response.

0 Kudos
Egge-Jan_Pollé
MVP Regular Contributor

Hi Jack,

Thanks for providing this additional example. I zoomed out to make sure the full dataset was visible (i.e. all the records were within the view extent). According to my explanation above, in this case, both the Layer View Count and the Layer Count should return the same result. But apparently, as you do proof in your example, they don't...

Sorry, I can not explain this behavior 😞

Maybe someone from Esri can jump in here? Kelly Hutchins‌?

BR,

Egge-Jan

0 Kudos
JackFairfield
Occasional Contributor II

I still don't understand this behavior.  Does anyone have any ideas?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jack,

   A LayerView is for querying the feature that are currently in the view (i.e. visible). If you need to query all the layers features you do not use LayerView you just query the layer directly using layer.queryFeatures.

JackFairfield
Occasional Contributor II

I am just wondering why all features aren't shown in my example.  I haven't set any definitionExpression or feature reduction properties.  Shouldn't all points be shown?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jack,

   I believe that behind the scenes the API makes decisions on what will be drawn based on coincidence. There is no need to draw two points if they are just feet apart and the views scale would not allow you to see that there are two there anyway. I am not 100% sure but I remember the Developers talking about all the optimizations they do to improve drawing speed.