Polyline not showing in MapKit [Xcode 9.0 - Swift 4.0] - swift

Ive made a view controller which tracks my location once the view is opened. Once the routeButton is pressed, I want the blue Polyline to show. However it does not. Ive set the delegates and wrote the rendering function but it still does not show. I don't get an error when calculating directions. It does run the self.map.add(route.polyline, level: .aboveRoads) line. But no polyline is added to the map.
Ive read multiple questions relating to this on here, but nothing fixes my issue.
Any help would be greatly appreciated.
Heres my code:
class ThirdViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate{
var startLocCoord = CLLocation()
var endLocCoord = CLLocation()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
let span:MKCoordinateSpan = MKCoordinateSpanMake(0.05,0.05)
let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude,location.coordinate.longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
map.setRegion(region, animated: true)
self.map.showsUserLocation = true
}
#IBAction func routeButton (_ sender: Any) {
let destinationLoc = CLLocationCoordinate2D(latitude: endLocCoord.coordinate.latitude, longitude: endLocCoord.coordinate.longitude)
let sourceLoc = CLLocationCoordinate2D(latitude: startLocCoord.coordinate.latitude, longitude: startLocCoord.coordinate.longitude)
let sourcePlaceMark = MKPlacemark(coordinate: sourceLoc)
let destinationPlaceMark = MKPlacemark(coordinate: destinationLoc)
let directionRequest = MKDirectionsRequest()
directionRequest.source = MKMapItem(placemark: sourcePlaceMark)
directionRequest.destination = MKMapItem(placemark: destinationPlaceMark)
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
directions.calculate { (response, error) in
guard let directionResponse = response else {
if let error = error {
print("Error with directions==\(error.localizedDescription)")
}
return
}
let route = directionResponse.routes[0]
print("route ------->", route)
self.map.add(route.polyline, level: .aboveRoads)
let rect = route.polyline.boundingMapRect
self.map.setRegion(MKCoordinateRegionForMapRect(rect), animated: true)
print(self.srcLat, self.srcLon, self.lat, self.long)
}
override func viewDidLoad() {
manager.desiredAccuracy = kCLLocationAccuracyBest
UIApplication.shared.isIdleTimerDisabled = true
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
manager.allowsBackgroundLocationUpdates = true
manager.pausesLocationUpdatesAutomatically = false
self.map.isZoomEnabled = false
self.map.isScrollEnabled = false
self.map.delegate = self
map.mapType = MKMapType.standard
}
func mapView(_mapView: MKMapView, rendererFor overlay: MKOverlay)-> MKOverlayRenderer{
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 5.0
print("render called")
return renderer
}
}
Thanks

It's probably just a typo. Replace
func mapView(_mapView: MKMapView, rendererFor overlay: MKOverlay)-> MKOverlayRenderer{
with
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {

Related

Why is my MKMapViewDelegate not reacting, despite finding the route?

I have been following Sean Allens tutorial on MapKit and Directions. I used the code to fit it to my SwiftUI project.
Everything works fine, the screen zoom to fit start and destination on the screen, and calculated the rout correctly.
However, it does to actually display the route.
The main Code in my ViewModel (note: .delegate = self is actually in a function, I wrote it at top level for easier understanding how I am setting the Delegat)
func checkForLocationServices() {
if CLLocationManager.locationServicesEnabled() {
locationManager = CLLocationManager()
locationManager!.delegate = self
}
}
//MARK: Directions
func getDirections() {
guard let location = locationManager?.location?.coordinate else {
return
}
let request = createDirectionRequest(from: location)
let directions = MKDirections(request: request)
directions.calculate { calcResponse, error in
guard let response = calcResponse else { return }
for route in response.routes {
print("Route \(route.name) is \(route.distance) long")
self.mapView.addOverlay(route.polyline, level: .aboveRoads)
self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)
}
}
}
func createDirectionRequest(from coordinate: CLLocationCoordinate2D) -> MKDirections.Request {
let startLocation = MKPlacemark(coordinate: coordinate)
let destinationLocation = MKPlacemark(coordinate: bbcLocation.coordinate)
let request = MKDirections.Request()
request.source = MKMapItem(placemark: startLocation)
request.destination = MKMapItem(placemark: destinationLocation)
request.transportType = .automobile
request.requestsAlternateRoutes = true
return request
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay as! MKPolyline)
renderer.strokeColor = .blue
renderer.lineWidth = 5.0
print(renderer.strokeStart)
print(renderer.strokeEnd)
return renderer
}
The Delegate function rendererFor is never called, despite me setting the Delegate as seen above. I also checked via Breakpoints that it is actually set, as well as downloaded Seans source code, which set the Delegate the same way I did.
My VM conforms to the MKMapViewDelegate Protocol.
Another user had the same problem, but since he got no response, I thought I might try I someone can help me.
Core-question: Why is my delegate method not called, despite me setting it correctly, and knowing (through console logs) that my route is found, calculated, and in fact zoomed in on?
If you need more code, feel free to ask.
Thanks in advance.
*Seans Project
func setupLocationManager() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func getDirections() {
guard let location = locationManager.location?.coordinate else {
//TODO: Inform user we don't have their current location
return
}
let request = createDirectionsRequest(from: location)
let directions = MKDirections(request: request)
resetMapView(withNew: directions)
directions.calculate { [unowned self] (response, error) in
//TODO: Handle error if needed
guard let response = response else { return } //TODO: Show response not available in an alert
for route in response.routes {
self.mapView.addOverlay(route.polyline)
self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)
}
}
}
func createDirectionsRequest(from coordinate: CLLocationCoordinate2D) -> MKDirections.Request {
let destinationCoordinate = getCenterLocation(for: mapView).coordinate
let startingLocation = MKPlacemark(coordinate: coordinate)
let destination = MKPlacemark(coordinate: destinationCoordinate)
let request = MKDirections.Request()
request.source = MKMapItem(placemark: startingLocation)
request.destination = MKMapItem(placemark: destination)
request.transportType = .automobile
request.requestsAlternateRoutes = true
return request
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay as! MKPolyline)
renderer.strokeColor = .blue
return renderer
}
``

add go button MapKit Swift

I am using MapKit. It draws the route between the two entered locations. But the go button does not appear. So he draws the route but doesn't describe how to go on the route. You can see in the photo. It puts the pins, but the Go to route button does not appear. How can I activate the go button?
class customPin: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?
init(pinTitle:String, pinSubTitle:String, location:CLLocationCoordinate2D) {
self.title = pinTitle
self.subtitle = pinSubTitle
self.coordinate = location
}
}
class mapViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
let sourceLocation = CLLocationCoordinate2D(latitude:39.173209 , longitude: -94.593933)
let destinationLocation = CLLocationCoordinate2D(latitude:38.643172 , longitude: -90.177429)
let sourcePin = customPin(pinTitle: "Kansas City", pinSubTitle: "aa", location: sourceLocation)
let destinationPin = customPin(pinTitle: "St. Louis", pinSubTitle: "ddd", location: destinationLocation)
self.mapView.addAnnotation(sourcePin)
self.mapView.addAnnotation(destinationPin)
let sourcePlaceMark = MKPlacemark(coordinate: sourceLocation)
let destinationPlaceMark = MKPlacemark(coordinate: destinationLocation)
let directionRequest = MKDirections.Request()
directionRequest.source = MKMapItem(placemark: sourcePlaceMark)
directionRequest.destination = MKMapItem(placemark: destinationPlaceMark)
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
directions.calculate { (response, error) in
guard let directionResonse = response else {
if let error = error {
print("we have error getting directions==\(error.localizedDescription)")
}
return
}
let route = directionResonse.routes[0]
self.mapView.addOverlay(route.polyline, level: .aboveRoads)
let rect = route.polyline.boundingMapRect
self.mapView.setRegion(MKCoordinateRegion(rect), animated: true)
}
self.mapView.delegate = self
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 4.0
return renderer
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Trying to pass annotation from one view controller to another

I am viewing a location on my first view controller. I want to also view the same location on a second view controller. How can I pass the location on the first view controller to the second view controller? or Trying to pass annotation from one view controller to another?
import UIKit
import Foundation
import MapKit
import CoreLocation
class FirstViewController: UIViewController, CLLocationManagerDelegate, UISearchBarDelegate, MKMapViewDelegate {
//Map
#IBOutlet weak var Map: MKMapView!
let manager = CLLocationManager()
var directionsArray: [MKDirections] = []
//user location constanatly updates
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let location = locations[0]
let span:MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
//my location coordinates????
let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude,location.coordinate.longitude)
let region:MKCoordinateRegion = MKCoordinateRegion(center: myLocation, span: span)
Map.showsScale = true
Map.showsPointsOfInterest = true
Map.setRegion(region, animated: true)
self.Map.showsUserLocation = true
}
// Search Button functions
#IBAction func SearchButton(_ sender: Any)
{
let searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.delegate = self
present(searchController, animated: true, completion: nil)
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
//Ignoring user
UIApplication.shared.beginIgnoringInteractionEvents()
//Activity Indicator
let activityIndicator = UIActivityIndicatorView()
activityIndicator.style = UIActivityIndicatorView.Style.gray
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.startAnimating()
self.view.addSubview(activityIndicator)
//hide search bar
searchBar.resignFirstResponder()
dismiss(animated: true, completion: nil)
//Create the search request
let searchRequest = MKLocalSearch.Request()
searchRequest.naturalLanguageQuery = searchBar.text
let activeSearch = MKLocalSearch(request: searchRequest)
activeSearch.start{ (response, error) in
activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
if response == nil
{
print("Error")
}
else
{
//Remove annotations
let annotations = self.Map.annotations
self.Map.removeAnnotations(annotations)
//Getting Data
let latitude = response?.boundingRegion.center.latitude
let longitude = response?.boundingRegion.center.longitude
//Create annotation
let annotation = MKPointAnnotation()
annotation.title = searchBar.text
//annotation.coordinate = locationManager.location!.coordinate
annotation.coordinate = CLLocationCoordinate2DMake(latitude!, longitude!)
self.Map.addAnnotation(annotation)
//Zooming in annotation
let coordinate:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude!, longitude!)
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let region = MKCoordinateRegion(center: coordinate,span: span)
self.Map.setRegion(region, animated: true)
let sourceCoordinates = self.manager.location?.coordinate
let destinationCoodinates = CLLocationCoordinate2DMake(latitude!, longitude!)
let sourcePlacemark = MKPlacemark(coordinate: sourceCoordinates!)
let destPlacemark = MKPlacemark(coordinate: destinationCoodinates)
let sourceItem = MKMapItem(placemark: sourcePlacemark)
let destItem = MKMapItem(placemark: destPlacemark)
let directionsRequest = MKDirections.Request()
directionsRequest.source = sourceItem
directionsRequest.destination = destItem
directionsRequest.transportType = .automobile
let directions = MKDirections(request: directionsRequest)
directions.calculate(completionHandler: { response, error in
guard let response = response else {
if let error = error {
print("Something Went Wrong")
}
return
}
// reset/clear prevous search route
resetMapView(withNew: directions)
// display single best route on map with a polyline
let route = response.routes[0]
self.Map.addOverlay(route.polyline, level: .aboveRoads)
// animate/draw route on map
let rekt = route.polyline.boundingMapRect
self.Map.setRegion(MKCoordinateRegion(rekt),animated: true)
})
//function removes current route on map
func resetMapView(withNew directions: MKDirections){
self.Map.removeOverlays(self.Map.overlays)
self.directionsArray.append(directions)
let _ = self.directionsArray.map { $0.cancel() }
}
}
}
}
//******************************************************************************************
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
// function displays route on map
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 5.0
return renderer;
}
}
// Second View controller code below
import UIKit
import Foundation
import MapKit
import CoreLocation
class SecondViewController: UIViewController, CLLocationManagerDelegate, UISearchBarDelegate, MKMapViewDelegate {
#IBOutlet weak var Map2: MKMapView!
let manager = CLLocationManager()
var directionsArray: [MKDirections] = []
//************************************************************
//user location constanatly updates
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations[0]
let span:MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
// my location coordinates
let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude,location.coordinate.longitude)
let region:MKCoordinateRegion = MKCoordinateRegion(center: myLocation, span: span)
Map2.showsScale = true
Map2.showsPointsOfInterest = true
Map2.setRegion(region, animated: true)
self.Map2.showsUserLocation = true
}
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
// function displays route on map
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 5.0
return renderer;
}
}

Route Between two A and B location

There is no error but I can not get the location from my current location to what I search. Can someone please help. It says this with I click on the Car logo to get directions: MKDirectionsErrorCode=7, NSLocalizedDescription=Directions Not Available}
I am only missing the line to get to the direction. When I click on the car logo, it just does not do anything but zoom out to my current location. I am missing anything or did something wrong?
Here is my code:
protocol HandleMapSearch {
func dropPinZoomIn(placemark:MKPlacemark)
}
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView! // Handle the Map Kit View
var selectedPin:MKPlacemark? = nil //Any incoming placemarks
// Destination for directions*********
var destination:MKMapItem = MKMapItem()
var MyPosition = CLLocationCoordinate2D()
var resultSearchController:UISearchController? = nil // Keep the UISearchController in memory after it's created
var locationManager = CLLocationManager() // Core Location
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest // Accuracy level
locationManager.requestWhenInUseAuthorization() // Triggers the location permission dialog
locationManager.startUpdatingLocation()
//locationManager.requestLocation() // Trigers a one-time location request
// Set up the search results table
let locationSearchTable = storyboard!.instantiateViewController(withIdentifier: "LocationSearchTable") as! LocationSearchTable
resultSearchController = UISearchController(searchResultsController: locationSearchTable)
resultSearchController?.searchResultsUpdater = locationSearchTable
// Set up the search bar
let searchBar = resultSearchController!.searchBar
searchBar.sizeToFit()
searchBar.placeholder = "Search for places"
navigationItem.titleView = resultSearchController?.searchBar
// Configure the UISearchController appearance
resultSearchController?.hidesNavigationBarDuringPresentation = false
resultSearchController?.dimsBackgroundDuringPresentation = true
definesPresentationContext = true
locationSearchTable.mapView = mapView // Passes along a handle of the mapView
locationSearchTable.handleMapSearchDelegate = self // Handles the map search
}
//Getting direction of location
#objc func getDirections(sender: AnyObject){
if let selectedPin = selectedPin {
let mapItem = MKMapItem(placemark: selectedPin)
//let launchOptions = [MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving]
//mapItem.openInMaps(launchOptions: launchOptions)
let request = MKDirectionsRequest()
request.source = MKMapItem.forCurrentLocation()
request.destination = destination
request.requestsAlternateRoutes = false
let directions = MKDirections(request: request)
// 8.
directions.calculate {
(response, error) -> Void in
guard let response = response else {
if let error = error {
print("Error: \(error)")
}
return
}
let route = response.routes[0]
self.mapView.add((route.polyline), level: MKOverlayLevel.aboveRoads)
let rect = route.polyline.boundingMapRect
self.mapView.setRegion(MKCoordinateRegionForMapRect(rect), animated: true)
}
}
/*
directions.calculate(completionHandler: {(response: MKDirectionsResponse!, error: Error!) in
if error != nil {
print("Error \(error)")
} else {
self.displayRout(response)
var overlays = self.mapView.overlays
for route in response.routes {
self.mapView.add(route.polyline, level: MKOverlayLevel.aboveRoads)
for next in route.steps {
print(next.instructions)
}
}
}
})
}
*/
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 4.0
return renderer
}
}
//destination = MKMapItem(placemark: selectedPin!)
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController : CLLocationManagerDelegate {
// When user responds to the permission dialog
private func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
locationManager.requestLocation()
}
}
// When location information comes back (Zoom to the user's current location)
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
//****
MyPosition = location.coordinate
locationManager.stopUpdatingLocation()
let span = MKCoordinateSpanMake(0.01, 0.01)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
mapView.setRegion(region, animated: true)
}
}
// Print out the error
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Error finding location: \(error.localizedDescription)")
}
}
// Searches the location and city/state
extension ViewController: HandleMapSearch {
func dropPinZoomIn(placemark:MKPlacemark){
// cache the pin
selectedPin = placemark
// clear existing pins
mapView.removeAnnotations(mapView.annotations)
let annotation = MKPointAnnotation()
annotation.coordinate = placemark.coordinate
annotation.title = placemark.name
if let city = placemark.locality,
let state = placemark.administrativeArea {
annotation.subtitle = "\(city) \(state)"
}
mapView.addAnnotation(annotation)
let span = MKCoordinateSpanMake(0.01, 0.01)
let region = MKCoordinateRegionMake(placemark.coordinate, span)
mapView.setRegion(region, animated: true)
}
}
// Shows Pins and Car Logo
extension ViewController : MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?{
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView?.pinTintColor = UIColor.red
pinView?.canShowCallout = true
let smallSquare = CGSize(width: 30, height: 30)
let button = UIButton(frame: CGRect(origin: CGPoint.zero, size: smallSquare))
button.setBackgroundImage(UIImage(named: "Car"), for: .normal)
button.addTarget(self, action: #selector(getDirections), for: .touchUpInside)
pinView?.leftCalloutAccessoryView = button
return pinView
}
}
Have a look at below code for reference hope it helps :
1 using two locations here as source and as destination and drawing a path according to locations
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
// Do any additional setup after loading the view, typically from a nib.
let sourceLocation = CLLocationCoordinate2D(latitude: 40.759011, longitude: -73.984472)
let destinationLocation = CLLocationCoordinate2D(latitude: 40.748441, longitude: -73.985564)
// 3.
let sourcePlacemark = MKPlacemark(coordinate: sourceLocation, addressDictionary: nil)
let destinationPlacemark = MKPlacemark(coordinate: destinationLocation, addressDictionary: nil)
// 4.
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
let destinationMapItem = MKMapItem(placemark: destinationPlacemark)
// 5.
let sourceAnnotation = MKPointAnnotation()
sourceAnnotation.title = "Times Square"
if let location = sourcePlacemark.location {
sourceAnnotation.coordinate = location.coordinate
}
let destinationAnnotation = MKPointAnnotation()
destinationAnnotation.title = "Empire State Building"
if let location = destinationPlacemark.location {
destinationAnnotation.coordinate = location.coordinate
}
// 6.
self.mapView.showAnnotations([sourceAnnotation,destinationAnnotation], animated: true )
// 7.
let directionRequest = MKDirectionsRequest()
directionRequest.source = sourceMapItem
directionRequest.destination = destinationMapItem
directionRequest.transportType = .walking
// Calculate the direction
let directions = MKDirections(request: directionRequest)
// 8.
directions.calculate {
(response, error) -> Void in
guard let response = response else {
if let error = error {
print("Error: \(error)")
}
return
}
let route = response.routes[0]
self.mapView.add((route.polyline), level: MKOverlayLevel.aboveRoads)
let rect = route.polyline.boundingMapRect
self.mapView.setRegion(MKCoordinateRegionForMapRect(rect), animated: true)
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 4.0
return renderer
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Output :

Converting Parse PFGeoPoint into an annotation on the map

I am trying to convert a saved PFGeopoint objects in Parse server into an annotation but i can't seem to figure it out and i don't know what's wrong.
I tried to apply the code from this question : Converting Parse GeoPoint into a CLLocation in Swift but i still couldn't figure it out.
Here is my Code :
import UIKit
import MapKit
import CoreLocation
import Parse
class MapVC: UIViewController, MKMapViewDelegate {
fileprivate let locationManager = CLLocationManager()
fileprivate var startedLoadingPOIs = false
fileprivate var places = [Place]()
var descLocation: PFGeoPoint = PFGeoPoint()
var mapHasCenteredOnce = false
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
locationManager.requestWhenInUseAuthorization()
mapView.userTrackingMode = MKUserTrackingMode.followWithHeading
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var annotationView: MKAnnotationView?
if annotation.isKind(of: MKUserLocation.self) {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "User")
annotationView?.image = UIImage(named: "loc.png")
}
return annotationView
}
}
extension MapVC: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//1
if locations.count > 0 {
let location = locations.last!
print("Accuracy: \(location.horizontalAccuracy)")
//2
if location.horizontalAccuracy < 100 {
//3
manager.stopUpdatingLocation()
let span = MKCoordinateSpan(latitudeDelta: 0.014, longitudeDelta: 0.014)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
mapView.region = region
if !startedLoadingPOIs {
startedLoadingPOIs = true
let loader = PlacesLoader()
loader.loadPOIS(location: location, radius: 1000) { placesDict, error in
if let dict = placesDict {
let query = PFQuery(className: "posts")
if let latitude = (PFUser.current()?["location"] as AnyObject).latitude {
if let longitude = (PFUser.current()?["location"] as AnyObject).longitude {
let geoPoint = PFGeoPoint(latitude: latitude, longitude: longitude)
query.whereKey("postLocation", nearGeoPoint: geoPoint, withinKilometers: 1)
}
}
query.findObjectsInBackground { (objects: [PFObject]?, error: Error?) in
if error == nil {
for object in objects! {
let pfObject = object as PFObject
let caption = pfObject["title"] as! String
self.descLocation = object["postLocation"] as! PFGeoPoint
let latitude: CLLocationDegrees = self.descLocation.latitude
let longitude: CLLocationDegrees = self.descLocation.longitude
let location = CLLocation(latitude: latitude, longitude: longitude)
let place = Place(location: location, name: caption )
self.places.append(place)
let annotation = PlaceAnnotation(location: place.location!.coordinate, title: place.placeName)
DispatchQueue.main.async {
self.mapView.addAnnotation(annotation)
}
}
}
}
}
}
}
}
}
}
}
I just had two uanessacry lines that blocked the operation, removed them and it worked for me.
loader.loadPOIS(location: location, radius: 1000) { placesDict, error in
if let dict = placesDict {