Swift:坐标变化时如何更新地图上标记的位置?

时间:2017-11-08 17:08:59

标签: ios arrays swift google-maps google-maps-markers

我使用的是Google地图SDK。我在更新标记的位置时遇到问题。目前使用xml数据的坐标绘制标记,但是,每次坐标在xml数据中发生变化时,我都会尝试更新它们的位置。这段代码可能有很多不足之处,因为我不太了解,但最终的目标是让这张地图显示我大学校园内公交车的位置,让他们在接收新坐标时在地图上实时移动。谢谢!

import UIKit
import GoogleMaps

class ViewController: UIViewController, GMSMapViewDelegate, 
XMLParserDelegate, CLLocationManagerDelegate {

var parser = XMLParser()
var mapsManager = CLLocationManager()
var busArray = [Bus]()
var markerDict: [String: GMSMarker] = [:]
@IBOutlet weak var mapView: GMSMapView!
var refreshTimer = Timer()
struct Pins {
    let name: String
    let subName: String
    let coord: CLLocationCoordinate2D
}

override func viewDidLoad()
{
    super.viewDidLoad()
    refreshTimer = Timer.scheduledTimer(timeInterval: 2, target: self, 
      selector: #selector(runRefresh), userInfo: nil, repeats: true)

    // Initial Parse:
    let urlString = URL(string: 
      "http://webservices.nextbus.com/service/publicXMLFeed?
      a=rutgers&command=vehicleLocations")
    self.parser = XMLParser(contentsOf: urlString!)!
    self.parser.delegate = self
    let success:Bool = self.parser.parse()
    if success {
        print("success")
        getLoc()
    } else {
        print("parse failure!")
    }

    mapsManager.delegate = self
    mapsManager.desiredAccuracy = kCLLocationAccuracyKilometer
    //minimum distance to be moved by device before update
    mapsManager.distanceFilter = 1000
    // permission to use location service
    mapsManager.requestWhenInUseAuthorization()
    // permission to use location when the app is run future
    mapsManager.requestAlwaysAuthorization()
    // Update user location
    mapsManager.startUpdatingLocation()
    // Make GMSMapView the current view
    self.view = mapView
}


// Gets location of pins and maps them to mapView
func getLoc() {
    for bus in busArray {
        let pins = [
            Pins(name: bus.routeTag, subName: "\(bus.busID)", 
            coord: bus.coordinate)
        ]

        for pin in pins {
            let coord = pin.coord
            let identifier = pin.subName
            self.markerDict[identifier]?.position = coord
            let pinMarker = GMSMarker()
            pinMarker.position = pin.coord
            pinMarker.title = pin.name
            pinMarker.snippet = pin.subName
            pinMarker.tracksViewChanges = true
            pinMarker.map = mapView
            markerDict[pin.name] = pinMarker
          }
     }
}

// PROBLEM HERE: FUNCTION IS SUPPOSED TO UPDATE MARKER POSITIONS WHEN 
NEW COORDINATES ARE RECEIVED FROM THE XML PARSING
func updateLoc() {
    for bus in busArray {
        let pins = [
            Pins(name: bus.routeTag, subName: "\(bus.busID)", coord: 
            bus.coordinate)
        ]
        for pin in pins {
            let pinMarker = GMSMarker()
            pinMarker.position = pin.coord
            pinMarker.title = pin.name
            pinMarker.snippet = pin.subName
            pinMarker.tracksViewChanges = true
            // print(pinMarker)
        }

    }
}

    //MARK: REFRESH FUNCTION WHICH IS CALLED BY TIMER IN VIEW. RECALLS 
    PARSE, UPDATE LOCATION FUNCTION
   @objc func runRefresh() {
    let urlString = URL(string: 
     "http://webservices.nextbus.com/service/publicXMLFeed?
     a=rutgers&command=vehicleLocations")
    self.parser = XMLParser(contentsOf: urlString!)!
    self.parser.delegate = self

    let success:Bool = self.parser.parse()
    if success {
        print("success")
        updateLoc()
    } else {
        print("parse failure!")
    }
}




func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus)
{
    if (status == CLAuthorizationStatus.authorizedWhenInUse)
    {
        mapView?.isMyLocationEnabled = true  //to get user’s current location
    }
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
    let newLocation = locations.last
    mapView?.camera = GMSCameraPosition.camera(withTarget: newLocation!.coordinate, zoom: 15.0)
    mapView?.settings.myLocationButton = true
    self.view = self.mapView

}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: PARSING FUNCTIONS ->
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
    if(elementName=="vehicle")
    {
        let bus = Bus()
        for string in attributeDict {
            let strvalue = string.value as NSString
            switch string.key {
            case "id":
                bus.busID = strvalue.integerValue
                break
            case "routeTag":
                bus.routeTag = strvalue as String
                break
            case "lat":
                bus.coordinate.latitude = strvalue.doubleValue
                break
            case "lon":
                bus.coordinate.longitude = strvalue.doubleValue
                break
            case "speedKmHr":
                bus.speed = strvalue.integerValue
                break
            default:
                break
            }
        }
        busArray.append(bus)
    }
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    //        for bus in self.busArray {
    //           print("\(bus.busID)\n\(bus.routeTag)\n\(bus.coordinate)\n\(bus.speed) mph");
    //            print("\n")
    //        }
}
func parser(_ parser: XMLParser, foundCharacters string: String) {

}
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
    print("failure error: ", parseError)
}


}

// BUS CLASS INITIALIZES OBJECTS TO HOLD VALUES FROM PARSE DATA
  class Bus: NSObject {
   var busID:Int = 0
   var routeTag:String = ""
   var coordinate = CLLocationCoordinate2D()
   var speed:Int = 0

}

0 个答案:

没有答案