Allow input files to be specified from the command line

etta-drone
Dan Howe 6 years ago
parent 8ca180f93f
commit 74c9351fe7

@ -1,414 +1,413 @@
import os import os
import sys import sys
import argparse import argparse
import subprocess import subprocess
from tqdm import tqdm from tqdm import tqdm
import numpy as np import numpy as np
from scipy import interpolate from scipy import interpolate
import pandas as pd import pandas as pd
import geopandas as gpd import geopandas as gpd
from shapely.geometry import Point, Polygon from shapely.geometry import Point, Polygon
from survey_tools import call_lastools from survey_tools import call_lastools
def remove_problems(x_list, y_list, z_list, x_now, y_now, check_value): def remove_problems(x_list, y_list, z_list, x_now, y_now, check_value):
z_ave=nine_pt_moving_average(z_list) z_ave=nine_pt_moving_average(z_list)
deriv_ave, chainage=forward_derivative(x_list, y_list, z_ave) deriv_ave, chainage=forward_derivative(x_list, y_list, z_ave)
deriv_real, chainage=two_point_derivative(x_list, y_list, z_list) deriv_real, chainage=two_point_derivative(x_list, y_list, z_list)
#first find the reference contour on the beach #first find the reference contour on the beach
#index_contour, x_now, y_now, distance=find_beach_reference_contour_choose_closest(chainage, z_ave, x_list, y_list, x_now, y_now,deriv_ave, check_value) #index_contour, x_now, y_now, distance=find_beach_reference_contour_choose_closest(chainage, z_ave, x_list, y_list, x_now, y_now,deriv_ave, check_value)
index_contour, x_now, y_now, distance=find_beach_reference_contour(chainage, z_ave, x_list, y_list, x_now, y_now,deriv_ave,deriv_real,check_value) index_contour, x_now, y_now, distance=find_beach_reference_contour(chainage, z_ave, x_list, y_list, x_now, y_now,deriv_ave,deriv_real,check_value)
if index_contour<len(chainage): #other wise keep everthing if index_contour<len(chainage): #other wise keep everthing
#find the beach slope, get the interpolated line (beach line) and the index of the reference contour +1 #find the beach slope, get the interpolated line (beach line) and the index of the reference contour +1
beach_slope, beach_line, index_high=find_beach_slope(chainage, z_ave,index_contour, check_value) beach_slope, beach_line, index_high=find_beach_slope(chainage, z_ave,index_contour, check_value)
#find the natural deviation of the lower beach #find the natural deviation of the lower beach
nat_dev=get_natural_deviation(chainage, z_list, index_contour, index_high, beach_line) nat_dev=get_natural_deviation(chainage, z_list, index_contour, index_high, beach_line)
for i in range(index_contour, len(z_list)): for i in range(index_contour, len(z_list)):
if abs(z_list[i]-float(beach_line(chainage[i])))>nat_dev: if abs(z_list[i]-float(beach_line(chainage[i])))>nat_dev:
break break
else: else:
i=index_contour i=index_contour
z_return=z_list[0:i] z_return=z_list[0:i]
chainage_return=chainage[0:i] chainage_return=chainage[0:i]
return z_return, chainage_return, x_now, y_now, distance return z_return, chainage_return, x_now, y_now, distance
def two_point_derivative(x_list, y_list, z_list): def two_point_derivative(x_list, y_list, z_list):
chain=[((x_list[0]-x_list[i])**2+(y_list[0]-y_list[i])**2)**0.5 for i in range(0,len(x_list))] chain=[((x_list[0]-x_list[i])**2+(y_list[0]-y_list[i])**2)**0.5 for i in range(0,len(x_list))]
deriv=[(z_list[i+1]-z_list[i-1])/(chain[i+1]-chain[i-1]) for i in range(1, len(z_list)-1)] deriv=[(z_list[i+1]-z_list[i-1])/(chain[i+1]-chain[i-1]) for i in range(1, len(z_list)-1)]
deriv.insert(0,0) deriv.insert(0,0)
deriv.append(0) deriv.append(0)
return deriv, chain return deriv, chain
def forward_derivative(x_list, y_list, z_list): def forward_derivative(x_list, y_list, z_list):
chain=[((x_list[0]-x_list[i])**2+(y_list[0]-y_list[i])**2)**0.5 for i in range(0,len(x_list))] chain=[((x_list[0]-x_list[i])**2+(y_list[0]-y_list[i])**2)**0.5 for i in range(0,len(x_list))]
deriv=[(z_list[i]-z_list[i-1])/(chain[i]-chain[i-1]) for i in range(0, len(z_list)-1)] deriv=[(z_list[i]-z_list[i-1])/(chain[i]-chain[i-1]) for i in range(0, len(z_list)-1)]
deriv.insert(0,0) deriv.insert(0,0)
return deriv, chain return deriv, chain
def find_first_over_reference(z_list, value): def find_first_over_reference(z_list, value):
i=len(z_list)-1 i=len(z_list)-1
while i>0 and z_list[i]<value: while i>0 and z_list[i]<value:
i=i-1 i=i-1
return i return i
def nine_pt_moving_average(z_list): def nine_pt_moving_average(z_list):
i=0 i=0
move_ave=[] move_ave=[]
while i<len(z_list): while i<len(z_list):
if i<5: if i<5:
ave=np.mean([z_list[j] for j in range(0,i+5)]) ave=np.mean([z_list[j] for j in range(0,i+5)])
elif i>len(z_list)-5: elif i>len(z_list)-5:
ave=np.mean([z_list[j] for j in range(i-4,len(z_list))]) ave=np.mean([z_list[j] for j in range(i-4,len(z_list))])
else: else:
ave=np.mean([z_list[j] for j in range(i-4,i+5)]) ave=np.mean([z_list[j] for j in range(i-4,i+5)])
move_ave.append(ave) move_ave.append(ave)
i=i+1 i=i+1
return move_ave return move_ave
def find_neg_derivative(z_list, deriv_list): def find_neg_derivative(z_list, deriv_list):
i=len(z_list)-5 i=len(z_list)-5
while z_list[i]>=0 and z_list[i+1]>=0 and z_list[i+2]>=0 and z_list[i+3]>=0 and z_list[i+4]>=0: while z_list[i]>=0 and z_list[i+1]>=0 and z_list[i+2]>=0 and z_list[i+3]>=0 and z_list[i+4]>=0:
i=i-1 i=i-1
return i return i
def find_beach_reference_contour_choose_closest(chain_list, z_ave_list, x_list, y_list, x_last, y_last, deriv_ave_list, check_value): def find_beach_reference_contour_choose_closest(chain_list, z_ave_list, x_list, y_list, x_last, y_last, deriv_ave_list, check_value):
#note that z_list should be the 9 point moving average #note that z_list should be the 9 point moving average
#assumes that beaches are shallow (|derivative|<0.3), sloping and between 0 - 4 m AHD #assumes that beaches are shallow (|derivative|<0.3), sloping and between 0 - 4 m AHD
i=0 i=0
choice_list=[] choice_list=[]
distance_list=[] distance_list=[]
if z_ave_list[i]>check_value: if z_ave_list[i]>check_value:
state_now='over' state_now='over'
else: else:
state_now='under' state_now='under'
while i<len(z_ave_list): while i<len(z_ave_list):
if state_now=='under' and z_ave_list[i]>check_value: #only keep if it is downward sloping if state_now=='under' and z_ave_list[i]>check_value: #only keep if it is downward sloping
state_now='over' state_now='over'
elif state_now=='over' and z_ave_list[i]<check_value: elif state_now=='over' and z_ave_list[i]<check_value:
choice_list.append(i) choice_list.append(i)
state_now='under' state_now='under'
if x_last!=None: if x_last!=None:
distance_list.append(((x_last - x_list[i])**2+(y_last - y_list[i])**2)**0.5) distance_list.append(((x_last - x_list[i])**2+(y_last - y_list[i])**2)**0.5)
i=i+1 i=i+1
if len(choice_list)>0 and x_last==None: #choose the first time for the first point if len(choice_list)>0 and x_last==None: #choose the first time for the first point
i=choice_list[0] i=choice_list[0]
distance=0 distance=0
elif len(choice_list)>0 and x_last!=None: elif len(choice_list)>0 and x_last!=None:
assert(len(choice_list)==len(distance_list)) assert(len(choice_list)==len(distance_list))
i=choice_list[distance_list.index(min(distance_list))] i=choice_list[distance_list.index(min(distance_list))]
distance=min(distance_list) distance=min(distance_list)
if i>=len(x_list): if i>=len(x_list):
i=len(x_list)-1 i=len(x_list)-1
if x_last!=None: if x_last!=None:
distance=((x_last - x_list[i])**2+(y_last - y_list[i])**2)**0.5 distance=((x_last - x_list[i])**2+(y_last - y_list[i])**2)**0.5
else: else:
distance=0 distance=0
x=x_list[i] x=x_list[i]
y=y_list[i] y=y_list[i]
return i, x, y, distance return i, x, y, distance
def find_beach_reference_contour(chain_list, z_ave_list, x_list, y_list, x_last, y_last, deriv_ave_list,deriv_real_list, check_value): def find_beach_reference_contour(chain_list, z_ave_list, x_list, y_list, x_last, y_last, deriv_ave_list,deriv_real_list, check_value):
#note that z_list should be the 9 point moving average #note that z_list should be the 9 point moving average
#assumes that beaches are shallow (|derivative|<0.3), sloping and between 0 - 4 m AHD #assumes that beaches are shallow (|derivative|<0.3), sloping and between 0 - 4 m AHD
i=len(z_ave_list)-1 i=len(z_ave_list)-1
while i>=0 and (z_ave_list[i]>check_value+2 or z_ave_list[i]<check_value-2 or deriv_ave_list[i]>0 or max([abs(i) for i in deriv_real_list[max(0,i-7):i]]+[0])>0.3):#beaches are shallow sloping, low while i>=0 and (z_ave_list[i]>check_value+2 or z_ave_list[i]<check_value-2 or deriv_ave_list[i]>0 or max([abs(i) for i in deriv_real_list[max(0,i-7):i]]+[0])>0.3):#beaches are shallow sloping, low
i=i-1 i=i-1
#find the first time it gets to check_value after this #find the first time it gets to check_value after this
while i>=0 and z_ave_list[i]<check_value: while i>=0 and z_ave_list[i]<check_value:
i=i-1 i=i-1
if i==0: if i==0:
i=len(z_ave_list)-1 # the whole this is above the beach i=len(z_ave_list)-1 # the whole this is above the beach
if x_last!=None: if x_last!=None:
distance=((x_last - x_list[i])**2+(y_last - y_list[i])**2)**0.5 distance=((x_last - x_list[i])**2+(y_last - y_list[i])**2)**0.5
else: else:
distance=0 distance=0
x=x_list[i] x=x_list[i]
y=y_list[i] y=y_list[i]
return i, x, y, distance return i, x, y, distance
def find_beach_slope(chain_list, z_ave_list, ref_index, check_value): def find_beach_slope(chain_list, z_ave_list, ref_index, check_value):
#ref index is the index of the check value #ref index is the index of the check value
#find the beach slope between this point and 1 m above this point #find the beach slope between this point and 1 m above this point
i=ref_index i=ref_index
while i>0 and z_ave_list[i]<check_value+1: while i>0 and z_ave_list[i]<check_value+1:
i=i-1 i=i-1
# Hide numpy floating point arithmetic warnings # Hide numpy floating point arithmetic warnings
np.seterr(all='ignore') np.seterr(all='ignore')
slope=(z_ave_list[i]-z_ave_list[ref_index])/(chain_list[i]-chain_list[ref_index]) slope=(z_ave_list[i]-z_ave_list[ref_index])/(chain_list[i]-chain_list[ref_index])
# Show numpy floating point arithmetic warnings # Show numpy floating point arithmetic warnings
np.seterr(all=None) np.seterr(all=None)
beach_ave=interpolate.interp1d([min(chain_list),max(chain_list)], [(min(chain_list)-chain_list[ref_index])*slope+z_ave_list[ref_index], (z_ave_list[ref_index]-(chain_list[ref_index]-max(chain_list))*slope)]) beach_ave=interpolate.interp1d([min(chain_list),max(chain_list)], [(min(chain_list)-chain_list[ref_index])*slope+z_ave_list[ref_index], (z_ave_list[ref_index]-(chain_list[ref_index]-max(chain_list))*slope)])
return slope, beach_ave, i return slope, beach_ave, i
def get_natural_deviation(chain_list, z_list, ref_index, ref_high, beach_ave): def get_natural_deviation(chain_list, z_list, ref_index, ref_high, beach_ave):
#for the points considered to be on the beach (reference contour to reference contour +1), find the average natural deviation #for the points considered to be on the beach (reference contour to reference contour +1), find the average natural deviation
deviation=[] deviation=[]
for i in range(ref_high, ref_index+1): for i in range(ref_high, ref_index+1):
dev_tmp=abs(z_list[i] - float(beach_ave(chain_list[i]))) dev_tmp=abs(z_list[i] - float(beach_ave(chain_list[i])))
deviation.append(dev_tmp) deviation.append(dev_tmp)
natural_deviation=min(np.max(deviation),0.4) #THIS MAY BE TOO CONSERVATIVE natural_deviation=min(np.max(deviation),0.4) #THIS MAY BE TOO CONSERVATIVE
return natural_deviation return natural_deviation
def distance_point_to_poly(x_list, y_list, x_now, y_now): def distance_point_to_poly(x_list, y_list, x_now, y_now):
#make a line from the mid of x_list, y_list #make a line from the mid of x_list, y_list
end=Point(x_list[-1], y_list[-1]) end=Point(x_list[-1], y_list[-1])
point=Point(x_now, y_now) point=Point(x_now, y_now)
dist=point.distance(end) dist=point.distance(end)
return dist return dist
def polygon_wave_runup(xyz_1m, direction, shp_name, set_check_value, distance_check, zone): def polygon_wave_runup(xyz_1m, direction, shp_name, set_check_value, distance_check, zone):
#print('starting processing of wave runup') #print('starting processing of wave runup')
all_data=pd.read_csv(xyz_1m, header=None, names=['X','Y','Z']) all_data=pd.read_csv(xyz_1m, header=None, names=['X','Y','Z'])
if direction=='north_south': if direction=='north_south':
all_data_sorted=all_data.sort_values(by=['X', 'Y'], ascending=[1,0]) all_data_sorted=all_data.sort_values(by=['X', 'Y'], ascending=[1,0])
elif direction=='west_east': elif direction=='west_east':
all_data_sorted=all_data.sort_values(by=['Y', 'X'], ascending=[0,1]) all_data_sorted=all_data.sort_values(by=['Y', 'X'], ascending=[0,1])
fixed_now=0 fixed_now=0
a=0 a=0
X_tmp=[] X_tmp=[]
processed_data = pd.DataFrame(columns=['X','Y','Z']) processed_data = pd.DataFrame(columns=['X','Y','Z'])
list_to_print=[10,20,30,40,50,60,70,80,90] list_to_print=[10,20,30,40,50,60,70,80,90]
crop_line=[] crop_line=[]
top_line=[] top_line=[]
tmp_x_last=None tmp_x_last=None
tmp_y_last=None tmp_y_last=None
exceed_list=[] exceed_list=[]
# Create progress bar # Create progress bar
pbar = tqdm(all_data_sorted.iterrows(), total=all_data_sorted.shape[0]) pbar = tqdm(all_data_sorted.iterrows(), total=all_data_sorted.shape[0])
for index, line in pbar: for index, line in pbar:
a=a+1 a=a+1
percent_done=round(a/len(all_data_sorted)*100,1) percent_done=round(a/len(all_data_sorted)*100,1)
if percent_done in list_to_print: if percent_done in list_to_print:
#print("Finished %s%% of the processing" % percent_done) #print("Finished %s%% of the processing" % percent_done)
list_to_print=list_to_print[1:len(list_to_print)] list_to_print=list_to_print[1:len(list_to_print)]
if direction=='north_south': if direction=='north_south':
check_this=line['X'] check_this=line['X']
elif direction=='west_east': elif direction=='west_east':
check_this=line['Y'] check_this=line['Y']
if check_this==fixed_now: if check_this==fixed_now:
X_tmp.append(line['X']) X_tmp.append(line['X'])
Y_tmp.append(line['Y']) Y_tmp.append(line['Y'])
Z_tmp.append(line['Z']) Z_tmp.append(line['Z'])
else: else:
if len(X_tmp)!=0: if len(X_tmp)!=0:
#try: ########may need to change!~! #try: ########may need to change!~!
if len(X_tmp)>10: if len(X_tmp)>10:
Z_set, chainage_tmp, temp_x, temp_y, distance=remove_problems(X_tmp, Y_tmp, Z_tmp,tmp_x_last, tmp_y_last, set_check_value) Z_set, chainage_tmp, temp_x, temp_y, distance=remove_problems(X_tmp, Y_tmp, Z_tmp,tmp_x_last, tmp_y_last, set_check_value)
#except: #except:
else: else:
Z_set=Z_tmp Z_set=Z_tmp
temp_x=X_tmp[len(Z_set)-1] temp_x=X_tmp[len(Z_set)-1]
temp_y=Y_tmp[len(Z_set)-1] temp_y=Y_tmp[len(Z_set)-1]
distance=0 distance=0
distance_2_old=distance_point_to_poly(X_tmp, Y_tmp, temp_x, temp_y) distance_2_old=distance_point_to_poly(X_tmp, Y_tmp, temp_x, temp_y)
if distance_2_old<distance_check: # find a way to change so it is checking the distance from the first crop polyogn, concave_now.buffer(buffer) if distance_2_old<distance_check: # find a way to change so it is checking the distance from the first crop polyogn, concave_now.buffer(buffer)
tmp_x_last=temp_x tmp_x_last=temp_x
tmp_y_last=temp_y tmp_y_last=temp_y
crop_line.append([X_tmp[len(Z_set)-1], Y_tmp[len(Z_set)-1]]) crop_line.append([X_tmp[len(Z_set)-1], Y_tmp[len(Z_set)-1]])
top_line.append([X_tmp[0], Y_tmp[0]]) top_line.append([X_tmp[0], Y_tmp[0]])
#otherwise crop by the distance_check #otherwise crop by the distance_check
else: else:
exceed_list.append(1) exceed_list.append(1)
try: try:
tmp_x_last=X_tmp[len(X_tmp)-distance_check] #beacuse this is a 1m DSM, this works tmp_x_last=X_tmp[len(X_tmp)-distance_check] #beacuse this is a 1m DSM, this works
tmp_y_last=Y_tmp[len(Y_tmp)-distance_check] tmp_y_last=Y_tmp[len(Y_tmp)-distance_check]
crop_line.append([tmp_x_last, tmp_y_last]) crop_line.append([tmp_x_last, tmp_y_last])
top_line.append([X_tmp[0], Y_tmp[0]]) top_line.append([X_tmp[0], Y_tmp[0]])
except: except:
print('problem with the last crop point, keeping whole line') print('problem with the last crop point, keeping whole line')
crop_line.append([X_tmp[-1], Y_tmp[-1]]) crop_line.append([X_tmp[-1], Y_tmp[-1]])
top_line.append([X_tmp[0], Y_tmp[0]]) top_line.append([X_tmp[0], Y_tmp[0]])
if direction=='north_south': if direction=='north_south':
fixed_now=line['X'] fixed_now=line['X']
elif direction=='west_east': elif direction=='west_east':
fixed_now=line['Y'] fixed_now=line['Y']
X_tmp=[line['X']] X_tmp=[line['X']]
Y_tmp=[line['Y']] Y_tmp=[line['Y']]
Z_tmp=[line['Z']] Z_tmp=[line['Z']]
else: else:
if direction=='north_south': if direction=='north_south':
fixed_now=line['X'] fixed_now=line['X']
elif direction=='west_east': elif direction=='west_east':
fixed_now=line['Y'] fixed_now=line['Y']
X_tmp=[line['X']] X_tmp=[line['X']]
Y_tmp=[line['Y']] Y_tmp=[line['Y']]
Z_tmp=[line['Z']] Z_tmp=[line['Z']]
#for the last line #for the last line
derivative, chainage=forward_derivative(X_tmp, Y_tmp, Z_tmp) derivative, chainage=forward_derivative(X_tmp, Y_tmp, Z_tmp)
if len(X_tmp)>10: if len(X_tmp)>10:
Z_set, chainage_tmp, temp_x, temp_y, distance=remove_problems(X_tmp, Y_tmp, Z_tmp,tmp_x_last, tmp_y_last, set_check_value) Z_set, chainage_tmp, temp_x, temp_y, distance=remove_problems(X_tmp, Y_tmp, Z_tmp,tmp_x_last, tmp_y_last, set_check_value)
#except: #except:
else: else:
Z_set=Z_tmp Z_set=Z_tmp
temp_x=X_tmp[len(Z_set)-1] temp_x=X_tmp[len(Z_set)-1]
temp_y=Y_tmp[len(Z_set)-1] temp_y=Y_tmp[len(Z_set)-1]
distance=0 distance=0
X_set=X_tmp[0:len(Z_set)] X_set=X_tmp[0:len(Z_set)]
Y_set=Y_tmp[0:len(Z_set)] Y_set=Y_tmp[0:len(Z_set)]
#write to new data frame #write to new data frame
#if len(Z_set)>0: #if len(Z_set)>0:
# for i in range(0, len(Z_set)): # for i in range(0, len(Z_set)):
# processed_data =processed_data.append({'X':X_set[i],'Y':Y_set[i],'Z':Z_set[i],'r':r_set[i],'g':g_set[i],'b':b_set[i]}, ignore_index=True) # processed_data =processed_data.append({'X':X_set[i],'Y':Y_set[i],'Z':Z_set[i],'r':r_set[i],'g':g_set[i],'b':b_set[i]}, ignore_index=True)
#add to crop line #add to crop line
distance_2_old=distance_point_to_poly(X_tmp, Y_tmp, temp_x, temp_y) distance_2_old=distance_point_to_poly(X_tmp, Y_tmp, temp_x, temp_y)
if distance_2_old<distance_check: # find a way to change so it is checking the distance from the first crop polyogn, concave_now.buffer(buffer) if distance_2_old<distance_check: # find a way to change so it is checking the distance from the first crop polyogn, concave_now.buffer(buffer)
tmp_x_last=temp_x tmp_x_last=temp_x
tmp_y_last=temp_y tmp_y_last=temp_y
crop_line.append([X_tmp[len(Z_set)-1], Y_tmp[len(Z_set)-1]]) crop_line.append([X_tmp[len(Z_set)-1], Y_tmp[len(Z_set)-1]])
top_line.append([X_tmp[0], Y_tmp[0]]) top_line.append([X_tmp[0], Y_tmp[0]])
#otherwise crop by the distance_check #otherwise crop by the distance_check
else: else:
exceed_list.append(1) exceed_list.append(1)
tmp_x_last=X_tmp[len(X_tmp)-distance_check] tmp_x_last=X_tmp[len(X_tmp)-distance_check]
tmp_y_last=Y_tmp[len(Y_tmp)-distance_check] tmp_y_last=Y_tmp[len(Y_tmp)-distance_check]
crop_line.append(tmp_x_last, tmp_y_last) crop_line.append(tmp_x_last, tmp_y_last)
top_line.append([X_tmp[0], Y_tmp[0]]) top_line.append([X_tmp[0], Y_tmp[0]])
#otherwise dont add. straight line is better #otherwise dont add. straight line is better
if direction=='north_south': if direction=='north_south':
y_filtered=nine_pt_moving_average([i[1] for i in crop_line]) y_filtered=nine_pt_moving_average([i[1] for i in crop_line])
crop_new=[[crop_line[i][0],y_filtered[i]] for i in range(0, len(crop_line))] crop_new=[[crop_line[i][0],y_filtered[i]] for i in range(0, len(crop_line))]
elif direction=='west_east': elif direction=='west_east':
x_filtered=nine_pt_moving_average([i[0] for i in crop_line]) x_filtered=nine_pt_moving_average([i[0] for i in crop_line])
crop_new=[[x_filtered[i],crop_line[i][1]] for i in range(0, len(crop_line))] crop_new=[[x_filtered[i],crop_line[i][1]] for i in range(0, len(crop_line))]
for_shape=crop_new+top_line[::-1] for_shape=crop_new+top_line[::-1]
for_shape.append(crop_new[0]) for_shape.append(crop_new[0])
#print('exceeded the manual distance_check %s%% of the time. manually cropping undertaken' % (round(len(exceed_list)/a,2)*100)) #print('exceeded the manual distance_check %s%% of the time. manually cropping undertaken' % (round(len(exceed_list)/a,2)*100))
#making the cropping shapefile #making the cropping shapefile
#print('making the crop polygon') #print('making the crop polygon')
# Export polygon as shapefile # Export polygon as shapefile
df = gpd.GeoDataFrame(geometry=[Polygon(for_shape)]) df = gpd.GeoDataFrame(geometry=[Polygon(for_shape)])
df.crs = {'init': 'epsg:283{}'.format(zone), 'no_defs': True} df.crs = {'init': 'epsg:283{}'.format(zone), 'no_defs': True}
df.to_file(shp_name, driver='ESRI Shapefile') df.to_file(shp_name, driver='ESRI Shapefile')
return None return None
def remove_temp_files(directory): def remove_temp_files(directory):
for f in os.listdir(directory): for f in os.listdir(directory):
os.unlink(os.path.join(directory, f)) os.unlink(os.path.join(directory, f))
return None return None
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(
'input_file', 'input_file',
metavar='PARAMS_FILE', metavar='PARAMS_FILE',
help='name of parameter file', help='name of parameter file',
default=None) default=None)
# Print usage if no arguments are provided # Print usage if no arguments are provided
if len(sys.argv) == 1: if len(sys.argv) == 1:
parser.print_help(sys.stderr) parser.print_help(sys.stderr)
sys.exit(1) sys.exit(1)
args = parser.parse_args() args = parser.parse_args()
# read the parameters file and scroll through it # read the parameters file and scroll through it
input_file = args.input_file input_file = args.input_file
input_file = 'Parameter Files/las-manipulation-survey-2.xlsx' params_file=pd.read_excel(input_file, sheet_name="PARAMS")
params_file=pd.read_excel(input_file, sheet_name="PARAMS")
for i, row in params_file.iterrows():
for i, row in params_file.iterrows(): print("Starting to process %s" % row['Beach'])
print("Starting to process %s" % row['Beach']) input_las = row['INPUT LAS']
input_las = row['INPUT LAS'] initial_crop_poly = row['INITIAL CROP POLY']
initial_crop_poly = row['INITIAL CROP POLY'] lasground_step = row['LASGROUND STEP']
lasground_step = row['LASGROUND STEP'] zone_MGA = row['ZONE MGA']
zone_MGA = row['ZONE MGA'] check_value = row['CHECK VALUE']
check_value = row['CHECK VALUE'] direct = row['DIRECTION']
direct = row['DIRECTION'] check_distance = row['CHECK DISTANCE']
check_distance = row['CHECK DISTANCE'] las_dir = row['LAS CLASSIFIED FOLDER']
las_dir = row['LAS CLASSIFIED FOLDER'] shp_dir = row['SHP SWASH FOLDER']
shp_dir = row['SHP SWASH FOLDER'] tmp_dir = row['TMP FOLDER']
tmp_dir = row['TMP FOLDER']
# Get base name of input las
# Get base name of input las las_basename = os.path.splitext(os.path.basename(input_las))[0]
las_basename = os.path.splitext(os.path.basename(input_las))[0]
# Crop to beach boundary
# Crop to beach boundary print('Clipping...')
print('Clipping...') las_data = call_lastools('lasclip', input=input_las, output='-stdout',
las_data = call_lastools('lasclip', input=input_las, output='-stdout', args=['-poly', initial_crop_poly], verbose=False)
args=['-poly', initial_crop_poly], verbose=False)
# Classify ground points
# Classify ground points print('Classifying ground...')
print('Classifying ground...') las_data = call_lastools('lasground_new', input=las_data, output='-stdout',
las_data = call_lastools('lasground_new', input=las_data, output='-stdout', args=['-step', lasground_step], verbose=False)
args=['-step', lasground_step], verbose=False)
# Save classified point cloud
# Save classified point cloud las_name = os.path.join(las_dir, las_basename + '.las')
las_name = os.path.join(las_dir, las_basename + '.las') with open (las_name, 'wb') as f:
with open (las_name, 'wb') as f: f.write(las_data)
f.write(las_data)
# Interpolate point cloud onto a grid
# Interpolate point cloud onto a grid print('Interpolating to grid...')
print('Interpolating to grid...') xyz_name = os.path.join(tmp_dir, las_basename + '.xyz')
xyz_name = os.path.join(tmp_dir, las_basename + '.xyz') call_lastools('las2dem', input=las_data, output=xyz_name,
call_lastools('las2dem', input=las_data, output=xyz_name, args=['-step', 1], verbose=False)
args=['-step', 1], verbose=False)
# Make runup clipping mask from gridded point cloud
# Make runup clipping mask from gridded point cloud print('Calculating runup clipping mask...')
print('Calculating runup clipping mask...') shp_name = os.path.join(shp_dir, las_basename + '.shp')
shp_name = os.path.join(shp_dir, las_basename + '.shp') polygon_wave_runup(xyz_name, direct, shp_name, check_value, check_distance, zone_MGA)
polygon_wave_runup(xyz_name, direct, shp_name, check_value, check_distance, zone_MGA) #NOTE THAT YOU NEED TO CHECK THE OUTPUT SHP FILE AND ADJUST AS REQUIRED
#NOTE THAT YOU NEED TO CHECK THE OUTPUT SHP FILE AND ADJUST AS REQUIRED
#delete the temp files
#delete the temp files remove_temp_files(tmp_dir)
remove_temp_files(tmp_dir)
if __name__ == '__main__':
if __name__ == '__main__': main()
main()

@ -13,7 +13,9 @@
import os import os
import io import io
import re import re
import sys
import math import math
import argparse
import datetime import datetime
import subprocess import subprocess
import numpy as np import numpy as np
@ -91,7 +93,7 @@ def calculate_volumes(profile_name, survey_date, csv_output_dir, ch_limits, volu
# Get Nielsen erosion volumes # Get Nielsen erosion volumes
chainage = profiles.loc[:, current_date].dropna().index chainage = profiles.loc[:, current_date].dropna().index
elevation = profiles.loc[:, current_date].dropna().values elevation = profiles.loc[:, current_date].dropna().values
volume = neilson_volumes.volume_available(chainage, elevation, ch_min) volume = nielsen_volumes.volume_available(chainage, elevation, ch_min)
# Update spreadsheet # Update spreadsheet
volumes.loc[profile_name, date] = volume volumes.loc[profile_name, date] = volume
@ -101,74 +103,100 @@ def calculate_volumes(profile_name, survey_date, csv_output_dir, ch_limits, volu
volumes.to_csv(csv_vol) volumes.to_csv(csv_vol)
input_file = 'Parameter Files/las-manipulation-survey-2.xlsx' def main():
params_file=pd.read_excel(input_file, sheet_name="PARAMS") parser = argparse.ArgumentParser()
parser.add_argument(
for i, row in params_file.iterrows(): 'input_file',
print("Starting to process %s" % row['Beach']) metavar='PARAMS_FILE',
beach=row['Beach'] help='name of parameter file',
survey_date = row['SURVEY DATE'] default=None)
original_las = row['INPUT LAS']
classified_las_dir = row['LAS CLASSIFIED FOLDER'] # Print usage if no arguments are provided
shp_swash_dir = row['SHP SWASH FOLDER'] if len(sys.argv) == 1:
crop_heatmap_poly = row['HEATMAP CROP POLY'] parser.print_help(sys.stderr)
output_las_dir = row['LAS OUTPUT FOLDER'] sys.exit(1)
zone_MGA = row['ZONE MGA']
output_poly_dir = row['SHP RASTER FOLDER'] args = parser.parse_args()
output_tif_dir = row['TIF OUTPUT FOLDER']
cp_csv = row['INPUT CSV'] # read the parameters file and scroll through it
profile_limit_file = row['PROFILE LIMIT FILE'] input_file = args.input_file
csv_output_dir = row['CSV OUTPUT FOLDER'] params_file=pd.read_excel(input_file, sheet_name="PARAMS")
graph_loc = row['PNG OUTPUT FOLDER']
volume_output_dir = row['CSV VOLUMES FOLDER'] for i, row in params_file.iterrows():
tmp_dir = row['TMP FOLDER'] print("Starting to process %s" % row['Beach'])
beach=row['Beach']
# Get base name of input las survey_date = row['SURVEY DATE']
las_basename = os.path.splitext(os.path.basename(original_las))[0] original_las = row['INPUT LAS']
classified_las_dir = row['LAS CLASSIFIED FOLDER']
# Get name of input point cloud shp_swash_dir = row['SHP SWASH FOLDER']
input_las = os.path.join(classified_las_dir, las_basename + '.las') crop_heatmap_poly = row['HEATMAP CROP POLY']
output_las_dir = row['LAS OUTPUT FOLDER']
# Get name of swash cropping polygon zone_MGA = row['ZONE MGA']
crop_swash_poly = os.path.join(shp_swash_dir, las_basename + '.shp') output_poly_dir = row['SHP RASTER FOLDER']
output_tif_dir = row['TIF OUTPUT FOLDER']
# Crop point cloud to swash boundary cp_csv = row['INPUT CSV']
las_data = call_lastools('lasclip', input=input_las, output='-stdout', profile_limit_file = row['PROFILE LIMIT FILE']
args=['-poly', crop_swash_poly], verbose=False) csv_output_dir = row['CSV OUTPUT FOLDER']
graph_loc = row['PNG OUTPUT FOLDER']
# Apply sea-side clipping polygon volume_output_dir = row['CSV VOLUMES FOLDER']
las_data = call_lastools('lasclip', input=las_data, output='-stdout', tmp_dir = row['TMP FOLDER']
args=['-poly', crop_heatmap_poly], verbose=False)
# Get base name of input las
# Create clipping polygon for heatmap raster las_basename = os.path.splitext(os.path.basename(original_las))[0]
shp_name = os.path.join(output_poly_dir, las_basename + '.shp')
call_lastools('lasboundary', input=las_data, output=shp_name, verbose=False) # Get name of input point cloud
input_las = os.path.join(classified_las_dir, las_basename + '.las')
# Make a raster from point cloud
tif_name = os.path.join(output_tif_dir, las_basename + '.tif') # Get name of swash cropping polygon
call_lastools('blast2dem', input=las_data, output=tif_name, crop_swash_poly = os.path.join(shp_swash_dir, las_basename + '.shp')
args=['-step', 0.2], verbose=False)
# Crop point cloud to swash boundary
# Extract elevations along profiles from triangulated surface print('Cropping swash...')
df = extract_pts( las_data = call_lastools('lasclip', input=input_las, output='-stdout',
las_data, args=['-poly', crop_swash_poly], verbose=False)
cp_csv,
survey_date, # Apply sea-side clipping polygon
beach, print('Cropping back of beach...')
args=['-parse', 'sxyz', '-keep_class', '2'], las_data = call_lastools('lasclip', input=las_data, output='-stdout',
verbose=False) args=['-poly', crop_heatmap_poly], verbose=False)
# Update survey profiles # Create clipping polygon for heatmap raster
update_survey_output(df, csv_output_dir) print('Creating heat map cropping polygon...')
shp_name = os.path.join(output_poly_dir, las_basename + '.shp')
# Get landward limit of surveys call_lastools('lasboundary', input=las_data, output=shp_name, verbose=False)
ch_limits = pd.read_excel(profile_limit_file, index_col='Profile')
# Make a raster from point cloud
# Plot profiles, and save sand volumes for current beach print('Creating heat map raster...')
profile_names = df['Profile'].unique() tif_name = os.path.join(output_tif_dir, las_basename + '.tif')
for profile_name in profile_names: call_lastools('blast2dem', input=las_data, output=tif_name,
plot_profiles(profile_name, survey_date, csv_output_dir, graph_loc, ch_limits) args=['-step', 0.2], verbose=False)
calculate_volumes(profile_name, survey_date, csv_output_dir, ch_limits, volume_output_dir)
# Extract elevations along profiles from triangulated surface
# Remove temprary files print('Extracting profile elevations...')
remove_temp_files(tmp_dir) df = extract_pts(
las_data,
cp_csv,
survey_date,
beach,
args=['-parse', 'sxyz', '-keep_class', '2'],
verbose=False)
# Update survey profiles
update_survey_output(df, csv_output_dir)
# Get landward limit of surveys
ch_limits = pd.read_excel(profile_limit_file, index_col='Profile')
# Plot profiles, and save sand volumes for current beach
print('Updating figures...')
profile_names = df['Profile'].unique()
for profile_name in profile_names:
plot_profiles(profile_name, survey_date, csv_output_dir, graph_loc, ch_limits)
calculate_volumes(profile_name, survey_date, csv_output_dir, ch_limits, volume_output_dir)
# Remove temprary files
remove_temp_files(tmp_dir)
if __name__ == '__main__':
main()

Loading…
Cancel
Save