Nxl*_*vel 19 html javascript php leaflet
我在我创建的地图上有一堆传单多边形.每个多边形代表不同的东西 根据用户所在的页面,弹出窗口中会显示一组特定信息.我需要找到一种方法,使"popup"气泡在它所代表的多边形的中心打开.
使用以下代码绘制每个多边形:
var L20 = [
[74.0995, -99.92615],
[74.14008, -99.4043],
[74.07691, -99.33838],
[74.03617, -99.86023]
];
var L19 = [
[74.02559, -99.84924],
[74.06636, -99.32739],
[74.0029, -99.26147],
[73.96197, -99.77783]
];
var L18 = [
[73.95142, -99.76684],
[73.99235, -99.25048],
[73.92889, -99.18456],
[73.8878, -99.69543]
];
var set1 = L.polygon([L20, L19, L18], {
color: "#fff",
weight: 1,
stroke: true,
opacity: 0.05,
fillColor: "#346B1F",
}).addTo(map);
Run Code Online (Sandbox Code Playgroud)
使用以下代码绘制弹出窗口:
var popup = L.popup({})
.setLatLng([73.64017, -100.32715])
.setContent(content).openOn(map);
var popup = L.popup();
Run Code Online (Sandbox Code Playgroud)
所以我需要找到一种方法.setLatLang来确定或给出多边形的中心.
我想出了3个可能有用的解决方案,不知道如何去做.
找到一种方法来使用多边形的坐标来确定弹出窗口打开的多边形的中心.
调用多边形的一个点,然后偏移弹出窗口的位置.
对每个多边形使用id,因此每个弹出窗口都知道可以打开的框区域(多边形).
有谁可以帮助我吗?
yar*_*arl 46
由于Leaflet有一段时间内置了getCenter()方法:
polygon.getBounds().getCenter();
Run Code Online (Sandbox Code Playgroud)
Ste*_*ton 29
有几种方法可以近似多边形的质心.
最简单(但最不准确的方法)是获取包含多边形的边界框的中心,如yarl建议的那样, polygon.getBounds().getCenter();
我最初用寻找点的质心的公式回答了这个问题,这可以通过平均其顶点的坐标来找到.
var getCentroid = function (arr) {
return arr.reduce(function (x,y) {
return [x[0] + y[0]/arr.length, x[1] + y[1]/arr.length]
}, [0,0])
}
centerL20 = getCentroid(L20);
Run Code Online (Sandbox Code Playgroud)
虽然点的质心足够逼近我,但是一位评论者指出它并不是多边形的质心.
var getCentroid2 = function (arr) {
var twoTimesSignedArea = 0;
var cxTimes6SignedArea = 0;
var cyTimes6SignedArea = 0;
var length = arr.length
var x = function (i) { return arr[i % length][0] };
var y = function (i) { return arr[i % length][1] };
for ( var i = 0; i < arr.length; i++) {
var twoSA = x(i)*y(i+1) - x(i+1)*y(i);
twoTimesSignedArea += twoSA;
cxTimes6SignedArea += (x(i) + x(i+1)) * twoSA;
cyTimes6SignedArea += (y(i) + y(i+1)) * twoSA;
}
var sixSignedArea = 3 * twoTimesSignedArea;
return [ cxTimes6SignedArea / sixSignedArea, cyTimes6SignedArea / sixSignedArea];
}
Run Code Online (Sandbox Code Playgroud)
Kri*_*her 14
您试图解决的问题被称为无法访问问题的极点.通过找到边界框的中心,找不到将标签放在多边形中的最佳位置.考虑字母U形状的多边形.边界框的中心将标签放在多边形之外.我花了很长时间才找到这个杰出的图书馆:https://github.com/mapbox/polylabel
来自README.MD:
一种快速算法,用于查找不可访问的多极点,多边形轮廓中最远的内点(不要与质心混淆),实现为JavaScript库.用于在多边形上最佳放置文本标签.
这是一个迭代网格算法,受到Garcia-Castellanos&Lombardo,2007年的论文的启发.与论文中的不同,这个算法:
- 保证在给定精度内找到全局最优
- 快了很多倍(10-40x)
用法:
给定GeoJSON格式和精度的多边形坐标(默认为1.0),Polylabel以[x,y]格式返回不可访问坐标的极点.
var p = polylabel(polygon, 1.0);
算法如何工作:
这是一种迭代的基于网格的算法,首先用大方形单元覆盖多边形,然后按照最有希望的单元的顺序迭代地分割它们,同时积极地修剪不感兴趣的单元.
- 生成完全覆盖多边形的初始方形单元格(单元格大小等于宽度或高度,以较低者为准).计算从每个单元格的中心到外部多边形的距离,如果该点位于多边形外部(通过光线投射检测),则使用负值.
- 将单元放入优先级队列,该队列按单元内单元点的最大可能距离排序,定义为距中心和单元半径的距离之和(等于cell_size*sqrt(2)/ 2).
- 计算距多边形质心的距离,并选择它作为第一个"迄今为止最好的".
- 从优先级队列中逐个拉出单元格.如果单元格的距离优于当前最佳距离,请将其保存.然后,如果单元格可能包含当前最佳的更好的解决方案(cell_max - best_dist> precision),则将其拆分为4个子单元格并将它们放入队列中.
- 当我们耗尽队列并将最佳单元的中心作为不可访问的极点返回时停止算法.它将保证在给定精度范围内成为全局最优.