After reading #2240 and #2244, and discussing it with @Desplandis, we thought of an improvement on PlanarLayer. Here is what we found out.
Your Environment
Version used: 2.42.0
Context
When creating a PlanarView, user has to specify an extent. This extent defines the view's terrain extent. It is used as the root level for terrain tiles subdivision, just like the root level of any given TMS. It is therefore subdivided into a quadtree according to the position of the camera.
However, this quadtree does not correspond with any known and referenced TMS. This causes issues when trying to display data arranged in a given TMS (from a TMSSource or a WMTSSource). Indeed, the extent and zoom level of terrain tiles do not match those of the TMS tiles, as described in the picture bellow.
When displaying data arranged in a TMS on a terrain, the zoom level of terrain tiles is used to fetch the corresponding data within the TMS. Therefore, on the image above, the red tile (which matches with the user specified extent at the PlanarView creation) will display data from the black tile (the matching level tile in data TMS). This gives the feeling that user specified extent is not accounted for, as stated in #2240.
These considerations make PlanarView incompatible with data arranged in a TMS (excepted obviously if the extent specified for the PlanarView is the exact same one as the one of the TMS root tile).
Proposal
The terrain subdivision of a PlanarView should follow a TMS, which could be parametrized by user. The extent parameter of a PlanarView constructor should only define what part of this TMS is actually displayed as terrain in the scene.
To do so, we thought of three implementation options :
Option 1 : Create the terrain as a sub-tree of the TMS quadtree
We could build terrain tiles according to a specific TMS. The root tile of the terrain would match the smallest TMS tile that contains the whole extent parametrized by user. This terrain root tile is illustrated in the first column of the table bellow, where n is the zoom level of the smallest TMS tile described earlier.
The terrain root tile could then be subdivided normally, following the TMS. We could add some culling to this mechanism, to only display tiles that intersect the user specified extent, as illustrated in the last three columns of the table bellow.
TMS zoom level n Terrain zoom level 0
TMS zoom level n + 1 Terrain zoom level 1
TMS zoom level n + 2 Terrain zoom level 2
mixed zoom levels
For this implementation, we would need to store the zoom level of the TMS tile matching terrain's root tile (n in the example above). It should then be added to the terrain zoom level to fetch the correct data within the TMS arranged dataset.
A downside of this solution is that the terrain displayed does not precisely match the extent specified by user.
Option 2 : Generate odd size terrain tiles from TMS
An other option would be to generate terrain tiles corresponding to the intersection of TMS tiles and the view's extent.
In this solution, we would two things :
A "shadow terrain" : a terrain equivalent whose tiles would match the TMS. It would never be displayed but it would be used along side the camera position to compute TMS tiles subdivision and culling.
A method to calculate the Geometry of the intersection of a TMS tile (given its coordinates) and an extent.
Knowing which TMS tiles are visible and having the method described in the second point above, we would be able to generate terrain tiles both matching the TMS quadtree and contained within the view's extent. These resulting terrain tiles are illustrated in blue in the table bellow.
TMS zoom level 0
TMS zoom level 1
TMS zoom level 2
mixed zoom levels
This solution solves the downside of the first option, since we only display terrain and data that are within the extent specified by user. However, its major flaw is that we would get a lot of terrain tiles with unique shapes. This would limit the use of a single Geometry shared by all terrain tiles, and most likely alter performances.
Option 3 : Create the terrain that matches the entire TMS and clip it
A final solution we found out is to create a terrain whose subdivision is just a copy of the TMS subdivision. This is more or less what is already done in a GlobeView. The terrain root tile would copy the TMS root tile, and so on for each subdivided tiles.
To only display terrain and data within the view's extent, we could add two processes :
A culling step in PlanarLayer update mechanism, to only process tiles which intersect the view's extent,
Specify four clipping planes for terrain tiles materials. these clipping planes would be vertical planes with positions matching each border of the view's extent.
The terrain copies the entire TMS
Culling : we only process tiles that intersect the extent
Clipping of the remaining terrain to exclude areas outside the extent
In this solution, all terrain tile can share the same Geometry, and only terrain and data within the view's extent are displayed. This makes it, in @Desplandis' and in my opinion, the best choice.
Open discussion
Maybe we missed an easier solution. If so, don't hesitate to add it in comments.
Also, I found the subject difficult to describe with text so @Desplandis, don't hesitate to edit the comment if I forgot something :wink:
After reading #2240 and #2244, and discussing it with @Desplandis, we thought of an improvement on
PlanarLayer
. Here is what we found out.Your Environment
Context
When creating a
PlanarView
, user has to specify an extent. This extent defines the view's terrain extent. It is used as the root level for terrain tiles subdivision, just like the root level of any given TMS. It is therefore subdivided into a quadtree according to the position of the camera. However, this quadtree does not correspond with any known and referenced TMS. This causes issues when trying to display data arranged in a given TMS (from aTMSSource
or aWMTSSource
). Indeed, the extent and zoom level of terrain tiles do not match those of the TMS tiles, as described in the picture bellow.When displaying data arranged in a TMS on a terrain, the zoom level of terrain tiles is used to fetch the corresponding data within the TMS. Therefore, on the image above, the red tile (which matches with the user specified extent at the
PlanarView
creation) will display data from the black tile (the matching level tile in data TMS). This gives the feeling that user specified extent is not accounted for, as stated in #2240.These considerations make
PlanarView
incompatible with data arranged in a TMS (excepted obviously if the extent specified for thePlanarView
is the exact same one as the one of the TMS root tile).Proposal
The terrain subdivision of a
PlanarView
should follow a TMS, which could be parametrized by user. Theextent
parameter of aPlanarView
constructor should only define what part of this TMS is actually displayed as terrain in the scene.To do so, we thought of three implementation options :
Option 1 : Create the terrain as a sub-tree of the TMS quadtree
We could build terrain tiles according to a specific TMS. The root tile of the terrain would match the smallest TMS tile that contains the whole extent parametrized by user. This terrain root tile is illustrated in the first column of the table bellow, where
n
is the zoom level of the smallest TMS tile described earlier. The terrain root tile could then be subdivided normally, following the TMS. We could add some culling to this mechanism, to only display tiles that intersect the user specified extent, as illustrated in the last three columns of the table bellow.n
Terrain zoom level
0
n + 1
Terrain zoom level
1
n + 2
Terrain zoom level
2
For this implementation, we would need to store the zoom level of the TMS tile matching terrain's root tile (
n
in the example above). It should then be added to the terrain zoom level to fetch the correct data within the TMS arranged dataset.A downside of this solution is that the terrain displayed does not precisely match the extent specified by user.
Option 2 : Generate odd size terrain tiles from TMS
An other option would be to generate terrain tiles corresponding to the intersection of TMS tiles and the view's extent.
In this solution, we would two things :
Geometry
of the intersection of a TMS tile (given its coordinates) and an extent.Knowing which TMS tiles are visible and having the method described in the second point above, we would be able to generate terrain tiles both matching the TMS quadtree and contained within the view's extent. These resulting terrain tiles are illustrated in blue in the table bellow.
0
1
2
This solution solves the downside of the first option, since we only display terrain and data that are within the extent specified by user. However, its major flaw is that we would get a lot of terrain tiles with unique shapes. This would limit the use of a single
Geometry
shared by all terrain tiles, and most likely alter performances.Option 3 : Create the terrain that matches the entire TMS and clip it
A final solution we found out is to create a terrain whose subdivision is just a copy of the TMS subdivision. This is more or less what is already done in a
GlobeView
. The terrain root tile would copy the TMS root tile, and so on for each subdivided tiles.To only display terrain and data within the view's extent, we could add two processes :
PlanarLayer
update mechanism, to only process tiles which intersect the view's extent,In this solution, all terrain tile can share the same
Geometry
, and only terrain and data within the view's extent are displayed. This makes it, in @Desplandis' and in my opinion, the best choice.Open discussion
Maybe we missed an easier solution. If so, don't hesitate to add it in comments. Also, I found the subject difficult to describe with text so @Desplandis, don't hesitate to edit the comment if I forgot something :wink: