【SwiftUI】Mapkit을 사용한 위치 정보의 취득과 역지오코데잉

소개



SwiftUI에서 Mapkit과 Firebase를 사용하여 위치 정보를 데이터베이스에 저장하는 것을 목적으로 한다.
이번은 SwiftUI로 취득한 현재지로부터 역지오코딩해, 도도부현명과 시구정촌명을 취득하는 곳까지를 기재.
Mapkit을 사용하여 현재 위치를 얻는 방법은 이전 기사를 참조하십시오.

참고 기사
【SwiftUI】Mapkit을 사용한 위치 정보의 취득과 핀의 표시

개발 환경



OSX 10.15.7 (Catalina)
Xcode 12.0.1
CocoaPods 1.10.0

획득한 현재 위치에서 역 지오코딩 수행


makeCoordinator 의 하단에 titlesubtitle 를 정의합니다.

ContentView.swift
func makeCoordinator() -> mapView.Coordinator {

        return mapView.Coordinator(parent1: self)
    }

    // ここから追加
    // 都道府県名
    @Binding var title : String
    // 市区町村名
    @Binding var subtitle : String

    func  makeUIView(context: UIViewRepresentableContext<mapView>) -> MKMapView {
        // Tokyo 35.6804° N, 139.7690° E

그런 다음 Coordinator 클래스의 locationManager 함수에 titlesubtitle를 추가합니다.
이번은 도도부현명과 시구정촌명을 취득할 수 있으면 좋기 때문에 administrativeArealocality 를 설정했습니다.
다른 지명이나 우편 번호 등 취득하고 싶은 경우는 이 개소를 변경, 또는 추가해 갑니다.

그 경우는 이하의 기사가 참고가 되었습니다.
[Swift] MapKit을 사용하여 "지오 코딩 / 역 지오 코딩"을 시도합니다.

ContentView.swift
class Coordinator: NSObject, CLLocationManagerDelegate {

        var parent : mapView

        init(parent1 : mapView) {

            parent = parent1
        }

        func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {

            if status == .denied{

                parent.alert.toggle()
                print("denied")
            }
        }

        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

            let location = locations.last

            let point = MKPointAnnotation()

            let georeader = CLGeocoder()
            georeader.reverseGeocodeLocation(location!) { (places, err) in

                if err != nil {

                    print((err?.localizedDescription)!)
                    return
                }

                // ここから追加
                // 都道府県名
                self.parent.title = (places?.first?.administrativeArea)!
                // 市町村名
                self.parent.subtitle = (places?.first?.locality)!

                // 前回記事から一部変更。ピンの選択時に都道府県名と市区町村名を表示できるように設定。

                let place = places?.first?.administrativeArea
                let subPlace = places?.first?.locality
                print(place as Any)
                point.title = place
                point.subtitle = subPlace

                point.coordinate = location!.coordinate
                self.parent.map.removeAnnotations(self.parent.map.annotations)
                self.parent.map.addAnnotation(point)

                let region = MKCoordinateRegion(center: location!.coordinate, latitudinalMeters: 10000, longitudinalMeters: 100000)
                print(region)
                self.parent.map.region = region

            }
        }
    }

향후, 여기에서 취득한 위도 경도와 도도부현명, 시구정촌명은 Firebase에 보존할 수 있도록 합니다.

도도부현명과 시구정촌명을 표시한다



ContentView.swift
struct ContentView: View {

    // ここから追加
    @State var title = ""
    @State var subtitle = ""

    @State var manager = CLLocationManager()
    @State var alert = false

    var body: some View {
        // 以下の行を追加
        // ContentViewに地図を表示
        ZStack(alignment: .bottom, content: {
            mapView(manager: $manager, alert: $alert, title: $title, subtitle: $subtitle).alert(isPresented: $alert) {

                Alert(title: Text("Please Enable Location Access In Setting Panel!!!"))
            }

            // 以下を追加
            // 地名を取得した場合に表示
            if self.title != "" {
                HStack(spacing: 12) {
                    Image(systemName: "info.circle.fill").font(.largeTitle).foregroundColor(.black)
                    VStack(alignment: .leading, spacing: 5){
                        Text(self.title).font(.body).foregroundColor(.black)
                        Text(self.subtitle).font(.caption).foregroundColor(.gray)
                    }
                Spacer()
                }
                .padding()
                // "Color"はAssets.xcassetsで設定
                .background(Color("Color"))
                .cornerRadius(15)
                .offset(y: -30)
            .padding()
            }
        })
    }
}

"Color"는 Assets.xcassets에서 설정했습니다. [+]에서 [Color set]을 선택하여 색상을 만들었습니다.


Simulator에서 지도 보기 및 확인





이상입니다.

좋은 웹페이지 즐겨찾기