leaflet-计算地图边界的重心点经纬度
目录
这两天在给公司做开发的时候,遇到一个需求:标出1000多个村的重心点位置(就是确定一点在村的中心位置的坐标)。以前在做安徽省内的系统时,村子没有那么多也就100左右,当时技术跟不上就用了笨方法,使用人眼去识别村子的经纬度(现在想想好傻呀。。。)。这个方法一是耗时,二是由于是人眼去识别容易出错。这次可是1000多个村子,要是这么搞得要人命!
于是乎我就在想如何让代码自己去找重心的位置,这样又快又准。在一个同事的提醒下,想起来自己以前在做移动端app的地图开发时,用过一个方法去寻找地图的重心位置。(通过已知的边界点去计算多边形的重心位置(数学算法果然重要))
说一下我的思路:
- 使用ajax异步向后台的表去取数据
- 将取回的边界数据放入重心的方法中
- 将得出的结果和村的编号一起存放在json数组中
- 在将数组中的数据重新编码生成excel表中
- 使用我之前处理excel数据的方法,将数据生成sql语句
- 将数据批量的更新到数据库中
使用Ajax异步获取数据
//定义一个变量存储返回的边界数据
var Cunjie;
function allcunjie() {
cleanpolygon();
for(var i=0;i<Alldata.length;i++ ) {
$.ajax({
type: 'POST',
url: '/gis/getZoneBorderByPk.in',
dataType: 'json',
data: {
'pk': Alldata[i].pk
},
async: true,
success: function (data) {
Cunjie = JSON.parse(data.data.border);
// console.log(data.data.zoneno);
if (data.type == 'success') {
L.geoJSON(Cunjie, {
style: function (feature) {
return {
color: '#FF0000',
fillOpacity: 0,
weight: 2
};
}
}).bindPopup(function (layer) {
return "<div class='table'><ul><li><a>" + layer.feature.properties.name + "</a></li><li onclick='GHTC(\""+layer.feature.properties.name+"\")'><a>管护人信息</a></li><li ><a onclick='DiKuaidkdm(\""+data.data.cjqydm+"\")'>查看地块信息</a></li></ul>";
}).on({
// mouseover: highlight, //鼠标移动上去高亮
// mouseout: resetHighlight, //鼠标移出恢复原样式
click: zoomTo //点击最大化
}).addTo(myGroup);
//生成地图重心
var a=eval('(' + data.data.border + ')');
var b=a.geometry.coordinates[0];
console.log(b);
border_center=getPolygonAreaCenter(exchenge(b),data.data.cjqydm);
console.log(border_center);
}
else {
alert("error");
}
}
});
}
}
使用for循环获取每一个村唯一的uuid值pk,再利用pk值使用ajax向后台异步请求,也就是说执行1000多次的ajax请求,并在每一个请求获得返回值后执行重心的方法(这样就不会出现数据不匹配的情况)
通过多边形边界的点数据求取重心位置
//定义数组存取数据
var testone;
/*计算三角形的面积*/
function Area(p0, p1, p2) {
var area = 0.0;
area = p0[1] * p1[0] + p1[1] * p2[0] + p2[1] * p0[0] - p1[1] * p0[0] - p2[1] * p1[0] - p0[1] * p2[0];
return area / 2;
}
// 计算polygon的质心
function getPolygonAreaCenter(points,code) {
console.log(code);
var xy = {};
var sum_x = 0;
var sum_y = 0;
var sum_area = 0;
var p1 = points[1];
//debugger;
for (var i = 2; i < points.length; i++) {
p2 = points[i];
area = Area(points[0], p1, p2);
sum_area += area;
sum_x += (points[0][1] + p1[1] + p2[1]) * area;
sum_y += (points[0][0] + p1[0] + p2[0]) * area;
p1 = p2;
}
var xx = sum_x / sum_area / 3;
var yy = sum_y / sum_area / 3;
xy.lat = yy.toFixed(5);
xy.lng = xx.toFixed(5);
xy.code=code;
//将生成的点坐标和cjqydm存放在数组testone中
testone.push(xy);
console.log(testone.length);
console.log(testone);
return xy;
}
将json数组的数据导出生成excel
function tableToExcel(){
//要导出的json数据
//列标题
var str = '<tr><td>lat</td><td>lng</td><td>cjqydm</td></tr>';
//循环遍历,每行加入tr标签,每个单元格加td标签
for(let i = 0 ; i < testone.length ; i++ ){
str+='<tr>';
for(let item in testone[i]){
//增加\t为了不让表格显示科学计数法或者其他格式
str+=`<td>${ testone[i][item] + '\t'}</td>`;
}
str+='</tr>';
}
//Worksheet名
var worksheet = 'Sheet1'
var uri = 'data:application/vnd.ms-excel;base64,';
//下载的表格模板数据
var template = `<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns="http://www.w3.org/TR/REC-html40">
<head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>
<x:Name>${worksheet}</x:Name>
<x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>
</x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->
</head><body><table>${str}</table></body></html>`;
//下载模板
window.location.href = uri + base64(template)
}
//输出base64编码
function base64 (s) { return window.btoa(unescape(encodeURIComponent(s))) }
在生成的excel中使用我之前文中提到的方法,批量生成update的sql语句,再更新到数据库中
转载自:https://blog.csdn.net/qq_36213352/article/details/85135889