Adding multiple annotations to map with polygons using swiftui

Issue

This Content is from Stack Overflow. Question asked by kostodian

I am using SwiftUI and UIViewRepresentable to display a map with different coloured MKPolygons as well as MKAnnotations.

While I can get the polygons to render correctly, I cannot get more than one annotation to load at a time. I think it has something to do with the way I am calculating the value of ‘landmarks’ as it’s only reading a single line of the data array, but having trouble figuring out another way to calculate this.

I intend to add more polygons and annotations so looking for a scaleable solution and hoping my current approach is somewhat in the right direction.

My code as follows: (I’m a beginner so apologies if the approach I’m taking is ugly!)


import SwiftUI
import MapKit

fileprivate class BlueSector: MKPolygon {
}

fileprivate class RedSector: MKPolygon {
}

fileprivate class MapPins: NSObject, MKAnnotation {
    let title: String?
    let subtitle: String?
    let coordinate: CLLocationCoordinate2D
    
    init(title: String?,
         subtitle: String?,
         coordinate: CLLocationCoordinate2D) {
        self.title = title
        self.subtitle = subtitle
        self.coordinate = coordinate
    }
}

struct MapView: UIViewRepresentable {

    let region: MKCoordinateRegion
    let todCoordinates: [CLLocationCoordinate2D]
    let oplCoordinates: [CLLocationCoordinate2D]
    let mapPoints: [(title: String, subtitle: String, coordinate: CLLocationCoordinate2D)]

  func makeUIView(context: Context) -> MKMapView {
      
      let mapView = MKMapView()
      mapView.delegate = context.coordinator
      mapView.region = region

      let todpolygon = BlueSector(coordinates: todCoordinates, count: todCoordinates.count)
      mapView.addOverlay(todpolygon)
      
      let oplpolygon = RedSector(coordinates: oplCoordinates, count: oplCoordinates.count)
      mapView.addOverlay(oplpolygon)
      
      let landmarks = MapPins(title: mapPoints[0].0, subtitle: mapPoints[0].1, coordinate: mapPoints[0].2)
      mapView.addAnnotation(landmarks)
              
    return mapView
  }

  func updateUIView(_ view: MKMapView, context: Context) {}

  func makeCoordinator() -> Coordinator {
    Coordinator(self)
  }
}


class Coordinator: NSObject, MKMapViewDelegate {
  var parent: MapView

  init(_ parent: MapView) {
    self.parent = parent
  }

  func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if let routePolyline = overlay as? MKPolygon {
        let renderer = MKPolygonRenderer(overlay: routePolyline)
        if overlay is BlueSector {
            renderer.strokeColor = UIColor.systemBlue
            renderer.lineWidth = 2
            renderer.fillColor = UIColor.systemCyan
            renderer.alpha = 0.5
        } else {
            renderer.strokeColor = UIColor.systemRed
            renderer.lineWidth = 2
            renderer.fillColor = UIColor.systemPink
            renderer.alpha = 0.5
        }
      return renderer
    }
      
    return MKOverlayRenderer()
  }
    
    func mapView(_ map: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        let identifier = "pinAnnotation"
        var annotationView = map.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView

        if annotationView == nil {
            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView?.canShowCallout = true
        }

        annotationView?.annotation = annotation
        return annotationView
    }
}


struct ContentView: View {
  @State private var region = MKCoordinateRegion(
    center: CLLocationCoordinate2D(latitude: -24.1500, longitude: 133.2500),
    span: MKCoordinateSpan(latitudeDelta: 50, longitudeDelta: 50)
  )

// BLUE POLYGON COORDINATES
  @State private var todCoordinates = [
        CLLocationCoordinate2D(latitude: -23.1902, longitude: 127.0806),
        CLLocationCoordinate2D(latitude: -24.2905, longitude: 128.0645),
        CLLocationCoordinate2D(latitude: -26.0708, longitude: 128.0648),
        CLLocationCoordinate2D(latitude: -28.4816, longitude: 130.4419),
        CLLocationCoordinate2D(latitude: -28.4826, longitude: 130.4852),
        CLLocationCoordinate2D(latitude: -28.1001, longitude: 131.3645),
        CLLocationCoordinate2D(latitude: -30.2052, longitude: 133.5951),
        CLLocationCoordinate2D(latitude: -29.0006, longitude: 136.4946),
        CLLocationCoordinate2D(latitude: -28.0017, longitude: 137.5943),
        CLLocationCoordinate2D(latitude: -26.1314, longitude: 138.2312),
        CLLocationCoordinate2D(latitude: -22.1747, longitude: 136.3819),
        CLLocationCoordinate2D(latitude: -21.5143, longitude: 136.2242),
        CLLocationCoordinate2D(latitude: -21.2947, longitude: 136.1949),
        CLLocationCoordinate2D(latitude: -21.1201, longitude: 131.5020),
        CLLocationCoordinate2D(latitude: -23.1304, longitude: 128.2753),
        CLLocationCoordinate2D(latitude: -23.1902, longitude: 127.0806),
  ];
    
 // RED POLYGON COORDINATES
    @State private var oplCoordinates = [
        CLLocationCoordinate2D(latitude: -30.2052, longitude: 133.5951),
        CLLocationCoordinate2D(latitude: -29.0006, longitude: 136.4946),
        CLLocationCoordinate2D(latitude: -28.0017, longitude: 137.5943),
        CLLocationCoordinate2D(latitude: -26.1314, longitude: 138.2312),
        CLLocationCoordinate2D(latitude: -28.5948, longitude: 143.3004),
        CLLocationCoordinate2D(latitude: -29.5342, longitude: 142.4100),
        CLLocationCoordinate2D(latitude: -31.0006, longitude: 142.4837),
        CLLocationCoordinate2D(latitude: -31.4744, longitude: 143.3102),
        CLLocationCoordinate2D(latitude: -33.0014, longitude: 143.3050),
        CLLocationCoordinate2D(latitude: -33.2030, longitude: 140.3420),
        CLLocationCoordinate2D(latitude: -33.0506, longitude: 140.1330),
        CLLocationCoordinate2D(latitude: -32.5153, longitude: 139.4819),
        CLLocationCoordinate2D(latitude: -31.3500, longitude: 138.5950),
        CLLocationCoordinate2D(latitude: -31.3456, longitude: 135.2446),
        CLLocationCoordinate2D(latitude: -30.2052, longitude: 133.5951),
    ];
 
// ANNOTATION DATA FOR BOTH POLYGONS
    @State private var mapPoints = [
        (title: "TOD",
         subtitle: "Tod",
         coordinate: CLLocationCoordinate2D(latitude: -23.6980, longitude: 133.8807)),
        (title: "OPL",
         subtitle: "Opal",
         coordinate: CLLocationCoordinate2D(latitude: -30.5929, longitude: 138.4039)),
         ];
    
  var body: some View {
      MapView(
      region: region,
      todCoordinates: todCoordinates,
      oplCoordinates: oplCoordinates,
      mapPoints: mapPoints
    )
      .edgesIgnoringSafeArea(.top)
      }
  }

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}



Solution

This question is not yet answered, be the first one who answer using the comment. Later the confirmed answer will be published as the solution.

This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?