iOS Mapbox SDK - Как добавить маркеры MGLPointAnnotation в слой карты

Мне нужно найти способ преобразовать маркеры из MGLPointAnnotation в MGLShapeSource или аналогичный, чтобы, например, добавить маркеры на слой карты и иметь полный контроль над их отображением и кластеризацией на карте.

Я создаю приложение для iOS, используя MapBox SDK v5.2. Приложение генерирует маркеры внутри (заголовок, подзаголовок, координаты и имя изображения значка), и при нажатии маркеры отображаются на карте с выноской. Маркеры создаются с помощью MGLPointAnnotation() и добавляются на карту с помощью mapView.addAnnotation().

Но для того, чтобы иметь полный контроль над тем, как отображаются маркеры, например, их кластеризация на основе уровня масштабирования или их включение / выключение, мне нужно добавить маркеры на слой карты, используя, например, MGLShapeSource, а затем style.addSource() и style.addLayer().

Проблема в том, что я не могу найти способ конвертера из MGLPointAnnotation в MGLShapeSource или аналогичного. Я исследовал это, но единственное решение, которое я могу придумать, - это поместить информацию о маркере в GeoJSON файл. Но я хочу избежать этого, поскольку маркеры генерируются внутри приложения при его запуске, а не из внешнего файла GeoJSON, доступного только для чтения.

Пример создания одного пои:

let poi1 = MGLPointAnnotation()
         poi1.coordinate = CLLocationCoordinate2D(latitude: 38.788534, longitude: -9.494489)
         poi1.title = "poi1"
         poi1.subtitle = "This is the text for poi1"
         poiTitleImage[poi1.title!] = "icon1"

mapView.addAnnotation(poi1)

person Bernardo Henriques    schedule 11.09.2019    source источник


Ответы (1)


Вы можете создать MGLShapeSource с помощью массив MGLPointAnnotation или _ 3_ объектов. Оттуда вы можете добавить кластерный слой, аналогичный этому примеру кластеризации.

Если вы также хотите назначить текст или другие данные для каждой точки, используйте MGLPointFeature объекты, а затем назначьте текст в качестве значения атрибутов.

Например:

        var features = [MGLPointFeature]()
        for _ in 1...100 {
            let point = MGLPointFeature()

            let lat = Double(arc4random_uniform(180) / 2)
            let lon = Double(arc4random_uniform(360) / 2)

            point.coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon)
            point.attributes["title"] = "\(lat) \(lon)"
            features.append(point)
        }
        let source = MGLShapeSource(identifier: "clusteredFeatures",
                                    features: features,
                                    options: [.clustered: true, .clusterRadius: 20])
        style.addSource(source)

Пример того, как представить выноску, содержащую информацию, можно найти на веб-сайте Mapbox < / а>. Похоже, что метод handleMapTap может содержать то, что вы ищете.

По сути, вы запрашиваете карту, на которую нажимает пользователь. Получите доступ к атрибутам выбранного объекта, а затем отобразите выноску, содержащую эту информацию. В приведенном выше примере для отображения информации используется UILabel.

Если вы хотите использовать выноску по умолчанию, см. Метод handleMapTap в пример динамического стиля интерактивных точек. В этом примере также создается источник формы из данных JSON, загружаемых во время выполнения.

person jmkiley    schedule 11.09.2019
comment
Да, мы можем добавлять сгенерированные таким образом точки к слою, и я ранее тестировал на коде пример кластеризации, о котором вы говорите. Проблема, которую я описываю, заключается в другом: мне нужно добавить точки к слою с помощью выноски-аннотаций; это означает, что на карте отображаются сгруппированные точки, представленные различными изображениями значков без текстовых подписей; когда пользователь нажимает на видимый значок (не сгруппированный), появляется выноска с заголовком и подпунктом. - person Bernardo Henriques; 13.09.2019
comment
Вы спрашиваете, как сохранить информацию о заголовке / подзаголовке? Если да, то я могу подробнее рассказать об этом в своем ответе. - person jmkiley; 16.09.2019
comment
Привет, да, а также информацию о том, какое изображение использовать - см. Мой код в начале этого сообщения. Спасибо. - person Bernardo Henriques; 30.09.2019
comment
пожалуйста, посмотрите мой ответ. Я добавил еще один пример, который показывает поведение, подобное тому, что вы хотите. - person jmkiley; 02.10.2019