这两天在给公司做开发的时候,遇到一个需求:标出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 ( ) {
return \"<div class=\'table\'><ul><li><a>\" + .feature.properties.name + \"</a></li><li =\'GHTC(\\\"\"+ .feature.properties.name+\"\\\")\'><a>管护人信息</a></li><li ><a =\'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; 64,\';
//下载的表格模板数据
var template = `<html ns:o=\"urn:schemas-microsoft-com:office:office\"
ns:x=\"urn:schemas-microsoft-com:office:excel\"
ns=\"http://www.w3.org/TR/REC-html40\">
<head><!--[if gte mso 9]>< ><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>
<x:Name>${worksheet}</x:Name>
<x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>
</x:ExcelWorksheets></x:ExcelWorkbook></ ><![endif]-->
</head><body><table>${str}</table></body></html>`;
//下载模板
window.location.href = uri + 64(template)
}
//输出 64编码
function 64 (s) { return window.btoa(unescape(encodeURIComponent(s))) }
在生成的excel中使用我之前文中提到的方法,批量生成update的sql语句,再更新到数据库中
继续阅读与本文标签相同的文章
上一篇 :
5G套餐价格下周揭谜底
-
虚拟机模拟部署Extended Clusters(五)总结
2026-05-18栏目: 教程
-
Java计算两个日期相差的月数
2026-05-18栏目: 教程
-
精准测试与自动化测试的无缝对接
2026-05-18栏目: 教程
-
Arthas 3.1.2 版本发布 | 增加 logger/heapdump/vmoption 命令
2026-05-18栏目: 教程
-
springboot数据库主从方案
2026-05-18栏目: 教程
