How To Create Heatmap From Array CLCoordinate2D In A SwiftUI Map

Hi, is there a heatmap class that can be used in a SwiftUI Map? I do not want to use MKMapView and I have seen libraries that are not Swifty and does not make use of the new Map()

Tips are welcome on how to go about this? Or if anyone has a sample code?

I basically have an array of CLCoordinate2D and i wish to use that to generate a heatmap in the map.

No Google Maps please. I decidede not to use this since they do not have a SwiftUI version for it.

Answered by robnotyou in 732082022

There's no need for a ViewController, though you can use one if you want to.
I find it bettor to wrap a UIKit MapView in a UIViewRepresentable.

Then you need something to act as the MKMapViewDelegate.
This can all be reusable.

You will find that the SwiftUI map is very limited.

I had to wrap a UIKit MKMapView, and use that.
Then you can add MKPolygons as map overlays...
... and use the delegate, to style the polygons.

Accepted Answer

There's no need for a ViewController, though you can use one if you want to.
I find it bettor to wrap a UIKit MapView in a UIViewRepresentable.

Then you need something to act as the MKMapViewDelegate.
This can all be reusable.

Google Maps is messy. Too many outdated code. A beginner can't tell which one should be followed. Im going back to MKMapView.

@robnotyou quick question. Since MKMapView doesnt require a binding to region, my map shows empty blue (probably in the middle of the sea). 

@State private var region = MKCoordinateRegion() 
MapView(region: region)
 .edgesIgnoringSafeArea(.all)
 .onAppear() {  
  region = ... array of CLLocationCoordinate2D
}

 This used to work when it was Map since i just had to go $region since the parameter required has to be binding but now it is not. How can it re-render once the region variable is set? 

This is my MapView

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {

  var region: MKCoordinateRegion
  var polylineCoordinates: [CLLocationCoordinate2D]?

  func makeUIView(context: Context) -> MKMapView {
    let mapView = MKMapView()
    mapView.delegate = context.coordinator
    mapView.region = region
    
    if let polylines = polylineCoordinates {
      let polyline = MKPolyline(coordinates: polylines, count: polylines.count)
      mapView.addOverlay(polyline)
    }
     
    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? MKPolyline {
      let renderer = MKPolylineRenderer(polyline: routePolyline)
      renderer.strokeColor = UIColor.systemBlue
      renderer.lineWidth = 5
      return renderer
    }
    return MKOverlayRenderer()
  }
}

You should post this as a new question.

Since MKMapView doesnt require a binding to region...

MKMapView has a property, "region".
To recenter (or zoom) the map, you set this property.

Your code doesn't currently have any way to do this, except when you first construct your MapView.