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

#記事一覧
[Swift MkMapViewで地図アプリ作成してみた（記事一覧）](https://qiita.com/rain_00_00_09/items/3151b3faf2303fe78312)

#MkMapViewのaddAnnotationでピンを立てる

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

1. 
    ```swift:サンプル：MkMapViewのaddAnnotation関数
    var mapView: MKMapView!
    var pointAno: MKPointAnnotation = MKPointAnnotation()
    
    // ピンを定義する
    pointAno.coordinate = center // 座標（CLLocationCoordinate2D）
    pointAno.title = "タイトル"
    pointAno.subtitle = "サブタイトル（ピンをタップすると表示される）"
 
    // MapViewにピンを立てる
    mapView.addAnnotation(pointAno)
    ```

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

1. 
    
    ```swift:サンプル：MkMapViewのremoveAnnotation関数
    mapView.removeAnnotation(pointAno)
    ```


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

1. ViewController.swiftにMKPointAnnotationの変数を定義する
    
    ```swift: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で地図アプリ作成してみた（08）- ロングタップした位置の緯度経度を取得する](https://qiita.com/rain_00_00_09/items/1be8bf72ecf0700ffdf5)を参照。

    ```swift: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)
        }
    }
    ```

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

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

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

    ピンと現在位置の距離の算出方法は、[Swift MkMapViewで地図アプリ作成してみた（09）- ロングタップした位置と現在位置の距離を求める](https://qiita.com/rain_00_00_09/items/70daa540bb5f8485b9b8)を参照。
    1m=1.09361yardなので、yardにしたい場合は1.09361を乗算すれば良い。

    ```swift: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シミュレータを起動して、ロングタップしたピンまでの距離を確認する。
    <img width="750" alt="debug.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/a6247cdf-f63a-490e-9555-454e1f79654e.png">



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

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


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

1. 現在位置の更新時に距離を再更新する
    
    ```swift: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で地図アプリ作成してみた（記事一覧）](https://qiita.com/rain_00_00_09/items/3151b3faf2303fe78312)