## Read, process, and merge bathymetry data
# Author: AJMR
# Date: 2022-02-10

#%% Import
import pandas as pd
import geopandas as gp
from mikeio import Mesh
import math

from scipy.spatial import cKDTree
from shapely.geometry import Point

import numpy as np
import cartopy.crs as ccrs
import contextily as ctx
import matplotlib.pyplot as plt

#%% Functions
def ckdnearest(gdA, gdB):

    nA = np.array(list(gdA.geometry.apply(lambda x: (x.x, x.y))))
    nB = np.array(list(gdB.geometry.apply(lambda x: (x.x, x.y))))
    btree = cKDTree(nB)
    dist, idx = btree.query(nA, k=1)
    gdB_nearest = gdB.iloc[idx].drop(columns="geometry").reset_index(drop=True)
    gdf = pd.concat(
        [
            gdA.reset_index(drop=True),
            gdB_nearest,
            pd.Series(dist, name='dist')
        ],
        axis=1)

    return gdf
#%% Setup Paths
dataPath = "C:/Users/arey/files/Projects/SouthShore/Bathy/"
mapbox = 'https://api.mapbox.com/styles/v1/alexander0042/ckemxgtk51fgp19nybfmdcb1e/tiles/256/{z}/{x}/{y}@2x?access_token=pk.eyJ1IjoiYWxleGFuZGVyMDA0MiIsImEiOiJjazVmdG4zbncwMHY4M2VrcThwZGUzZDFhIn0.w6oDHoo1eCeRlSBpwzwVtw'

#%%  Read in Source 1
S1 = pd.read_csv(dataPath + '211102_05 South MLW Breakwall inner Breakwall SBES and Median MBES NAD83 NAVD88 1x1.xyz',
                 delimiter='\s+', header=None, names=['x', 'y', 'z'])

#%%  Read in Source 2
S2 = pd.read_csv(dataPath + '211102_05 South MLW Breakwall sturcture Median MBES NAD83 NAVD88 1x1.xyz',
                 delimiter='\s+', header=None, names=['x', 'y', 'z'])

#%%  Read in Source 3
S3 = pd.read_csv(dataPath + '211102_05 South MLW Breakwall outer Breakwall Median MBES NAD83 NAVD88 1x1.xyz',
                 delimiter='\s+', header=None, names=['x', 'y', 'z'])

#%% Merge Sources
bathy_merged = pd.concat([S1, S2, S3])

# Convert to GeoPandas
bathy_gdf = gp.GeoDataFrame(bathy_merged, crs='EPSG:2289',
                            geometry=gp.points_from_xy(bathy_merged.x, bathy_merged.y))
bathy_gdf.to_crs('EPSG:32616', inplace=True)

bathy_gdf.loc[:, 'z'] = bathy_gdf.loc[:, 'z'] * 0.3048

del S1
del S2
del S3
del bathy_merged

bathy_gdf.drop(columns=['x', 'y'], inplace=True)

#%%  Read in Previous Bathymetry
previousBath = gp.read_file("//srv-mad3.baird.com/Projects/13632.101 South Shore Breakwater/06_Models/02_Mike21SW/SSB_Mesh_v40_Nodes.shp")


#%%  Read in new mesh
currenMesh = Mesh("//oak-spillway.baird.com/F/13632.101 South Shore Breakwater/SetupFiles/southshore_mesh2_v3InnerBounds.mesh")

#%% Make Geodataframe of mesh
currenMesh_gdf = gp.GeoDataFrame(currenMesh.node_coordinates, crs='EPSG:32616',
                                 geometry=gp.points_from_xy(currenMesh.node_coordinates[:, 0],
                                                            currenMesh.node_coordinates[:, 1]))
#%% Find Nearest Points to All
Bathy_nearest = ckdnearest(currenMesh_gdf, bathy_gdf)

# Save to file
Bathy_nearest.rename(columns={0: 'x'}, inplace=True)
Bathy_nearest.rename(columns={1: 'y'}, inplace=True)
Bathy_nearest.rename(columns={2: 'z_old'}, inplace=True)
Bathy_nearest.to_parquet("C:/Users/arey/Files/Projects/SouthShoreNearest.parquet")
Bathy_nearest.to_file("C:/Users/arey/Files/Projects/SouthShoreNearest.shp")
#%% Update Mesh
newMesh = currenMesh

newMesh.node_coordinates[Bathy_nearest.dist<100, 2] = Bathy_nearest.loc[Bathy_nearest.dist<100, 'z']

newMesh.write("//oak-spillway.baird.com/F/13632.101 South Shore Breakwater/SetupFiles/southshore_mesh2_v3InnerBounds_Bathy.mesh")








