检查位置是否在矩形周长内的有效方法

本文关键字:周长内 有效 方法 位置 是否 检查 | 更新日期: 2023-09-27 18:34:31

我将首先介绍这个问题:我正在开发一个应用程序,其中必须显示地图字段,并覆盖标记和线条。但是,在 BlacBerry OS 5.0 中,API 中唯一可用的MapField不提供覆盖内容的方法,仅显示某个位置的地图。它还提供了将屏幕坐标(像素(转换为 WGS84 坐标/从 WGS84 坐标转换的方法。这些方法的计算成本可能很高。

因此,要绘制我自己的项目,我需要扩展这个类并覆盖它的 paint(( 方法。扩展类还将包含位置集合。这就是覆盖方法的样子(我将在这里使用 Java(:

        public void paint (Graphics g) {
            super.paint(g); //draws the map
            //TODO
            //Draw placemarks. The placemarks are basically holder objects
            //(for latitude and longitude) stored in a collection in this class.
        }

但是,要在屏幕上绘制这些对象,我们应该首先将地标位置(纬度,经度(转换为屏幕坐标(x,y,以像素为单位(。由于地图不是静态的,因此无法提前完成此操作,因此可以滚动和放大。这就是为什么在每个绘画循环中,我们至少应该绘制可见对象。也就是说,我的问题是:

给定一个矩形周长,其中角是地理位置(当前显示的地图部分的转换后的四个角(,是否有一种快速方法可以循环收集中的每个地标并确定它们是否可见?

我不需要这个测试是 100% 准确的,我不介意是否绘制了屏幕外的几个位置。但是,由于地标集合可以包含许多元素 (<100(,并且每次屏幕重绘时都会调用 paint 方法,因此尝试绘制集合中的每个位置而不检查它是否可见可能会影响性能,并在用户与地图交互时引入延迟。

在尝试提供朴素的答案之前,请注意这不是一个简单的几何问题:我们使用的是地理坐标,而不是整数屏幕坐标。世界不会在经度+180或纬度+90结束。这个函数应该在极点和赤道中工作,所以当我们有一条过渡线(从 -180 到 +180,或从 -90 到 +90,或两条线(与矩形相交时,我也需要它工作。由于逻辑可能会变得复杂,我想知道是否有现有的算法或开源库已经完成并测试了,而不是实现我自己的算法或开源库。

我还可以先将集合中的每个位置转换为屏幕坐标,然后轻松检查仅由正屏幕坐标组成的矩形(从 x=0、y=0 开始(,但由于转换函数可能很昂贵,我认为在每次刷新(可见地图角(中只转换 4 个点比不确定数量的地标更好。

任何其他方法或想法也将不胜感激。

提前谢谢。

检查位置是否在矩形周长内的有效方法

只是一个原始的想法:取"矩形"的两个相对角,例如左上角和右下角。通过以下方式将两个角转换为笛卡尔空间坐标(x,y,z)

x = cos[long] cos[lat]
y = sin[long] cos[lat]
z = sin[lat] 

两个(x,y,z)坐标都是单位向量(想象球体的中心在(0,0,0),向量是从那里到表面的箭头(。找到地图区域的"中间"作为两个角向量的赋范平均值(添加为向量,然后除以总和向量的长度以确保您有一个新的单位向量(。当你有中间(xMiddle,yMiddle,zMiddle)时,对于每个地标坐标转换为笛卡尔(x,y,z),使用点积和(xMiddle,yMiddle,zMiddle)作为与中间接近度的度量。

现在包括带(xMiddle,yMiddle,zMiddle)的点积大于左上角带(xMiddle,yMiddle,zMiddle)的点积的每个地标。

这应该为您提供以"中间"为中心的圆形圆盘内的所有地标。

您至少可以在地图坐标空间中使用朴素的框检查来排除大量候选者。这里可能有三个主要案例。要么矩形中有杆子,要么没有。如果极点不可见,则矩形是否与 +/-180 度线相交。不可能有任何 +/-90 线,因为这会将北极和南极放在一起,并且您不使用 4D 地图,对吗?;-)

情况1,一根杆子可见:如果是北极,请找出哪个角的纬度最小。任何小于此值的纬度都可能在屏幕外。如果是南极,只需颠倒逻辑,即使用最大纬度并排除任何具有较大纬度的项目。我知道,把极点放在一个角落,把赤道放在另一个角落,意味着你仍然包括整个半球。但至少你可以便宜地排除另一半。

情况2,没有极点,不越过+/-180经线:找到最小/最大经度和纬度值,并将其用于简单的框检查。任何开箱即用的东西都在屏幕外。

情况 3,没有极点,但越过 +/-180 经线:纬度同上。对于经度,分别查找距离 +180 和 -180 最远的经度。排除纬度超出最小/最大值或介于找到的两个最远经度之间的任何项目。

案例 2 和 3 应该能够排除足够的候选者,以便对其他情况进行暴力检查。案例 1 可能需要进一步的后期处理,但如果你想要一些复杂的东西,恐怕这部分对我来说有点太复杂了。我想如果极点离屏幕中心更远,你可以以某种方式找到一个最靠近极点的屏幕外点。然后以某种方式构造一个三角形形状,在该点上有一个角,并在不接触屏幕矩形的情况下使其尽可能大。

我认为您只需要将矩形周长转换为地理坐标即可。而不是尝试将地理坐标转换为屏幕坐标。

很抱歉,答案很幼稚——但你问的是逻辑。因此,我想象的合乎逻辑的事情是窗口在喷头上滑动,这意味着您需要将该窗口地理坐标作为参考点。

处理完该"3d"信息后,可以开始渲染视图。