Como abrir o aplicativo de mapas de forma programática com coordenadas em swift?

107

Tenho latitude e longitude que desejo abrir em meu aplicativo de mapa. Tentei este código AQUI .

    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 função abre mapas com sucesso, mas não mostra nenhum pino. Também mostra a localização do usuário que eu não quero. Quero apenas um alfinete no mapa para a latitude e longitude fornecidas.

Dharmesh Kheni
fonte
2
Este código se destina a mostrar instruções de direção desde a localização do usuário até o destino. Para mostrar apenas um único destino, use MKLaunchOptionsMapCenterKey e um único item do mapa. Consulte stackoverflow.com/questions/28427557/… .
Obrigado pela sugestão Anna.
Dharmesh Kheni

Respostas:

157

Este código está funcionando bem para mim.

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
fonte
Você pode confirmar se a opção MKLaunchOptionsMapSpanKey tem o efeito desejado? Não importa o valor que eu use para CLLocationDistance, o zoom do mapa é bem próximo.
pedra de
2
Parece que o MKLaunchOptionsMapSpanKeyé ignorado quando um ou mais MKMapItemsão adicionados ao mapa: stackoverflow.com/a/32484331/422288
Eneko Alonso
4
Não se esqueça: import MapKit
jobima
5
Só queria salientar que é "latitude" e "longitude", não "latitude" e "longitude", embora "tute" seja mais engraçado
Chris
2
se o usuário removeu o aplicativo de mapas, como podemos verificar nesse caso ??
Amrit Tiwari
67

Se você deseja apenas fornecer instruções de direção ao usuário, esta é a sintaxe Swift mais recente em sua forma mais simples:

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
fonte
1
Isso funcionou bem para mim, exceto que a chave e o valor são invertidos nas opções de inicialização. Deveria sermapItem.openInMapsWithLaunchOptions([MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])
Keith
1
Certifique-se de adicionar o MapKit de importação à parte superior do arquivo para resolver os erros.
Joseph Astrahan
2
Também no swift 3, a última linha agora é ... mapItem.openInMaps (launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])
Joseph Astrahan
45

Você poderia chamar a função de classe de MKMapItempassagem de itens lá, ela usa apenas o primeiro e o último para origem / destino de forma apropriada, se você quiser passar mais de dois itens.

Swift 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])

ou usando extensão:

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
fonte
oi dimpiax! Obrigado pela sua resposta, não testei, mas parece estar bem. É possível enviar vários waypoints? Quão!? Você pode por favor me ajudar.
Frade
@Frade ei, com o MapKit você não pode ver: developer.apple.com/documentation/mapkit/mkmapitem/… Mas você pode conseguir usando o Google Maps.
dimpiax
36

A MKMapItemabordagem acima funciona muito bem se você deseja controle granular sobre as informações que são exibidas no Maps.

Caso contrário, o código abaixo também funciona bem:

// 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)!)

No entanto, o código acima não permite que você envie um nome personalizado do local. Em vez disso, ele mostrará o endereço.

O código acima também permite que você navegue a partir de qualquer coordenada de origem, o que não sei se você pode fazer com a abordagem MKMapItem.

Daniel Saidi
fonte
4
Se você deixar "saddr =" em branco, o aplicativo definirá "sua localização" como padrão. Algo como "http: // maps.apple.com/maps?saddr=&daddr=(to.latitude),(to.longitude)"
Mariano Zorrilla
instruções não disponíveis
Marlhex
11

Isso funciona como um encanto para mim

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
fonte
1
Isso não está mais funcionando comigo. Acabei com "Nenhuma direção disponível."
Hemang
3

Você pode usar o código abaixo para mostrar o PIN em lat, long in no mapa da 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
fonte
1

Se o que você deseja é algo simples, sem importar nenhum framework, você pode apenas criar um URL: https://maps.apple.com/?ll=\(latitude),\(longitude)

É semelhante à resposta de @saniel-saidi, mas esta abre apenas o mapa com a localização enviada, não a coisa de navegação

rgkobashi
fonte
apenas remove () em torno das coordenadas, não as encontra com elas.
Boris Gafurov
1

Eu sei que todas as respostas estão completas, mas aqui eu tenho uma resposta que é mais fácil de copiar e colar e também dá ao usuário opções de roteamento com Apple Maps, Google Map e Waze.

Trabalhando com Swift 5+

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

Pode ajudar alguém ...

Alfi
fonte
0

Atualização da resposta prática de Daniel Saidi . Este exemplo é para informar apenas as coordenadas de destino. Os mapas obterão como origem a posição atual do usuário.

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