Reputation: 1516
i am using this project to generate my heatmap:
https://github.com/dataminr/DTMHeatmap
I integrated the code as stated in:
https://github.com/dataminr/DTMHeatmap/issues/1
from @johndpope:
https://github.com/johndpope/TranSafe
First, it is compiled successfully, but when i use the "readData" like this:
readData([[52.517138, 13.401489], [52.517137, 13.401488], [52.517136, 13.401487]])
i get the
Thread 1: EXC_BAD_ACCESS(code=2, address=blabla) error
here is the method:
func readData(_ array: [[Double]]){
self.heatmap = DTMHeatmap()
var dict = Dictionary<NSObject, AnyObject>();
for entry in array{
let coordinate = CLLocationCoordinate2D(latitude: entry[1], longitude: entry[0]);
let mapPoint = MKMapPointForCoordinate(coordinate)
let type = NSValue(mkCoordinate: coordinate).objCType // <- THIS IS IT
let value = NSValue(bytes: Unmanaged.passUnretained(mapPoint as AnyObject).toOpaque(), objCType: type);
dict[value] = 1 as AnyObject?;
}
self.heatmap.setData(dict as [AnyHashable: Any]);
self.mapView.add(self.heatmap)
}
func MKMapPointForCoordinate(_ coordinate: CLLocationCoordinate2D) -> MKMapPoint {
return MKMapPointForCoordinate(coordinate);
}
// etc ...
I have really no idea what i have done wrong, anybody could help me with this issue?
Upvotes: 3
Views: 2479
Reputation: 1020
Very performant heatmap library. I managed to get this working and it renders nicely. I am adding this answer because it also includes the rendererFor overlay delegate function needed to work.
class HeatmapViewController: UIViewController, MKMapViewDelegate {
var heatmap: DTMHeatmap? = nil
var diffHeatmap: DTMDiffHeatmap? = nil
@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
var ret: [AnyHashable: Any] = [:]
for location in locations {
var mapPoint = MKMapPointForCoordinate(location.coordinate)
let mapPointValue = NSValue(bytes: &mapPoint, objCType: "{MKMapPoint=dd}")
ret[mapPointValue] = 10.0 // weight
}
self.heatmap = DTMHeatmap()
self.heatmap?.setData(ret)
self.mapView.delegate = self; // Important
self.mapView.add(self.heatmap!)
}
}
This part is very important and for this to work you need to set the mapView's delegate to self.
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
return DTMHeatmapRenderer(overlay: overlay)
}
Upvotes: 0
Reputation: 47896
As far as I can read from the original code of DTMHeatmap
, the keys for the dictionary passed for setData
need to be NSValue
s containing MKMapPoint
. And the code you have shown is not a proper code to make such NSValue
s. (I really doubt the original Swift 2 code you have found would actually work..., MKMapView
cannot be bridged to Objective-C object in Swift 2, so mapPoint as! AnyObject
should always fail.)
The readData
method should be something like this:
func readData(_ array: [[Double]]){
self.heatmap = DTMHeatmap()
var dict: [AnyHashable: Any] = [:]
for entry in array{
let coordinate = CLLocationCoordinate2D(latitude: entry[1], longitude: entry[0]);
var mapPoint = MKMapPointForCoordinate(coordinate)
//Creating `objCType` manually is not recommended, but Swift does not have `@encoding()`...
let type = "{MKMapPoint=dd}"
let value = NSValue(bytes: &mapPoint, objCType: type)
dict[value] = 1
}
self.heatmap.setData(dict)
self.mapView.add(self.heatmap)
}
(I haven't checked with the actual DTMHeatmap
, so you may need some more fixes.)
Upvotes: 3