Javascript 计算Voronoï;非常接近点的大型数据集上的图表
我有一个很大的地理点数据集(大约22000个点,但我将来可能会更多),我需要计算他们的Voronoï图。我首先将我的点从Javascript 计算Voronoï;非常接近点的大型数据集上的图表,javascript,leaflet,gis,computational-geometry,voronoi,Javascript,Leaflet,Gis,Computational Geometry,Voronoi,我有一个很大的地理点数据集(大约22000个点,但我将来可能会更多),我需要计算他们的Voronoï图。我首先将我的点从(lat,lng)投影到(x,y)(使用传单中的latLngToLayerPoint()),然后根据一个值计算图表。我恢复图表的每个单元格,或者更准确地说,恢复va和vb,分别为: “具有定义起点的x和y属性的Voronoi.Vertex对象 此Voronoi.Edge的点(相对于左侧的Voronoi站点) 对象。” 及 “一个Voronoi.Vertex对象,具有定义端点的x
(lat,lng)
投影到(x,y)
(使用传单中的latLngToLayerPoint()),然后根据一个值计算图表。我恢复图表的每个单元格,或者更准确地说,恢复va
和vb
,分别为:
“具有定义起点的x和y属性的Voronoi.Vertex对象
此Voronoi.Edge的点(相对于左侧的Voronoi站点)
对象。”
及
“一个Voronoi.Vertex对象,具有定义端点的x和y属性
此Voronoi.Edge的点(相对于左侧的Voronoi站点)
对象。”
(参见文件)
最后,我将这些点投影回来,用传单显示图表。我知道,为了计算图表,每个点都必须是唯一的,所以我在计算图表之前去掉了重复项。但问题是,我最终得到了一个非常糟糕的结果(非节点交点、复杂多边形):
特写镜头
我在图表上有漏洞,我不知道为什么。这些点是住址,所以其中一些,即使他们不平等,也非常(非常)接近。我想知道问题是否不是来自投影(如果(lat1,lng1)
和(lat2,lng2)
几乎相等,那么(x1,y1)
和(x2,y2)
是否相等?)。我强烈怀疑这就是问题的根源,但我不知道如何解决(设置阈值?)
编辑:我希望在投影后删除重复项,因此这与投影的精度无关,更重要的是如果两个点相距一个像素会发生什么 我强烈建议您不要自己实现Voronoi tesselation算法,而是使用它。因此我找到了我的问题的解决方案,如果有人需要使用传单和草皮在地图上计算Voronoï图,并且在实现《财富》算法时遇到困难(直到草皮Voronoi工作)。 (我认为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,请使用:
var xl = 0,
xr = $(document).width(),
yt = 0,
yb = $(document).height();
计算完图表后,只需恢复单元(如果您想要正确的多边形,则需要将边按逆时针顺序排列(或顺时针顺序排列,但您需要将它们按顺序排列),谢天谢地,该算法提供了给定Voronoï.Vertex
逆时针顺序排列的半边)。要恢复每个单元格的顶点,可以使用getStartpoint()
或getEndpoint()
,而不会忘记将它们从(x,y)
投影回(lat,lng)
(使用layerPointToLatLng()
)
diagram.cells.forEach(函数(c){
var边缘=[];
变量大小=c.halfedges.length;
对于(变量i=0;i
最后,您必须使用FeatureCollection
来显示图表:
你是在计算LAT/long值还是x/y值?对于基于“足够接近”的DeDuPug,你必须找到一个对你有用的值。你提到你正在使用地址,所以在我看来,如果两个点在10英尺的范围内,我会考虑它们是重复的。“足够近”这是我最初计划的,但它似乎还没有准备好使用(而且构建失败了)
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));
});