OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Creating buffer circle to know which IDs fall within 1000 meters from a given point

  • Thread starter Thread starter Amit Kumar
  • Start date Start date
A

Amit Kumar

Guest
My df is looks like this:

[th]
latitude​
[/th]​
[th]
longitude​
[/th]​
[th]
ID​
[/th]​
[td]
-22.582779​
[/td]​
[td]
29.080456​
[/td]​
[td]
0​
[/td]​
[td]
81.128575​
[/td]​
[td]
9.709794​
[/td]​
[td]
1​
[/td]​
[td]
41.758910​
[/td]​
[td]
-53.626698​
[/td]​
[td]
2​
[/td]​
[td]
17.758527​
[/td]​
[td]
-2.443443​
[/td]​
[td]
3​
[/td]​
[td]
-61.916645​
[/td]​
[td]
-48.565211​
[/td]​
[td]
4​
[/td]​

I wanna create a function which intake this above df and for each record it calculates the count and the corresponding IDs which falls within 1000 meters of radius.

Code:
R = 6371000  #earths' radius 

def haversine(lat1, lon1, lat2, lon2):
    phi1, phi2 = radians(lat1), radians(lat2)
    delta_phi = radians(lat2 - lat1)
    delta_lambda = radians(lon2 - lon1)
    
    a = sin(delta_phi / 2)**2 + cos(phi1) * cos(phi2) * sin(delta_lambda / 2)**2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))
    
    return R * c

def lat_lon_to_cartesian(lat, lon):
    lat, lon = np.radians(lat), np.radians(lon)
    x = R * np.cos(lat) * np.cos(lon)
    y = R * np.cos(lat) * np.sin(lon)
    z = R * np.sin(lat)
    return x, y, z

# Add Cartesian coordinates to the DataFrame
df['x'], df['y'], df['z'] = zip(*df.apply(lambda row: lat_lon_to_cartesian(row['lat'], row['lon']), axis=1))

# Build a KD-Tree for fast spatial indexing
tree = cKDTree(df[['x', 'y', 'z']])

# Function to find points within a 1000 meters radius using the KD-Tree
def points_within_radius_kdtree(lat, lon, radius=1000):
    x, y, z = lat_lon_to_cartesian(lat, lon)
    indices = tree.query_ball_point([x, y, z], radius / R)  # Adjust radius for Cartesian space
    nearby_points = df.iloc[indices].copy()
    nearby_points['distance'] = nearby_points.apply(lambda row: haversine(lat, lon, row['lat'], row['lon']), axis=1)
    return nearby_points[nearby_points['distance'] <= radius]

# Function to calculate the count and IDs of records within a 1000 meters radius for each record in the DataFrame
def calculate_nearby_counts(df, radius=1000):
    counts = []
    ids = []
    
    for idx, row in df.iterrows():
        nearby_points = points_within_radius_kdtree(row['lat'], row['lon'], radius)
        count = len(nearby_points) - 1  # Subtract 1 to exclude the point itself
        nearby_ids = nearby_points[nearby_points['ID'] != row['ID']]['ID'].tolist()  # Exclude the point itself
        counts.append(count)
        ids.append(nearby_ids)
    
    df['nearby_count'] = counts
    df['nearby_ids'] = ids
    return df

result_df = calculate_nearby_counts(df)
print(result_df)

Above code isn't giving me the intended results.
<p>My df is looks like this:</p>
<div class="s-table-container"><table class="s-table">
<thead>
<tr>
<th style="text-align: center;">latitude</th>
<th style="text-align: center;">longitude</th>
<th style="text-align: center;">ID</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">-22.582779</td>
<td style="text-align: center;">29.080456</td>
<td style="text-align: center;">0</td>
</tr>
<tr>
<td style="text-align: center;">81.128575</td>
<td style="text-align: center;">9.709794</td>
<td style="text-align: center;">1</td>
</tr>
<tr>
<td style="text-align: center;">41.758910</td>
<td style="text-align: center;">-53.626698</td>
<td style="text-align: center;">2</td>
</tr>
<tr>
<td style="text-align: center;">17.758527</td>
<td style="text-align: center;">-2.443443</td>
<td style="text-align: center;">3</td>
</tr>
<tr>
<td style="text-align: center;">-61.916645</td>
<td style="text-align: center;">-48.565211</td>
<td style="text-align: center;">4</td>
</tr>
</tbody>
</table></div>
<p>I wanna create a function which intake this above df and for each record it calculates the count and the corresponding IDs which falls within 1000 meters of radius.</p>
<pre><code>R = 6371000 #earths' radius

def haversine(lat1, lon1, lat2, lon2):
phi1, phi2 = radians(lat1), radians(lat2)
delta_phi = radians(lat2 - lat1)
delta_lambda = radians(lon2 - lon1)

a = sin(delta_phi / 2)**2 + cos(phi1) * cos(phi2) * sin(delta_lambda / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))

return R * c

def lat_lon_to_cartesian(lat, lon):
lat, lon = np.radians(lat), np.radians(lon)
x = R * np.cos(lat) * np.cos(lon)
y = R * np.cos(lat) * np.sin(lon)
z = R * np.sin(lat)
return x, y, z

# Add Cartesian coordinates to the DataFrame
df['x'], df['y'], df['z'] = zip(*df.apply(lambda row: lat_lon_to_cartesian(row['lat'], row['lon']), axis=1))

# Build a KD-Tree for fast spatial indexing
tree = cKDTree(df[['x', 'y', 'z']])

# Function to find points within a 1000 meters radius using the KD-Tree
def points_within_radius_kdtree(lat, lon, radius=1000):
x, y, z = lat_lon_to_cartesian(lat, lon)
indices = tree.query_ball_point([x, y, z], radius / R) # Adjust radius for Cartesian space
nearby_points = df.iloc[indices].copy()
nearby_points['distance'] = nearby_points.apply(lambda row: haversine(lat, lon, row['lat'], row['lon']), axis=1)
return nearby_points[nearby_points['distance'] <= radius]

# Function to calculate the count and IDs of records within a 1000 meters radius for each record in the DataFrame
def calculate_nearby_counts(df, radius=1000):
counts = []
ids = []

for idx, row in df.iterrows():
nearby_points = points_within_radius_kdtree(row['lat'], row['lon'], radius)
count = len(nearby_points) - 1 # Subtract 1 to exclude the point itself
nearby_ids = nearby_points[nearby_points['ID'] != row['ID']]['ID'].tolist() # Exclude the point itself
counts.append(count)
ids.append(nearby_ids)

df['nearby_count'] = counts
df['nearby_ids'] = ids
return df

result_df = calculate_nearby_counts(df)
print(result_df)
</code></pre>
<p>Above code isn't giving me the intended results.</p>
 

Latest posts

Top