iOS - Generate map image for the latitude and longitude - ios

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)&center=\(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()
}

Related

Can i change pointer(MGLPointAnnotation) image in mapbox swift

Hello I'm working on Mapbox I getting data from API and I am showing that data on the map but I want to show the default pointer to the image I'm getting from API can anybody help me
for locationStruct in self.locations
{
let annotation = MGLPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: Double(locationStruct.latitude) ?? 0.0, longitude: Double(locationStruct.longitude) ?? 0.0)
annotation.title = locationStruct.name
//Getting image
let url = URL(string:"http://app.freewayfinder.com/assets/uploads/spots/\(locationStruct.img)")
//Convert image in to data
let data = (try? Data(contentsOf: url!))!
self.mapview.addAnnotation(annotation)
}
this is code where I'm showing pointer's in map

What is wrong with this code? When it opens up in the native maps app it takes me to a random location

Followed a video tutorial. When i build this app and hit the directions button it takes me to a random area instead of the coordinates provided. I am a beginner. Also, is there a way to pass in the locations address instead of coordinates, or should i just use the coordinates. Thanks for any responses. I am using Swift 5 in xCode 10. I changed the coordinate for privacy.
#IBAction func directionsClinic(_ sender: UIButton) {
let latitude:CLLocationDegrees = 38.465492
let longitude:CLLocationDegrees = 91.338905
let regionDistance:CLLocationDistance = 1000;
let coordinates = CLLocationCoordinate2DMake(latitude,
longitude)
let regionSpan = MKCoordinateRegion(center: coordinates,
latitudinalMeters: regionDistance, longitudinalMeters:
regionDistance)
let options = [MKLaunchOptionsMapCenterKey:
NSValue(mkCoordinate:regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan:
regionSpan.span)]
let placemark = MKPlacemark(coordinate: coordinates)
let mapItem = MKMapItem(placemark:placemark)
mapItem.openInMaps(launchOptions: options)
}
i have just tried a few different youtube videos guides, but most were a year+ old and im not sure if the code has changed
Expected the location of the coordinates to show up in the native iphone maps app, instead it was taking me to a place on the other side of the globe.
You can try this to open with a specific address:
let baseUrl: String = "http://maps.apple.com/?q="
let encodedName = theAddress.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed) ?? ""
let finalUrl = baseUrl + encodedName
if let url = NSURL(string: finalUrl) {
UIApplication.shared.open(url)
}
The Maps app will intercept the request and open the app.

How do I remove this Polyline of the map route?

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)

finding distance of a Autocomplete resulted location from current location IOS

I m working on application like Uber and Careem. When user searches for a location using Google Places Autocomplete API, I want to show the distance as well along with the name of the autocomplete resulted place like Uber and Careem does this.
Plz have a look on this image for further clarification
Edit:
where cuGMS is array of GMSAutocompletePrediction
let cuGMS = self.resultsArray[indexPath.row]
let placesClient = GMSPlacesClient()
placesClient.lookUpPlaceID(cuGMS.placeID!, callback: { (response , error) in
print("response \(response)")
if(error == nil)
{
let coor = response?.coordinate
let lat = coor?.latitude
let lon = coor?.longitude
}
else
{
}
})
try this
let loc1:CLLocation = CLLocation.init(latitude: 30.0000, longitude:29.2545)
let loc2:CLLocation = CLLocation.init(latitude: 28.02002, longitude:27.00021)
let dis = loc1.distance(from: loc2)

Open Apple Maps programmatically

I want to open the Apple Maps App in my own Swift App, but I have only zipcode, city & street. I have NO Coordinates. I researched a lot, but there were only ways with using coordination information.
You can just pass your address information as URL parameters in the URL with which you open the maps app. Say you wanted the maps app to open centered on The White House.
UIApplication.sharedApplication().openURL(NSURL(string: "http://maps.apple.com/?address=1600,PennsylvaniaAve.,20500")!)
The Maps app opens with the ugly query string in the search field but it shows the right location. Note that the city and state are absent from the search query, it's just the street address and the zip.
A potentially better approach, depending on your needs, would be to get the CLLocation of the address info you have using CLGeocoder.
let geocoder = CLGeocoder()
let str = "1600 Pennsylvania Ave. 20500" // A string of the address info you already have
geocoder.geocodeAddressString(str) { (placemarksOptional, error) -> Void in
if let placemarks = placemarksOptional {
print("placemark| \(placemarks.first)")
if let location = placemarks.first?.location {
let query = "?ll=\(location.coordinate.latitude),\(location.coordinate.longitude)"
let path = "http://maps.apple.com/" + query
if let url = NSURL(string: path) {
UIApplication.sharedApplication().openURL(url)
} else {
// Could not construct url. Handle error.
}
} else {
// Could not get a location from the geocode request. Handle error.
}
} else {
// Didn't get any placemarks. Handle error.
}
}
Swift 4 and above
Use this version to get the coordinates for the Address, there is also a way to open it directly with the address, but that is susceptible to errors
import CoreLocation
let myAddress = "One,Apple+Park+Way,Cupertino,CA,95014,USA"
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(myAddress) { (placemarks, error) in
guard let placemarks = placemarks?.first else { return }
let location = placemarks.location?.coordinate ?? CLLocationCoordinate2D()
guard let url = URL(string:"http://maps.apple.com/?daddr=\(location.latitude),\(location.longitude)") else { return }
UIApplication.shared.open(url)
}
Apple has a Documentation about the Map URL Scheme. Look here: https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html#//apple_ref/doc/uid/TP40007899-CH5-SW1
Using Swift 4 and Xcode 9
At the top:
import CoreLocation
Then:
let geocoder = CLGeocoder()
let locationString = "London"
geocoder.geocodeAddressString(locationString) { (placemarks, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let location = placemarks?.first?.location {
let query = "?ll=\(location.coordinate.latitude),\(location.coordinate.longitude)"
let urlString = "http://maps.apple.com/".appending(query)
if let url = URL(string: urlString) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}
}
Swift 5: Directly open maps app
///Opens text address in maps
static func openAddressInMap(address: String?){
guard let address = address else {return}
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(address) { (placemarks, error) in
guard let placemarks = placemarks?.first else {
return
}
let location = placemarks.location?.coordinate
if let lat = location?.latitude, let lon = location?.longitude{
let destination = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: lat, longitude: lon)))
destination.name = address
MKMapItem.openMaps(
with: [destination]
)
}
}
}

Resources