leaflet-计算地图边界的重心点经纬度

这两天在给公司做开发的时候,遇到一个需求:标出1000多个村的重心点位置(就是确定一点在村的中心位置的坐标)。以前在做安徽省内的系统时,村子没有那么多也就100左右,当时技术跟不上就用了笨方法,使用人眼去识别村子的经纬度(现在想想好傻呀。。。)。这个方法一是耗时,二是由于是人眼去识别容易出错。这次可是1000多个村子,要是这么搞得要人命!

于是乎我就在想如何让代码自己去找重心的位置,这样又快又准。在一个同事的提醒下,想起来自己以前在做移动端app的地图开发时,用过一个方法去寻找地图的重心位置。(通过已知的边界点去计算多边形的重心位置(数学算法果然重要))

说一下我的思路:

  1. 使用ajax异步向后台的表去取数据
  2. 将取回的边界数据放入重心的方法中
  3. 将得出的结果和村的编号一起存放在json数组中
  4. 在将数组中的数据重新编码生成excel表中
  5. 使用我之前处理excel数据的方法,将数据生成sql语句
  6. 将数据批量的更新到数据库中

使用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

You may also like...