Python 射线法判断一个点坐标是否在一个坐标区域内

本文介绍了一个使用Python实现的射线法算法,该算法用于判断一个点坐标是否位于一个多边形坐标区域内部。通过计算外包矩形并判断点与多边形各边的关系,实现了高效的点位置判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python 射线法判断一个点坐标是否在一个坐标区域内

class Point:
    lng = ''
    lat = ''
 
    def __init__(self, lng, lat):
        self.lng = lng
        self.lat = lat
 
 
# 求外包矩形
def get_polygon_bounds(points):
    length = len(points)
    top = down = left = right = points[0]
    for i in range(1, length):
        if points[i].lng > top.lng:
            top = points[i]
        elif points[i].lng < down.lng:
            down = points[i]
        else:
            pass
        if points[i].lat > right.lat:
            right = points[i]
        elif points[i].lat < left.lat:
            left = points[i]
        else:
            pass
    top_left = Point(top.lng, left.lat)
    top_right = Point(top.lng, right.lat)
    down_right = Point(down.lng, right.lat)
    down_left = Point(down.lng, left.lat)
    return [top_left, top_right, down_right, down_left]
 
 
# 判断点是否在外包矩形外
def is_point_in_rect(point, polygon_bounds):
    top_left = polygon_bounds[0]
    top_right = polygon_bounds[1]
    down_right = polygon_bounds[2]
    down_left = polygon_bounds[3]
    return (down_left.lng <= point.lng <= top_right.lng
            and top_left.lat <= point.lat <= down_right.lat)
 
 
def is_point_in_polygon(point, points):
    polygon_bounds = get_polygon_bounds(points)
    if not is_point_in_rect(point, polygon_bounds):
        return False
    length = len(points)
    point_start = points[0]
    flag = False
    for i in range(1, length):
        point_end = points[i]
        # 点与多边形顶点重合
        if (point.lng == point_start.lng and point.lat == point_start.lat) or (
                point.lng == point_end.lng and point.lat == point_end.lat):
            return True
        # 判断线段两端点是否在射线两侧
        if (point_end.lat < point.lat <= point_start.lat) or (
                point_end.lat >= point.lat > point_start.lat):
            # 线段上与射线 Y 坐标相同的点的 X 坐标
            if point_end.lat == point_start.lat:
                x = (point_start.lng + point_end.lng) / 2
            else:
                x = point_end.lng - (point_end.lat - point.lat) * (
                        point_end.lng - point_start.lng) / (
                        point_end.lat - point_start.lat)
            # 点在多边形的边上
            if x == point.lng:
                return True
            # 射线穿过多边形的边界
            if x > point.lng:
                flag = not flag
            else:
                pass
        else:
            pass
 
        point_start = point_end
    return flag
 
 
def test(input_lat=116.732617, input_lon=39.722676):
    # polyline 是多个坐标点,形如
    polyline = ['115.732617,40.722676', '117.732617,40.722676', '115.732617,38.722676',
    '117.732617,38.722676', '118.732617,39.722676']
    # polyline = []

    points = []
    for line in polyline:
        if line:
            try:
                lat, lon = line.split(',')
                points.append(Point(float(lat), float(lon)))
            except ValueError:
                pass
    if points:
        a = is_point_in_polygon(Point(float(input_lat), float(input_lon)), points)
        print(a)

test(116.732617, 39.722676)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值