Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Visualize a layer underground/pitch a map underground #13342

Open
janneskruse opened this issue Dec 5, 2024 · 6 comments
Open

Visualize a layer underground/pitch a map underground #13342

janneskruse opened this issue Dec 5, 2024 · 6 comments

Comments

@janneskruse
Copy link

Motivation

First of all thank you for your awesome work at Mapbox! I love building with your platform!

Now, the feature request:
In urban planning/smart city visualization (among other areas) it is necessary to visualize data underground. For example pipes, drainage basins or subways should be visible when displaying a city and planning for it, as else valuable information might get lost. Here, it would be great to have the option to visualize such data under and not above the ground. Or preferably even pitch the map underground.

Design

  1. The currently experimental z-offset of layers should extend to negative values
  2. If possible an easy "glassview" toggle configuration property should be available to make all layers at/above ground level transparent.
  3. If possible the pitch (and/or zoom) property should extend beyond zero to view the layers from 1 in detail. I am aware that this might be more difficult with the current map

Mock-Up

There is a good example for ESRI's sceneview how this could look like. Of course with the nicer Mapbox models and styling.
image

Help welcome

In the meantime I would be very grateful for any hints on how too implement this using the current Mapbox state!

@oosafff
Copy link

oosafff commented Dec 5, 2024

Thank you for the very detailed request! This is definitely an interesting topic and something we consider exploring.

The line-z-offset should already allow you to set a negative value to the z-axis to render lines blow surface. Same holds true for the symbol z-offset and model-translation altitude offset, which enables you to place 2D icons and 3D models underground as well.

While we do not support a 'glassview' toggle out of the box, there are a few tools that might help you achieve the desired effect.

  1. You can use the line-occlusion-opacity to make underground content “shine through” the ground.
  2. You can use the clip layer to remove basemap content that overlaps with your underground geometries.
  3. On legacy and custom styles you should also be able to control the opacity and visibility of map layers to achieve the "glassview" look. While Standard Style does not support layer opacity controls for all layers, you can still toggle label and 3D content visibility.

I'd appreciate if you could try out these suggestions and get back to us with feedback!

@kamami
Copy link

kamami commented Dec 5, 2024

I tried to use line-occlusion-opacity for this, but it does not work. Should'nt the lines be invisible under the 3D buildings? I am using the standard mapbox 3D style.

image

This is my layer:

export const chargerLine = {
  type: "line",
  source: "line",
  id: "line-background",

  paint: {
    "line-occlusion-opacity": 0,
    "line-color": "#00D48E",
    "line-width": 6,
  },
};

@endanke
Copy link
Contributor

endanke commented Dec 5, 2024

@kamami could you try to disable line-occlusion-opacity and just place the layer below the layer of the buildings? If you use standard style, you can set the slot of the layer to be middle.

@kamami
Copy link

kamami commented Dec 5, 2024

Yes, the slot did the trick! Thanks

@janneskruse
Copy link
Author

janneskruse commented Dec 8, 2024

Thanks a lot for the quick response and all the hints @oosafff !!
I tried them out, but so far I haven't been able to achieve the effect.

Testing configuration

The screenshot shows:

  1. setting all layers fill-color and background-color to be transparent (0.1):
if (layer.paint && layer.paint['fill-color']) {
  layer.paint['fill-color'] = 'rgba(255, 255, 255, 0.1)';
}

if (layer.paint && layer.paint['background-color']) {
  layer.paint['background-color'] = 'rgba(255, 255, 255, 0.1)';
}

if (layer.paint['hillshade-accent-color']) {
  layer.paint['hillshade-accent-color'] = 'rgba(255, 255, 255, 0.1)';
}
if (layer.paint['hillshade-shadow-color']) {
  layer.paint['hillshade-shadow-color'] = 'rgba(0, 0, 0, 0.1)';
}
if (layer.paint['hillshade-highlight-color']) {
  layer.paint['hillshade-highlight-color'] = 'rgba(255, 255, 255, 0.1)';
}

  1. Adding a line layer to slot: "bottom" and setting line-z-offset and line-elevation-reference:
 paint: {
  'line-color': '#3b70d4',
  'line-width': 2,
  'line-elevation-reference': 'ground',
  'line-z-offset': -10,
},
  1. setting projection to mercator as from the docs I understand that globe doesnt support z-offset:
    newStyle.projection.name = 'mercator';

Feedback

From this I noticed:
i. For my configuration, line-z-offset has no effect (also for positive values) - thus, the line is always rendered above the layers below slot bottom.
Does line-z-offset have other dependencies that I am missing? fill-z-offset works for the same map.

ii. The 3D terrain is still fully visible, hiding the background below.
Is there a way to make the 3D terrain transparent as well, that I am missing? Setting opacity on the terrain raster would be really great!

iii. Out of curiosity I tried model-translation on the 3D building model layer but it seems to have no effect neither: layer.paint['model-translation'] = [100, 100, -100]; I suppose this only works on custom models, correct?

grafik grafik

Again thank you! If you have any further hints, I would really appreciate it!

Btw. I am using 3.7.0: ├─┬ @types/[email protected]
│ └── [email protected] deduped
├── [email protected]
└─┬ [email protected]
└── [email protected] deduped

@janneskruse
Copy link
Author

janneskruse commented Dec 8, 2024

Edit

I managed to get the glassview toggle more or less by adding a new slot layer below the background layer and then toggle the opacity of all layers:

//add slot at the bottom
  const newLayer = {
    id: 'underground',
    type: 'slot',
    metadata: {
      'mapbox:description': 'Slot below the ground',
    },
  };

  const backgroundLayerIndex = newStyle.imports[0].data.layers.findIndex(
    (layer: { type: string }) => layer.type === 'background',
  );
  if (backgroundLayerIndex !== -1) {
    newStyle.imports[0].data.layers.splice(backgroundLayerIndex, 0, newLayer);
  }

This is already nice! However, having the line-z-offset working and being able to set opacity on the terrain raster would be a great add on, as it would allow to show more accurate information

grafik grafik

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants