Fix distance_to_intersection function

Added two extra considerations:
1) Need to distinguish between positive and negative values when calculating distance to starting point, hence the seaward and landward intersecting lines.
2) Need to consider only checking lines with the same beach property, otherwise it is going to take too long when we have all the beaches
master
Chris Leaman 6 years ago
parent 863976c532
commit 2974b5a897

@ -19,10 +19,12 @@ def shapes_from_shp(shp_file):
""" """
shapes = [] shapes = []
ids = [] ids = []
properties = []
for feat in fiona.open(shp_file, 'r'): for feat in fiona.open(shp_file, 'r'):
shapes.append(shape(feat['geometry'])) shapes.append(shape(feat['geometry']))
ids.append(feat['id']) ids.append(feat['id'])
return shapes, ids properties.append(feat['properties'])
return shapes, ids, properties
def convert_coord_systems(g1, in_coord_system='EPSG:4326', out_coord_system='EPSG:28356'): def convert_coord_systems(g1, in_coord_system='EPSG:4326', out_coord_system='EPSG:28356'):
@ -98,12 +100,12 @@ def get_slope(x, z, top_elevation, btm_elevation, method='end_points'):
return -slope return -slope
def distance_to_intersection(lat, lon, orientation, line_strings): def distance_to_intersection(lat, lon, landward_orientation, beach, line_strings, line_properties):
""" """
Returns the distance at whjch a line drawn from a lat/lon at an orientation intersects a line stinrg Returns the distance at whjch a line drawn from a lat/lon at an orientation intersects a line stinrg
:param lat: :param lat:
:param lon: :param lon:
:param orientation: Angle, clockwise positive from true north in degrees, of the tangent to the shoreline facing :param landward_orientation: Angle, anticlockwise positive from east in degrees, towards the land
towards the towards the
land. land.
:param line_string: :param line_string:
@ -113,15 +115,26 @@ def distance_to_intersection(lat, lon, orientation, line_strings):
start_point = convert_coord_systems(start_point) start_point = convert_coord_systems(start_point)
distance = 1000 # m look up to 1000m for an intersection distance = 1000 # m look up to 1000m for an intersection
new_point = Point(start_point.coords.xy[0] + distance * np.cos(np.deg2rad(orientation)), landward_point = Point(start_point.coords.xy[0] + distance * np.cos(np.deg2rad(landward_orientation)),
start_point.coords.xy[1] + distance * np.sin(np.deg2rad(orientation))) start_point.coords.xy[1] + distance * np.sin(np.deg2rad(landward_orientation)))
profile_line = LineString([start_point, new_point]) landward_line = LineString([start_point, landward_point])
seaward_point = Point(start_point.coords.xy[0] - distance * np.cos(np.deg2rad(landward_orientation)),
# Check whether profile_line intersects with any lines in line_string start_point.coords.xy[1] - distance * np.sin(np.deg2rad(landward_orientation)))
seaward_line = LineString([start_point, seaward_point])
# Look at relevant line_strings which have the same beach property in order to reduce computation time
line_strings = [s for s, p in zip(line_strings, line_properties) if p['beach'] == beach]
# Check whether profile_line intersects with any lines in line_string. If intersection point is landwards,
# consider this negative, otherwise seawards is positive.
for line_string in line_strings: for line_string in line_strings:
intersection_points = profile_line.intersection(line_string) land_intersect_points = landward_line.intersection(line_string)
if not intersection_points.is_empty: if not land_intersect_points.is_empty:
return intersection_points.distance(start_point) return -land_intersect_points.distance(start_point)
sea_intersect_points = seaward_line.intersection(line_string)
if not sea_intersect_points.is_empty:
return sea_intersect_points.distance(start_point)
# If no intersections are found, return nothing. # If no intersections are found, return nothing.
return None return None

Loading…
Cancel
Save