Edited at

Swift MkMapViewで地図アプリ作成してみた(6)- ロングタップした位置にピンを立て距離を表示する


記事一覧

Swift MkMapViewで地図アプリ作成してみた(記事一覧)


MkMapViewのaddAnnotationでピンを立てる

地図にピンを立てるには、MkMapViewのaddAnnotation関数を使用する。



  1. サンプル:MkMapViewのaddAnnotation関数

    var mapView: MKMapView!
    
    var pointAno: MKPointAnnotation = MKPointAnnotation()

    // ピンを定義する
    pointAno.coordinate = center // 座標(CLLocationCoordinate2D)
    pointAno.title = "タイトル"
    pointAno.subtitle = "サブタイトル(ピンをタップすると表示される)"

    // MapViewにピンを立てる
    mapView.addAnnotation(pointAno)



ピンを削除するには、MkMapViewのremoveAnnotation関数を使用する。



  1. サンプル:MkMapViewのremoveAnnotation関数

    mapView.removeAnnotation(pointAno)
    



ロングタップ終了時にタップした位置にピンを立てる



  1. ViewController.swiftにMKPointAnnotationの変数を定義する


    ViewController.swift:MKPointAnnotationの変数を定義

        class ViewController:   UIViewController,
    
    CLLocationManagerDelegate,
    UIGestureRecognizerDelegate {

    @IBOutlet var mapView: MKMapView!
    var locManager: CLLocationManager!
    @IBOutlet var longPressGesRec: UILongPressGestureRecognizer!
    var pointAno: MKPointAnnotation = MKPointAnnotation()





  2. ロングタップ終了時にタップした位置にピンを立てる

    ロングタップした位置の取得方法は、Swift MkMapViewで地図アプリ作成してみた(4)- ロングタップした位置の緯度経度を取得するを参照。


    ViewController.swift:ロングタップ終了時にタップした位置にピンを立てる

    // UILongPressGestureRecognizerのdelegate:ロングタップを検出する
    
    @IBAction func mapViewDidLongPress(_ sender: UILongPressGestureRecognizer) {
    // ロングタップ開始
    if sender.state == .began {
    }
    // ロングタップ終了(手を離した)
    else if sender.state == .ended {
    // タップした位置(CGPoint)を指定してMkMapView上の緯度経度を取得する
    let tapPoint = sender.location(in: view)
    let center = mapView.convert(tapPoint, toCoordinateFrom: mapView)

    let lonStr = center.longitude.description
    let latStr = center.latitude.description
    print("lon : " + lonStr)
    print("lat : " + latStr)

    // 現在位置とタッウプした位置の距離(m)を算出する
    let distance = calcDistance(mapView.userLocation.coordinate, center)
    print("distance : " + distance.description)

    // ロングタップを検出した位置にピンを立てる
    pointAno.coordinate = center
    mapView.addAnnotation(pointAno)
    }
    }


    該当の処理は以下となる。

            // ロングタップを検出した位置にピンを立てる
    
    pointAno.coordinate = center
    mapView.addAnnotation(pointAno)



  3. ピンに現在位置からの距離を表示する

    ピンと現在位置の距離の算出方法は、Swift MkMapViewで地図アプリ作成してみた(5)- ロングタップした位置と現在位置の距離を求めるを参照。

    1m=1.09361yardなので、yardにしたい場合は1.09361を乗算すれば良い。


    ViewController.swift:ピンに現在位置からの距離を表示する


    // ピンに設定する文字列を生成する
    var str:String = Int(distance).description
    str = str + " m"

    // yard
    let yardStr = Int(distance * 1.09361)
    str = str + " / " + yardStr.description + " yard"

    if pointAno.title != str {
    // ピンまでの距離に変化があればtiteを更新する
    pointAno.title = str
    mapView.addAnnotation(pointAno)
    }


    ▶︎を押してPCシミュレータを起動して、ロングタップしたピンまでの距離を確認する。

    debug.png




ロングタップ開始時に古いピンを削除する



  1. ロングタップ開始時に古いピンを削除する


    ViewController.swift:ロングタップ開始時に古いピンを削除する

    // UILongPressGestureRecognizerのdelegate:ロングタップを検出する
    
    @IBAction func mapViewDidLongPress(_ sender: UILongPressGestureRecognizer) {
    // ロングタップ開始
    if sender.state == .began {
    // ロングタップ開始時に古いピンを削除する
    mapView.removeAnnotation(pointAno)
    }




現在位置の更新時に距離を再更新する



  1. 現在位置の更新時に距離を再更新する


    ViewController.swift:現在位置の更新時に距離を再更新する

    // CLLocationManagerのdelegate:現在位置取得
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations:[CLLocation]) {

    // 現在位置とタッウプした位置の距離(m)を算出する
    let distance = calcDistance(mapView.userLocation.coordinate, pointAno.coordinate)

    if (0 != distance) {
    // ピンに設定する文字列を生成する
    var str:String = Int(distance).description
    str = str + " m"

    // yard
    let yardStr = Int(distance * 1.09361)
    str = str + " / " + yardStr.description + " yard"

    if pointAno.title != str {
    // ピンまでの距離に変化があればtitleを更新する
    pointAno.title = str
    mapView.addAnnotation(pointAno)
    }
    }
    }


    ピンを立てていなければ、distanceは0となる。




記事一覧

Swift MkMapViewで地図アプリ作成してみた(記事一覧)