Source code for landlab.plot.network_sediment_transporter.locate_parcel_xy
"""
Created on Fri Oct 24 16:28:00 2019
This code converts location in a link to an X, Y
@author: Jon Czuba, Katy Barnhart
"""
import numpy as np
[docs]
def locate_parcel_xy(grid, parcels, parcel_time_index, parcel_number):
# determine the location of that parcel in its link
parcel_loc = parcels.dataset.location_in_link[
parcel_number, parcel_time_index
].values
# parcels that end their timestep off network have the starting link id
# recorded, and np.nan as the distance.
if not np.isnan(parcel_loc):
# get link id
parcel_link = int(
parcels.dataset.element_id[parcel_number, parcel_time_index].values
)
# DANGER DANGER: This code assumes the verticies of links are ordered
# from upstream to downstream. This should be the case for delineated
# river networks, so this line should not be necessary. A quick
# work-around is the following, but ideally verticies should be flipped in GIS.
# parcel_loc = 0.9999 - parcel_loc
# get the X, Y vertices of the squiggly line for that link (loaded by
# import_shapefile.py)
# I am not sure these next 2 lines are necessary here, but I don't know
# how to do this differently and/or better.
if "x_of_polyline" in grid.at_link:
link_x = grid["link"]["x_of_polyline"][parcel_link]
link_y = grid["link"]["y_of_polyline"][parcel_link]
else:
flow_dir = grid.at_link["flow__link_direction"][parcel_link]
head_node = grid.node_at_link_head[parcel_link]
tail_node = grid.node_at_link_tail[parcel_link]
if flow_dir == -1:
link_x = [grid.x_of_node[head_node], grid.x_of_node[tail_node]]
link_y = [grid.y_of_node[head_node], grid.y_of_node[tail_node]]
elif flow_dir == 1:
# 1 = with direction of from tail to head.
link_x = [grid.x_of_node[tail_node], grid.x_of_node[head_node]]
link_y = [grid.y_of_node[tail_node], grid.y_of_node[head_node]]
else:
raise ValueError(
"trying to plot on an inactive link. this should not happen."
)
# eventually need to use x_of_node, y_of_node, and nodes_at_link,
# but the upstream to downstream ordering also matters.
# cumulative distance between squiggly-line link vertices [0 to link length]
link_dist = np.concatenate(
[[0], np.cumsum(np.sqrt(np.diff(link_x) ** 2 + np.diff(link_y) ** 2))]
)
# cumulative relative distance between squiggly-line link verticies [0 to 1]
# divide cumulative distance by max distance to get vector of distances between
# 0 and 1
link_rel_dist = link_dist / np.max(link_dist)
# # determine which two points on squiggly line bound parcel location in that link
# upper_loc_idx = np.argmax(link_rel_dist - parcel_loc > 0)
#
# to_interp_link_loc = link_rel_dist[upper_loc_idx - 1 : upper_loc_idx + 1]
# to_interp_link_x = link_x[upper_loc_idx - 1 : upper_loc_idx + 1]
# to_interp_link_y = link_y[upper_loc_idx - 1 : upper_loc_idx + 1]
#
# # check values are increasing
# np.all(np.diff(to_interp_link_loc) > 0)
# interpolate the X,Y coordinates from the parcel location
parcel_x = np.interp(
parcel_loc, link_rel_dist, link_x
) # , left=np.nan, right=np.nan)
parcel_y = np.interp(parcel_loc, link_rel_dist, link_y)
# assert np.isnan(parcel_x) == False
# save data to a single variable. better would be to save this info as
# an element of parcels.dataset.X and ...Y
XY = [parcel_x, parcel_y]
# parcels.dataset["X"] = parcel_x
# parcels.dataset["Y"] = parcel_y
else:
# if that parcel is no longer in the system do not try to compute X,Y and
# instead return NaN
XY = [np.nan, np.nan]
# return the X,Y values
return XY