首页 > 解决方案 > 在所选位置周围的矩形区域内创建附近位置列表

问题描述

我正在尝试在矩形边界内的选定点周围创建一个位置列表。边界的尺寸由d1d2提供,其中d1在东西方向上延伸矩形,d2在南北方向上延伸区域。例如,如果位置点 L83 的经纬度为 (x,y),则搜索空间将创建一个矩形区域,其中东北 (NE)、西北 (NW)、南- 西 (SW) 和东南 (SE) 角将是

NE = (x+d1, y+d2)  
NW = (x-d1, y+d2)  
SW = (x-d1, y-d2)  
SE = (x+d1, y-d2)  

以下是 CSV 数据文件的片段:

LocId,Latitude,Longitude,Category
L1,4.5692,2.747,P
L2,2.2551,16.7944,H
L3,15.761,15.1464,R
L4,15.6516,5.1249,C
L5,6.0939,9.8601,S
L18,17.2331,18.7218,R
L47,16.3438,18.5479,H
L53,16.7774,17.4848,R
L83,16.9767,17.0477,R
L91,16.4508,18.9552,P

我努力了

 querylocid = "L83"
    d1=1.5
    d2=2.2
    
    infile = open(<CSV FILE NAME>, "r")
    infile.readline()
    for line in infile:
        line = line.strip().split(",")
        if line[0] == querylocid:
            ne = (float(line[1])+d1, float(line[2])+d2)
            nw = (float(line[1])-d1, float(line[2])+d2)
            sw = (float(line[1])-d1, float(line[2])-d2)
            se = (float(line[1])+d1, float(line[2])-d2)
            
            # checking if location is within rectangle boundary
            if float(line[1]) >= nw[0] and float(line[1]) <= ne[0] and float(line[2]) >= sw[1] and float(line[2]) <= nw[1]:
                list.append(line[0])
                print(list)

这只给了我

['L83']

我正在寻找的输出是

['L3', 'L18', 'L47', 'L53', 'L91']  

我可能猜到问题是如果 line[0] == querylocid:,但如果我没有这条线,我不确定如何指定所选位置周围的矩形边界。

标签: python

解决方案


要查找具有重叠矩形的所有位置,您可以计算它们的差异并检查它是否小于距离的两倍 [沿同一方向(纵向/纬度)],即abs(long1 -long2) < 2*d2.

我曾经itertools.combinations找到所有可能的配对。

警告:stringto floatcast 是基于廉价检查:'.' in string

import itertools as it

geo = """L1,4.5692,2.747,P
L2,2.2551,16.7944,H
L3,15.761,15.1464,R
L4,15.6516,5.1249,C
L5,6.0939,9.8601,S
L18,17.2331,18.7218,R
L47,16.3438,18.5479,H
L53,16.7774,17.4848,R
L91,16.4508,18.9552,P"""


# data from string to dictionary + casting numbers to float!
geo_data = {}
attrs = ['LocId', 'Latitude', 'Longitude' ,'Category']
for line  in geo.split('\n'):
    attrs_values = [float(g) if '.' in g else g for g in line.split(',')]
    
    geo_data[attrs_values[0]] = dict(zip(attrs[1:], attrs_values[1:]))


def is_in_interval(c1, c2, r):
    """c1, c2 are center of an interval with radius r, to have an intersection the maximum distance allowed is 2r"""
    return  abs(c2-c1) <= 2*r


# size of a single box
d1 = 1.5
d2 = 2.2

pairwise_overlapping_locations = []
for id1, id2 in it.combinations(geo_data, 2):
    lat1 = geo_data[id1]['Latitude']
    lat2 = geo_data[id2]['Latitude']
    is_in_lat = is_in_interval(lat1, lat2, d1)

    long1 = geo_data[id1]['Longitude']
    long2 = geo_data[id2]['Longitude']
    is_in_long = is_in_interval(long2, long1, d2)

    if is_in_lat and is_in_long:
        pairwise_overlapping_locations += [(id1, id2)]


print(pairwise_overlapping_locations)
print(set(it.chain(*pairwise_overlapping_locations)))

输出

[('L3', 'L18'), ('L3', 'L47'), ('L3', 'L53'), ('L3', 'L91'), ('L18', 'L47'), ('L18', 'L53'), ('L18', 'L91'), ('L47', 'L53'), ('L47', 'L91'), ('L53', 'L91')]
{'L91', 'L18', 'L47', 'L53', 'L3'}

推荐阅读