Open wipfli opened 1 year ago
The 3D landmarks should be loaded only for things which are displayed. For this, we create a point layer in an MVT at z15. This source layer is called 3d-landmarks
and the only property of a point is name
.
In a MapLibre style layer, we use the 3d-landmarks
data to create styleimagemissing
events. These are events which are issued if a map style does not have access to an image. This is called run-time styling.
The MapLibre style layer could look like this:
{
"id": "3d-landmarks",
"type": "symbol",
"source": "my-source",
"source-layer": "3d-landmarks",
"layout": {
"icon-image": "please-load-3d-landmark-{name}"
}
}
Say we look at the eifel tower with name eifel-tower
, then since the icon image please-load-3d-landmark-eifel-tower
is not available, this will create a styleimagemissingevent
. We can catch that event, request https://{base_url}/eifel-tower.gltf
and add it to the map with something like this:
https://maplibre.org/maplibre-gl-js-docs/example/3d-buildings/
The only downside with this is that the rendering of the 3d landmark happens in a separate webgl layer or however it is called. As a consequence, the landmark is either always above or always below the 2.5D building extrusions.
What we need is a way to get obtrusion right between the 2.5D and 3D content.
Maybe babylon could render the 2.5D buildings and the 3D buildings. Maybe MapLibre could render both.
The simplest way to achieve a good looking result of the currently available technology is to render the 3D building with Babylon or three JS and also render some 2.5D buildings around the 3D building with Babylon.
If we assume a certain maximum pitch then we know at tile generation time how many buildings around the 3D building have to be removed and rendered with Babylon.
This feels a bit like cheating, but I think it can work very well...
Ah but actually then the problem just happens at another place where we want to have obstruction of 2.5 d and Babylon but it doesn't work.
Maybe we can use deckgl:
deckgl seems to work nicely for this purpose.
Assume we have a set of 3D landmarks for a city. The landmarks are stored as glTF files and can be requested at HTTP endpoints of the form
https://{base_url}/{landmark_name}.gltf
. The basemap for the city has building footprints and building heights.Below z15, only the building footprints are shown and the map pitch is 0.
At z15 and higher, the map pitches to 45 degrees and the buildings are shown as 2.5D extrusions.
If we have a 3D landmark model for a building, then we show it a z15 and higher and turn the 2.5D extrusion of the building footprint off. So building footprints need to know if they have a 3D model or not. This can be stored in a property called
has-3d-landmark: yes/no
.