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

2023-11-09

1、理论支持:如果从需要判断的点出发的一条射线与该多边形的焦点个数为奇数,则该点在此多边形内,否则该点在此多边形外。(射线不能与多边形顶点相交)

2、编程思路:

该程序的思路是从A点出发向左做一条水平射线(平行于x轴,向X轴的反方向),判断与各边是否有焦点。

dLon1, dLon2, dLat1, dLat2分别表示边的起点和终点的经度和纬度(x轴和y轴)。

先判断A点是否在边的两端点d1和d2的水平平行线之间,不在则不可能有交点,继续判断下一条边。

在之间则说明可能与A点向左的射线有交点,接下来利用几何方法得到A点的水平直线与该边交点的x坐标。

然后判断交点的x坐标在A点的左侧还是右侧,左侧则总交点数加一,右侧则不在A点左射线上,继续判断下一条边。

3、原文代码如下(Dephi):
Type
  TMyPoint
= packed record
    X : double;
    Y : double;
 
end;

{*------------------------------------------------------------------------------
  判 断指定的经纬度坐标点是否落在指定的多边形区域内
  @param ALon   指定点的经度
  @param ALat   指定点的纬度
  @param APoints   指定多边形区域各个节点坐标
  @return True 落在范围内 False 不在范围内
------------------------------------------------------------------------------*
}
function IsPtInPoly(ALon, ALat: double; APoints: array of TMyPoint): Boolean;
var
  iSum, iCount, iIndex: Integer;
  dLon1, dLon2, dLat1, dLat2, dLon: double;
begin
  Result :
= False;
 
if (Length(APoints) < 3) then
 
begin
    Result :
= False;
    Exit;
 
end;
  iSum :
= 0;
  iCount :
= Length(APoints);
 
for iIndex :=0 to iCount - 1 do
 
begin
   
if (iIndex = iCount - 1) then
   
begin
      dLon1 :
= APoints[iIndex].X;
      dLat1 :
= APoints[iIndex].Y;
      dLon2 :
= APoints[0].X;
      dLat2 :
= APoints[0].Y;
   
end
   
else
   
begin
      dLon1 :
= APoints[iIndex].X;
      dLat1 :
= APoints[iIndex].Y;
      dLon2 :
= APoints[iIndex + 1].X;
      dLat2 :
= APoints[iIndex + 1].Y;
   
end;
   //以下语句判断A点是否在边的两端点的水平平行线之间,在则可能有交点,开始判断交点是否在左射线上
   
if ((ALat >= dLat1) and (ALat < dLat2)) or ((ALat>=dLat2) and (ALat < dLat1)) then
   
begin
     
if (abs(dLat1 - dLat2) > 0) then
     
begin

       //得到 A点向左射线与边的交点的x坐标
        dLon :
= dLon1 - ((dLon1 -dLon2) * (dLat1 -ALat)) / (dLat1 - dLat2);

       // 如果交点在A点左侧(说明是做射线与 边的交点),则射线与边的全部交点数加一
        if (dLon < ALon) then
          Inc(iSum);
     
end;
   
end;

 
end;
 
if (iSum mod 2 <> 0) then
    Result :
= True;
end;


(C#)

public bool IsPtInPoly(double ALon, double ALat, List<Point> APoints)
        {
            int iSum = 0, iCount;
            double dLon1, dLon2, dLat1, dLat2, dLon;
            if (APoints.Count < 3)
                return false;
            iCount = APoints.Count;
            for (int i = 0; i < iCount - 1; i++)
            {
                if (i == iCount - 1)
                {
                    dLon1 = APoints[i].X;
                    dLat1 = APoints[i].Y;
                    dLon2 = APoints[0].X;
                    dLat2 = APoints[0].Y;
                }
                else
                {
                    dLon1 = APoints[i].X;
                    dLat1 = APoints[i].Y;
                    dLon2 = APoints[i + 1].X;
                    dLat2 = APoints[i + 1].Y;
                }
                //以下语句判断A点是否在边的两端点的水平平行线之间,在则可能有交点,开始判断交点是否在左射线上
                if (((ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1)))
                {
                    if (Math.Abs(dLat1 - dLat2) > 0)
                    {
                        //得到 A点向左射线与边的交点的x坐标:
                        dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat)) / (dLat1 - dLat2);

                        // 如果交点在A点左侧(说明是做射线与 边的交点),则射线与边的全部交点数加一:
                        if (dLon < ALon)
                            iSum++;
                    }
                }
            }
            if (iSum % 2 != 0)
                return true;
            return false;
        }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何判断一个指定的经纬度点是否落在一个多边形内 的相关文章

  • 必须打开存储才能执行此操作 - System.IO.Packaging.Package

    我正在使用 System IO Packaing Package 类来压缩文件 我的应用程序的多个实例可以同时运行 并读取和保存文件 当处理小文件时 一切似乎都很好 但是当涉及大文件时 如果应用程序的两个实例同时保存 我会收到一个异常 消息
  • SetWindowsHookEx 函数返回 NULL

    我正在研究 DLL 注入 但收到错误如下 挂接进程失败 87 参数不正确 目标进程和dll都是64位的 注入代码为 BOOL HookInjection TCHAR target TCHAR dll name https msdn micr
  • C修改printf()输出到文件

    有没有办法修改printf为了将字符串输出到文件而不是控制台 我尝试在互联网上查找一些内容 发现了类似的电话dup dup2 and fflush这可能与此有关 EDIT 也许我不清楚 问题是这是C考试问题 问题如下 解释一个通常将字符串输
  • 使用不带参数的 Split() 时,默认分隔符是什么?

    所以我看了看String Split 今天 C 中的方法 我意识到你也可以向它传递零参数 这是我从未考虑过的 使用时默认的分隔符是什么Split 没有任何参数 如果没有值 则为空白 来源自here https msdn microsoft
  • 为什么派生类不使用基类的operator=(赋值运算符)?

    以下是实际问题的简化版本 而不是打电话Base operator int 代码似乎生成了一个临时的Derived对象并复制它 既然函数签名似乎完美匹配 为什么不使用基本赋值运算符 这个简化的示例没有显示任何不良影响 但原始代码在析构函数中有
  • 如何将pdf页面设置设置为打印属性对话框?

    大家好 我想知道如何设置 pdf 页面设置到打印属性对话框 例如 如果我的 PDF 页面设置为横向 则布局会自动显示横向而不是纵向 如果我的 PDF 页面设置为纵向 则布局会自动显示纵向 我在这个主题上做了很多研发 但没有找到任何满意的链接
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 如何使用汇编获取BIOS时间?

    我正在从头开始实现一个小型操作系统 用于教育目的 现在 我想使用汇编来获取 BIOS 时间 我对此进行了很多搜索 但找不到任何代码示例来执行此操作 如果有人可以提供任何参考或代码示例或与此相关的任何内容 我将非常感激 See 时钟中断 1a
  • 如何将字节块读入结构体

    我有一个需要处理的资源文件 它包含一组文件 首先 资源文件列出了其中包含的所有文件 以及一些其他数据 例如在此结构中 struct FileEntry byte Value1 char Filename 12 byte Value2 byt
  • C 中的模仿函数重写

    具体来说 函数重写能够调用基本重写方法 这有两部分 一个是预编译的库代码 1 另一个是库的用户代码 2 我在这里实现了一个尽可能最小的经典 Person 和 Employee 示例 非常感谢了解 OOP 概念的铁杆 C 开发人员的回应 我正
  • 为什么重载方法在 ref 仅符合 CLS 方面有所不同

    公共语言规范对方法重载非常严格 仅允许根据其参数的数量和类型来重载方法 如果是泛型方法 则根据其泛型参数的数量进行重载 根据 csc 为什么此代码符合 CLS 无 CS3006 警告 using System assembly CLSCom
  • 为什么WCF中不允许方法重载?

    假设这是一个ServiceContract ServiceContract public interface MyService OperationContract int Sum int x int y OperationContract
  • `cosf`、`sinf` 等不在 `std` 中 [重复]

    这个问题在这里已经有答案了 根据这里的讨论 我有报告了一个错误 https bugs launchpad net ubuntu source gcc 8 bug 1831385给 Ubuntu 开发者 编译以下示例 C 程序时 includ
  • 当在 Repository/UnitOrWork 之上使用 Service 类时,我应该在哪里放置逻辑不适合 Repository 的常用数据访问代码?

    In my 先前的问题 https stackoverflow com questions 24906548 using the generic repository unit of work pattern in large projec
  • 在 .NET 中记录 StackOverflowException

    最近 我的 NET 应用程序 asp net 网站 中出现了堆栈溢出异常 我之所以知道该异常是因为它出现在我的 EventLog 中 我知道 StackOverflow 异常无法被捕获或处理 但是有没有办法在它杀死您的应用程序之前记录它 我
  • 正在获取“未终止 [] 设置”。 C# 中的错误

    我正在 C 中使用以下正则表达式 Regex find new Regex url
  • 如何使用 ASP.NET Web 表单从代码隐藏中访问更新面板内的文本框、标签

    我在更新面板中定义了一些控件 它们绑定到中继器控件 我需要根据匿名字段隐藏和显示用户名和国家 地区 但问题是我无法以编程方式访问更新面板中定义的控件 我如何访问这些控件 我也在网上查找但找不到很多参考资料 下面是来自aspx页面和 cs页面
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D
  • 如何确定给定方法可以抛出哪些异常?

    我的问题和这个真的一样 找出 C 中方法可能抛出的异常 https stackoverflow com questions 264747 finding out what exceptions a method might throw in

随机推荐

  • 【从零开始的Java开发】1-2-4 Java方法

    文章目录 方法 方法分类 数组作为方法参数 方法重载 基本数据类型的传值 数组的传值 引用数据类型 可变参数列表 可变参数列表作为方法参数的重载 文档注释 方法的调试 细节与总结 方法 所谓方法 就是用来解决一类问题的代码的有序组合 是一个
  • MCU,MPU,MMU,CACHE的含义

    1 mcu和mpu CPU Central Processing Unit 中央处理器 发展出来三个分枝 一个是DSP Digital Signal Processing Processor 数字信号处理 另外两个是MCU Micro Co
  • HTML <colgroup> 标签

    实例 两个 colgroup 元素为表格中的三列规定了不同的对齐方式和样式 注意第一个 colgroup 元素横跨两列 table width 100 border 1 table
  • [138]小米笔记本怎么关闭secure boot

    关闭Secure Boot的步骤 一 关闭 快速启动 功能 1 右键 开始菜单 电源选项 进入后 点击 选择电源按钮的功能 2 进入电源选项设置后 点击 更改当前不可用的设置 再把 启用快速启动 推荐 前边的勾去掉 若没有该选择则不需要操作
  • MDK与芯片的联系

    程序执行的时候FLASH空间 code RO data 程序执行时SRAM空间 RW data ZI data 程序存储时占用空间 code RO data RW data 在目录下打开命令行窗口 按shift 鼠标右键 gt 可以将信息输
  • 区块链:Solidity值类型(Solidity 枚举Enums & 结构体Structs)

    枚举Enums 案例 pragma solidity 0 4 4 contract test enum ActionChoices GoLeft GoRight GoStraight SitStill ActionChoices choic
  • 华为OD机试 C++ 叠积木

    题目 你手里有一堆砖头 它们都有一样的宽和高 但长度不同 你想用这些砖头堆砌一堵墙 每一层墙可以只用一个砖头 也可以用两个拼接起来 但这两种情况下 每层的长度必须都是一样的 如果你想使用所有的砖头 并堆砌出尽可能多的层数 那么最多可以搭建多
  • C#(winform)调用pytorch模型

    winform调用pytorch上训练好的unet模型 项目是写一个辅助诊断系统软件 用winform写软件 调用pytorch和matlab的模型 这篇博客只包含调用pytorch模型的部分 1 c libtorch 调用模型 2 c 生
  • java使用aspose.pdf或者spire.pdf 将pdf文件转word,实测

    1 aspose pdf aspose pdf不是破解版的只能转3页 所以我弄了个破解版 aspose pdf破解版在网上都有破解方法也比较简单 这里就不说了 直接引入破解版的jar包 在这里我用的是aspose pdf 21 11 jar
  • Qt第四十五章:QComboBox 禁止滚轮

    很简单 直接反射将QComboBox的wheelEvent方法重置掉即可 self combo box QComboBox self setattr self combo box wheelEvent lambda a None
  • 车联网Apollo(阿波罗),研究carlife车机端集成及开发,(WeLink,carplay/carlife)

    Apollo 阿波罗 是携程框架部门研发的分布式配置中心 能够集中化管理应用不同环境 不同集群的配置 配置修改后能够实时推送到应用端 并且具备规范的权限 流程治理等特性 适用于微服务配置管理场景 https github com ctrip
  • C语言提取一列数据并保存

    c语言求教 txt文档只有一列数据但是有很多 需要把它提取出来 每1024个数保存在一个文件中 求大神指教 c语言
  • 什么时候需要使用引用?使用引用的好处是什么?

    作者 谢之易 链接 https www zhihu com question 34267829 answer 58414818 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 记忆里 C 的设计与演化 一书提
  • 【华为机试真题 Python实现】仿 LISP 运算【2022 Q1 Q2

    题目描述 LISP 语言唯一的语法就是括号要配对 形如 OP P1 P2 括号内元素由单个空格分割 其中第一个元素 OP 为操作符 后续元素均为其参数 参数个数取决于操作符类型 注意 参数 P1 P2 也有可能是另外一个嵌套的 OP P1
  • 语音识别-初识

    ASRT https blog ailemon net 2018 08 29 asrt a chinese speech recognition system ASR Automatic Speech Recognition Paddle
  • 计算机加入域的一种方法

    重装系统后 想把机子加入域 却总是不成功 隐约记得以前老大们讲过 厚着脸皮问了 o 之后 决定记下来 省的我以后又忘了 计算机加入域 一 在网络中加入DNS地址 二 step 1 更改计算机名字 右键点击 我的电脑 打开 属性 页面 找到
  • redis-benchmark测试Redis集群性能

    基础环境配置 Redis5 三主三从cluster 1 100个并发连接 100000个请求 检测host为172 16 254 124端口为7004的redis服务器性能 redis benchmark h 172 16 254 124
  • C# 单例模式详解

    定义 单例模式是比较常见的一种设计模式 目的是保证一个类只能有一个实例 而且自行实例化并向整个系统提供这个实例 避免频繁创建对象 节约内存 单例模式的应用场景很多 比如我们电脑的操作系统的回收站就是一个很好的单例模式应用 电脑上的文件 视频
  • 2023年大唐杯仿真部分-5G信令流程仿真实验

    参考视频连接 第十届大唐杯信令流程仿真讲解 哔哩哔哩 bilibili 1 5G系统消息的获取 根据题目要求 UE开机需要获取消息 消息分别是MIB SIB1 SIB2 SIB3 上面为什么选的是SIB1 Systeminformation
  • 如何判断一个指定的经纬度点是否落在一个多边形内

    1 理论支持 如果从需要判断的点出发的一条射线与该多边形的焦点个数为奇数 则该点在此多边形内 否则该点在此多边形外 射线不能与多边形顶点相交 2 编程思路 该程序的思路是从A点出发向左做一条水平射线 平行于x轴 向X轴的反方向 判断与各边是