代码之家  ›  专栏  ›  技术社区  ›  Bartłomiej Semańczyk

地图框-检测缩放级别更改

  •  2
  • Bartłomiej Semańczyk  · 技术社区  · 8 年前

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

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

    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 回复  |  直到 8 年前
        1
  •  4
  •   Minh Nguyễn jmkiley    8 年前

    两个主要的 ways to add overlays MGLMapView 运行时样式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)
    

    在自定义这些样式层时,请特别注意 MGL符号样式层 它控制附近的符号是否由于碰撞而自动隐藏。您可能会发现自动碰撞检测不需要指定 textOpacity 属性。


    创建源时,可以将其中一个选项传递到 MGLShapeSource 初始值设定项为 MGLShapeSourceOption.clustered . 但是,要使用该选项,必须创建 MGLPointFeature 不是,不是 MGLPolygonFeature 幸运的是, 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)
    

    此群集源只能用于 MGL符号样式层 MGLCircleStyleLayer 不是 MGLFillStyleLayer . This example 更详细地显示了如何使用聚集点。

        2
  •  3
  •   jmkiley    8 年前

    一种选择是将标签添加为 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 示例显示了一种方法。

        3
  •  0
  •   Coder-256    8 年前

    问题是当你缩小时,你的注释太靠近了吗?如果是这样的话,最好把它们组合在一起,而不是完全隐藏起来。见 Decluttering a Map with MapKit Annotation Clustering .

    Before After