1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Swift MkMapViewで地図アプリ作成してみた(12)- ロングタップした位置と現在位置の標高差をピンに表示する

Last updated at Posted at 2019-12-21

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

#国土地理院から現在位置の標高を取得する

国土地理院のWebAPIから標高を取得する方法の詳細は、「ロングタップした位置の標高を国土地理院から取得する」を参照してください。

  1. URLを生成する

    国土地理院から現在位置の標高をJSONで取得するためのURLを作成する。

    ViewController.swift:URLを生成する
    // 国土地理院のURL
    let baseUrl = "https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?"
    // 現在位置でクエリを設定する
    let lonUrl = "&lon=" + mapView.userLocation.coordinate.longitude.description
    let latUrl = "&lat=" + mapView.userLocation.coordinate.latitude.description
    // アウトプット形式をJSONに設定する
    let outtypeUrl = "&outtype=JSON"
    // URLとクエリを連結
    let listUrl = baseUrl + lonUrl + latUrl + outtypeUrl        
    // URLを生成する
    guard let url = URL(string: listUrl) else { return }
    

    現在位置を取得するで現在位置受信を有効にしていれば、mapView.userLocationに現在位置が自動で設定されている。

  2. 標高を取得する

    URLSessionで生成したURLにアクセスして標高を取得する。

    ViewController.swift:標高を取得する
    
    // URLを生成する
    guard let url = URL(string: listUrl) else { return }
    URLSession.shared.dataTask(with: url) { (data, response, error) in
        if error != nil {
            print(error!.localizedDescription)
        }
        guard let data = data else { return }
        // JSONを取得する
        let json = try? JSONDecoder().decode(JsonElevation.self, from: data)
        if nil != json {
            // mainスレッドで処理する
            DispatchQueue.main.async {
                // JSONから標高を取得する
                self.currentElevation = (json?.elevation)!
            }
        }.resume()
    }
    

    サブスレッドからメインスレッドに切り替えるためには、DispatchQueue.main.asyncを使用する。

#ロングタップした位置と現在位置の標高差をピンに表示する

  1. 標高差を計算する

    ロングタップした位置の標高を国土地理院から取得するで取得した標高との差を

    ViewController.swift:標高差を計算する
    self.lblDiffElevation = "高低差:" + (round(((self.longTapElevation - self.currentElevation)*10))/10).description + " m"
    // ロングタップしたアノテーション情報を更新する
    updateLongTapPointAno()
    

    少数第1桁となる様に、"*10))/10"としている。

  2. 標高差をピンに表示する

    ロングタップした位置にピンを立て距離を表示するで設定したピンのタイトルに連結する。

    ViewController.swift:標高差をピンに表示する
    // ロングタップしたアノテーション情報を更新する
    func updateLongTapPointAno() {
        // 現在位置とタッウプした位置の距離(m)を算出する
        let distance = calcDistance(mapView.userLocation.coordinate, pointAno.coordinate)
            
        // ピンに設定する文字列を生成する
        var str:String = Int(distance).description
        str = str + " m"
            
        // yard
        let yardStr = Int(distance * 1.09361)
        str = str + " / " + yardStr.description + " y"
            
        // 標高差を連結する
        str = str + "\n" + lblDiffElevation.description
            
        if pointAno.title != str {
            // ピンまでの距離に変化があればtitleを更新する
            pointAno.title = str
            mapView.addAnnotation(pointAno)
        }
    }
    

    シミュレータの実行結果は以下の様になる。

Qiita(12)-01.png

#参考文書
国土地理院 ヘルプ

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?