¿Cómo abrir la aplicación de mapas mediante programación con coordenadas en Swift?

107

Tengo latitud y longitud que quiero abrir en mi aplicación de mapas. Probé este código de AQUÍ .

    func goToMap(){

    var lat1 : NSString = self.venueLat
    var lng1 : NSString = self.venueLng

    var latitude:CLLocationDegrees =  lat1.doubleValue
    var longitude:CLLocationDegrees =  lng1.doubleValue

    var coordinate = CLLocationCoordinate2DMake(latitude, longitude)

    var placemark : MKPlacemark = MKPlacemark(coordinate: coordinate, addressDictionary:nil)

    var mapItem:MKMapItem = MKMapItem(placemark: placemark)

    mapItem.name = "Target location"

    let launchOptions:NSDictionary = NSDictionary(object: MKLaunchOptionsDirectionsModeDriving, forKey: MKLaunchOptionsDirectionsModeKey)

    var currentLocationMapItem:MKMapItem = MKMapItem.mapItemForCurrentLocation()

    MKMapItem.openMapsWithItems([currentLocationMapItem, mapItem], launchOptions: launchOptions)

}

Esta función abre mapas con éxito pero no muestra ningún pin. También muestra la ubicación del usuario que no quiero. Solo quiero un pin en el mapa para la latitud y longitud proporcionadas.

Dharmesh Kheni
fuente
2
Este código está destinado a mostrar direcciones de conducción desde la ubicación del usuario hasta el destino. Para mostrar un solo objetivo, use MKLaunchOptionsMapCenterKey y un solo elemento de mapa. Consulte stackoverflow.com/questions/28427557/… .
Gracias por la sugerencia Anna.
Dharmesh Kheni

Respuestas:

157

Este código funciona bien para mí.

func openMapForPlace() {

    let lat1 : NSString = self.venueLat
    let lng1 : NSString = self.venueLng

    let latitude:CLLocationDegrees =  lat1.doubleValue
    let longitude:CLLocationDegrees =  lng1.doubleValue

    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 = "\(self.venueName)"
    mapItem.openInMapsWithLaunchOptions(options)

}

Para swift 3.0:

import UIKit
import MapKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        openMapForPlace()
    }

    func openMapForPlace() {

        let latitude: CLLocationDegrees = 37.2
        let longitude: CLLocationDegrees = 22.9

        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 = "Place Name"
        mapItem.openInMaps(launchOptions: options)
    }
}
Dharmesh Kheni
fuente
¿Puede confirmar que la opción MKLaunchOptionsMapSpanKey tiene el efecto deseado? Independientemente del valor que use para CLLocationDistance, el mapa se acerca bastante.
piedra
2
Parece que MKLaunchOptionsMapSpanKeyse ignora cuando MKMapItemse agregan uno o más al mapa: stackoverflow.com/a/32484331/422288
Eneko Alonso
4
No olvide: importar MapKit
jobima
5
Solo quería señalar que es "latitud" y "longitud", no "latitud" y "longitud", aunque "tute" es más divertido
Chris
2
si el usuario ha eliminado la aplicación de mapas, ¿cómo podemos verificar ese caso?
Amrit Tiwari
67

Si solo desea dar instrucciones de manejo al usuario, aquí está la última sintaxis de Swift en su forma más simple:

let coordinate = CLLocationCoordinate2DMake(theLatitude,theLongitude)
let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: coordinate, addressDictionary:nil))
mapItem.name = "Target location"
mapItem.openInMaps(launchOptions: [MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving])
Joe C
fuente
1
Esto funcionó bien para mí, excepto que la clave y el valor están invertidos en las opciones de inicio. Debería sermapItem.openInMapsWithLaunchOptions([MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])
Keith
1
Asegúrese de agregar Import MapKit en la parte superior del archivo para resolver errores.
Joseph Astrahan
2
También en Swift 3 la última línea ahora es ... mapItem.openInMaps (launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])
Joseph Astrahan
45

Puede llamar a la función de clase de MKMapItempasar elementos allí, usa solo el primero y el último para origen / destino de manera adecuada, si desea pasar más de dos elementos.

Rápido 5, 4

let source = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: lat, longitude: lng)))
source.name = "Source"

let destination = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: lat, longitude: lng)))
destination.name = "Destination"

MKMapItem.openMaps(with: [source, destination], launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])

o usando la extensión:

extension MKMapItem {
  convenience init(coordinate: CLLocationCoordinate2D, name: String) {
    self.init(placemark: .init(coordinate: coordinate))
    self.name = name
  }
}

let source = MKMapItem(coordinate: .init(latitude: lat, longitude: lng), name: "Source")
let destination = MKMapItem(coordinate: .init(latitude: lat, longitude: lng), name: "Destination")

MKMapItem.openMaps(
  with: [source, destination], 
  launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])
dimpiax
fuente
hola dimpiax! Gracias por tu respuesta, no lo probé pero parece bastante bueno. ¿Es posible enviar varios waypoints? ¿¡Cómo!? Podrías ayudarme.
Frade
@Frade oye, con MapKit no puedes, consulta: developer.apple.com/documentation/mapkit/mkmapitem/… Pero puedes lograrlo usando Google Maps.
dimpiax
36

El MKMapItemenfoque anterior funciona muy bien si desea un control granular sobre la información que se muestra en Maps.

De lo contrario, el siguiente código también funciona muy bien:

// Open and show coordinate
let url = "http://maps.apple.com/maps?saddr=\(coord.latitude),\(coord.longitude)"
UIApplication.shared.openURL(URL(string:url)!)

// Navigate from one coordinate to another
let url = "http://maps.apple.com/maps?saddr=\(from.latitude),\(from.longitude)&daddr=\(to.latitude),\(to.longitude)"
UIApplication.shared.openURL(URL(string:url)!)

Sin embargo, el código anterior no le permite enviar un nombre personalizado del lugar. En cambio, mostrará la dirección.

El código anterior también le permite navegar desde cualquier coordenada de origen, lo que no sé si puede hacer con el enfoque MKMapItem.

Daniel Saidi
fuente
4
Si deja "saddr =" en blanco, la aplicación establecerá "su ubicación" como predeterminada. Algo como "http: // maps.apple.com/maps?saddr=&daddr=(to.latitude),(to.longitude)"
Mariano Zorrilla
direcciones no disponibles
Marlhex
11

Esto funciona como un encanto para mi

let coordinate = CLLocationCoordinate2DMake(theLatitude, theLongitude)
let region = MKCoordinateRegionMake(coordinate, MKCoordinateSpanMake(0.01, 0.02))
let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
let options = [
    MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: region.center),
    MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: region.span)]
mapItem.name = theLocationName
mapItem.openInMaps(launchOptions: options)
Wayne Huang
fuente
1
Esto ya no me funciona. Terminé con "No hay direcciones disponibles".
Hemang
3

Puede usar el siguiente código para mostrar el PIN en lat, long in en el mapa de Apple.

let coordinates = CLLocationCoordinate2DMake(-37.848854,144.990295)

let regionSpan =   MKCoordinateRegionMakeWithDistance(coordinates, 1000, 1000)

let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)

let mapItem = MKMapItem(placemark: placemark)

mapItem.name =Desired place”

mapItem.openInMaps(launchOptions:[
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center)
] as [String : Any])
Malik 007
fuente
1

Si lo que desea es algo simple sin importar ningún marco, simplemente puede crear una URL: https://maps.apple.com/?ll=\(latitude),\(longitude)

Es similar a la respuesta de @ saniel-saidi, pero esta abre solo el mapa con la ubicación enviada, no la navegación.

rgkobashi
fuente
simplemente elimina () alrededor de las coordenadas, no lo encuentra con ellas.
Boris Gafurov
1

Sé que todas las respuestas están completas, pero aquí obtuve una respuesta que es más fácil de copiar y pegar y también le brinda al usuario opciones para enrutar con Apple Maps, Google Map y Waze.

Trabajar con Swift 5+

https://stackoverflow.com/a/60930491/6449292

Podría ayudar a alguien ...

Alfi
fuente
0

Actualización de la respuesta práctica de Daniel Saidi . Este ejemplo es para decir solo las coordenadas de destino. Los mapas obtendrán como origen la posición actual del usuario.

let url = URL(string: "http://maps.apple.com/maps?saddr=&daddr=\(lat),\(lon)")
UIApplication.shared.open(url!)
Nicola Mingotti
fuente