2025年判断一个点是否在多边形区域内

判断一个点是否在多边形区域内主要是用在地图上判断 网上看到主要有两种方式 1 PNPoly 算法 def IsPtInPoly aLon aLat pointList param aLon double 经度 param aLat double 纬度 param pointList list lon lat

大家好,我是讯享网,很高兴认识大家。

主要是用在地图上判断

网上看到主要有两种方式

1.PNPoly 算法


讯享网

def IsPtInPoly(aLon, aLat, pointList): ''' :param aLon: double 经度 :param aLat: double 纬度 :param pointList: list [(lon, lat)...] 多边形点的顺序需根据顺时针或逆时针,不能乱 ''' iSum = 0 iCount = len(pointList) if (iCount < 3): return False for i in range(iCount): pLon1 = pointList[i][0] pLat1 = pointList[i][1] if (i == iCount - 1): pLon2 = pointList[0][0] pLat2 = pointList[0][1] else: pLon2 = pointList[i + 1][0] pLat2 = pointList[i + 1][1] if ((aLat >= pLat1) and (aLat < pLat2)) or ((aLat >= pLat2) and (aLat < pLat1)): if (abs(pLat1 - pLat2) > 0): pLon = pLon1 - ((pLon1 - pLon2) * (pLat1 - aLat)) / (pLat1 - pLat2) if (pLon < aLon): iSum += 1 if (iSum % 2 != 0): return True else: return False

讯享网

2.射线法

输入的是墨卡托坐标

讯享网# -*- coding: utf-8 -*- """ @Description: 几何计算工具类 @Author: @Date: 2020-05-27 17:10 """ from typing import Tuple class Coord: """ 坐标类 """ x, y = 0, 0 def __init__(self, x: int, y: int): self.x = x self.y = y def __eq__(self, other): return self.x == other.x and self.y == other.y def __hash__(self): return hash(self.x + self.y) def __str__(self): return str(self.x) + ',' + str(self.y) def __lt__(self, other): return (self.x + self.y) < (other.x + other.y) class Section: """ 线段 """ def __init__(self, x1, y1, x2, y2): self.x1 = x1 self.x2 = x2 self.y1 = y1 self.y2 = y2 def cross_point(section1: Section, section2: Section) -> Tuple[bool, int or None, int or None]: """ 计算线段交点 Args: section1: 线段1 section2: 线段2 Returns: 交点坐标 """ # ab cd 两条线段求交点坐标 area_abc = (section1.x1 - section2.x1) * (section1.y2 - section2.y1) - \ (section1.y1 - section2.y1) * (section1.x2 - section2.x1) area_abd = (section1.x1 - section2.x2) * (section1.y2 - section2.y2) - \ (section1.y1 - section2.y2) * (section1.x2 - section2.x2) if (area_abc * area_abd) >= 0: return False, None, None area_cda = (section2.x1 - section1.x1) * (section2.y2 - section1.y1) - (section2.y1 - section1.y1) * ( section2.x2 - section1.x1) area_cdb = area_cda + area_abc - area_abd if (area_cda * area_cdb) >= 0: return False, None, None # 计算交点坐标 tmp = area_cda / (area_abd - area_abc) dx = tmp * (section1.x2 - section1.x1) dy = tmp * (section1.y2 - section1.y1) return True, section1.x1 + dx, section1.y1 + dy def is_in_polygon(pt: tuple, rings: list) -> bool: """ 判断点在多边形内,向右射线法 Args: pt: 点 rings: 多边形点集 Returns: 点是否在多边形内 """ count = 0 for i in range(len(rings)): prev = i + 1 if prev == len(rings): prev = 0 r1 = rings[i] r2 = rings[prev] # 向右射线, 线段至少有一个点在判断点的右侧 if ((r1.y >= pt[1] >= r2.y) and (r1.x > pt[0] or r2.x > pt[0])) or ( (r2.y >= pt[1] >= r1.y) and (r1.x > pt[0] or r2.x > pt[0])): # 向右射线共线 if cross_point(Section(r1.x, r1.y, r2.x, r2.y), Section(pt[0], pt[1], pt[0] + 10000, pt[1]))[0]: count += 1 elif r1.y == pt[1]: count += 1 return count % 2 == 1 

为什么不用经纬度,是因为画图的时候,三维和二维直线有误差,所以在计算的时候用二维坐标

小讯
上一篇 2025-02-20 11:30
下一篇 2025-03-22 22:46

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/75942.html