Из двух основных способов добавления оверлеев к 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
, В этом примере более подробно показано, как работать с кластеризованными точками.