ios - MapBox - detect zoomLevel changes
问题描述
How can I simply detect zoom level changes? Is it possible?
I simply need to hide my annotation views when zoom level is not enough.
regionDidChange:animated:
is not intended to use for me. Any other way?
I need to hide my labels here:
and show them here:
This is what I currently do with my labels:
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)
解决方案
在向 中添加叠加层的两种主要方法中,运行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)
当您自定义这些样式图层时,请特别注意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)
此群集源只能与MGLSymbolStyleLayer
or一起使用MGLCircleStyleLayer
,而不是MGLFillStyleLayer
. 此示例更详细地展示了如何使用聚类点。
推荐阅读
- php - 如何在有限的时间内验证/授权匿名用户?
- javascript - 如何更新作为数组的对象属性?
- android - Android studio Gradle 的依赖缓存可能已损坏,无法加载
- powershell - 为 CSV 中的每个 sAMAccountName 设置名字和姓氏
- javascript - 使用jQuery选择具有特定类的元素的正确方法是什么
- swift - tvOS UIImageView 焦点阴影被剪裁
- php - 如何在 wordpress 的 metaslider 中添加联系表格 7,我想在图像为幻灯片时显示不同的表格
- asp.net-mvc - LINQ:具有最大值的列表
- node.js - 使用 Mongoose 将项目推送到对象中的数组
- java - 如何将 RadioGroup 和 EditText 添加到 AlertDialog?