Hi guys so what I'm trying to do is create a button that triggers the findRandomPlace() func. Its suppose to show me a random place in places array. When it gives me a random place it should draw the polyline from the source to destination (which it does) and then if I don't like that place I can click the Button again and it should show me another place (which it does), the problem is the polyline from the last place. I don't know how to remove it.
let route = response.routes[0]
self.Map.add(route.polyline, level: .aboveRoads)
The above code is what draws the polyline but im not sure what I can do to remove it.
Thanks in advance if you could pitch in any ideas.
var previousIndex:Int = 999999
func findRandomPlace() {//need an if statement to check if its near u or in the area
let randomIndex = Int(arc4random_uniform(UInt32(places.count)))
if randomIndex != previousIndex {//Makes sure next place can't be current place
previousIndex = randomIndex
Name.text = (places[randomIndex][0])
Description.text = (places[randomIndex][1])
//Draw Direction Line
let positionX:Double? = Double(places[randomIndex][2])
let positionY:Double? = Double(places[randomIndex][3])
let sourceCoordinates = manager.location?.coordinate
let destinationCoordinates = CLLocationCoordinate2DMake(positionX!, positionY!)
print(sourceCoordinates!)
let sourcePlacemark = MKPlacemark(coordinate: sourceCoordinates!)
let destinationPlacemark = MKPlacemark(coordinate: destinationCoordinates)
let sourceItem = MKMapItem(placemark: sourcePlacemark)
let destinationItem = MKMapItem(placemark: destinationPlacemark)
let directionRequest = MKDirectionsRequest()
directionRequest.source = sourceItem
directionRequest.destination = destinationItem
directionRequest.transportType = .walking
let directions = MKDirections(request: directionRequest)
directions.calculate(completionHandler: {
response, error in
//Draw Polyline and Zoom Into It
guard let response = response else {
if let error = error {
print("error")
}
return
}
let route = response.routes[0]
self.Map.add(route.polyline, level: .aboveRoads)
let rect = route.polyline.boundingMapRect
self.Map.setRegion(MKCoordinateRegionForMapRect(rect), animated: true)
})
} else {
findRandomPlace()
}
}
I figured it out myself.
I am ashamed it took so long but I'm happy I found out in the end.
self.Map.removeOverlays(self.Map.overlays)
Related
I am working on an app like Uber. I succeeded in drawing the line between the user and the driver on the map but I want also to track the driver movements, how to update the polyline according to driver moves.
Note: I have an API that I can get the current location of the driver.
let sourcePlaceMark = MKPlacemark(coordinate: sourceLocation, addressDictionary: nil)
let destinationPlaceMark = MKPlacemark(coordinate: destinationLocation, addressDictionary: nil)
let sourceMapItem = MKMapItem(placemark: sourcePlaceMark)
let destinationItem = MKMapItem(placemark: destinationPlaceMark)
let sourceAnotation = MKPointAnnotation()
sourceAnotation.title = sourceAddress
if let location = sourcePlaceMark.location {
sourceAnotation.coordinate = location.coordinate
}
let destinationAnotation = MKPointAnnotation()
destinationAnotation.title = destinationAddress
if let location = destinationPlaceMark.location {
destinationAnotation.coordinate = location.coordinate
}
mapView.showAnnotations([sourceAnotation, destinationAnotation], animated: true)
let directionRequest = MKDirections.Request()
directionRequest.source = sourceMapItem
directionRequest.destination = destinationItem
directionRequest.transportType = .automobile
let direction = MKDirections(request: directionRequest)
direction.calculate { (response, error) in
guard let response = response else {
if let error = error {
print("ERROR FOUND : \(error.localizedDescription)")
}
return
}
let route = response.routes[0]
mapView.addOverlay(route.polyline, level: MKOverlayLevel.aboveRoads)
You already have the most important part working, getting driver's location, and drawing a route to it.
Now, you can simply run a timer and periodically perform following steps:
get driver location
check if new location is different (beyond some threshold) from previous location
calculate new route with updated location
remove old route polyline overlay
add new route polyline overlay
First off, I would like to say I'm quite new to Swift. The simplest answer is probably the best in my situation.
I currently have some code that draws a route from my current location to the Grand Canyon, using the mapkit. The starting- and ending location is build in the code:
let soucrceCoordinates = locationManager.location?.coordinate
//coordinates off the grand canyon, placeholder
let destCoordinates = CLLocationCoordinate2DMake(36.1070, -112.1130)
let sourcePlacemark = MKPlacemark(coordinate: soucrceCoordinates!)
let destPlacemark = MKPlacemark(coordinate: destCoordinates)
let sourceItem = MKMapItem(placemark: sourcePlacemark)
let destItem = MKMapItem(placemark: destPlacemark)
let directionRequest = MKDirectionsRequest()
directionRequest.source = sourceItem
directionRequest.destination = destItem
directionRequest.transportType = .automobile
Now I would like to calculate the distance of this route (not as the crow flies). The preferable unit would be meters. Is there anyway to do this? Thanks in advance
You have to create an MKDirections instance as well, not just an MKDirectionsRequest and call MKDirections.calculate to calculate the navigation routes.
let sourceCoordinates = locationManager.location?.coordinate
//coordinates of the grand canyon, placeholder
let destCoordinates = CLLocationCoordinate2D(latitude: 36.1070, longitude: -112.1130)
let sourcePlacemark = MKPlacemark(coordinate: sourceCoordinates!)
let destPlacemark = MKPlacemark(coordinate: destCoordinates)
let sourceItem = MKMapItem(placemark: sourcePlacemark)
let destItem = MKMapItem(placemark: destPlacemark)
let directionRequest = MKDirectionsRequest()
directionRequest.source = sourceItem
directionRequest.destination = destItem
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
directions.calculate(completionHandler: { response, error in
guard error == nil, let response = response, let route = response.routes.first else {return}
print("Distance:\(route.distance)meters")
})
I have searched the internet but couldn't find if I can get the map image from the latitude and logitude.
Is there any api which can give me the map image .
Because I got start location and end location.
When I give the start and end location , it should give me map image with route .
Is the possible .
If I am on mapview I can manage snapshot , but here I won't have any mapview.
Any links, ideas , suggestions highly appreciated.
Regards.
I don´t know if there are any API´s available for this, but when I do this I just call the Apple Maps app and provide a latitude and longitude for my position and open up that app.
In that way the user can use the Apple Maps application to navigate and get full information about roads etc.
Here is how I call this:
func navigateWithAppleMaps(latitude: Double, longitude: Double) {
let regionDistance:CLLocationDistance = 10000
let coordinates = CLLocationCoordinate2DMake(latitude, longitude)
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)
]
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = "Start"
mapItem.openInMaps(launchOptions: options)
}
I think you have to use google developer static map api for this
https://developers.google.com/maps/documentation/static-maps/intro
You can get image from just passing latitude and longitude from following code. You can set zoom on mapview in URL.
var staticMapUrl: String = "http://maps.google.com/maps/api/staticmap?markers=color:red|\(YOUR LATITUDE HERE),\(YOUR LONGITUDE HERE)&\("zoom=16&size=400x400")&sensor=true"
var mapUrl = URL(string: staticMapUrl.addingPercentEscapes(using: String.Encoding.utf8))
var image = UIImage(data: Data(contentsOf: mapUrl))
SWIFT 5 creating two pins on map and path between them
Lets first get path between 2 points using google api:
//=== get points ===
var encodedPathPoints = "" //we'll get this from google api
let pointsUrl = "https://maps.googleapis.com/maps/api/directions/json?origin=\(location1.lat!),\(location1.long!)&destination=\(location2.lat!),\(location2.long!)&sensor=false&mode=driving&key=\(ServiceConstants.MAP_KEY)"
if Reachability.isConnectedToNetwork(){
AF.request(pointsUrl).responseJSON { response in
let json = try? JSON(data: response.data!)
if json != nil {
print("JSON map results: \(json)")
let routes = json!["routes"].arrayValue
for route in routes
{
let routeOverviewPolyline = route["overview_polyline"].dictionary
let points = routeOverviewPolyline?["points"]?.stringValue
if points != nil {
encodedPathPoints = points!
}
}
}
}
}
Once i have path between my two points let set static map image
let MAP_BASE_URL = "https://maps.googleapis.com/maps/api/staticmap?"
let MAP_IMAGE_SIZE = "size=\(2 * Int(imageView.frame.size.width))x\(2 * Int(imageView.frame.size.height))"
let MAP_MARKER = "&markers=icon:https://www.google.com|";//your icon url
let MAP_deliveryLocation = "\(location.lat!),\(location.long!)"
let MAP_WAYPOINT = "\(storeLocation.lat!),\(storeLocation.long!)"
let MAP_KEY = "&key=\(ServiceConstants.MAP_KEY)"
let MAP_STYLE = "&format=png&maptype=roadmap&style=element:geometry|color:0xf5f5f5&style=element:labels.icon|visibility:off&style=element:labels.text.fill|color:0x616161&style=element:labels.text.stroke|color:0xf5f5f5&style=feature:administrative.land_parcel|element:labels.text.fill|color:0xbdbdbd&style=feature:poi|element:geometry|color:0xeeeeee&style=feature:poi|element:labels.text.fill|color:0x757575&style=feature:poi.park|element:geometry|color:0xe5e5e5&style=feature:poi.park|element:labels.text.fill|color:0x9e9e9e&style=feature:road|element:geometry|color:0xffffff&style=feature:road.arterial|element:labels.text.fill|color:0x757575&style=feature:road.highway|element:geometry|color:0xdadada&style=feature:road.highway|element:labels.text.fill|color:0x616161&style=feature:road.local|element:labels.text.fill|color:0x9e9e9e&style=feature:transit.line|element:geometry|color:0xe5e5e5&style=feature:transit.station|element:geometry|color:0xeeeeee&style=feature:water|element:geometry|color:0xc9c9c9&style=feature:water|element:labels.text.fill|color:0x9e9e9e&size=480x360"
let PATH = "&path=color:0x11C856|weight:5|enc:\(encodedPathPoints)" //use 'enc:' if you're using encoded path just like me, you can ignore this if you're using normal lat lng points concatenated in string.
let mapStaticImgUrlStr = "\(MAP_BASE_URL)\(MAP_IMAGE_SIZE)\(PATH)¢er=\(MAP_deliveryLocation)|\(MAP_WAYPOINT)\(MAP_MARKER)\(MAP_deliveryLocation)\(MAP_MARKER)\(MAP_WAYPOINT)\(MAP_STYLE)\(MAP_KEY)"
let url = URL(string: mapStaticImgUrlStr.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
do {
let data = try NSData(contentsOf: url3!, options: NSData.ReadingOptions())
imageView.image = UIImage(data: data as Data)
} catch {
imageView.image = UIImage()
}
I have a set of polylines defining a route. Is there some way that I can use mapkit to calculate the expected travel time along this route? If not in MapKit, then in Google Maps or any other maps api?
let sourcePlaceMark = MKPlacemark(coordinate: fromCoordinate, addressDictionary: nil)
let destPlaceMark = MKPlacemark(coordinate: toCoordinate, addressDictionary: nil)
let from = MKMapItem(placemark: sourcePlaceMark)
let to = MKMapItem(placemark: destPlaceMark)
print("caculateDirections ")
let request = MKDirectionsRequest()
request.source = from
request.destination = to
request.transportType = .Automobile
let directions = MKDirections(request: request)
directions.calculateDirectionsWithCompletionHandler { (response, error) -> Void in
if let response = response {
// Here you can get the routes and draw it on the map
let routeSeconds = response.routes.first!.expectedTravelTime
let routeDistance = response.routes.first!.distance
}
}
my question is about the mapkit in the iOS SDK. Is it possible to draw routes from a location to another? Is there any built-in API? If no, how can I do?
Thanks
In iOS 7, there is an API for getting the direction from a location to another called MKDirection. You can call -[MKDirection calculateDirectionsWithCompletionHandler:] method for that. This method's argument is MKDirectionsHandler block which contains the MKDirectionsResponse. The MKDirectionsResponse contains the routes data which is array of MKRoute. In each MKRoute there is a polyline (MKPolyline) which you can add these polyline as overlays to the MKMapView.
MKDirections allows you to find routes between two locations and MapKit allows you to add this routes as an overlay.
func drawRoutes(sourceLocation:CLLocationCoordinate2D ,
destinationLocation:CLLocationCoordinate2D)
{
let sourcePlacemark = MKPlacemark(coordinate: sourceLocation, addressDictionary: nil)
let destinationPlacemark = MKPlacemark(coordinate: destinationLocation, addressDictionary: nil)
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
let destinationMapItem = MKMapItem(placemark: destinationPlacemark)
let directionRequest = MKDirectionsRequest()
directionRequest.source = sourceMapItem
directionRequest.destination = destinationMapItem
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
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)
}
}