FeatureLayerView.queryFeatures() returns all the field values and the geometry, but using SceneLayerView.queryFeatures() I can get only the objectid.
Can you post some code snippet on how you do the query? Posting the service url would also be really helpful.
But some general tips:
- make sure you set `outFields: ["*"]` on the query that you pass into the queryFeatures method.
- you can't get the geometry of a SceneLayer feature from the queryFeatures method, but you can get the 3D extent using queryExtent.
Otherwise check this sample on how to use SceneLayerView queries: ArcGIS API for JavaScript Sandbox
Can you show an example sceneLayer to test this?
It may be that, in general, sceneLayers features don't send their attributes to the client.
I mean the SceneLayerView, not the SceneLayer, so the queryFeatures function only do query at the client side, there's no such a process about sending something, am I right?
1.
the code snippet is really simple, I just find the scenelayerview instance from sceneview's allLayerViews property and do the query:
lyrVw <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">this</SPAN><SPAN class="punctuation token">.</SPAN>view<SPAN class="punctuation token">.</SPAN>allLayerViews<SPAN class="punctuation token">.</SPAN><SPAN class="token function">find</SPAN><SPAN class="punctuation token">(</SPAN>l<SPAN class="operator token">=</SPAN><SPAN class="operator token">></SPAN>l<SPAN class="punctuation token">.</SPAN>layer<SPAN class="punctuation token">.</SPAN>title <SPAN class="operator token">===</SPAN><SPAN class="string token">'LayerTitle'</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">let</SPAN> featureSet <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">await</SPAN> lyrVw<SPAN class="punctuation token">.</SPAN><SPAN class="token function">queryFeatures</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN></SPAN>
featureSet.features has all the loaded features of this scenelayer currently in the scene, but there geometry property is null.
2.
As soon as I got your reply, I changed the code and execute the query like this:
<SPAN class="keyword token">let</SPAN> featureSet <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">await</SPAN> lyrVw<SPAN class="punctuation token">.</SPAN><SPAN class="token function">queryFeatures</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">{</SPAN>outFields<SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="string token">'*'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN></SPAN>
this time the featureSet.features have all the field values! I'm confused here because the same code(leaving the queryFeatures's parameter blank) returns the expected result, the only difference is changing the LayerTitle to let the lyrVw equals an instance of FeatureLayerView. Is it a better practice to always set the Query params?
3.
You said I can't get the SceneLayer feature's geometry, is this going to be supported in future?
For now, I want to get the particular feature from query and open the popup, so I did wanted to pass the geometry as parameter to the Popup's open function to set the popup windows's location. I will try calculating the center point from the extent, it should work the same.
When you set outFields to ["*"] I don't think the query is going to be client-side anymore. This may be okay for your use case. You can check in dev tools, but I'd bet that you're firing off a bunch of requests when you do this.
Scene Layers only fetch the object id field by default. They also fetch any field that is needed in the client for a renderer. There's no easy way to specify which fields should be fetched, although there are probably a number of options for forcing the layer to fetch the attributes you want.
This means that, normally, SceneLayerView.queryFeatures() will only return the object id plus whichever fields the layer decided are required by the renderer. The client-side query can't return any fields that weren't fetched to draw the layer to begin with. When you pass in outFields, the layer seems to query the Scene Service rather than doing a client-side query. This is a little confusing: my assumption was that LayerView.queryFeatures() is always client-side.
I don't know a lot about Scene Layer geometries, but I don't think they're like Esri geometries. Scene Services return some binary format that can represent vertices, meshes, pyramids, etc. I'm not sure how to get access to that data or what coordinate system it will be in.
I've just debugged the code, yes, you're right. When I set outFields to ["*"] several new request appear in the Network panel of Chrome Dev Tools. I didn't noticed that and thought LayerView.queryFeatures() is always client-side.
You mentioned that there're probably some options for forcing the attributes fetch, is there some similar api to force the SceneLayer to fetch attributes from its linked FeatureLayer/FeatureService?
I need to set the SceneLayer's renderer to reflect its attribute changes, but attributes stored in SceneLayer/SceneService and been used to render never change after the service has been published. I have asked about this (here), for now I have to watch the SceneLayerView's updating and request attributes from the connected FeatureService manually.
A bit late to the party, but here is some more information:
1. & 3. yes, the geometry property is `null` because the geometry of a SceneLayer is, like Thomas said, in a binary format. The closest you can get to a readable geometry format is to get its extent, which is a geometry extent: Extent | API Reference | ArcGIS API for JavaScript 4.5. You can then calculate the center point to place the popup.
How did you publish the service? Sometimes popup info comes with the service, so you get the popup with all the attributes for free, and you don't need to configure anything. For example here. What is your use case? Do you want to trigger showing a popup by other action than clicking on the building?
2. Getting attributes: the SceneLayer only downloads the objectId and the attributes that it needs for the renderer. If the SceneLayer has a linked FeatureLayer the SceneLayerView query will query the FeatureLayer for attributes directly. If it doesn't have a linked FeatureLayer then the SceneLayerView query will still make a request to the server, but this time to get the attributes stored in the cache of the Scene Service. I know this is a bit confusing as the queries on the LayerView should be client-side. We are working on a guide topic that hopefully will make these workflows more clear. They are different from the FeatureLayerView.
And about updating the renderer, yes, unfortunately that can't be done using standard solutions, thanks Thomas for providing that hack...
I published the service from ArcGIS Pro, right click on the layer name and click 'Share As Web Layer'. Then three new service appeared in the REST Service Directory of ArcGIS Server, FeatureServer, MapServer and SceneServer.
I need to open the popup programmatically, so I need to do some query first and prepare the features and location for the Popup. I have tested and successfully opened the popup window by using FeatureLayerView.queryExtent().
Thank you for explaining the mechanism to me. Both of you are so kind~
ok, in this case I guess queryExtent is the best way to get the location of the popup. Happy to hear that it worked.
Signed in members can post, follow updates, and more. New here? Register a free account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.