Search code examples
mapboxmapbox-ios

Why is mapBoxMap.elevation(at:) returning nil?


I've got my map defined as

 let myResourceOptions = ResourceOptions(accessToken: mapBoxPk)
        let myMapInitOptions = MapInitOptions(resourceOptions: myResourceOptions, styleURI: StyleURI(rawValue: "mapbox://styles/mapbox/outdoors-v12")) //mapbox.mapbox-bathymetry-v2
        
        mapView = MapView(frame: view.bounds, mapInitOptions: myMapInitOptions)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        mapView.location.delegate = self

And add a terrain as follows:

  let style = mapView.mapboxMap.style

        var source = RasterDemSource()
        source.url = "mapbox://mapbox.mapbox-terrain-dem-v1"
        try! style.addSource(source, id: "sourceId")

        let terrain = Terrain(sourceId: "sourceId")
        
        
        do {
            try mapView.mapboxMap.style.setTerrain(terrain)

        } catch {
        print("Error when adding sources and layers: \(error.localizedDescription)")
        }

Every single time I get some coordinates the user inputs and call elevation(at:) I get nil.

 let coordinateForElevation = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
            let elevation = self.mapView.mapboxMap.elevation(at:coordinateForElevation)
            print("DEBUG:: Elevation: \(elevation)")

What am I missing?


Solution

  • That method call self.mapView.mapboxMap.elevation(at:coordinateForElevation) it seems to be expected to be nil as documentation recommends getting elevation from Tilequery api. And of course they charge per number of requests.

    Documentation on how to do a web request in tilequery api: https://docs.mapbox.com/help/tutorials/find-elevations-with-tilequery-api/

    Then, based on this documentation above, I did a code sample in swift (just the service request though):

    class TilequeryService {
    func fetchElevation(latitude: Double, longitude: Double, completion: @escaping (Result<TilequeryResponse, Error>) -> Void) {
        let accessToken = mapBoxPk
        let tilesetQueryURL = "https://api.mapbox.com/v4/mapbox.mapbox-terrain-v2/tilequery/\(longitude),\(latitude).json?layers=contour&limit=50&access_token=\(accessToken)"
        
        guard let url = URL(string: tilesetQueryURL) else {
            completion(.failure(NSError(domain: "Invalid URL", code: 0, userInfo: nil)))
            return
        }
        
        URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            
            guard let data = data else {
                completion(.failure(NSError(domain: "No data received", code: 0, userInfo: nil)))
                return
            }
            
            do {
                let decoder = JSONDecoder()
                let tilequeryResponse = try decoder.decode(TilequeryResponse.self, from: data)
                
                completion(.success(tilequeryResponse))
            } catch {
                completion(.failure(error))
            }
        }.resume()
    } 
    

    }