mapbox / mapbox-maps-ios

Interactive, thoroughly customizable maps for iOS powered by vector tiles and Metal
https://www.mapbox.com/mapbox-mobile-sdk
Other
451 stars 148 forks source link

Use DEM or Raster data for client side rendering in a CustomLayer. #1907

Open Gnative opened 1 year ago

Gnative commented 1 year ago

New Feature

How can I replicate the HillshadeLayer to create my own coloured shaded layers using DEM data ?

There could be some nice effects produced by doing this, especially in conjunction with Terrain layer, but I haven't been unable to see how this is done. The closest is the CustomLayer example but can't see how this could be used with a Raster or DEM source..

Could this be a new Layer type perhaps ? DEMRasterLayer ?

Gnative commented 1 year ago

Would be great to also be able to do this with a RasterLayer, To be able to apply Metal vertex and fragment shaders to a specific set of raster tiles. I figure this would be the same thing as accessing the DEM tiles.

If there is an example of this, I can't find anything.

harikhalsa commented 1 year ago

Are you trying to do something different than what is already offered with HillshadeLayer?

import UIKit
import MapboxMaps

public class ViewController: UIViewController {

    let accessToken: String = "YOUR_ACCESS_TOKEN"

    internal var mapView: MapView!

    public override func viewDidLoad() {
        super.viewDidLoad()

        // Create an initial camera that is centered over Los Angeles and use it
        // when initializing the `MapView`.
        let center = CLLocationCoordinate2D(latitude: 48.854690, longitude:2.337515)
        let resourceOptions = ResourceOptions(accessToken: accessToken, tileStore: .default)
        let cameraOptions = CameraOptions(center: center, zoom: 8)
        let mapInitOptions = MapInitOptions(resourceOptions: resourceOptions, cameraOptions: cameraOptions, styleURI: .streets)

        mapView = MapView(frame: view.bounds, mapInitOptions: mapInitOptions)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        mapView.ornaments.options.scaleBar.visibility = .hidden

        view.addSubview(mapView)

        // Once the map has finished loading, add the museum and traffic layers to the map's style,
        // then add switches that toggle the visibility for those two layers.
        mapView.mapboxMap.onNext(event: .mapLoaded) { _ in
            self.addHillshade()
        }
    }

    func addHillshade() {

        let sourceId = "hillshade-source"

        var source = RasterDemSource()
        source.url = "mapbox://mapbox.mapbox-terrain-dem-v1"
        source.tileSize = 512
        source.maxzoom = 14.0

        // Create a hillshade layer with a unique layer ID.
        var layer = HillshadeLayer(id: "hillshade-layer")
        layer.source = sourceId
        layer.hillshadeAccentColor = .constant(StyleColor(.blue))
        layer.hillshadeExaggeration = .constant(1)
        layer.hillshadeHighlightColor = .constant(StyleColor(.green))
        layer.hillshadeShadowColor = .constant(StyleColor(.black))

        // Add the data source and style layer to the map.
        try! mapView.mapboxMap.style.addSource(source, id: sourceId)
        try! mapView.mapboxMap.style.addLayer(layer, layerPosition: nil)
}
}
Gnative commented 1 year ago

Hi @harikhalsa, yes I'm trying to do something different to how the HillshadeLayer works. The HillshadeLayer is great but limiting.

Knowing how the HillshadeLayer works code wise would help in seeing how we can use the DEM data to render with fragments and shaders could be used to cast shadows or real-time sunset on land masses such as mountains. Other ideas would be indicating sea level rise etc.

Also just generally being able to add another level of styling to a our maps.

Especially in conjunction with using 3D terrain this could help with some pretty nice custom styling effects.

Gnative commented 1 year ago

Still looking for an answer on this.

Gnative commented 9 months ago

Hello, please still looking for a solution to this. There would be some pretty amazing use cases for this ability.

Gnative commented 7 months ago

I'm looking at v11 docs and https://docs.mapbox.com/ios/maps/api/11.0.0-rc.2/documentation/mapboxmaps/customlayerrenderconfiguration

with the use of [init(isRenderToTileSupported: Bool, shouldRerenderTiles: Bool)]

Is this going to open up the possibility of what i am describing above ?

Gnative commented 2 weeks ago

Ideally I'm still looking to achieve the following in IOS, Android which would mean I can apply a custom shader to a layer.. I know this happens with the HillshadeLayer but want to have full control over the rendering. this would open soo many possibilities for animations etc.

https://dnomadb.github.io/shader/#6.47/37.527/-122.114

Gnative commented 2 weeks ago

This is possible with mapbox-gl-js

https://github.com/mapbox/mapbox-gl-js/blob/7dec10fe9c1a9a5a7ddf1116dbf03345026245bc/src/shaders/hillshade.fragment.glsl