iOS - Swift 3 - 热力图

3
我正在使用这个项目来生成我的热力图:
https://github.com/dataminr/DTMHeatmap

我按照以下所述的方式集成了代码:

https://github.com/dataminr/DTMHeatmap/issues/1

from @johndpope:

https://github.com/johndpope/TranSafe

首先,代码已经成功编译。但当我像这样使用“readData”时:
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

这里是方法:

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 ...

我真的不知道我做错了什么,有人能帮我解决这个问题吗?


“coordinate” 看起来符合预期吗? - shallowThought
请参见以下链接:https://dev59.com/Eo7ea4cB1Zd3GeqPHONn - Sulthan
坐标看起来是否符合预期? - Creative crypter
那我应该做什么? - Creative crypter
2个回答

3
据我从 DTMHeatmap 的原始代码中所读取的内容,传递给 setData 的字典的键需要是包含 MKMapPointNSValue。而你展示的代码不是制作这样的 NSValue 的正确代码。(我真的怀疑你找到的原始 Swift 2 代码是否能正常工作...,MKMapView 无法在 Swift 2 中桥接到 Objective-C 对象,因此 mapPoint as! AnyObject 应该总是失败。) readData 方法应该像这样:
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)
}

(我没有实际检查过DTMHeatmap,所以您可能需要进行更多修复。)



感谢参与...我已经替换了代码,但仍然无法绘制地图...我甚至无法猜测这个实现有什么问题...此外,奇怪的是,iOS/Swift没有提供基本的热力图库? - Creative crypter
@Creativecrypter,我能给你的一个建议是,你应该从实际工作的示例代码开始。你不应该依赖于一些甚至不能构造一个简单的NSValue的代码... - OOPer
是的,但说实话,这是关于“iOS上热力图”的唯一资源,所以没有其他选择...你觉得呢? - Creative crypter
@Creativecrypter,如果有足够的信息,我可以修复一些小部分的代码,但是仅凭不工作的示例是无法做任何事情的。如果您能找到一个工作正常的示例,只需要将其中一些部分移植或修复一些缺陷,我或许其他读者可以帮助您。在此之前,您可能需要自己找出哪个部分的代码存在问题。 - OOPer

0
非常高效的热力图库。我成功地让它工作并且渲染得很好。我添加了这个答案,因为它还包括了必要的rendererFor覆盖委托函数。
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!)   
  }
}

这部分非常重要,为了使其正常工作,您需要将mapView的代理设置为self。

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    return DTMHeatmapRenderer(overlay: overlay)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接