Google Maps iOS не позволяет настраивать изображение маркера карты - PullRequest
1 голос
/ 04 июля 2019

Я использую Google Maps SDK для iOS - https://developers.google.com/maps/documentation/ios-sdk/marker#use_the_markers_icon_property

В сочетании с служебной библиотекой Maps SDK для iOS https://developers.google.com/maps/documentation/ios-sdk/utility/kml-geojson#render-kml-data

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

Изначально я думал, что это проблема с библиотекой утилит, поэтому я потратил некоторое время, пытаясь написать свой собственный код, чтобы просмотреть файл kml и добавить собственные маркеры самостоятельно. Однако, прежде чем я зашел слишком далеко, я заметил, что даже когда я пытаюсь добавить базовый маркер с пользовательским значком, я не могу. Это заставило меня поверить, что это проблема не с библиотекой утилит, а с SDK для iOS. Я попытался переместить папку, в которой находится изображение, и убедиться, что код может видеть путь к изображениям, но я не могу заставить его работать.

Это код, который у меня есть в моем проекте

let path = Bundle.main.path(forResource: testFile, ofType: "kml")
let url = URL(fileURLWithPath: path!)
let kmlParser = GMUKMLParser(url: url)
kmlParser.parse()

let camera = GMSCameraPosition.camera(withLatitude: lat, longitude: long, zoom: zoom)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.mapType = GMSMapViewType.terrain
mapView.isMyLocationEnabled = true
mapView.settings.zoomGestures = true
mapView.settings.myLocationButton = true

let renderer = GMUGeometryRenderer(map: mapView, geometries: kmlParser.placemarks, styles: kmlParser.styles, styleMaps: kmlParser.styleMaps)
renderer.render()

Это тоже не работает

let position = CLLocationCoordinate2D(latitude: lat, longitude: long)
let marker = GMSMarker(position: position)
marker.title = "Test"
marker.icon = UIImage(named: "icon-1")
marker.map = mapView

Заранее спасибо за любую помощь

1 Ответ

0 голосов
/ 05 июля 2019

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

Сначала я создал новый массивметки, которые имели все, кроме маркеров карты.Затем я использовал этот массив меток вместо kmlParser.placemarks, чтобы все остальное могло быть добавлено утилитарной библиотекой.

//Removing markers without icons
var myIndex = 0
var removed = [GMUGeometryContainer]()
for mark in kmlParser.placemarks{
    if(mark.geometry.type != "Point"){
         removed.append(kmlParser.placemarks[myIndex])
    }
    myIndex += 1
}

let renderer = GMUGeometryRenderer(map: mapView, geometries: removed, styles: kmlParser.styles, styleMaps: kmlParser.styleMaps)
renderer.render() 

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

func addMarkers(fileName:String) -> [GMSMarker]{
    var markers = [GMSMarker]()
    if let path = Bundle.main.path(forResource: fileName, ofType: "kml"){
        do{
            let data = try String(contentsOfFile: path, encoding: .utf8)
            let myStrings = data.components(separatedBy: .newlines)
            var styleToIcon = [String: String]()

            var lineNum = 0
            for line in myStrings{
                //Detecting new style that will be used in placemarks
                if line.contains("Style id") && line.contains("normal") && !line.contains("line-"){
                    let newKey = String(line.split(separator: "\"")[1])
                    let newValue = String(myStrings[lineNum+4].split(separator: ">")[1].split(separator: "/")[1].split(separator: "<")[0])
                    styleToIcon[newKey] = newValue
                }

                //Detecting new placemark on map
                else if(line.contains("<Placemark>") && !myStrings[lineNum+2].contains("#line")){
                    //Get name
                    var name = myStrings[lineNum+1].split(separator: ">")[1].split(separator: "<")[0]
                    //Sometimes name has weird CDATA field in it that needs to be removed
                    if(name.contains("![CDATA")){
                        name = name.split(separator: "[")[2].split(separator: "]")[0]
                    }

                    //Get snippet (description)
                    var snippet = myStrings[lineNum+2].split(separator: ">")[1].split(separator: "<")[0]
                    //Sometimes snippet has weird CDATA field in it that needs to be removed
                    if(snippet.contains("![CDATA")){
                        snippet = snippet.split(separator: "[")[2].split(separator: "]")[0]
                    }

                    //Get style
                    let style = String(myStrings[lineNum+3].split(separator: ">")[1].split(separator: "#")[0].split(separator: "<")[0] + "-normal")

                    //Get Coordinates
                    let coordStringSplit = myStrings[lineNum+6].split(separator: ",")
                    var lat = 0.0
                    var long = 0.0
                    if(coordStringSplit[0].contains("-")){
                        long = Double(coordStringSplit[0].split(separator: "-")[1])! * -1.0
                    }else{
                        long = Double(coordStringSplit[0])!
                    }
                    if(coordStringSplit[1].contains("-")){
                        lat = Double(coordStringSplit[1].split(separator: "-")[1])! * -1.0
                    }else{
                        lat = Double(coordStringSplit[1])!
                    }

                    //Create marker and add to list of markers
                    let position = CLLocationCoordinate2D(latitude: lat, longitude: long)
                    let marker = GMSMarker(position: position)
                    marker.title = String(name)
                    marker.snippet = String(snippet)
                    marker.icon = UIImage(named: styleToIcon[style]!)
                    markers.append(marker)
                }
                lineNum += 1
            }
        }catch{
            print(error)
        }
    }
    return markers
}

Это так сильно связано с тем, как выглядят мои файлы kml, что я сомневаюсь, что это поможет кому-то еще, но я решил опубликовать это на всякий случай.

Теперь, когда у нас есть этот метод, все, что нам нужно сделать, это вернуться туда, где мы рендерили все данные kml, и отобразить эти маркеры на карте

//Adding markers with icons
let newMarkers = addMarkers(fileName: courseName)
for mark in newMarkers{
    mark.map = mapView
}

У меня также былчтобы просмотреть мои файлы kml вручную и исправить некоторые имена изображений, но это не было проблемой.Даже если бы служебная библиотека работала, я должен был бы сделать это, потому что служебная библиотека работает только с файлами kml, а не с kmz, поэтому каждый файл kml ссылается на одну и ту же папку для изображений и использует одинаковые имена для изображений.Это нормально, занимает всего несколько минут на файл.Было бы хорошо, если бы была библиотека kmz, ну да ладно.

Надеюсь, это поможет кому-то еще, и, надеюсь, я скоро смогу найти реальное решение (если только это не проблема с утилитарной библиотекой, в этом случае, надеюсь, она скоро будет исправлена).

...