#記事一覧
Swift MkMapViewで地図アプリ作成してみた(記事一覧)
#国土地理院から現在位置の標高を取得する
国土地理院のWebAPIから標高を取得する方法の詳細は、「ロングタップした位置の標高を国土地理院から取得する」を参照してください。
-
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に現在位置が自動で設定されている。
-
標高を取得する
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を使用する。
#ロングタップした位置と現在位置の標高差をピンに表示する
-
標高差を計算する
ロングタップした位置の標高を国土地理院から取得するで取得した標高との差を
ViewController.swift:標高差を計算するself.lblDiffElevation = "高低差:" + (round(((self.longTapElevation - self.currentElevation)*10))/10).description + " m" // ロングタップしたアノテーション情報を更新する updateLongTapPointAno()
少数第1桁となる様に、"*10))/10"としている。
-
標高差をピンに表示する
ロングタップした位置にピンを立て距離を表示するで設定したピンのタイトルに連結する。
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) } }
シミュレータの実行結果は以下の様になる。
#参考文書
国土地理院 ヘルプ