見出し画像

【徒然iOS】気ままにUIKit56〜CLGeocoder 住所を座標に変換してピンを刺す。〜

概要

このマガジンは四十を過ぎたおっさんが、

を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけな記事を気ままに上げてます。

今回

をハイ、レッツゴ🕺

前準備

念の為、

  1. バックアップ

  2. 新しいクラス

  3. ビューコントローラの追加

  4. イニシャルビューの変更

をいつも通りやってから本題へ💃

こんな感じで

本題

要は、

住所を座標に変換してピンを刺す方法
ピンを刺した座標を住所に変換する方法

らしい👀

⒈今回はVerticalStackViewさんにまたお世話になって、、、

VStack先生を選んで〜〜〜
配置〜〜〜
TextFieldとMapKitをVStack先生に格納
VStack自体にPin制約を付けて〜〜〜
VStackをEqual Centeringにしてから、
MapKitのコンフリクトを解消しにAdd MIssing〜〜〜
ハイ、なんかそれっぽい感じになりました〜〜〜
念の為、シミュレータで実行してもOKな感じ🕺

⒉下のコードを参考に、、、

//
//  ViewController.swift
//
import UIKit
import MapKit
class ViewController: UIViewController,UITextFieldDelegate {
    @IBOutlet weak var testMapView: MKMapView!
    @IBOutlet weak var testTextField: UITextField!
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //デリゲート先に自分を設定する。
        testTextField.delegate = self
    }
    //Returnキー押下時の呼び出しメソッド
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        self.view.endEditing(true)
        let myGeocoder:CLGeocoder = CLGeocoder()
        //住所
        let searchStr = testTextField.text
        //住所を座標に変換する。
        myGeocoder.geocodeAddressString(searchStr!, completionHandler: {(placemarks, error) in
            if(error == nil) {
                for placemark in placemarks! {
                    let location:CLLocation = placemark.location!
                    //中心座標
                    let center = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
                    //表示範囲
                    let span = MKCoordinateSpanMake(0.001, 0.001)
                    //中心座標と表示範囲をマップに登録する。
                    let region = MKCoordinateRegionMake(center, span)
                    self.testMapView.setRegion(region, animated:true)
                    //地図にピンを立てる。
                    let annotation = MKPointAnnotation()
                    annotation.coordinate = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
                    self.testMapView.addAnnotation(annotation)
                }
            } else {
                self.testTextField.text = "検索できませんでした。"
            }
        })
        //改行を入れない。
        return false
    }
}

要は、追記したTextFieldとMapKitをアウトレット接続すりゃいいようなので、、、

それぞれ
てな感じでアウトレット接続

⒊⒉のコードを参考にコードを組み込む

class MapAddressLocationViewController: UIViewController,UITextFieldDelegate {
    @IBOutlet weak var myTextField: UITextField!
    @IBOutlet weak var myMapKitView: MKMapView!
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //デリゲート先に自分を設定する。
        myTextField.delegate = self
    }
    //Returnキー押下時の呼び出しメソッド
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.view.endEditing(true)
        let myGeocoder:CLGeocoder = CLGeocoder()
        //住所
        let searchStr = myTextField.text
        //住所を座標に変換する。
        myGeocoder.geocodeAddressString(searchStr!, completionHandler: {(placemarks, error) in
            if(error == nil) {
                for placemark in placemarks! {
                    let location:CLLocation = placemark.location!
                    //中心座標
                    let center = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
                    //表示範囲
                    let span = MKCoordinateSpan(latitudeDelta: 0.001, longitudeDelta: 0.001)
                    //中心座標と表示範囲をマップに登録する。
                    let region = MKCoordinateRegion(center: center, span: span)
                    self.myMapKitView.setRegion(region, animated:true)
                    //地図にピンを立てる。
                    let annotation = MKPointAnnotation()
                    annotation.coordinate = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
                    self.myMapKitView.addAnnotation(annotation)
                }
            } else {
                self.myTextField.text = "検索できませんでした。"
            }
        })
        //改行を入れない。
        return false
    }
}

てな感じでコードを組み込むと〜〜〜

⒋シミュレータ実行

ハイ、検索できた🕺

しか〜〜〜〜し、よく見ると、PINが昔のヤツじゃなくて気に入らないので、

今回のコード(キーワード検索)

class MapAddressLocationViewController: UIViewController,UITextFieldDelegate,MKMapViewDelegate {
    
    @IBOutlet weak var myTextField: UITextField!
    @IBOutlet weak var myMapKitView: MKMapView!
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //デリゲート先に自分を設定する。
        myTextField.delegate = self
        //デリゲート先に自分を設定する。
        myMapKitView.delegate = self
    }
    //アノテーションビューを返すメソッド
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let myView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: nil)
        //吹き出しを表示可能にする。
        myView.canShowCallout = true
        return myView
    }
    //Returnキー押下時の呼び出しメソッド
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.view.endEditing(true)
        let myGeocoder:CLGeocoder = CLGeocoder()
        //住所
        let searchStr = myTextField.text
        //住所を座標に変換する。
        myGeocoder.geocodeAddressString(searchStr!, completionHandler: {(placemarks, error) in
            if(error == nil) {
                for placemark in placemarks! {
                    let location:CLLocation = placemark.location!
                    //中心座標
                    let center = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
                    //表示範囲
                    let span = MKCoordinateSpan(latitudeDelta: 0.001, longitudeDelta: 0.001)
                    //中心座標と表示範囲をマップに登録する。
                    let region = MKCoordinateRegion(center: center, span: span)
                    self.myMapKitView.setRegion(region, animated:true)
                    //地図にピンを立てる。
                    let annotation = MKPointAnnotation()
                    annotation.coordinate = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
                    self.myMapKitView.addAnnotation(annotation)
                }
            } else {
                self.myTextField.text = "検索できませんでした。"
            }
        })
        //改行を入れない。
        return false
    }
}

に変更して、実行すると

ちゃんと、今までのPINにもなった🕺

座標を住所に変換する

ちょいと、ここからは全然テキストビューも使わないので、
別の手順てことで💦

⒈いつもどおり新しいビュー追加して、MapKitを配置とアウトレット接続

こんな感じで〜〜〜
ここまで完了🕺

⒉LongPressGestureを配置してアクション接続

配置して接続するところ〜〜〜
接続完了🕺

⒊下のコードを参考に組み込む

//
//  ViewController.swift
//
import UIKit
import MapKit
class ViewController: UIViewController,MKMapViewDelegate{
    @IBOutlet weak var testMapView: MKMapView!
    @IBOutlet weak var testTextField: UITextField!
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //デリゲート先に自分を設定する。
        testMapView.delegate = self
        //中心座標
        let center = CLLocationCoordinate2DMake(35.690553, 139.699579)
        //表示範囲
        let span = MKCoordinateSpanMake(0.001, 0.001)
        //中心座標と表示範囲をマップに登録する。
        let region = MKCoordinateRegionMake(center, span)
        self.testMapView.setRegion(region, animated:true)
    }
    //長押し時の呼び出しメソッド
    @IBAction func pressMap(sender: UILongPressGestureRecognizer) {
        //マップビュー内のタップした位置を取得する。
        let location:CGPoint = sender.locationInView(testMapView)
        //長押し終了
        if (sender.state == UIGestureRecognizerState.Ended){
            //タップした位置を緯度、経度の座標に変換する。
            let mapPoint:CLLocationCoordinate2D = testMapView.convertPoint(location, toCoordinateFromView: testMapView)
            let location = CLLocation(latitude:mapPoint.latitude, longitude: mapPoint.longitude)
            //座標を住所に変換する。
            let myGeocoder:CLGeocoder = CLGeocoder()
            myGeocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error) in
                if(error == nil) {
                    for placemark in placemarks! {
                        //ピンを地図に刺す。
                        let annotation = MKPointAnnotation()
                        annotation.coordinate = CLLocationCoordinate2DMake(mapPoint.latitude, mapPoint.longitude)
                        annotation.title = "住所"
                        annotation.subtitle = "\(placemark.administrativeArea!)\(placemark.locality!)\(placemark.thoroughfare!)\(placemark.subThoroughfare!)"
                        self.testMapView.addAnnotation(annotation)
                    }
                } else {
                        self.testTextField.text = "住所不明"
                }
            })
        }
    }
}

を組み込んで下のコードに変更〜〜〜

class MapLongAddressLocationViewController: UIViewController,MKMapViewDelegate {
    @IBOutlet weak var myMapKitView: MKMapView!
    
    let x = 139.692101
    let y = 35.689634
    let latitudeDelta = 0.01
    let longitudeDelta = 0.01
    
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //デリゲート先に自分を設定する。
        myMapKitView.delegate = self
        //中心座標
        let center = CLLocationCoordinate2DMake(y, x)
        //表示範囲
        let span = MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta)
        //中心座標と表示範囲をマップに登録する。
        let region = MKCoordinateRegion(center: center, span: span)
        self.myMapKitView.setRegion(region, animated:true)
    }
    //長押し時の呼び出しメソッド
    @IBAction func myPressMap(_ sender: UILongPressGestureRecognizer) {
        //マップビュー内のタップした位置を取得する。
        let location:CGPoint = sender.location(in: myMapKitView)
        //長押し終了
        if (sender.state == UIGestureRecognizer.State.ended){
            //タップした位置を緯度、経度の座標に変換する。
            let mapPoint:CLLocationCoordinate2D = myMapKitView.convert(location, toCoordinateFrom: myMapKitView)
            let location = CLLocation(latitude:mapPoint.latitude, longitude: mapPoint.longitude)
            //座標を住所に変換する。
            let myGeocoder:CLGeocoder = CLGeocoder()
            myGeocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error) in
                if(error == nil) {
                    for placemark in placemarks! {
                        //ピンを地図に刺す。
                        let annotation = MKPointAnnotation()
                        annotation.coordinate = CLLocationCoordinate2DMake(mapPoint.latitude, mapPoint.longitude)
                        annotation.title = "住所"
                        annotation.subtitle = "\(placemark.administrativeArea!)\(placemark.locality!)\(placemark.thoroughfare!)\(placemark.subThoroughfare!)"
                        self.myMapKitView.addAnnotation(annotation)
                    }
                }
            })
        }
    }
    //アノテーションビューを返すメソッド
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let myView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: nil)
        //吹き出しを表示可能にする。
        myView.canShowCallout = true
        return myView
    }
}

⒋シミュレータ実行

ハイ、完了🕺

ブラッシュアップ

ここまででやってるから今回もなし💦

今回のポイント


てな感じらしい🙇

Apple公式

さて、次回は

をレッツゴする🕺


この記事が気に入ったらサポートをしてみませんか?