R中同心圆中的地理编码点数
Number of geocoded points in concentric circles in R
我有大约 36,000 家使用经纬度进行地理编码的酒店的数据集。
对于它们中的每一个,我需要知道在每个点(2 英里、5 英里、10 英里)周围的不同同心圆中还有多少其他酒店(以及其他哪些酒店)。
例如,数据集如下所示:
ID Latitude Longitude Rooms
1 N K 200
2 N K 150
3 N K 80
4 N K 140
5 N K 100
我需要测量每个同心圆中每家酒店的密度(通常通过将每个酒店的焦点酒店的房间数除以其同心圆内的房间总数来计算)
通常,我会计算每个点之间的距离,然后过滤每个距离内的点,但是有 36k 个点,这会花费很多时间,因为我会去计算每个点之间的距离我可能需要每个点与其他 4-5 个最大值的距离。
您知道如何使用 R 或 ArcGIS 有效地计算距离然后计算密度吗?
谢谢
看来让您的代码更高效的最佳方法不是获得更高效的距离计算算法,而是将该算法仅应用于几家酒店。
您可以非常快速地进行粗略的“平方”近似:
- 制作一个按纬度排序的新酒店数据集
- 制作一个按经度排序的新酒店数据集
每家酒店:
- 创建 2 个新的空列表:
hotels_in_lat_range
和 hotels_in_long_range
- 从您在按纬度排序的数据集中的酒店开始,一直向上直到达到某个限制
- 返回到下限,边走边将酒店添加到
hotels_in_lat_range
- 对经度排序的数据集重复步骤 4 和 5,将酒店添加到
hotels_in_long_range
- 对于两个列表中的每家酒店,计算您的测试酒店与该酒店之间的距离。如果距离小于你的圆半径,在计算密度时将其包括在内。
对于纬度和经度的上限和下限,我建议使用以下近似值(我在Python中写这个因为我不知道R):
min_lat = max(-89.9, test_lat - 4 * math.degrees(test_rad/Earth_rad))
max_lat = min(89.9, test_lat + 4 * math.degrees(test_rad/Earth_rad))
min_long = max(
-180.0,
test_lat - 4 * math.degrees(
test_rad/(Earth_rad * min(cos(min_lat), cos(max_lat)))
)
)
max_long = min(
180.0,
test_lat + 4 * math.degrees(
test_rad/(Earth_rad * min(cos(min_lat), cos(max_lat)))
)
)
当您的测试半径明显小于地球半径时,这是一个合理的近似值。我建议保持在 100 英里以内。
我有大约 36,000 家使用经纬度进行地理编码的酒店的数据集。
对于它们中的每一个,我需要知道在每个点(2 英里、5 英里、10 英里)周围的不同同心圆中还有多少其他酒店(以及其他哪些酒店)。
例如,数据集如下所示:
ID Latitude Longitude Rooms
1 N K 200
2 N K 150
3 N K 80
4 N K 140
5 N K 100
我需要测量每个同心圆中每家酒店的密度(通常通过将每个酒店的焦点酒店的房间数除以其同心圆内的房间总数来计算)
通常,我会计算每个点之间的距离,然后过滤每个距离内的点,但是有 36k 个点,这会花费很多时间,因为我会去计算每个点之间的距离我可能需要每个点与其他 4-5 个最大值的距离。
您知道如何使用 R 或 ArcGIS 有效地计算距离然后计算密度吗?
谢谢
看来让您的代码更高效的最佳方法不是获得更高效的距离计算算法,而是将该算法仅应用于几家酒店。
您可以非常快速地进行粗略的“平方”近似:
- 制作一个按纬度排序的新酒店数据集
- 制作一个按经度排序的新酒店数据集
每家酒店:
- 创建 2 个新的空列表:
hotels_in_lat_range
和hotels_in_long_range
- 从您在按纬度排序的数据集中的酒店开始,一直向上直到达到某个限制
- 返回到下限,边走边将酒店添加到
hotels_in_lat_range
- 对经度排序的数据集重复步骤 4 和 5,将酒店添加到
hotels_in_long_range
- 对于两个列表中的每家酒店,计算您的测试酒店与该酒店之间的距离。如果距离小于你的圆半径,在计算密度时将其包括在内。
对于纬度和经度的上限和下限,我建议使用以下近似值(我在Python中写这个因为我不知道R):
min_lat = max(-89.9, test_lat - 4 * math.degrees(test_rad/Earth_rad))
max_lat = min(89.9, test_lat + 4 * math.degrees(test_rad/Earth_rad))
min_long = max(
-180.0,
test_lat - 4 * math.degrees(
test_rad/(Earth_rad * min(cos(min_lat), cos(max_lat)))
)
)
max_long = min(
180.0,
test_lat + 4 * math.degrees(
test_rad/(Earth_rad * min(cos(min_lat), cos(max_lat)))
)
)
当您的测试半径明显小于地球半径时,这是一个合理的近似值。我建议保持在 100 英里以内。