MapBox - обнаружение изменений zoomLevel - PullRequest
0 голосов
/ 22 мая 2018

Как я могу просто обнаружить изменения уровня масштабирования?Возможно ли это?

Мне просто нужно скрыть свои аннотации, когда уровень масштабирования недостаточен.

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 голосов
/ 22 мая 2018

Один из вариантов - добавить метки как MGLSymbolStyleLayer, а затем определить textOpacity на основе уровня масштабирования.

Если вы используете текущую версию Maps SDK для iOS, вы можете попробоватьчто-то вроде:

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

Пример динамически стилизованных интерактивных точек демонстрирует один подход к этому.

0 голосов
/ 23 мая 2018

Из двух основных способов добавления оверлеев к 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 с, а не 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)

Этот кластерный источник может использоваться только с MGLSymbolStyleLayer или MGLCircleStyleLayer, но не MGLFillStyleLayer, В этом примере более подробно показано, как работать с кластеризованными точками.

0 голосов
/ 22 мая 2018

Проблема в том, что когда вы уменьшаете масштаб, ваши аннотации слишком близко друг к другу?Если так, то лучше сгруппировать их, чем спрятать полностью.См. Декларация карты с кластеризацией аннотаций MapKit .

Before After

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...