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

时间:2012-05-17 08:49:50

标签: c# java blackberry geolocation geometry

我将首先介绍这个问题:我正在开发一个应用程序,我将显示一个地图字段,并覆盖标记和线条。但是,在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.
        }

但是,要在屏幕上绘制这些对象,我们应首先将地标位置(lat,long)转换为屏幕坐标(x,y,以像素为单位)。这不能提前完成,因为地图不是静态的,所以它能够滚动和放大。这就是为什么在每个油漆循环中我们应该至少绘制可见物体。那就是说,我的问题是:

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

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

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

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

任何其他方法或想法也将受到赞赏。

提前致谢。

3 个答案:

答案 0 :(得分:3)

只是一个原始的想法:取你的“矩形”的两个对角,例如左上角和右下角。通过以下方法将两个角转换为笛卡尔空间坐标(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)

这应该为您提供以“middle”为中心的圆盘内的所有地标。

答案 1 :(得分:2)

你至少可以在地图坐标空间中使用天真的盒子检查排除大量候选人。这里可能有三个主要案例。要么在矩形中有一个极点,要么没有。如果杆不可见,则矩形与+/- 180度线交叉。没有任何+/- 90线,因为这会将北极和南极组合在一起而你没有使用4D地图,是吗? ; - )

案例1,杆子可见: 如果它是北极,找出哪个角具有最小的纬度。任何小于此的纬度都可能在屏幕外。如果它是南极只是颠倒逻辑,即使用最大的纬度并排除任何具有更大纬度的物品。 我知道,将杆子放在一个角落,将赤道放在另一个角落,意味着你仍然包括整个半球。但至少你可以廉价地排除另一半。

情况2,没有极点,没有越过+/- 180经度线: 找到最小/最大经度和纬度值,并使用它们进行简单的框检查。盒子外面的任何东西都在屏幕外。

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

案例2和案例3应该能够排除足够的候选人对其他人进行蛮力检查。案例1可能需要进一步的后处理,但是如果你想要一些复杂的东西,我担心这部分对我来说有点太复杂了。 我想如果杆距离屏幕中心更远,你可以以某种方式找到最靠近杆的离屏点。然后以某种方式构造一个类似三角形的形状,在该点有一个角,并使其尽可能大,而不触及屏幕矩形。

答案 2 :(得分:0)

我认为您只需要将您的rectengular周边转换为地理坐标。 而不是试图将geogrpahic坐标转换为屏幕坐标。

我很抱歉答案是天真的 - 但你问的是逻辑。 因此,我可视化的逻辑事物是在一个spehere上滑动的窗口,这意味着你需要将该窗口的地理坐标作为你的参考点。

处理完“3d”信息后,您可以开始渲染视图。