maplibre / maplibre-style-spec

MapLibre Style Specification & Utilities
https://maplibre.org/maplibre-style-spec/
Other
85 stars 65 forks source link

Design proposal: enhancements ro raster-dem to improve hillshade and shaded-relief #338

Open dBitech opened 1 year ago

dBitech commented 1 year ago

User Story

Currently, vector styling of dem data is somewhat limited, meaning most of my base layer work needs to be done as pre-styled rasters. This reduces the usefulness of what I can provide to mobile users in offline modes.

Rationale

There are some very good example write-ups on doing more advanced shaded relief using GDAL, and as shown in the following tutorial Intro to GDAL: part 5 shaded relief It would be great if we could offer this kind of shaded- relief directly within maplibre. If we start with the aspect mode, we could quickly realize Swiss Style Relief Shading which was brought to life by Eduard Imhof. Further modes like Slope could be used to help visually highlight areras that could be of intrest to a number of market segments, from Recreational Maps users such as Hiking and Skiing to areas of risk assessment related to Avalanches and Landslides.

Impact

HarelM commented 1 year ago

I would recommend defining exactly which parameters in the style definition would allow this. The current definition is a bit vague unfortunately.

dBitech commented 1 year ago

For aspect, my thought would as a start be an array under paint such as: aspect-color: [ [degree, rgba], [degree, rgba], [degree, rgba],...]

my though this would be a paint-property on the hillshade style layer

So that would look like:

...
layers: [
  {
    id: 'shaded-releif',
    type: 'hillshade',
    source: 'hillshadesource',
    layout: {visibility: 'visible'},
    paint: {'aspect-color':
      [
          [0, rgba(243,241,231,1)],
          [22.5, rgba(242,241,235,1)],
          [45, rgba(241,241,2390,1)],
          [67.5, rgba(240,241,243,1)],
          [90, rgba(239,241,246,1)],
          [112.5, rgba(238,240,250,1)],
          [135, rgba(236,240,254,1)],
          [157.5, rgba(238,240,250,1)],
          [180, rgba(239,241,246,1)],
          [202.5, rgba(240,241,243,1)],
          [225, rgba(241,241,239,1)],
          [247.5, rgba(242,241,235,1)],
          [270, rgba(243,241,231,1)],
          [292.5, rgba(245,241,227,1)],
          [315, rgba(246,241,222,1)],
          [337.5, rgba(245,241,227,1)],
          [359.999, rgba(243,241,231,1)]
      ]
    }
  },
...

resulting in a hillshade that is colored based on the aspect of the slope. image

(Images courtesy of Robert Simmon's Intro to GDAL: part 5 shaded relief

HarelM commented 1 year ago

I'm not sure I understand your last comment can you elaborate? How would the style spec look after this change and what would the tiles look like on the map? See also the following discussion, which might be somewhat related: https://github.com/maplibre/maplibre-gl-js/discussions/3109

dBitech commented 1 year ago

Once we have supporting code for aspect, then adding multi-direction lighting support would become fairly trivial. (note that maplibre uses 335 as the default illumination direction vs the 315 in the publication), this functionality would produce hillshade similar to gdaldem's multidirectional hillshade mode.

...
layers: [
  {
    id: 'shaded-releif',
    type: 'hillshade',
    source: 'hillshadesource',
    layout: {visibility: 'visible'},
    paint: {'hillshade-multidirection': true }
 }
],
...

In the event that hillshade-illumination-direction was specified then the multi-direction weighting would be centered around the provided direction

HarelM commented 1 year ago

It's says 335 in the docs: image

I'm not sure I fully understand the definition or how would this affect. I would recommend bringing this to the monthly meeting and present it there. Meetings invite are sent in our slack channel.

dBitech commented 10 months ago

There would be no change to the existing functionality with respect to hillshade-illumination-direction, but in the event it was specified along with paint: {'hillshade-multidirection': true } then the offsets used to create the multi-direction lighting would use the hillshade-illumination-direction as it's primary lighting direction, rotating the other light sources relitive to this direction.