MapBox - 检测zoomLevel的变化

时间:2018-05-22 15:55:26

标签: ios swift mapbox

如何简单地检测缩放级别变化?有可能吗?

当缩放级别不够时,我只需要隐藏我的注释视图。

regionDidChange:animated:并非打算用于我。还有别的吗?

我需要在这里隐藏我的标签:

enter image description here

并在此处显示:

enter image description here

这就是我目前对标签的处理方式:

class CardAnnotation: MGLPointAnnotation {

    var card: Card

    init(card: Card) {
        self.card = card
        super.init()

        let coordinates = card.border.map { $0.coordinate }
        let sumLatitudes = coordinates.map { $0.latitude }.reduce(0, +)
        let sumLongitudes = coordinates.map { $0.longitude }.reduce(0, +)
        let averageLatitude = sumLatitudes / Double(coordinates.count)
        let averageLongitude = sumLongitudes / Double(coordinates.count)

        coordinate = CLLocationCoordinate2D(latitude: averageLatitude, longitude: averageLongitude)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
var annotations = [CardAnnotation]()
mapView.addAnnotations(annotations)

3 个答案:

答案 0 :(得分:4)

MGLMapView的两个主ways to add overlays中,运行时样式API更适合文本标签,也适用于根据缩放级别改变外观。当你在它的时候,你也可以使用相同的API创建多边形。

首先为要隐藏的区域创建面要素:

var cards: [MGLPolygonFeature] = []
var coordinates: [CLLocationCoordinate2D] = […]
let card = MGLPolygonFeature(coordinates: &coordinates, count: UInt(coordinates.count))
card.attributes = ["address": 123]
// …
cards.append(card)

在地图完成加载后运行的任何方法(例如MGLMapViewDelegate.mapView(_:didFinishLoading:))中,将包含这些要素的形状源添加到当前样式中:

let cardSource = MGLShapeSource(identifier: "cards", features: cards, options: [:])
mapView.style?.addSource(cardSource)

使用形状源,创建一个样式图层,将多边形要素渲染为紫红色填充:

let fillLayer = MGLFillStyleLayer(identifier: "card-fills", source: cardSource)
fillLayer.fillColor = NSExpression(forConstantValue: #colorLiteral(red: 0.9098039216, green: 0.8235294118, blue: 0.9647058824, alpha: 1))
mapView.style?.addLayer(fillLayer)

然后创建另一个样式图层,在每个面要素的质心处呈现标注。 (MGLSymbolStyleLayer自动计算质心,计算不规则形状的多边形。)

// Same source as the fillLayer.
let labelLayer = MGLSymbolStyleLayer(identifier: "card-labels", source: cardSource)
// Each feature’s address is an integer, but text has to be a string.
labelLayer.text = NSExpression(format: "CAST(address, 'NSString')")
// Smoothly interpolate from transparent at z16 to opaque at z17.
labelLayer.textOpacity = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)",
                                      [16: 0, 17: 1])
mapView.style?.addLayer(labelLayer)

在自定义这些样式图层时,请特别注意MGLSymbolStyleLayer上控制附近符号是否因碰撞而自动隐藏的选项。您可能会发现自动碰撞检测使得无需指定textOpacity属性。

创建源代码时,您可以传递到MGLShapeSource初始值设定项的其中一个选项是MGLShapeSourceOption.clustered。但是,要使用该选项,您必须创建MGLPointFeature s,而不是MGLPolygonFeature s。幸运的是,MGLPolygonFeature具有coordinate属性,可让您无需手动计算即可找到质心:

var cardCentroids: [MGLPointFeature] = []
var coordinates: [CLLocationCoordinate2D] = […]
let card = MGLPolygonFeature(coordinates: &coordinates, count: UInt(coordinates.count))
let cardCentroid = MGLPointFeature()
cardCentroid.coordinate = card.coordinate
cardCentroid.attributes = ["address": 123]
cardCentroids.append(cardCentroid)
// …
let cardCentroidSource = MGLShapeSource(identifier: "card-centroids", features: cardCentroids, options: [.clustered: true])
mapView.style?.addSource(cardCentroidSource)

此群集源只能与MGLSymbolStyleLayerMGLCircleStyleLayer一起使用,而不能与MGLFillStyleLayer一起使用。 This example显示了如何更详细地使用聚簇点。

答案 1 :(得分:3)

一种选择是将标签添加为MGLSymbolStyleLayer,然后根据缩放级别确定textOpacity

如果您使用的是适用于iOS的Maps SDK的当前版本,则可以尝试以下内容:

symbols.textOpacity = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", [16.9: 0, 17: 1])

dynamically styled interactive points示例显示了一种方法。

答案 2 :(得分:0)

当你缩小时,你的注释是否太靠近了?如果是这样,最好将它们组合在一起而不是完全隐藏它们。请参阅Decluttering a Map with MapKit Annotation Clustering

Before After

相关问题