Comment ouvrir une application de cartes par programme avec des coordonnées en Swift?

107

J'ai la latitude et la longitude que je souhaite ouvrir dans mon application cartographique. J'ai essayé ce code ICI .

    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)

}

Cette fonction ouvre les cartes avec succès mais ne montre aucune épingle. Il montre également l'emplacement de l'utilisateur que je ne veux pas. Je veux seulement une épingle sur la carte pour la latitude et la longitude fournies.

Dharmesh Kheni
la source
2
Ce code est destiné à afficher les itinéraires routiers entre l'emplacement de l'utilisateur et la cible. Pour n'afficher qu'une seule cible, utilisez MKLaunchOptionsMapCenterKey et un seul élément de carte. Voir stackoverflow.com/questions/28427557/… .
Merci pour la suggestion Anna.
Dharmesh Kheni

Réponses:

157

Ce code fonctionne très bien pour moi.

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)

}

Pour 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
la source
Pouvez-vous confirmer que l'option MKLaunchOptionsMapSpanKey a l'effet souhaité? Quelle que soit la valeur que j'utilise pour CLLocationDistance, la carte est agrandie assez étroitement.
pierre
2
Il semble que le MKLaunchOptionsMapSpanKeysoit ignoré lorsqu'un ou plusieurs MKMapItemsont ajoutés à la carte: stackoverflow.com/a/32484331/422288
Eneko Alonso
4
N'oubliez pas: import MapKit
jobima
5
Je voulais juste souligner que c'est "latitude" et "longitude" et non "latitute" et "longitute" bien que "tute" soit plus drôle
Chris
2
si l'utilisateur a supprimé l'application de cartes que comment pouvons-nous vérifier ce cas ???
Amrit Tiwari
67

Si vous souhaitez simplement donner à l'utilisateur des indications routières, voici la dernière syntaxe Swift dans sa forme la plus 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
la source
1
Cela a bien fonctionné pour moi, sauf que la clé et la valeur sont inversées dans les options de lancement. Devrait êtremapItem.openInMapsWithLaunchOptions([MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])
Keith
1
Assurez-vous d'ajouter Import MapKit en haut du fichier pour résoudre les erreurs.
Joseph Astrahan
2
Aussi dans Swift 3, la dernière ligne est maintenant ... mapItem.openInMaps (launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])
Joseph Astrahan
45

Vous pouvez appeler la fonction de classe pour y MKMapItempasser des éléments, elle n'utilise que le premier et le dernier pour la source / destination de manière appropriée, si vous voulez passer plus de deux éléments.

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 en utilisant l'extension:

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
la source
salut dimpiax! Merci pour votre réponse, je ne l'ai pas testé mais cela semble plutôt correct. Est-il possible d'envoyer plusieurs waypoints? Comment!? Pouvez-vous m'aider s'il vous plaît.
Frade le
@Frade hey, avec MapKit vous ne pouvez pas, voir: developer.apple.com/documentation/mapkit/mkmapitem/... Mais vous pouvez y parvenir en utilisant Google Maps.
dimpiax
36

L' MKMapItemapproche ci-dessus fonctionne très bien si vous souhaitez un contrôle granulaire sur les informations affichées dans Maps.

Sinon, le code ci-dessous fonctionne également très 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)!)

Cependant, le code ci-dessus ne vous permet pas d'envoyer un nom personnalisé du lieu. Au lieu de cela, il affichera l'adresse.

Le code ci-dessus vous permet également de naviguer à partir de n'importe quelle coordonnée source, ce que je ne sais pas si vous pouvez faire avec l'approche MKMapItem.

Daniel Saidi
la source
4
Si vous laissez "saddr =" vide, l'application définirait "votre emplacement" par défaut. Quelque chose comme "http: // maps.apple.com/maps?saddr=&daddr=(to.latitude),(to.longitude)"
Mariano Zorrilla
itinéraire non disponible
Marlhex
11

Cela fonctionne comme un charme pour moi

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
la source
1
Cela ne fonctionne plus pour moi. Je me suis retrouvé avec "Aucune route disponible".
Hemang
3

Vous pouvez utiliser le code ci-dessous pour afficher le code PIN sur lat, long dans la carte 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
la source
1

Si ce que vous voulez est quelque chose de simple sans importer de framework, vous pouvez simplement créer une URL: https://maps.apple.com/?ll=\(latitude),\(longitude)

Est similaire à la réponse @ saniel-saidi mais celle-ci ouvre uniquement la carte avec l'emplacement envoyé, pas la navigation

rgkobashi
la source
il suffit de supprimer () autour des coordonnées, ne le trouve pas avec eux.
Boris Gafurov
1

Je sais que toutes les réponses sont complètes, mais ici, j'ai une réponse qui est plus facile à copier-coller et qui donne également aux utilisateurs des options de routage avec Apple Maps, Google Map et Waze.

Travailler avec Swift 5+

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

Pourrait aider quelqu'un ...

Alfi
la source
0

Mise à jour de la réponse pratique de Daniel Saidi . Cet exemple sert uniquement à indiquer les coordonnées de destination. Les cartes obtiendront comme origine la position actuelle de l'utilisateur.

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