I try to add a Polyline to the map, but it is not visible.
locationManager.startUpdatingLocation()
guard let locValue: CLLocationCoordinate2D =
locationManager.location?.coordinate else { return }
Map.setCenter(locValue, animated: true)
if !locations.contains(where: {$0.latitude == locValue.latitude && $0.longitude == locValue.longitude}) {
locations.append(locValue)
NSLog("Add: %f %f -> Count: %i", locValue.latitude, locValue.longitude, locations.count)
let polyline = MKPolyline(coordinates: &locations, count: locations.count)
Map.addOverlay(mapView(Map, rendererFor: polyline).overlay)
}
"My" mapView function:
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let polyLine = overlay
let polyLineRenderer = MKPolylineRenderer(overlay: polyLine)
polyLineRenderer.strokeColor = UIColor.red
polyLineRenderer.lineWidth = 5.0
return polyLineRenderer
}
You can try
self.map.delegate = self
let polyline = MKPolyline(coordinates:locations, count: locations.count)
self.map.addOverlay(routeLine)
Related
I am struggling to try and Highlight the road between 2 points using MapKit. All I don't want directions i just want to try and Highlight the road between these two points.
My code is:
import UIKit
import MapKit
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
struct Points {
var name: String
var lattitude: CLLocationDegrees
var longtitude: CLLocationDegrees
}
override func viewDidLoad() {
super.viewDidLoad()
let points = [
Points(name: "Point 1", lattitude: 52.100525, longtitude: -9.623071),
Points(name: "Point 2", lattitude: 52.07241, longtitude: -9.575299)
]
fetchPointsOnMap(points)
}
func fetchPointsOnMap(_ points: [Points]) {
for points in points {
let annotations = MKPointAnnotation()
annotations.title = points.name
annotations.coordinate = CLLocationCoordinate2D(latitude:
points.lattitude, longitude: points.longtitude)
mapView.addAnnotation(annotations)
}
}
}`
You can draw a line:
directionsRequest.transportType = MKDirectionsTransportType.automobile
//Draw polyline by using MKRoute so it follows the street roads...
for (k, item) in arrayarrayPlacemarks.enumerated() {
if k < (arrayarrayPlacemarks.count - 1) {
directionsRequest.source = item
directionsRequest.destination = arrayarrayPlacemarks[k+1]
let directions = MKDirections(request: directionsRequest)
directions.calculate { (response:MKDirections.Response!, error: Error!) -> Void in
if error == nil {
self.locRoute = response.routes[0] as? MKRoute
let geodesic:MKPolyline = self.locRoute!.polyline
self.mapView.addOverlay(geodesic)
}
}
}
}
Delegate:
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay.isKind(of: MKPolyline.self){
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.fillColor = UIColor.blue
polylineRenderer.strokeColor = UIColor.blue
polylineRenderer.lineWidth = 2
return polylineRenderer
}
return MKOverlayRenderer(overlay: overlay)
}
we are writing a code for navigation at swift. We implemented local database and downloaded our data into the app for offline navigation. But we have a problem. When we drawing road, its connecting beginning and endpoints
override func viewDidLoad() {
super.viewDidLoad()
CizimVeriler();
}
func CizimVeriler(){
var annotationCizim = getMapCizim()
var polyline2 : MKPolyline = MKPolyline()
var points: [CLLocationCoordinate2D] = [CLLocationCoordinate2D]()
for annotation in annotationCizim {
points.append(annotation.coordinate)
}
polyline2 = MKPolyline(coordinates: &points, count: points.count)
mapView.add(polyline2)
}
func getMapCizim() -> [Station] {
var annotationCizim:Array = [Station]()
annotationCizim.removeAll()
var stationCizim: NSArray?
do {
let secim = UserDefaults.standard.value(forKey: "RotaId") as! Int;
let filtrele = try self.database.prepare(self.RotaKoordinatTable.where(RotaKoorId == secim))
for rota in filtrele {
let x1 = Double(rota[(self.KoorX)])
let y1 = Double(rota[(self.KoorY)])
let annotation = Station(latitude: y1!, longitude: x1!)
annotation.title = "S1" as? String
annotationCizim.append(annotation)
}
} catch {
print(error)
}
return annotationCizim
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolyline {
let polyLineRenderer = MKPolylineRenderer(polyline: overlay as! MKPolyline)
polyLineRenderer.strokeColor = #colorLiteral(red: 0.8961519599, green: 0.1830670238, blue: 0.06986772269, alpha: 1)
polyLineRenderer.lineWidth = 1
return polyLineRenderer
}
return MKOverlayRenderer()
}
I want to give name to the green and right pin annotation above.
I see a video tutorial, and he can give name to the annotation by using annotation.title = but I don't know why I can get the name correctly show in my MapKit.
here is the code I use
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapKit: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapKit.delegate = self
let bakrieTowerCoordinate = CLLocation(latitude: -6.23860724759536, longitude: 106.789429759178)
let GBKCoordinate = CLLocation(latitude: -6.23864960081552, longitude: 106.789627819772)
let locationGBK : CLLocationCoordinate2D = CLLocationCoordinate2DMake(-6.23864960081552, 106.789627819772)
let locationBakrieToweer : CLLocationCoordinate2D = CLLocationCoordinate2DMake(-6.23860724759536, 106.789429759178)
let annotation = MKPointAnnotation()
annotation.coordinate = locationGBK
annotation.title = "GBK"
annotation.subtitle = "Stadion"
mapKit.addAnnotation(annotation)
let annotation2 = MKPointAnnotation()
annotation2.coordinate = locationBakrieToweer
annotation2.title = "Bakrie Tower"
annotation2.subtitle = "Office"
mapKit.addAnnotation(annotation2)
zoomMapOn(location1: GBKCoordinate, location2: bakrieTowerCoordinate)
}
func zoomMapOn(location1: CLLocation, location2: CLLocation) {
let distanceOf2CoordinateInMeters = location1.distance(from: location2)
let radius = distanceOf2CoordinateInMeters * 3
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location1.coordinate, radius, radius)
mapKit.setRegion(coordinateRegion, animated: true)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
guard let locationName = annotation.title else {return nil}
if locationName == "GBK" {
annotationView.pinTintColor = UIColor.green
} else if locationName == "Bakrie Tower" {
annotationView.pinTintColor = UIColor.red
}
return annotationView
}
}
Add this code to your view controller -
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapKit: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapKit.delegate = self
let bakrieTowerCoordinate = CLLocation(latitude: -6.23860724759536, longitude: 106.789429759178)
let GBKCoordinate = CLLocation(latitude: -6.23864960081552, longitude: 106.789627819772)
let locationGBK : CLLocationCoordinate2D = CLLocationCoordinate2DMake(-6.23864960081552, 106.789627819772)
let locationBakrieToweer : CLLocationCoordinate2D = CLLocationCoordinate2DMake(-6.23860724759536, 106.789429759178)
let annotation = MKPointAnnotation()
annotation.coordinate = locationGBK
annotation.title = "GBK"
annotation.subtitle = "Stadion"
mapKit.addAnnotation(annotation)
let annotation2 = MKPointAnnotation()
annotation2.coordinate = locationBakrieToweer
annotation2.title = "Bakrie Tower"
annotation2.subtitle = "Office"
mapKit.addAnnotation(annotation2)
zoomMapOn(location1: GBKCoordinate, location2: bakrieTowerCoordinate)
}
func zoomMapOn(location1: CLLocation, location2: CLLocation) {
let distanceOf2CoordinateInMeters = location1.distance(from: location2)
let radius = distanceOf2CoordinateInMeters * 3
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location1.coordinate, radius, radius)
mapKit.setRegion(coordinateRegion, animated: true)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
guard let locationName = annotation.title else {return nil}
if locationName == "GBK" {
annotationView.canShowCallout = true
} else if locationName == "Bakrie Tower" {
annotationView.pinTintColor = UIColor.red
}
annotationView.canShowCallout = true // Add this line in your code
return annotationView
}
}
When you tap on the pin, it will show the text, Like -
Just Add
annotationView.canShowCallout = true inside your mapView(_ mapView:). Thank you.
You need to set this property in mapView(_:viewFor:) before returning your annotationView:
annotationView.canShowCallout = true
Now when you tap the pin, it will show your text.
I have made an project and followed a tutorial on the internet. It shows annotations and has a custom callout view.I have added a label with a button feature which is shown in my screenshot. I now would like some help to get the feature to start maps app from my project. I have made comments in the project which shows what i have done and what i need help with
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate, UISearchBarDelegate {
#IBOutlet var mapView: MKMapView!
#IBOutlet var searchBarMap: UISearchBar!
var coordinates: [[Double]]!
var names:[String]!
var addresses:[String]!
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation
{
return nil
}
if annotation is MKPointAnnotation
{
return nil
}
var annotationView = self.mapView.dequeueReusableAnnotationView(withIdentifier: "Pin")
if annotationView == nil{
annotationView = AnnotationView(annotation: annotation, reuseIdentifier: "Pin")
annotationView?.canShowCallout = false
}else{
annotationView?.annotation = annotation
}
annotationView?.image = UIImage(named: "parking-sign")
return annotationView
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
searchBarMap.delegate = self
coordinates = [[57.638486,18.299698],[57.636859,18.300468],[57.634807, 18.293389]]// Latitude,Longitude
names = ["Österport","Åhléns","Söderport/busstation"]
addresses = ["regler: p-skiva 2 timmar 9-18, oftast få platser lediga","stor med två våningar, övre plan oftast väl fylld och komplicerade parkeringsrutor","Nära om du vill till adelsgatan"]
self.mapView.delegate = self
for i in 0...2
{
let coordinate = coordinates[i]
let point = StarbucksAnnotation(coordinate: CLLocationCoordinate2D(latitude: coordinate[0] , longitude: coordinate[1] ))
point.name = names[i]
point.address = addresses[i]
self.mapView.addAnnotation(point)
}
let region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 57.630615, longitude: 18.303023), span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))
self.mapView.setRegion(region, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func mapView(_ mapView: MKMapView,
didSelect view: MKAnnotationView)
{
// 1
if view.annotation is MKUserLocation
{
return
}
if view.annotation is MKPointAnnotation
{
return
}
let starbucksAnnotation = view.annotation as! StarbucksAnnotation
let views = Bundle.main.loadNibNamed("CustomCalloutView", owner: nil, options: nil)
let calloutView = views?[0] as! CustomCalloutView
calloutView.starbucksName.text = starbucksAnnotation.name
calloutView.starbucksAddress.text = starbucksAnnotation.address
// declaring label as a button
let button = UIButton(frame: calloutView.directions.frame)
button.addTarget(self, action: #selector(ViewController.openInMaps(sender:)), for: .touchUpInside)
calloutView.addSubview(button)
calloutView.center = CGPoint(x: view.bounds.size.width / 2, y: -calloutView.bounds.size.height*0.52)
view.addSubview(calloutView)
mapView.setCenter((view.annotation?.coordinate)!, animated: true)
}
func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
if view.isKind(of: AnnotationView.self)
{
for subview in view.subviews
{
subview.removeFromSuperview()
}
}
}
//I want to know what i should fill this function with to open maps and give me directions
func openInMaps(sender: UIButton)
{
//This is what i tested so far
let coordinates1 = coordinates
let point = StarbucksAnnotation(coordinate: CLLocationCoordinate2D(latitude: coordinates1[0] , longitude: coordinates1[1] ))
let regionDistance:CLLocationDistance = 10000
let regionSpan = MKCoordinateRegionMakeWithDistance(point, regionDistance, regionDistance)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)
]
let placemark = MKPlacemark(coordinate: point, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = "destination"
mapItem.openInMaps(launchOptions: options)
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBarMap.resignFirstResponder()
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(searchBar.text!) { (placemarks:[CLPlacemark]?, error:Error?) in
if error == nil {
let placemark = placemarks?.first
let anno = MKPointAnnotation()
anno.coordinate = (placemark?.location?.coordinate)!
anno.title = self.searchBarMap.text!
self.mapView.addAnnotation(anno)
self.mapView.selectAnnotation(anno, animated: true)
}else{
print(error?.localizedDescription ?? "error")
}
}
}
}
I want to add a overlay path among multiple coordinates in mapview. I tried like below code, but it shows a error of "cannot invoke 'map' with an argument list of type ((CLLocation) -> CLLocationCoordinate2D)". Please let me know how can i fix this ?
My ViewController.swift file
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate{
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
//For Location 1
let location1 = CLLocationCoordinate2D(
latitude: 51.481188400000010000,
longitude: -0.190209099999947280
)
let annotation1 = MKPointAnnotation()
annotation1.coordinate = location1;
annotation1.title = "Chelsea"
annotation1.subtitle = "Chelsea"
let span = MKCoordinateSpanMake(0.15, 0.15)
let region1 = MKCoordinateRegion(center: location1, span: span)
mapView.setRegion(region1, animated: true)
mapView.addAnnotation(annotation1)
//For Location 2
let location2 = CLLocationCoordinate2D(
latitude: 51.554947700000010000,
longitude: -0.108558899999934510
)
let annotation2 = MKPointAnnotation()
annotation2.coordinate = location2;
annotation2.title = "Arsenal"
annotation2.subtitle = "Arsenal"
let region2 = MKCoordinateRegion(center: location1, span: span)
mapView.setRegion(region2, animated: true)
mapView.addAnnotation(annotation2)
var locations = [CLLocation(latitude: 51.481188400000010000, longitude: -0.190209099999947280), CLLocation(latitude: 51.554947700000010000,longitude: -0.108558899999934510)]
//This line shows error
var coordinates = locations.map({(location: CLLocation) -> CLLocationCoordinate2D in return location.coordinate})
var polyline = MKPolyline(coordinates: &coordinates, count: locations.count)
mapView.addOverlay(polyline)
}
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKPolyline {
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.blueColor()
polylineRenderer.lineWidth = 5
return polylineRenderer
}
return nil
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This should work:
var coordinates = locations.map {
location in
return location.coordinate
}
One-liner:
var coordinates = locations.map { $0.coordinate }
The problem with your code was that locations is a variable of type [CLLocation!] (note the exclamation mark here), but you are declaring its elements as CLLocation (without the !) in the closure:
(location: CLLocation) -> CLLocationCoordinate2D