3

我将首先介绍这个问题:我正在开发一个应用程序,我必须在其中显示一个地图字段,并覆盖标记和线条。但是,在 BlacBerry OS 5.0 中,唯一MapField可用的 API 不提供覆盖内容的方法,仅在某个位置显示地图。它还提供了将屏幕坐标(像素)转换为 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。这个函数应该在两极和 ecuator 中工作,所以当我们有一条与矩形相交的过渡线(从 -180 到 +180,或从 -90 到 +90,或两条线)时,我也需要它工作。由于逻辑可能变得复杂,我想知道是否存在已经完成和测试的现有算法或开源库,而不是实现我自己的。

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

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

提前致谢。

4

3 回答 3

3

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

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

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

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

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

于 2012-05-17T10:46:11.873 回答
2

您至少可以通过在地图坐标空间中进行简单的复选框检查来排除大量候选人。这里可能有三种主要情况。矩形中要么有一个极点,要么没有。如果看不到极点,则矩形与 +/-180 度线相交或不相交。不可能有任何 +/-90 线,因为这会将北极和南极放在一起,而您没有使用 4D 地图,是吗?;-)

案例1,一个极点是可见的:如果它是北极,找出哪个角落的纬度最小。任何小于该值的纬度都可能在屏幕外。如果是南极,则将逻辑颠倒过来,即使用最大纬度并排除纬度较大的任何项目。我知道,将极点放在一个角落,将赤道放在另一个角落意味着您仍然包括整个半球。但至少你可以廉价地排除另一半。

案例 2,无极点,不越过 +/-180 经线:找到最小/最大经度和纬度值,并将其用于简单的复选框检查。框外的任何东西都在屏幕外。

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

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

于 2012-05-17T09:42:04.057 回答
0

I think you just need to Convert your rectengular perimeter to geographic coordinates. Instead of trying to convert the geogrpahic coordinates to screen coordinates.

I'm sorry that the answer is naive - but you do you ask about logic. And so the logical thing I visualize is a window sliding on a spehere and that means you need to have that window geographical coordinates as your points of reference.

After you process that "3d" information you can start rendering your view.

于 2012-05-17T09:24:48.573 回答