【GIS新探索】算法实现在不规则区域内均匀分布点

简介: 1 概要         在不规则区域内均匀分布点,这个需求初看可能不好理解。如果设想一下需求场景就比较简单了。         场景1:在某个地区范围内,例如A市区有100W人口,需要将这100W人口在地图上面相对均匀的标识出来。

1 概要

        在不规则区域内均匀分布点,这个需求初看可能不好理解。如果设想一下需求场景就比较简单了。

        场景1:在某个地区范围内,例如A市区有100W人口,需要将这100W人口在地图上面相对均匀的标识出来。

        场景2:某不规则场馆,需要均匀布置展位,快速生成展位示意图。

        场景其他:规则的电线杆、移动基站等模拟生成。

 

2 设计方案

        既然是要求相对均匀的分布,我想到了格网法,即将多边形分割成特定边长的正方形格子,每个格子的中心点作为分布点。

        好处:得到的点是绝对均匀的。

        难点:需要判断格子是否在多边形范围内。

        示意图:

        

        其中1 2 3 4 四个点代表了不规则多边形的外接矩形角点。绿色的点用来算出1 2 3 4点的。

3 实现

        第一步先看看模拟区域。

        第二步画格子。

        第三步标注格子中间的点。

        第四步取出在区域范围内的格子中心点。

        至此,基本满足了要求,部分格子的位置细节稍作调整就好。

4 代码    

        第一步,绘制区域,使用的是canvas。

//公共方法,canvas绘制
var drawFunc={
    ctx:null,
    init:function(domId){
        //获取canvas容器
        var can = document.getElementById(domId);
        //创建一个画布
        var ctx = can.getContext('2d');
        this.ctx=ctx;
    },
    drawArea:function(pts,background){
        this.ctx.beginPath();
         
        var pt=pts[0];
        this.ctx.moveTo(pt[0],pt[1]);          
 
        for(var i=1;i<pts.length;i++){
            var pt=pts[i];
            this.ctx.lineTo(pt[0],pt[1]);    
        }
        this.ctx.fillStyle = background;
        this.ctx.fill();
         
        this.ctx.closePath();
    },
     
    drawPoint:function(point,color,size){
        this.ctx.beginPath();
        this.ctx.arc(point[0], point[1], size, 0, 2*Math.PI, true);
         
        this.ctx.fillStyle =color;
        this.ctx.fill();   
         
        this.ctx.closePath();
    },
     
    drawLine:function(pts,lineWidth,color){
        this.ctx.beginPath();
        this.ctx.lineWidth=lineWidth;
         
        var pt=pts[0];
        this.ctx.moveTo(pt[0],pt[1]);    
        for(var i=1;i<pts.length;i++){
            var pt=pts[i];
            this.ctx.lineTo(pt[0],pt[1]);    
        }
        this.ctx.strokeStyle = color;
        this.ctx.stroke();
    }
}

  

//01 创建不规则多边形
    var pts=[];
    pts.push([100,400]);
    pts.push([800,400]);
    pts.push([800,100]);
    pts.push([500,100]);
    pts.push([500,250]);
    pts.push([100,250]);
    drawFunc.drawArea(pts,"#cddc39");

  

        第二步,绘制格子。这里有两个步骤,获取外接矩形和根据特定间距绘制格子。

/**
*绘制格网,并返回格网中心点
**/
function buildBox(space,startPt,endPt){
    var width=endPt[0]-startPt[0];
    var height=endPt[1]-startPt[1];
         
    var y2=endPt[1];
    for(var i=0;i<width;i+=space){
        var x=startPt[0]+i;
         
        var y1=startPt[1];    
         
        drawFunc.drawLine([[x,y1],[x,y2]],1,"#eee");
    }
     
    var x2=endPt[0];
    for(var i=0;i<height;i+=space){    
        var x1=startPt[0];    
        var y=startPt[1]+i;       
         
        drawFunc.drawLine([[x1,y],[x2,y]],1,"#eee");
    }
     
    var points=[];
     
    for(var i=space;i<width;i+=space){
        var x=startPt[0]+i-space/2;       
        for(var n=space;n<height;n+=space){
            var y=startPt[1]+n-space/2;           
             
            points.push([x,y]);
        }
    }
     
    return points;
}

  

   //02 求不规则多边形外接矩形左上右下点
    var box=queryMaxMinPt(pts);
        //03 以一定的间距绘制格网,并返回格网中心点  
    var points= buildBox(20,box.startPt,box.endPt);
/*
*求多边形外接矩形左上右下点
*/
function queryMaxMinPt(points){
    var x_min=100000000000000;
    var x_max=-1;
     
    var y_min=100000000000000;
    var y_max=-1;
     
    for(var i=0;i<points.length;i++){
        var pt=points[i];
         
        if(pt[0]<x_min)
            x_min=pt[0];
        if(pt[0]>x_max)
            x_max=pt[0];
             
        if(pt[1]<y_min)
            y_min=pt[1];
        if(pt[1]>y_max)
            y_max=pt[1];
    }
     
    return {
        startPt:[x_min,y_min],
        endPt:[x_max,y_max]
    }
         
     
}

    第三和四步,查找在区域范围内的格子,并绘制。

/**
*检查点是否在多边形范围内
**/
function checkInside (point, vs) {    
    var x = point[0], y = point[1];
     
    var inside = false;
    for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
        var xi = vs[i][0], yi = vs[i][1];
        var xj = vs[j][0], yj = vs[j][1];
         
        var intersect = ((yi > y) != (yj > y))
            && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
        if (intersect) inside = !inside;
    }
     
    return inside;
};

      注:checkInside方法来源自Git,地址:https://github.com/substack/point-in-polygon/blob/master/index.js

//04 遍历中心点,判断点是否在范围内
    var pointCount=0;
    for(var i=0;i<points.length;i++){
        var pt=points[i];
        if(checkInside(pt,pts)){
            drawFunc.drawPoint(pt,"red",2);
            pointCount++;
        }
             
    }
     
    console.log("范围内有:"+pointCount+"个点");

  

以上就是核心的实现代码,如果需要下载源码请移步我的博客下载,地址:

http://www.88gis.cn/web/pages/blog/blogInfo.html?id=38d8959a-f348-41df-b507-6c10e517e7a7

 

查看更多GIS、WPF、JAVA、前端技术分享,请访问我的个人技术网站,查看更多技术分享。网站地址:www.88gis.cn

 

相关文章
|
3月前
|
算法 前端开发 机器人
一文了解分而治之和动态规则算法在前端中的应用
该文章详细介绍了分而治之策略和动态规划算法在前端开发中的应用,并通过具体的例子和LeetCode题目解析来说明这两种算法的特点及使用场景。
一文了解分而治之和动态规则算法在前端中的应用
|
4月前
|
数据可视化 算法 前端开发
基于python flask+pyecharts实现的中药数据可视化大屏,实现基于Apriori算法的药品功效关系的关联规则
本文介绍了一个基于Python Flask和Pyecharts实现的中药数据可视化大屏,该系统应用Apriori算法挖掘中药药材与功效之间的关联规则,为中医药学研究提供了数据支持和可视化分析工具。
138 2
|
5月前
|
数据采集 机器学习/深度学习 算法
Python基于Apriori关联规则算法实现商品零售购物篮分析
Python基于Apriori关联规则算法实现商品零售购物篮分析
321 0
|
6月前
|
机器学习/深度学习 算法 测试技术
如何应对缺失值带来的分布变化?探索填充缺失值的最佳插补算法
该文探讨了缺失值插补的不同方法,比较了它们恢复数据真实分布的效果。文章指出,处理插补尤其在小样本或复杂数据时是个挑战,需要选择能适应数据分布变化的方法。文中介绍了完全随机缺失(MCAR)、随机缺失(MAR)和非随机缺失(MNAR)三种机制,并以一个简单的例子展示了数据分布变化。文章通过比较均值插补、回归插补和高斯插补,强调了高斯插补在重现数据分布方面更优。评估插补方法时,不应仅依赖于RMSE,而应关注分布预测,使用如能量距离这样的指标。此外,即使在随机缺失情况下,数据分布也可能因模式变化而变化,需要考虑适应这些变化的插补方法。
161 2
|
6月前
|
机器学习/深度学习 算法 搜索推荐
【机器学习】Apriori算法在关联规则学习中的应用
【机器学习】Apriori算法在关联规则学习中的应用
96 0
|
7月前
|
机器学习/深度学习 算法
应用规则学习算法识别有毒的蘑菇
应用规则学习算法识别有毒的蘑菇
|
7月前
|
算法 数据可视化 数据挖掘
【视频】关联规则模型、Apriori算法及R语言挖掘商店交易数据与交互可视化|数据分享
【视频】关联规则模型、Apriori算法及R语言挖掘商店交易数据与交互可视化|数据分享
|
7月前
|
数据采集 机器学习/深度学习 算法
数据分享|WEKA关联规则挖掘Apriori算法在学生就业数据中的应用
数据分享|WEKA关联规则挖掘Apriori算法在学生就业数据中的应用
|
7月前
|
数据可视化 算法 数据挖掘
R语言关联规则模型(Apriori算法)挖掘杂货店的交易数据与交互可视化
R语言关联规则模型(Apriori算法)挖掘杂货店的交易数据与交互可视化
|
7月前
|
算法 数据可视化 搜索推荐
数据分享|Python用Apriori算法关联规则分析亚马逊购买书籍关联推荐客户和网络图可视化
数据分享|Python用Apriori算法关联规则分析亚马逊购买书籍关联推荐客户和网络图可视化