如何使用 Mapbox 在 iOS 上进行 3D 地图可视化 [英] How 3D map visualizations on iOS using Mapbox

查看:145
本文介绍了如何使用 Mapbox 在 iOS 上进行 3D 地图可视化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 mapbox 中绘制这个,遇到了

-----更新---尝试了下面的只是能够在平面视图中呈现 GEOJson,而不是高度.

导入 UIKit导入 Mapbox类 SignUpAccount: UIViewController, MGLMapViewDelegate {var mapView:MGLMapView!覆盖 func viewDidLoad() {super.viewDidLoad()mapView = MGLMapView(frame: view.bounds)mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]mapView.setCenter(CLLocationCoordinate2D(纬度:41.866282,经度:-87.618312),缩放级别:11,动画:假)view.addSubview(mapView)mapView.delegate = self}func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {加载GeoJson()}func loadGeoJson() {DispatchQueue.global().async {//获取应用程序包中 example.geojson 的路径.守卫让 jsonUrl = Bundle.main.url(forResource: "example", withExtension: "geojson") else {preconditionFailure("加载本地 GeoJSON 文件失败")}守卫让 jsonData = 试试?数据(contentsOf:jsonUrl)其他{preconditionFailure("解析GeoJSON文件失败")}DispatchQueue.main.async {self.drawPolyline(geoJson: jsonData)}}}func drawPolyline(geoJson:数据){//将我们的 GeoJSON 数据作为 MGLGeoJSONSource 添加到地图中.//然后我们可以从 MGLStyleLayer 引用这些数据.//MGLMapView.style 是可选的,所以你必须防止它不被设置.守卫让风格 = self.mapView.style else { return }守卫让 shapeFromGeoJSON = 试试?MGLShape(数据:geoJson,编码:String.Encoding.utf8.rawValue)其他{致命错误(无法生成 MGLShape")}让源 = MGLShapeSource(标识符:折线",形状:shapeFromGeoJSON,选项:nil)style.addSource(source)//为线创建新层.让图层 = MGLLineStyleLayer(标识符:折线",来源:来源)//将线连接和帽设置为圆形末端.layer.lineJoin = NSExpression(forConstantValue: "round")layer.lineCap = NSExpression(forConstantValue: "round")//将线条颜色设置为恒定的蓝色.layer.lineColor = NSExpression(forConstantValue: UIColor(red: 59/255, green: 178/255, blue: 208/255, alpha: 1))//使用 `NSExpression` 在缩放级别 14 和 18 之间平滑地将线宽从 2pt 调整到 20pt.`interpolationBase` 参数允许值沿着指数曲线进行插值.layer.lineWidth = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)",[20:2, 18:5])//style.addLayer(层)让上层 = MGLFillExtrusionStyleLayer(标识符:建筑物",来源:来源)upperlayer.sourceLayerIdentifier = "建筑"//过滤掉不应挤出的建筑物.upperlayer.predicate = NSPredicate(格式: "extrude == 'true'")//将填充挤出高度设置为建筑物高度属性的值.upperlayer.fillExtrusionHeight = NSExpression(forConstantValue: 40.75)upperlayer.fillExtrusionOpacity = NSExpression(forConstantValue: 0.75)upperlayer.fillExtrusionColor = NSExpression(forConstantValue: UIColor.white)upperlayer.fillExtrusionBase = NSExpression(forConstantValue: 0.75)style.addLayer(上层)style.insertLayer(层,下面:上层)}

}

输出

解决方案

尝试不使用这一行:

upperlayer.predicate = NSPredicate(格式: "extrude == 'true'")

它有效.

I am trying to achieve to draw this in mapbox, came across

https://docs.mapbox.com/ios/maps/examples/extrusions/

but nothing helpfull

as I have the latitude and longitude, I want to draw the shape like the yellow shown below .but not sure where to start

they are doing using three.js as mentioned here

-----Update--- tried the below just able to render GEOJson in flat view, not the height.

import UIKit
import Mapbox

class SignUpAccount: UIViewController, MGLMapViewDelegate {

var mapView: MGLMapView!

override func viewDidLoad() {
    super.viewDidLoad()

    mapView = MGLMapView(frame: view.bounds)
    mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    mapView.setCenter(
        CLLocationCoordinate2D(latitude: 41.866282, longitude: -87.618312),
        zoomLevel: 11,
        animated: false)
    view.addSubview(mapView)

    mapView.delegate = self
}

func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {

    loadGeoJson()
}
func loadGeoJson() {
    DispatchQueue.global().async {
        // Get the path for example.geojson in the app’s bundle.
        guard let jsonUrl = Bundle.main.url(forResource: "example", withExtension: "geojson") else {
            preconditionFailure("Failed to load local GeoJSON file")
        }

        guard let jsonData = try? Data(contentsOf: jsonUrl) else {
            preconditionFailure("Failed to parse GeoJSON file")
        }

        DispatchQueue.main.async {
            self.drawPolyline(geoJson: jsonData)
        }
    }
}

func drawPolyline(geoJson: Data) {
    // Add our GeoJSON data to the map as an MGLGeoJSONSource.
    // We can then reference this data from an MGLStyleLayer.

    // MGLMapView.style is optional, so you must guard against it not being set.
    guard let style = self.mapView.style else { return }

    guard let shapeFromGeoJSON = try? MGLShape(data: geoJson, encoding: String.Encoding.utf8.rawValue) else {
        fatalError("Could not generate MGLShape")
    }

    let source = MGLShapeSource(identifier: "polyline", shape: shapeFromGeoJSON, options: nil)
    style.addSource(source)


    // Create new layer for the line.
    let layer = MGLLineStyleLayer(identifier: "polyline", source: source)

    // Set the line join and cap to a rounded end.
    layer.lineJoin = NSExpression(forConstantValue: "round")
    layer.lineCap = NSExpression(forConstantValue: "round")

    // Set the line color to a constant blue color.
    layer.lineColor = NSExpression(forConstantValue: UIColor(red: 59/255, green: 178/255, blue: 208/255, alpha: 1))

    // Use `NSExpression` to smoothly adjust the line width from 2pt to 20pt between zoom levels 14 and 18. The `interpolationBase` parameter allows the values to interpolate along an exponential curve.
    layer.lineWidth = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)",
                                   [20: 2, 18: 5])

    //style.addLayer(layer)



    let upperlayer = MGLFillExtrusionStyleLayer(identifier: "buildings", source: source)
    upperlayer.sourceLayerIdentifier = "building"

    // Filter out buildings that should not extrude.
    upperlayer.predicate = NSPredicate(format: "extrude == 'true'")

    // Set the fill extrusion height to the value for the building height attribute.
    upperlayer.fillExtrusionHeight = NSExpression(forConstantValue: 40.75)
    upperlayer.fillExtrusionOpacity = NSExpression(forConstantValue: 0.75)
    upperlayer.fillExtrusionColor = NSExpression(forConstantValue: UIColor.white)
    upperlayer.fillExtrusionBase  = NSExpression(forConstantValue: 0.75)


        style.addLayer(upperlayer)
        style.insertLayer(layer, below: upperlayer)

}

}

output here

[![enter image description here][3]][3]

解决方案

try without this line:

upperlayer.predicate = NSPredicate(format: "extrude == 'true'")

and it works.

这篇关于如何使用 Mapbox 在 iOS 上进行 3D 地图可视化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆