[iOS] Map Overlay

RudinP·2024년 6월 29일
0

Study

목록 보기
239/258

Overlay

  • 지도 위에 직선이나 도형을 그리는 기능
  • 공식 문서

오버레이 종류

  • MKCircle
  • MKPolygon
  • MKPolyline

뒤에 Renderer가 붙은 클래스는 오버레이를 출력할 때 라인의 두께, 컬러 등을 정하는 객체이다.

MKPolyline

1. 두 개의 CLLocationCoordinate2D 객체를 생성한다.

2. 배열에 두 객체를 저장한다.

3. MKPolyline(coordinates: count:) 생성자로 폴리라인 객체를 생성한다.

4. MKMapView의 addOverlay 메소드를 호출한다.

5. MKMapViewDelegate의 rendererFor 메소드를 구현한다.

func addOverlay(){
        let coordinate1 = CLLocationCoordinate2D(latitude: 37.29197366738964, longitude: 127.20029876492822)
        let coordinate2 = CLLocationCoordinate2D(latitude: 37.29341613873919, longitude: 127.2023157861073)
        
        let coordinates = [coordinate1, coordinate2]
        let polyline = MKPolyline(coordinates:coordinates, count: coordinates.count)
        mapView.addOverlay(polyline)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        switch overlay{
        case is MKPolyline:
            let r = MKPolylineRenderer(overlay: overlay)
            r.strokeColor = .systemRed //색
            r.lineWidth = 10 //라인 두께
            return r
        default:
            return MKOverlayRenderer()
        }
}

MKCircle

1. 중심 좌표가 될 CLLocationCoordinate2D와 원의 radius를 설정한다.(m단위)

2. MKCircle 생성자로 중심위치좌표와 원의 반지름을 넣고 생성한다.

3. MKMapView의 addOverlay 메소드를 호출한다.

4. MKMapViewDelegate의 rendererFor 메소드를 구현한다.

let circle = MKCircle(center: mapView.centerCoordinate, radius: 100)//radius는 meter단위
mapView.addOverlay(circle)
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        switch overlay{
        	...
			case is MKCircle:
            let r = MKCircleRenderer(overlay: overlay)
            r.strokeColor = .blue
            r.lineWidth = 10
            return r
            ...

MKPolygon

  • GeoJSON 파일에서 geometry 섹션에 coordinates가 여러개 있다면 MKGeoJSON이 자동으로 폴리곤으로 디코딩해준다.
  • 따라서 렌더러만 리턴해주면 된다.

1. GeoJSON 파싱 후 geometry의 값을 MKPolygon으로 캐스팅

@IBAction func addOverlay(_ sender: Any){
        mapView.removeOverlays(mapView.overlays)
        
        for obj in geoJsonObjects {
            guard let feature = obj as? MKGeoJSONFeature else {continue}
            let jsonDecoder = JSONDecoder()
            
            guard let pdata = feature.properties,
                  let properties = try? jsonDecoder.decode(Property.self, from: pdata) else {continue}
          
            if let section = feature.geometry.first as? MKPolygon {
                section.title = properties.name
                mapView.addOverlay(section)
            }
        }
    }

2. MKPolygonRenderer을 delegate에서 리턴

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        switch overlay{
        case is MKPolyline:
            let r = MKPolylineRenderer(overlay: overlay)
            r.strokeColor = .systemRed //색
            r.lineWidth = 10 //라인 두께
            return r
        case is MKCircle:
            let r = MKCircleRenderer(overlay: overlay)
            r.strokeColor = .blue
            r.lineWidth = 10
            return r
        case is MKPolygon:
            let r = MKPolygonRenderer(overlay: overlay)
            r.fillColor = .yellow
            return r
        default:
            return MKOverlayRenderer()
        }
    }

3. overlay의 title마다 색을 다르게 하고 싶다면 switch로 분기를 나누면 된다.

case is MKPolygon:
            let r = MKPolygonRenderer(overlay: overlay)
            switch overlay.title {
            case "유러피안 어드벤처":
                r.fillColor = .systemGreen
            case "매직랜드":
                r.fillColor = .systemRed
            case "아메리칸 어드벤처":
                r.fillColor = .systemBlue
            case "글로벌페어":
                r.fillColor = .systemPurple
            case "주토피아":
                r.fillColor = .systemOrange
            default:
                r.fillColor = .systemYellow
            }
            r.alpha = 0.2
            return r

profile
iOS 개발자가 되기 위한 스터디룸...

0개의 댓글