|
|
|
@ -16,7 +16,9 @@ from logs import setup_logging
|
|
|
|
|
logger = setup_logging()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def lat_lon_from_profile_x_coord(center_lat_lon, orientation, center_profile_x, x_coord):
|
|
|
|
|
def lat_lon_from_profile_x_coord(
|
|
|
|
|
center_lat_lon, orientation, center_profile_x, x_coord
|
|
|
|
|
):
|
|
|
|
|
"""
|
|
|
|
|
Returns the lat/lon of a point on a profile with the given x_coord
|
|
|
|
|
:param center_lat_lon: Shapely point of lat/lon of profile center
|
|
|
|
@ -31,7 +33,9 @@ def lat_lon_from_profile_x_coord(center_lat_lon, orientation, center_profile_x,
|
|
|
|
|
point_x = center_x + (center_profile_x - x_coord) * np.cos(np.deg2rad(orientation))
|
|
|
|
|
point_y = center_y + (center_profile_x - x_coord) * np.sin(np.deg2rad(orientation))
|
|
|
|
|
point_xy = Point(point_x, point_y)
|
|
|
|
|
point_lat_lon = convert_coord_systems(point_xy, in_coord_system="EPSG:28356", out_coord_system="EPSG:4326")
|
|
|
|
|
point_lat_lon = convert_coord_systems(
|
|
|
|
|
point_xy, in_coord_system="EPSG:28356", out_coord_system="EPSG:4326"
|
|
|
|
|
)
|
|
|
|
|
return point_lat_lon
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -41,7 +45,9 @@ def lat_lon_from_profile_x_coord(center_lat_lon, orientation, center_profile_x,
|
|
|
|
|
@click.option("--crest-toes-csv", required=True, help=".csv file to convert")
|
|
|
|
|
@click.option("--impacts-csv", required=True, help=".csv file to convert")
|
|
|
|
|
@click.option("--output-geojson", required=True, help="where to store .geojson file")
|
|
|
|
|
def R_high_to_geojson(sites_csv, profiles_csv, crest_toes_csv, impacts_csv, output_geojson):
|
|
|
|
|
def R_high_to_geojson(
|
|
|
|
|
sites_csv, profiles_csv, crest_toes_csv, impacts_csv, output_geojson
|
|
|
|
|
):
|
|
|
|
|
"""
|
|
|
|
|
Converts impact R_high into a lat/lon geojson that we can plot in QGIS
|
|
|
|
|
:param sites_csv:
|
|
|
|
@ -58,10 +64,14 @@ def R_high_to_geojson(sites_csv, profiles_csv, crest_toes_csv, impacts_csv, outp
|
|
|
|
|
# Create geojson file
|
|
|
|
|
schema = {
|
|
|
|
|
"geometry": "Point",
|
|
|
|
|
"properties": OrderedDict([("beach", "str"), ("site_id", "str"), ("elevation", "float")]),
|
|
|
|
|
"properties": OrderedDict(
|
|
|
|
|
[("beach", "str"), ("site_id", "str"), ("elevation", "float")]
|
|
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
with fiona.open(output_geojson, "w", driver="GeoJSON", crs=from_epsg(4326), schema=schema) as output:
|
|
|
|
|
with fiona.open(
|
|
|
|
|
output_geojson, "w", driver="GeoJSON", crs=from_epsg(4326), schema=schema
|
|
|
|
|
) as output:
|
|
|
|
|
for index, row in df_impacts.iterrows():
|
|
|
|
|
|
|
|
|
|
site_id = index
|
|
|
|
@ -72,12 +82,18 @@ def R_high_to_geojson(sites_csv, profiles_csv, crest_toes_csv, impacts_csv, outp
|
|
|
|
|
|
|
|
|
|
# Get poststorm profile
|
|
|
|
|
df_profile = df_profiles.loc[(site_id, "prestorm")]
|
|
|
|
|
int_x = crossings(df_profile.index.get_level_values("x").tolist(), df_profile.z.tolist(), R_high_z)
|
|
|
|
|
int_x = crossings(
|
|
|
|
|
df_profile.index.get_level_values("x").tolist(),
|
|
|
|
|
df_profile.z.tolist(),
|
|
|
|
|
R_high_z,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Take the intersection closest to the dune face.
|
|
|
|
|
try:
|
|
|
|
|
x_cols = [x for x in df_crest_toes.columns if '_x' in x]
|
|
|
|
|
dune_face_x = np.mean(df_crest_toes.loc[(site_id, "prestorm"),x_cols].tolist())
|
|
|
|
|
x_cols = [x for x in df_crest_toes.columns if "_x" in x]
|
|
|
|
|
dune_face_x = np.mean(
|
|
|
|
|
df_crest_toes.loc[(site_id, "prestorm"), x_cols].tolist()
|
|
|
|
|
)
|
|
|
|
|
int_x = min(int_x, key=lambda x: abs(x - dune_face_x))
|
|
|
|
|
except:
|
|
|
|
|
continue
|
|
|
|
@ -91,7 +107,9 @@ def R_high_to_geojson(sites_csv, profiles_csv, crest_toes_csv, impacts_csv, outp
|
|
|
|
|
x_coord=int_x,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
prop = OrderedDict([("beach", beach), ("site_id", site_id), ("elevation", R_high_z)])
|
|
|
|
|
prop = OrderedDict(
|
|
|
|
|
[("beach", beach), ("site_id", site_id), ("elevation", R_high_z)]
|
|
|
|
|
)
|
|
|
|
|
output.write({"geometry": mapping(point_lat_lon), "properties": prop})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -99,7 +117,9 @@ def R_high_to_geojson(sites_csv, profiles_csv, crest_toes_csv, impacts_csv, outp
|
|
|
|
|
@click.option("--sites-csv", required=True, help=".csv file to convert")
|
|
|
|
|
@click.option("--profile-features-csv", required=True, help=".csv file to convert")
|
|
|
|
|
@click.option("--output-geojson", required=True, help="where to store .geojson file")
|
|
|
|
|
def profile_features_crest_toes_to_geojson(sites_csv, profile_features_csv, output_geojson):
|
|
|
|
|
def profile_features_crest_toes_to_geojson(
|
|
|
|
|
sites_csv, profile_features_csv, output_geojson
|
|
|
|
|
):
|
|
|
|
|
"""
|
|
|
|
|
Converts profile_features containing dune toes and crest locations to a geojson we can load into QGIS
|
|
|
|
|
:param sites_csv:
|
|
|
|
@ -131,7 +151,9 @@ def profile_features_crest_toes_to_geojson(sites_csv, profile_features_csv, outp
|
|
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
with fiona.open(output_geojson, "w", driver="GeoJSON", crs=from_epsg(4326), schema=schema) as output:
|
|
|
|
|
with fiona.open(
|
|
|
|
|
output_geojson, "w", driver="GeoJSON", crs=from_epsg(4326), schema=schema
|
|
|
|
|
) as output:
|
|
|
|
|
for index, row in df_profile_features.iterrows():
|
|
|
|
|
beach = index[:-4]
|
|
|
|
|
site_id = index
|
|
|
|
@ -185,9 +207,14 @@ def sites_csv_to_geojson(input_csv, output_geojson):
|
|
|
|
|
df_sites = pd.read_csv(input_csv, index_col=[0])
|
|
|
|
|
logger.info(os.environ.get("GDAL_DATA", None))
|
|
|
|
|
|
|
|
|
|
schema = {"geometry": "LineString", "properties": OrderedDict([("beach", "str"), ("site_id", "str")])}
|
|
|
|
|
schema = {
|
|
|
|
|
"geometry": "LineString",
|
|
|
|
|
"properties": OrderedDict([("beach", "str"), ("site_id", "str")]),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
with fiona.open(output_geojson, "w", driver="GeoJSON", crs=from_epsg(4326), schema=schema) as output:
|
|
|
|
|
with fiona.open(
|
|
|
|
|
output_geojson, "w", driver="GeoJSON", crs=from_epsg(4326), schema=schema
|
|
|
|
|
) as output:
|
|
|
|
|
for index, row in df_sites.iterrows():
|
|
|
|
|
|
|
|
|
|
center_lat_lon = Point(row["lon"], row["lat"])
|
|
|
|
@ -215,10 +242,16 @@ def sites_csv_to_geojson(input_csv, output_geojson):
|
|
|
|
|
|
|
|
|
|
@click.command()
|
|
|
|
|
@click.option("--sites-csv", required=True, help="sites.csv file to convert")
|
|
|
|
|
@click.option("--observed-impacts-csv", required=True, help="impacts-observed.csv file to convert")
|
|
|
|
|
@click.option("--forecast-impacts-csv", required=True, help="impacts-forecast.csv file to convert")
|
|
|
|
|
@click.option(
|
|
|
|
|
"--observed-impacts-csv", required=True, help="impacts-observed.csv file to convert"
|
|
|
|
|
)
|
|
|
|
|
@click.option(
|
|
|
|
|
"--forecast-impacts-csv", required=True, help="impacts-forecast.csv file to convert"
|
|
|
|
|
)
|
|
|
|
|
@click.option("--output-geojson", required=True, help="where to store .geojson file")
|
|
|
|
|
def impacts_to_geojson(sites_csv, observed_impacts_csv, forecast_impacts_csv, output_geojson):
|
|
|
|
|
def impacts_to_geojson(
|
|
|
|
|
sites_csv, observed_impacts_csv, forecast_impacts_csv, output_geojson
|
|
|
|
|
):
|
|
|
|
|
"""
|
|
|
|
|
Converts impacts observed and forecasted to a geojson for visualization in QGIS
|
|
|
|
|
:param sites_csv:
|
|
|
|
@ -231,7 +264,9 @@ def impacts_to_geojson(sites_csv, observed_impacts_csv, forecast_impacts_csv, ou
|
|
|
|
|
# Get information from .csv and read into pandas dataframe
|
|
|
|
|
df_sites = pd.read_csv(sites_csv, index_col=[0])
|
|
|
|
|
df_observed = pd.read_csv(observed_impacts_csv, index_col=[0])
|
|
|
|
|
df_forecast = pd.read_csv(forecast_impacts_csv, index_col=[0]).rename({"storm_regime": "forecast_storm_regime"})
|
|
|
|
|
df_forecast = pd.read_csv(forecast_impacts_csv, index_col=[0]).rename(
|
|
|
|
|
{"storm_regime": "forecast_storm_regime"}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Rename columns, so we can distinguish between forecast and observed
|
|
|
|
|
df_observed = df_observed.rename(columns={"storm_regime": "observed_storm_regime"})
|
|
|
|
@ -241,7 +276,9 @@ def impacts_to_geojson(sites_csv, observed_impacts_csv, forecast_impacts_csv, ou
|
|
|
|
|
df = pd.concat([df_sites, df_observed, df_forecast], sort=True, axis=1)
|
|
|
|
|
|
|
|
|
|
# Make new column for accuracy of forecast. Use underpredict/correct/overpredict classes
|
|
|
|
|
df.loc[df.observed_storm_regime == df.forecast_storm_regime, "forecast_accuray"] = "correct"
|
|
|
|
|
df.loc[
|
|
|
|
|
df.observed_storm_regime == df.forecast_storm_regime, "forecast_accuray"
|
|
|
|
|
] = "correct"
|
|
|
|
|
|
|
|
|
|
# Observed/Forecasted/Class for each combination
|
|
|
|
|
classes = [
|
|
|
|
@ -256,7 +293,10 @@ def impacts_to_geojson(sites_csv, observed_impacts_csv, forecast_impacts_csv, ou
|
|
|
|
|
("overwash", "overwash", "correct"),
|
|
|
|
|
]
|
|
|
|
|
for c in classes:
|
|
|
|
|
df.loc[(df.observed_storm_regime == c[0]) & (df.forecast_storm_regime == c[1]), "forecast_accuracy"] = c[2]
|
|
|
|
|
df.loc[
|
|
|
|
|
(df.observed_storm_regime == c[0]) & (df.forecast_storm_regime == c[1]),
|
|
|
|
|
"forecast_accuracy",
|
|
|
|
|
] = c[2]
|
|
|
|
|
|
|
|
|
|
schema = {
|
|
|
|
|
"geometry": "Point",
|
|
|
|
@ -271,7 +311,9 @@ def impacts_to_geojson(sites_csv, observed_impacts_csv, forecast_impacts_csv, ou
|
|
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
with fiona.open(output_geojson, "w", driver="GeoJSON", crs=from_epsg(4326), schema=schema) as output:
|
|
|
|
|
with fiona.open(
|
|
|
|
|
output_geojson, "w", driver="GeoJSON", crs=from_epsg(4326), schema=schema
|
|
|
|
|
) as output:
|
|
|
|
|
for index, row in df.iterrows():
|
|
|
|
|
|
|
|
|
|
# Locate the marker at the seaward end of the profile to avoid cluttering the coastline.
|
|
|
|
|