Mapbox Swift SDK - показывать аннотации на определенном треке (привязка к маршруту)

Я использую Mapbox SDK с моим проектом Swift и добавляю собственные треки для некоторых путей поездов. Временно я тестирую приложение в офисе, поэтому я создал собственный маршрут по офису.

Эти настраиваемые маршруты не являются маршрутами или дорогами, существующими в Mapbox или Google Maps.

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

Давайте возьмем пример кода, у меня есть следующий код, который показывает мое местоположение по GPS, где я нахожусь.

      func setAnnotation(atLocation location: CLLocation, forDevice device: String, andUser userId: Int) {

    var locationMarker = LSTPointAnnotation()
    
    // Check from list of annotations if the annotation exists or not 
    // as I am showing multiple annotations at a time for different people
    // and all annotations update their individual locations in async fashion
    if let userMarker = self.markerAnnotations[device] {
        locationMarker = userMarker
    } else {
        markerAnnotations[device] = locationMarker
        userDevices[userId] = device
        self.mapView?.addAnnotation(locationMarker)
    }

    // We are creating annotation from Mapbox's 'viewForAnnotation' method
    if let annotationView = self.mapView?.view(for: locationMarker) as? LSTLocoAnnotationView {
        // I am changing color of annotation view after some processing
        // Here only UI customisation is done
    }

    // Updating location of the annotation
    locationMarker.coordinate = location.coordinate

}

В основном то, что делает вышеуказанная функция,

  • Получить маркер пользователя из списка доступных маркеров аннотации или создать новую аннотацию
  • Обновите местоположение этого маркера с новым местоположением, которое у нас есть location

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

Ниже приведен результат этой функции, где вы сможете увидеть место, где я стою (вне маршрута).

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

Однако моя цель - не показывать локацию вне трассы, а всегда на трассе.

Ниже приведен код, который я добавил, чтобы показать свое местоположение на трассе, но это немного пугает :(.

Мы обновляем то же самое функционировать здесь,

      func setAnnotation(atLocation location: CLLocation, forDevice device: String, andUser userId: Int) {

    var locationMarker = LSTPointAnnotation()
    
    // Check from list of annotations if the annotation exists or not 
    // as I am showing multiple annotations at a time for different people
    // and all annotations update their individual locations in async fashion
    if let userMarker = self.markerAnnotations[device] {
        locationMarker = userMarker
    } else {
        markerAnnotations[device] = locationMarker
        userDevices[userId] = device
        self.mapView?.addAnnotation(locationMarker)
    }

    // Now I have geoJson file for custom route 
    // as I have stylised that route with dash lines
    // Accessing all features with dash-lines
    let features = self.mapView?.visibleFeatures(in: map.bounds, styleLayerIdentifiers: Set(arrayLiteral: "polyline-dash"))

    // Will mark nearest-coordinates and nearest distance with new location of that coordinate
    var nearestCoord: CLLocationCoordinate2D?
    var nearest: Double?

    // Sorting all feature points based on nearest location distance (Assumption)
    if let json = features?.sorted(by: { firstFeature, secondFeature in
        let firstDistance = firstFeature.coordinate.distance(to: location.coordinate)
        let secondDistance = secondFeature.coordinate.distance(to: location.coordinate)
        
        return firstDistance < secondDistance
    }).first?.geoJSONDictionary(),
       let geometry = json["geometry"] as? Dictionary<String, Any>,
       let coords = geometry["coordinates"] as? Array<Array<Any>> {

            // Have to take geoJSONDictionary as without it
            // I would not be able to access underlying coordinates of the feature
            // feature.coordinate gives centre of Mapbox View (It always keep annotation at centre of the screen which is not required)

        // Loop through all coordinates and finding nearest coord with new location
        for coord in coords {
            if let inners = coord as? Array<Any> {
                for inner in inners {
                    guard let t1 = inner as? Array<Double> else {   return   }
                    let c1 = CLLocationCoordinate2D(latitude: t1[1], longitude: t1[0])
                    
                    let firstDistance = c1.distance(to: location.coordinate)
                    
                    // Save nearest location and nearest distance
                    if let dist = nearest {
                        if firstDistance < dist {
                            nearest = firstDistance
                            nearestCoord = c1
                        }
                    } else {
                        nearest = firstDistance
                        nearestCoord = c1
                    }
                }
            }
        }

    }

    // We are creating annotation from Mapbox's 'viewForAnnotation' method
    if let annotationView = self.mapView?.view(for: locationMarker) as? LSTLocoAnnotationView {
        // I am changing color of annotation view after some processing
        // Here only UI customisation is done
    }

    // Updating location of the annotation with nearest coordinate from route
    // But if distance is too large then we are showing original location
    if let near = nearestCoord, (nearest ?? 0) <= 100 {
        locationMarker.coordinate = near
    } else {
        locationMarker.coordinate = location.coordinate
    }

}

Что делает функция выше,

  • Взять характерные точки из geoJson
  • Отфильтруйте все координаты и найдите ближайшую координату, проверив расстояние с новым местоположением
  • Как только ближайшая координата найдена, покажите аннотацию к ближайшей координате, которая всегда соответствует заданному маршруту, или, если расстояние слишком велико, затем покажите аннотацию в исходном местоположении

Это в основном показывает мое местоположение на трассе, но я не тестировал всю трассу (что я скоро сделаю).

Результат вышеуказанной функции, он может давать прерывистый ответ,

Однако я хочу реорганизовать эту функцию, а также мне нужны указатели, могу ли я извлечь файл geoJSON из URL-адреса стиля Mapbox или нет (я уже добавил стили в карту Mapbox).

0 ответов

Другие вопросы по тегам