在非常接近点的大型数据集上计算Voronoï图

时间:2016-03-30 14:18:23

标签: javascript leaflet gis computational-geometry voronoi

我有一个大的地理点数据集(大约22000点,但未来我可能会更多),我需要计算他们的Voronoï图。我首先将我的点从(lat,lng)投射到(x,y)(使用Leaflet中的latLngToLayerPoint()),然后根据Javascript implementation of Fortune's algorithm 计算图表。我恢复了图表的每个单元格,或更精确地vavb,分别为:

  

“Voronoi.Vertex对象,其x和y属性定义了开始   这个Voronoi.Edge的点(相对于左边的Voronoi站点)   对象“。

  

“Voronoi.Vertex对象,其x和y属性定义结束   这个Voronoi.Edge的点(相对于左边的Voronoi站点)   对象“。

(参见文献资料)

最后,我投射这些点以使用传单显示图表。我知道,为了计算图表,每个点都需要是唯一的,所以我在计算图表之前就删除了重复项。但问题是,我的结果非常糟糕(非节点交叉点,复杂多边形):

enter image description here

特写

enter image description here

我在图中有洞,我不知道为什么。积分是房子地址所以其中一些,即使它们不相等,也真的(非常)接近。我想知道问题是否来自预测(如果(lat1,lng1)(lat2,lng2)几乎相等,(x1,y1)(x2,y2)是否等于?)。我强烈怀疑这是问题的来源,但我不知道如何解决(建立一个门槛?)

编辑:我确切地说我在投影后删除了重复项,所以它不是关于投影的精确度,而是关于如果两个点相距一个像素会发生什么?

2 个答案:

答案 0 :(得分:1)

所以我找到了我的问题的解决方案,我发布它以防任何人需要使用Leaflet和Turf在地图上计算Voronoï图并且在实施Fortune算法时遇到麻烦(直到turf-voronoi工作)。 Other sources of how to compute a Voronoï diagram on map can be found (but using d3)(我认为d3也使用Fortune算法的这个Javascript实现)

问题不是由数据集的大小或点的接近度引起的,而是由我如何恢复单元格引起的。

首先,您需要将您的观点从(lat,lng)投射到(x,y)(使用latLngToLayerPoint()),计算图表:voronoi.compute(sites,bbox),其中网站是您的点这个[ {x: 200, y: 200}, {x: 50, y: 250}, {x: 400, y: 100} /* , ... */ ](请注意,您的网站需要唯一),如果您希望当前缩放的屏幕边框成为您的bbox juste,请使用:

var xl = 0, 
    xr = $(document).width(),
    yt = 0,
    yb = $(document).height();

一旦你计算了图表,只需恢复单元格(carfull,如果你想要正确的多边形,你需要边缘是逆时针排序的(或顺时针排序,但你要对它们进行排序),幸好算法提供了一半逆时针顺序给定Voronoï.Vertex的边缘)。要恢复每个单元格的顶点,您可以使用getStartpoint()getEndpoint(),而不要忘记将它们从(x,y)投射回(lat,lng)(使用layerPointToLatLng()

diagram.cells.forEach(function (c) {
    var edges=[];

    var size = c.halfedges.length;
    for (var i = 0; i < size; i++) {

        var pt = c.halfedges[i].getEndpoint();
        edges.push(map.layerPointToLatLng(L.point(pt.x,pt.y)));

    };

    voronoi_cells.push(L.polygon(edges));
});

最后,您必须使用FeatureCollection来显示图表:

enter image description here

答案 1 :(得分:0)

我强烈建议您不要自己实施Voronoi tesselation算法,而是使用https://github.com/Turfjs/turf-voronoi代替。