Быстрое изменение точек карты при изменении SegmentedControl - PullRequest
0 голосов
/ 27 августа 2018

Я пытаюсь работать с Mapbox.

Я создал точку на карте и показываю из файла

Я хочу, чтобы при изменении SegmentedControl, item.type былоизменились соответственно и получили правильные данные

Например, если нажать 0 case -> make 0 == item.type

Я создаю пользовательские точки

func addItemsToMap(features: [MGLPointFeature]) {

    guard let style = mapView.style else { return }
    let source = MGLShapeSource(identifier: "mapPoints", features: features, options: nil)
    style.addSource(source)

    let colors = [
            "black": MGLStyleValue(rawValue: UIColor.black)
    ]
    let circles = MGLCircleStyleLayer(identifier: "mapPoints-circles", source: source)
    circles.circleColor = MGLSourceStyleFunction(interpolationMode: .identity,
                                                     stops: colors,
                                                     attributeName: "color",
                                                     options: nil)
    circles.circleRadius = MGLStyleValue(interpolationMode: .exponential,
                                             cameraStops: [2: MGLStyleValue(rawValue: 5),
                                                           7: MGLStyleValue(rawValue: 8)],
                                             options: nil)
    circles.circleStrokeWidth = MGLStyleValue(rawValue: 2)
    circles.circleStrokeColor = MGLStyleValue(rawValue: UIColor.white)

    style.addLayer(circles)
}

Поместить данные в mapbox

func test(number: Int) {

    guard let documentsDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
    let urlBar = documentsDirectoryUrl.appendingPathComponent("Persons.json")

    do {
        let jsonData = try Data(contentsOf: urlBar)
        //Переводим их в модель
        let result = try JSONDecoder().decode(CollectionTest.self, from: jsonData)
        let coll: CollectionTest = result
        let features = parseJSONItems(collection: coll, number: number)

        addItemsToMap(features: features)
        print(features)
    } catch { print("Error while parsing: \(error)") }
}

Получить данные из файла

func parseJSONItems(collection: CollectionTest, number: Int) -> [MGLPointFeature] {

    var features = [MGLPointFeature]()
    for item in collection.prices {
            if item.type == number {
...get data to annotation and location
let feature = MGLPointFeature()
            feature.coordinate = coordinate
            feature.title = "\(name)"
            feature.attributes = [
                "color" : color,
                "name" : "\(name)"
            ]
            features.append(feature)
        }
                    }
                }}}
    }
    return features
}

Мне нужно изменить number с 0 на 4, потому что в данных у меня есть тип от 0 до 4 и точки нужно изменить с 0 - 4, если SegmentedControl изменилось

в SegmentedControl У меня есть

@objc func change(sender: UISegmentedControl) {
    switch sender.selectedSegmentIndex {
        case 0:
        test(number: 0)
        case 1:
        test(number: 1)
        case 2:
        ttest(number: 2)
        case 3:
        test(number: 3)
        case 4:
        test(number: 4)
        default:
        test(number: 2)
    }
}

В viewDidLoad:

override func viewDidLoad() {

    super.viewDidLoad()
    styleToggle.addTarget(self, action: #selector(change(sender:)), for: .valueChanged)

    test(number: 2)
}

Когда приложение запускается - работает хорошо и показывает все данные == type 2

Но когда я меняю кнопку в SegmentedControl на case 0 или другие - я получаю сбой и при выводе на консоль

Завершение работы приложения из-за необработанного исключения
'MGLRedundantSourceIdentifierException', причина: 'Source mapPoints уже существует'

Что я делаю неправильно?Как это исправить?

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Похоже, вы пытаетесь добавить на свою карту источник, который уже существует.Чтобы избежать этого сообщения, вам нужно:

  1. Проверить наличие источника перед добавлением его в свой стиль.В вашем случае, возможно, назовите ваши источники mapPoints-circles-\(number).Если источник уже существует, используйте его повторно.

  2. Добавить источник на карту один раз (желательно в пределах начальных -mapView:didFinishLoadingStyle:).Чтобы создать новые слои из этого слоя, вы можете получить доступ к источнику из стиля карты.

Если точки получены из источника с идентификатором my-source, вы должны попытаться:

guard let source = style.source(withIdentifier: "my-source") else { return }
0 голосов
/ 27 августа 2018

при нажатии на сегмент, удалите все маркеры, которые уже присутствуют на карте, затем добавьте новые маркеры

Вы можете использовать map.removeLayer (marker);удалить маркер (объект ILayer).

...