features display incomplete significantly when using SceneView but correctly when using MapView

1474
6
Jump to solution
10-06-2017 06:09 PM
AhmadLibda
Occasional Contributor

I do not know why "line" features display incomplete significantly when using SceneView but correctly when using MapView.

-local Arcgis server.

-local Sceneview.

-FeatureLayer of a dynamic map service.

MapView:

Scene View:

SceneView

0 Kudos
1 Solution

Accepted Solutions
ThomasSolow
Frequent Contributor

Features in a feature layer are fetched using the query function on a feature service, which is documented here: ArcGIS REST API 

The controller is in charge of determining when to send those queries, besides the first query, which is sent before the controller is instantiated.  The controller watches its extent property and the layer's definition expression for changes, and it sends a new query when a change occurs.  This is why changing the extent property on the controller or changing the definition expression causes new features to be fetched.

If you need to set this process up for all feature layers, you might try something like this:

view.watch('stationary', isStationary => {
  if (isStationary){
    view.layerViews.forEach(lv => {
      if (lv.layer.type === 'feature'){
        lv.controller.extent = view.extent);
      }
    })
  }
});‍‍‍‍‍‍‍‍‍‍‍‍

I think that will catch group layers.

In general, there's one layerView for each layer.  The layer itself represents the reference to some back-end resource (or sometimes a front-end resource) while the layerView contains logic and information about how the layer is actually displayed in the view.

View solution in original post

6 Replies
AhmadLibda
Occasional Contributor

I raised map service "maximum Number of Records Returned by Server" from 1000 to 5000 and now it is better but still incomplete. it kept this level no matter how much I raise that value: 

sceneview5000

0 Kudos
ThomasSolow
Frequent Contributor

One option may be to use a map server instead of a feature server, so an image is served up, rather than features.

I understand this may not be ideal, but I think there are likely performance limits on what can be displayed in 3D at the moment.  I don't know if this is documented anywhere, but the scene viewer in portal will not allow you to add layers with more than 2000 features.  My understanding is that this is an area of the API that is being worked on.

AhmadLibda
Occasional Contributor

Thank you Thomas

Indeed, this layer contains about 13000 features. However, what confused me, is an opposite issue on This Post.

Nevertheless, I may have found a solution by using DefinitionExpression on the layer where only a portion of the layer will appear (but correctly).

I only need a way to alter that Expression dynamically.. 

Any ideas?

0 Kudos
ThomasSolow
Frequent Contributor

You might try something like this for 3D:

view.watch('stationary', isStationary => {
  if (isStationary){
    let lv = view.layerViews.find(lv => lv.layer === featureLayer);
    if (lv){
      lv.controller.extent = view.extent; 
    }
  }
});

For 2D, this becomes:

view.watch('stationary', isStationary => {
  if (isStationary){
    let lv = view.layerViews.find(lv => lv.layer === featureLayer);
    if (lv){
      lv.controller.activeController.extent = view.extent; 
    }
  }
});

This should cause your layer to re-query using a filter based on the extent of the view. 

AhmadLibda
Occasional Contributor

Thank you Thomas,

This is exactly what I needed, but now I have a problem that it doesn't work with layers nested inside a LayerGroup.

Also, I need to understand this "Controller" and what data is queried and How. (the relation between a layer and its layerview and data flow)

0 Kudos
ThomasSolow
Frequent Contributor

Features in a feature layer are fetched using the query function on a feature service, which is documented here: ArcGIS REST API 

The controller is in charge of determining when to send those queries, besides the first query, which is sent before the controller is instantiated.  The controller watches its extent property and the layer's definition expression for changes, and it sends a new query when a change occurs.  This is why changing the extent property on the controller or changing the definition expression causes new features to be fetched.

If you need to set this process up for all feature layers, you might try something like this:

view.watch('stationary', isStationary => {
  if (isStationary){
    view.layerViews.forEach(lv => {
      if (lv.layer.type === 'feature'){
        lv.controller.extent = view.extent);
      }
    })
  }
});‍‍‍‍‍‍‍‍‍‍‍‍

I think that will catch group layers.

In general, there's one layerView for each layer.  The layer itself represents the reference to some back-end resource (or sometimes a front-end resource) while the layerView contains logic and information about how the layer is actually displayed in the view.