-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add experimental "distance to alpine ridge" feature (#23)
* Add new experimental feature * Fix tests
- Loading branch information
Showing
2 changed files
with
113 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
"""This module implements experimental features""" | ||
from typing import List, Tuple | ||
|
||
import numpy as np | ||
from pyproj import CRS, Transformer | ||
|
||
|
||
def reproject_points( | ||
latlon_wgs84: List[Tuple[float, float]], dst_epsg: str | ||
) -> List[Tuple[float, float]]: | ||
transformer = Transformer.from_crs(CRS("epsg:4326"), CRS(dst_epsg), always_xy=True) | ||
lon_src = [p[1] for p in latlon_wgs84] | ||
lat_src = [p[0] for p in latlon_wgs84] | ||
x_dst, y_dst = transformer.transform(lon_src, lat_src) | ||
return [(x, y) for x, y in zip(x_dst, y_dst)] | ||
|
||
|
||
def distance_point_to_segment( | ||
point: Tuple[float, float], | ||
segment_start: Tuple[float, float], | ||
segment_end: Tuple[float, float], | ||
) -> float: | ||
"""Calculate the distance from a point to a line segment.""" | ||
point = np.array(point) | ||
segment_start = np.array(segment_start) | ||
segment_end = np.array(segment_end) | ||
|
||
# Vector from start to point and start to end | ||
start_to_point = point - segment_start | ||
start_to_end = segment_end - segment_start | ||
|
||
# Project start_to_point onto start_to_end | ||
projection = np.dot(start_to_point, start_to_end) / np.dot( | ||
start_to_end, start_to_end | ||
) | ||
|
||
# Check if projection is in the segment | ||
if projection < 0: | ||
closest_point = segment_start | ||
elif projection > 1: | ||
closest_point = segment_end | ||
else: | ||
closest_point = segment_start + projection * start_to_end | ||
|
||
# Compute the distance from the point to the closest point | ||
return np.linalg.norm(point - closest_point) | ||
|
||
|
||
def distances_points_to_line( | ||
points: List[Tuple[float, float]], line_points: List[Tuple[float, float]] | ||
) -> List[float]: | ||
"""For a list of points, find the minimum distance a polyline.""" | ||
min_distances = [] | ||
for point in points: | ||
min_distance = float("inf") | ||
for i in range(len(line_points) - 1): | ||
segment_start = line_points[i] | ||
segment_end = line_points[i + 1] | ||
distance = distance_point_to_segment(point, segment_start, segment_end) | ||
if distance < min_distance: | ||
min_distance = distance | ||
min_distances.append(min_distance) | ||
return min_distances |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters