Skip to content

Commit

Permalink
account for curvature when calculating width slope
Browse files Browse the repository at this point in the history
  • Loading branch information
cyschneck committed Apr 12, 2024
1 parent e6ea217 commit a736f2a
Show file tree
Hide file tree
Showing 53 changed files with 71 additions and 16 deletions.
Binary file modified centerline_width/pytests/baseline_plots/dark_mode_false.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified centerline_width/pytests/baseline_plots/dark_mode_true.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified centerline_width/pytests/baseline_plots/equal_axis_false.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified centerline_width/pytests/baseline_plots/equal_axis_true.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified centerline_width/pytests/baseline_plots/width_isDarkModeTrue.png
Binary file modified centerline_width/pytests/baseline_plots/width_isEqualAxisTrue.png
45 changes: 39 additions & 6 deletions centerline_width/pytests/test_verifyWidth.py
Expand Up @@ -59,35 +59,68 @@ def generate_expectedCenterline(span_distance=None):
centerline_slope_expected = generate_expectedCenterline(span_distance)


def test_riverWidthFromCenterline_transectSlopeAverage():
def test_riverWidthFromCenterline_transectSlopeAverage_RelativeCenterline():
river_width_dict = test_river.riverWidthFromCenterline(
transect_slope="Average",
transect_span_distance=span_distance,
coordinate_reference="Centerline",
apply_smoothing=False)
# Verify same keys are used
assert list(
river_width_dict.keys()) == pytest.approx(centerline_slope_expected)
# Verify output
assert river_width_dict == pytest.approx({
(-4.269872495291112, 48.28213146317461):
0.476108068803046,
0.515263253111841,
(-4.263272551474902, 48.281909175456114):
0.4790787641902623
0.47396221154877105
})


def test_riverWidthFromCenterline_transectSlopeDirect():
def test_riverWidthFromCenterline_transectSlopeAverage_RelativeBanks():
river_width_dict = test_river.riverWidthFromCenterline(
transect_slope="Average",
transect_span_distance=span_distance,
coordinate_reference="Banks",
apply_smoothing=False)
# Verify output
assert river_width_dict == pytest.approx({
((-4.267374383747516, 48.283954817156506), (-4.272059498223084, 48.28053518517227)):
0.515263253111841,
((-4.262940530490867, 48.28035744890995), (-4.263843392504115, 48.284577046528305)):
0.47396221154877105
})


def test_riverWidthFromCenterline_transectSlopeDirect_RelativeCenterline():
river_width_dict = test_river.riverWidthFromCenterline(
transect_slope="Direct",
transect_span_distance=span_distance,
coordinate_reference="Centerline",
apply_smoothing=False)
# Verify same keys are used
assert list(
river_width_dict.keys()) == pytest.approx(centerline_slope_expected)
# Verify output
assert river_width_dict == pytest.approx({
(-4.269872495291112, 48.28213146317461):
0.476108068803046,
0.515263253111841,
(-4.263272551474902, 48.281909175456114):
0.4790787641902623
0.47396221154877105
})


def test_riverWidthFromCenterline_transectSlopeDirect_RelativeBanks():
river_width_dict = test_river.riverWidthFromCenterline(
transect_slope="Direct",
transect_span_distance=span_distance,
coordinate_reference="Banks",
apply_smoothing=False)
# Verify output
print(river_width_dict)
assert river_width_dict == pytest.approx({
((-4.267374383747516, 48.283954817156506), (-4.272059498223084, 48.28053518517227)):
0.515263253111841,
((-4.262940530490867, 48.28035744890995), (-4.263843392504115, 48.284577046528305)):
0.47396221154877105
})
42 changes: 32 additions & 10 deletions centerline_width/width.py
@@ -1,12 +1,14 @@
# Built-in Python functions
import logging
import csv
import math

# External Python libraries
import numpy as np
from shapely.geometry import Point, LineString
from shapely.ops import split
import geopy.distance
import pyproj
from pyproj import Geod

# Internal centerline_width reference to access functions, global variables, and error handling
import centerline_width
Expand Down Expand Up @@ -42,21 +44,35 @@ def riverWidthFromCenterlineCoordinates(
groups_of_n_points.append(
centerline_coordinates[i - 1:i + transect_span_distance])

geodesic = Geod(ellps=river_object.ellipsoid)

# Average all slopes for every n points to chart (slope of A->B + B->C)
if transect_slope == "Average":
for group_points in groups_of_n_points:
slope_sum = 0
total_slopes = 0
for i in range(len(group_points)):
if i + 1 < len(group_points):
lon_start = group_points[i][0]
lat_start = group_points[i][1]
lon_end = group_points[i + 1][0]
lat_end = group_points[i + 1][1]
forward_bearing, reverse_bearing, distance_between_meters = geodesic.inv(
lon_start, lat_start, lon_end, lat_end)
x_diff = math.sin(
np.deg2rad(forward_bearing)) * distance_between_meters
y_diff = math.cos(
np.deg2rad(forward_bearing)) * distance_between_meters
dy = group_points[i + 1][1] - group_points[i][1]
dx = group_points[i + 1][0] - group_points[i][0]
if dx != 0:
slope_sum += (dy / dx)
slope_sum += (y_diff / x_diff)
total_slopes += 1
#print(f"angle is 90 = {math.floor(np.rad2deg(math.atan((1/(y_diff / x_diff) - (y_diff / x_diff)) / (1.00000001 + y_diff / x_diff * -1/(y_diff / x_diff)))))}")
if slope_sum != 0:
slope_avg = slope_sum / total_slopes
normal_of_slope = -1 / slope_avg
#print(f"angle is 90 = {math.ceil(np.rad2deg(math.atan((slope_avg - normal_of_slope) / (1.00000001 + (slope_avg * normal_of_slope)))))}")
middle_of_list = (
len(group_points) + 1
) // 2 # set centerline point to be the middle point being averaged
Expand All @@ -67,15 +83,22 @@ def riverWidthFromCenterlineCoordinates(
if transect_slope == "Direct":
for group_points in groups_of_n_points:
if len(group_points) > 1:
dx_i = group_points[0][0]
dy_i = group_points[0][1]
dx_f = group_points[-1][0]
dy_f = group_points[-1][1]
lon_start = group_points[0][0]
lat_start = group_points[0][1]
lon_end = group_points[-1][0]
lat_end = group_points[-1][1]
forward_bearing, reverse_bearing, distance_between_meters = geodesic.inv(
lon_start, lat_start, lon_end, lat_end)
x_diff = math.sin(
np.deg2rad(forward_bearing)) * distance_between_meters
y_diff = math.cos(
np.deg2rad(forward_bearing)) * distance_between_meters
slope = 0
if (dx_f - dx_i) != 0:
slope = (dy_f - dy_i) / (dx_f - dx_i)
if x_diff != 0:
slope = (y_diff / x_diff)
if slope != 0:
normal_of_slope = -1 / slope
#print(f"angle = {math.ceil(np.rad2deg(math.atan((slope - normal_of_slope) / (1.00000001 + (slope * normal_of_slope)))))}")
middle_of_list = (
len(group_points) + 1
) // 2 # set centerline point to be the middle point being averaged
Expand Down Expand Up @@ -333,9 +356,8 @@ def riverWidthFromCenterline(
transect_span_distance=transect_span_distance,
remove_intersections=remove_intersections,
coordinate_unit="Decimal Degrees")
width_dict = {}

geodesic = pyproj.Geod(ellps=river_object.ellipsoid)
width_dict = {}

for centerline_coord, _ in right_width_coordinates.items():
# store the distance between the lat/lon position of the right/left bank
Expand Down
Binary file modified data/example_script_outputs/equal_distance_coordinates.mat
Binary file not shown.

0 comments on commit a736f2a

Please sign in to comment.