iTowns / itowns

A Three.js-based framework written in Javascript/WebGL for visualizing 3D geospatial data
http://www.itowns-project.org
Other
1.11k stars 299 forks source link

FeatureGeometryLayer doesn't seem to be remove form the list of layer after few iteration #1863

Closed agrignard closed 1 year ago

agrignard commented 2 years ago

I am actually working with this team https://github.com/VCityTeam where some of our features are based on itowns. In my research projects, I am working on ABM simulation and I am now trying to implement a visualizator in VCITY/Itowns (see this issue https://github.com/VCityTeam/UD_ReAgent_ABM/issues/11).

The idea is to get a geojson file from a server ( in this case a simulation run by Gama Platform) updating the geojson at each step of the iteration. I got some first results using a FeatureGeometryLayerthat I'd like to update each frame.

To do so I create a FeatureGeometryLayer first and then to update it I erase it and the recreate it and readd it in the itowns view.

However I get the same error described in this issue after 31 iteration I get this error message

Too much three.js layers. Starting from now all of them will use layerMask = 31

This is what I have in my SetInterval function

if (added) {
    app.view.removeLayer("GAMA");
    view.notifyChange();
}  
added = 1;

_source = new itowns.FileSource({
  fetchedData: geojson,
  crs: 'EPSG:3946',
  format: 'application/json',
});

gama_layer = new itowns.FeatureGeometryLayer('GAMA', {
  source: _source,
  transparent: true,
  opacity: 1,
  style: new itowns.Style({
    fill: {
         color: 'red' ,
    }
  })
});

app.view.addLayer(gama_layer);

This seems somehow related to this issue https://github.com/iTowns/itowns/issues/1283 however the fix proposed seems not to work in my case.

FYI we are defining this in our package.json "itowns": "2.37.0"

agrignard commented 2 years ago

Dear @gchoqueux and @mgermerie , I was wandering if you had any chance to see this issue?

Also I was wandering if my method that consist in adding and removing a layer at each frame is the most optimal one, maybe I should only update the layer but I didn't find the right method to do so.

Looking forward to hearing from you if you have any insight.

mgermerie commented 2 years ago

Hi ! I'm sorry, I somehow missed the notification. I shall dive into your issue and let you know of my findings soon.

agrignard commented 2 years ago

Great thank you for your answer. I have the feeling that it is somehow related to this one https://github.com/iTowns/itowns/issues/1283

mgermerie commented 2 years ago

After a bit of digging, I found out that the issue is a tad different from #1283. It is caused by the way we currently manage ThreeJS Layers. For iTowns, ThreeJS layers - which have nothing to do with iTowns Layers - allow to gather instances or groups of ThreeJS Object3D into a layer to jointly manage their visibility. We could for example set a layer visibility to false to hide all Object3D within it. The ThreeJS Layer is basically an integer ID, which is stored in the properties of the Object3D attached to it. ThreeJS viewer only supports up to 32 layers.

The thing is : when we create a GeometryLayer with iTowns, we grant its Object3D content a new ThreeJS Layer ID, which is incremented by 1 at each GeometryLayer creation. However we don't need ThreeJS Layers anymore to manage Object3D visibility in GeometryLayers, thanks to the #1822 PR. The use of ThreeJS Layers only remains for Helpers visibility, which are only used in dev mode - those are tools that allow us to see tiles bounding boxes for example.

I'm working on a refactoring to include Helpers into specific GeometryLayers. This will allow us to completely get rid of ThreeJS Layers, and should therefore fix the issue you're facing. I will link this issue to my PR when it will be somewhat more ready, so you can be notified when it will be merged.

agrignard commented 2 years ago

Ok great thanks for your answer.

I get the idea of ThreeJS supporting only 32 layers. In my case (and i am not sure it's the right way to do it) I was planning to create a layer at each iteration of a simulation and deleting the previous one (knowing that a simulation can have in theory an infinite number of iteration)

Do you think it is the right path to explore? or is there a better way to "update" a layer (when I mean update, I mean the position, size, color or even the number of object in the layer can evolve).

In any case I stay in touch with the coming PR.

mgermerie commented 2 years ago

When the issue with ThreeJS Layers will be fixed, doing what you do will be the best way (and actually the only way at the moment).

The thing is : once data for a given Source is fetched, it is stored in cache and always accessed through the cache later on. ITowns lacks a feature to force a Source to refresh its cache, so that modifications on the data server can be considered. Should such a feature be implemented, updating your GeometryLayer and more broadly every Layers would be much more simple.