将纬度和经度值转换为自定义大小的网格

4
我正在制作一个java程序,将一组lat/lng坐标分类到特定大小的矩形中,从而实现将地球表面映射到自定义网格并能够识别点所在的矩形/多边形。我正在研究的方法是使用地图投影(可能是Mercator)。例如,假设我想将经纬度分类为100米x 100米的“正方形”,则44.727549、10.419704和44.727572、10.420460将被归类为区域X,而44.732496、10.528092和44.732999、10.529465会被归类为区域Y,因为它们之间的距离小于100米(当然要求它们在同一边界内)。我不太担心畸变,因为我不需要显示地图,但我确实需要能够知道一组坐标属于哪个多边形。这是否可能?欢迎任何建议。谢谢。 编辑 省略极点的投影也是可以接受的损失。

你可能不用担心失真,但你需要担心两极的边缘情况。 - hatchet - done with SOverflow
我正在做非常类似的事情。你已经实现了吗?你能分享一些代码样例吗? - performanceuser
@performanceuser 刚刚为您发布了一个答案。 - Gmeister4
你可能想要使用的是https://en.wikipedia.org/wiki/Military_Grid_Reference_System。MGRS是实现基于位置的数据缓存的有效关键,这也是我假设你的最终目标。 - Gajus
3个回答

4

这是我的最终解决方案(使用PHP),为每个100m的正方形创建一个垃圾箱:

function get_static_pointer_table_id($lat, $lng)
{
    $earth_circumference = 40000; // km

    $lat_bin = round($lat / 0.0009);
    $lng_length = $earth_circumference * cos(deg2rad($lat));
    $number_of_bins_on_lng = $lng_length * 10;
    $lng_bin = round($number_of_bins_on_lng * $lng / 360);
    //the 'bin' unique identifier
    return $lat_bin . "_" . $lng_bin;

}

1
如果我理解正确,您正在寻找以下内容:
1. 将地球表面划分为大约100米x100米的正方形。 2. 找到一个点所在的正方形。
问题1对于正方形来说几乎是不可能的,但对于多边形来说则容易得多。创建多边形的一个非常简单的方法是使用坐标本身。如果每个多边形在纬度和经度上都是0.0009°,则在赤道上你将拥有大约100米x100米的正方形网格,但靠近极点的切片会变得非常细。
问题2取决于用于解决上述挑战的近似方法。如果你使用上述非常简单的方法,那么将每个坐标放入一个bin中仅需要除以0.0009(并向下舍入到最接近的整数)。
因此,首先您必须决定可以妥协的事项。是否重要在多边形中具有相等的面积、相等的经度距离、相等的纬度距离等?是否重要在多边形中有四个角?是否重要在靠近极点和赤道附近具有类似或几乎相似的多边形?一旦您知道应用程序设置的限制,选择投影就变得更容易了。

我已经考虑过将纬度的一部分四舍五入,但正如您所要求的那样,在极地区域这会使面积非常小,在赤道则会很大。我需要每个多边形大致相同的大小(约100米为宜),不需要四个角,但这会让生活更轻松,因此形状不需要恒定。极点本身(以及两侧的几度)可以忽略。感谢回复。 - Gmeister4
那么,如果您可以将极点旁边的最后一度扔掉,并且如果您的网格不需要具有公共节点(角点),则有一种相对简单的方法。通过纬度将地球分成0.0009°的部分。现在您有200000条带,每条带宽100米。将每个带子分成_n_个正方形,其中_n_是带子长度(纬度余弦)除以100米并四舍五入到最接近的整数。因此,在赤道上,您将拥有400000个正方形,在60°时,您将拥有200000个正方形。 - DrV
我得到了将纬度划分为表示0.0009纬度的整数,但是这句话“将每个条纹分成n个正方形,其中n是条纹长度(纬度余弦)除以100米并四舍五入到最接近的整数”的工作原理是什么?这种方法没有以任何方式提到解决经度问题。你能给一个具体的例子,包括经纬度吗?谢谢。 - Gmeister4
让我们试试。如果纬度为60.127,则介于60.1269和60.1278之间(条带中心在60.12735)。该经线的长度为40,000公里x cos(60.12735°)= 19922.95公里,因此应有199230个箱子。知道这一点后,从格林威治向西取经度(假设为56.234°),并计算56.234° / 360° x 199230 = 31120.83,即箱号31120.83。 - DrV
此外,如果您可以接受这样一个事实,即您有少量(几十万个中的一个)小于其他矩形的矩形,则可以使用简单的公式:纬度 x cos(经度)x 40000 公里/100米,然后将其向下舍入(或最近的或向上或任何地方)。 - DrV
啊,是的,那正是我所需要的。将点聚类到它们最近的“箱子”中完美地完成了任务。感谢您的帮助! - Gmeister4

1
你在这里尝试的是将一个椭球体投影到平面上。只要你的点彼此接近,而且你不介意答案略有偏差,你可以假设你的投影平面与你的点集中心相交,并且每个纬度和经度都是一定数量的米。然后问题就变成了一个简单的平面计算。
当然,这是错误的。我建议你研究地图投影,选择一个合适的投影方式并进行处理。记住,你可以将投影中心移动到你的点集中心以减少失真。
我怀疑PROJ.4可能会帮助你使用库。当然也必须有一个好的Java库,但那不是我的专业领域。
最后,你可以假设地球是一个球体,并在球体上进行计算。或者,如果你真的想做得正确,你可以选择标准的地球椭球体并在其上进行计算。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接