如何判断一个指定的经纬度点是不是落在一个多边形区域内

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何判断一个指定的经纬度点是不是落在一个多边形区域内相关的知识,希望对你有一定的参考价值。

参考技术A 1、理论支持:如果从需要判断的点出发的一条射线与该多边形的焦点个数为奇数,则该点在此多边形内,否则该点在此多边形外。(射线不能与多边形顶点相交)2、编程思路:该程序的思路是从A点出发向左做一条水平射线(平行于x轴,向X轴的反方向),判断与各边是否有焦点。dLon1,dLon2,dLat1,dLat2分别表示边的起点和终点的经度和纬度(x轴和y轴)。先判断A点是否在边的两端点d1和d2的水平平行线之间,不在则不可能有交点,继续判断下一条边。在之间则说明可能与A点向左的射线有交点,接下来利用几何方法得到A点的水平直线与该边交点的x坐标。然后判断交点的x坐标在A点的左侧还是右侧,左侧则总交点数加一,右侧则不在A点左射线上,继续判断下一条边。3、原文代码如下(Dephi):TypeTMyPoint=packedrecordX:double;Y:double;end;

如何判断点在一个区域内?用户绘制区域(射线法)判断点在多边形区域,报警区域

参考文章:判断一个点是否在指定区域内

文章目录

VS测试代码:test.c(测试传入坐标顺时针、逆时针,发现没啥区别!)

#pragma warning(disable : 4996)
#include<stdio.h>
#include<stdlib.h>

#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)

typedef struct

    double x, y;
Point;


int InsidePolygon(Point* polygon, int N, Point p)

    int counter = 0;
    int i;
    double xinters;
    Point p1, p2;
    p1 = polygon[0];
    for (i = 1; i <= N; i++)
    
        p2 = polygon[i % N];
        if (p.y > MIN(p1.y, p2.y))
        
            //低
            if (p.y <= MAX(p1.y, p2.y))
            
                //高
                if (p.x <= MAX(p1.x, p2.x))
                
                    //右
                    if (p1.y != p2.y)
                    
                        //简单忽略平行X轴这种情况
                        xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
                        //交叉点坐标 参考./media/point-and-polygon/xinters.jpg
                        if (p1.x == p2.x || p.x <= xinters)
                            counter++;
                    
                
            
        
        p1 = p2;
    
    if (counter % 2 == 0)
        return 0;
    else
        return 1;


int main()

    Point points[4] =  0, 1, 3, 0, 3, 4, 0, 3 ;	//逆时针闭合图形
    Point points[4] =  0, 1, 0, 3, 3, 4, 3, 0 ;	//顺时针闭合图形	//测试发现,顺时针和逆时针的结果是相同的
    //Point p0 =  0, 0 ;    //0   //外
    //Point p0 =  0, 1 ;    //1   //边界
    //Point p0 =  1, 0 ;    //0   //外
    //Point p0 =  2, 1 ;    //1   //内
    //Point p0 =  2, 2 ;    //1     //内
    //Point p0 =  2, 3 ;    //1   //内
    //Point p0 =  2, 4 ;    //0   //外
    //Point p0 =  4, 0 ;        //0     //外
    //Point p0 =  -2, -2 ;    //0   //外  
    //Point p0 =  -2, 2 ;       //0     外
    //Point p0 =  2, -2 ;       //0     //外
    Point p0 =  1, 1 ;    //1 //内
    printf("is point in polygon: %d\\n", InsidePolygon(points, sizeof(points) / sizeof(Point), p0)); //在区域外返回0,区域内返回1,边界上没有测试

    return 0;

测试从外部横向穿越多边形顶点、从内部穿越多边形顶点、穿越水平边的情况

#pragma warning(disable : 4996)
#include<stdio.h>
#include<stdlib.h>

#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)

typedef struct

    double x, y;
Point;


int InsidePolygon(Point* polygon, int N, Point p)

    int counter = 0;
    int i;
    double xinters;
    Point p1, p2;
    p1 = polygon[0];
    for (i = 1; i <= N; i++)
    
        p2 = polygon[i % N];
        if (p.y > MIN(p1.y, p2.y))
        
            //低
            if (p.y <= MAX(p1.y, p2.y))
            
                //高
                if (p.x <= MAX(p1.x, p2.x))
                
                    //右
                    if (p1.y != p2.y)
                    
                        //简单忽略平行X轴这种情况
                        xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
                        //交叉点坐标 参考./media/point-and-polygon/xinters.jpg
                        if (p1.x == p2.x || p.x <= xinters)
                            counter++;
                    
                
            
        
        p1 = p2;
    
    if (counter % 2 == 0)
        return 0;
    else
        return 1;


int main()



    Point points[6] =  0, 1, 1, 2, 0, 3, 3, 3, 5, 4, 3, 0 ;
    

    //0外1内
    
    //Point p0 =  0, 0 ;  //从外部横向穿越顶点   //0


    //Point p0 =  0, 2 ;    //从内部横向穿越顶点 //0
    //Point p0 =  2, 2 ;    //从内部横向穿越顶点 //1
    
    //Point p0 =  -1, 3 ;  //横向跨越水平线(在多边形外)    //0
    Point p0 =  4, 3 ;  //横向跨越水平线(在多边形内)    //1
    
    printf("is point in polygon: %d\\n", InsidePolygon(points, sizeof(points) / sizeof(Point), p0)); //在区域外返回0,区域内返回1,边界上没有测试

    return 0;

测试发现没啥问题,基本正确

VS测试代码:test.c(测试百分比坐标模式)

#pragma warning(disable : 4996)
#include<stdio.h>
#include<stdlib.h>

#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)

typedef struct

    double x, y;
Point;


int InsidePolygon(Point* polygon, int N, Point p)

    int counter = 0;
    int i;
    double xinters;
    Point p1, p2;
    p1 = polygon[0];
    for (i = 1; i <= N; i++)
    
        p2 = polygon[i % N];
        if (p.y > MIN(p1.y, p2.y))
        
            //低
            if (p.y <= MAX(p1.y, p2.y))
            
                //高
                if (p.x <= MAX(p1.x, p2.x))
                
                    //右
                    if (p1.y != p2.y)
                    
                        //简单忽略平行X轴这种情况
                        xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
                        //交叉点坐标 参考./media/point-and-polygon/xinters.jpg
                        if (p1.x == p2.x || p.x <= xinters)
                            counter++;
                    
                
            
        
        p1 = p2;
    
    if (counter % 2 == 0)
        return 0;
    else
        return 1;


int main()

    //Point points[4] =  0, 1, 0, 3, 3, 4, 3, 0;  
    Point points[4] =  0, 0.25, 0, 0.75, 1, 1, 1, 0 ; //假设总区域是(0, 0)-> (3, 4)
    

    //0外1内
    
    //Point p0 =  0, 0 ;
    //Point p0 =  0, 0 ;  //0


    //Point p0 =  1, 0 ;
    //Point p0 =  0.33, 0 ; //0
    
    //Point p0 =  2, 0 ;
    //Point p0 =  0.66, 0 ; //0
    
    //Point p0 =  1, 1 ;
    //Point p0 =  0.33, 0.25 ;  //1

    //Point p0 =  1, 2 ;
    //Point p0 =  0.33, 0.5 ;   //1
    // 
    //Point p0 =  2, 2 ;
    //Point p0 =  0.66, 0.5 ;   //1

    //Point p0 =  1, 3 ;
    //Point p0 =  0.33, 0.75 ;    //1

    //Point p0 =  2, 3 ;
    //Point p0 =  0.66, 0.75 ;  //1
    
    //Point p0 =  1, 4 ;
    //Point p0 =  0.33, 1 ; //0

    //Point p0 =  2, 4 ;
    //Point p0 =  0.33, 1 ; //0
    // 
    //Point p0 =  3, 5 ;
    //Point p0 =  1, 1.25 ; //0

    //Point p0 = 4, 0;
    Point p0 = 1.33, 0;  //0


    printf("is point in polygon: %d\\n", InsidePolygon(points, sizeof(points) / sizeof(Point), p0)); //在区域外返回0,区域内返回1,边界上没有测试

    return 0;

百分比坐标测试也没有问题

代码原理

主要是射线法

参考文章:【计算几何】判断一个点是否在多边形内部

以上是关于如何判断一个指定的经纬度点是不是落在一个多边形区域内的主要内容,如果未能解决你的问题,请参考以下文章

根据GPS经纬度判断当前所属的市区

百度地图多边形画区域获取节点经纬度坐标判断某一点是否在此区域内

如何判断点在一个区域内?用户绘制区域(射线法)判断点在多边形区域,报警区域

如何判断点在一个区域内?用户绘制区域(射线法)判断点在多边形区域,报警区域

怎么判断一个点是不是在多边形区域内

Mongodb:如何检查一个点是不是包含在多边形中?