{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "eae9c760-f19d-4057-bea2-73cc22b4f81b",
   "metadata": {},
   "source": [
    "# Import libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d4d6430b-2880-4b66-804d-10e4b0e80d11",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load Libraries\n",
    "import sys\n",
    "import os\n",
    "sys.path.append(os.path.abspath(\"../\"))\n",
    "\n",
    "import numpy as np\n",
    "import rasterio\n",
    "from scipy.spatial import cKDTree\n",
    "\n",
    "# Import preprocessing functions\n",
    "from functions.preprocessing_functions import (\n",
    "    load_raster_data,\n",
    "    generate_and_export_mask,\n",
    "    find_and_validate_seed,\n",
    "    sea_core_from_seed,\n",
    "    land_core_from_sea,\n",
    "    extract_raster_coordinates,\n",
    "    convert_wl_coordinates,\n",
    "    save_aligned_stations_to_shapefile\n",
    ")\n",
    "\n",
    "# Import configuration constants\n",
    "from config import (\n",
    "    DEM_FILE,\n",
    "    LANDCOVER_FILE,\n",
    "    SEED_CSV,\n",
    "    SEA_CORE_TIF,\n",
    "    LAND_CORE_TIF,\n",
    "    ALIGNED_WATER_STATIONS_SHP,\n",
    "    DEM_EPSG\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d23f6033-4ad0-4559-a302-d4c876662058",
   "metadata": {},
   "source": [
    "## Preprocessing files for Coastal Flood Map (CFM)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "d4f17305-45f8-4c4e-8b3f-04dc660d5d4b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Coordinates extracted in UTM\n",
      "Seed point verified: Water class (ID=21). Elevation = -18.47 m\n",
      "Seed point saved to ../output_data\\seed_ocean.csv\n",
      "../output_data\\01_dem_sea_core.tif generated and saved | total time: 1.78 seconds\n",
      "../output_data\\01_dem_land_core.tif generated and saved | total time: 1.80 seconds\n",
      "Transformed 71 water level coordinates to raster CRS.\n",
      "Saved aligned water stations to ../output_data\\Aligned_Water_Stations.shp\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\as229858\\Videos\\PyFlood\\functions\\preprocessing_functions.py:282: UserWarning: Column names longer than 10 characters will be truncated when saved to ESRI Shapefile.\n",
      "  gdf.to_file(output_shapefile)\n"
     ]
    }
   ],
   "source": [
    "# --------------------------------------------------\n",
    "# Load DEM and Land Cover Data\n",
    "# --------------------------------------------------\n",
    "z_dem, transform, crs = load_raster_data(DEM_FILE)\n",
    "\n",
    "with rasterio.open(LANDCOVER_FILE) as src:\n",
    "    land_cover = src.read(1).astype(float)\n",
    "    land_cover[land_cover == 255] = np.nan\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Extract Raster Coordinates\n",
    "# --------------------------------------------------\n",
    "dem_lon, dem_lat, _ = extract_raster_coordinates(z_dem, transform, crs)\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Identify and Validate Seed Ocean Point\n",
    "# --------------------------------------------------\n",
    "row_seed, col_seed = find_and_validate_seed(\n",
    "    z_dem, land_cover, transform, crs,\n",
    "    output_csv=SEED_CSV\n",
    ")\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Generate and Save Sea Core Mask\n",
    "# --------------------------------------------------\n",
    "sea_core_mask = sea_core_from_seed(z_dem, row_seed, col_seed)\n",
    "generate_and_export_mask(\n",
    "    name=SEA_CORE_TIF.replace(\".tif\", \"\"),\n",
    "    compute_fn=lambda: sea_core_mask,\n",
    "    reference_tif=DEM_FILE\n",
    ")\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Generate and Save Land Core Mask\n",
    "# --------------------------------------------------\n",
    "land_core_mask = land_core_from_sea(z_dem, sea_core_mask)\n",
    "generate_and_export_mask(\n",
    "    name=LAND_CORE_TIF.replace(\".tif\", \"\"),\n",
    "    compute_fn=lambda: land_core_mask,\n",
    "    reference_tif=DEM_FILE\n",
    ")\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Build KDTree from DEM Coordinates\n",
    "# --------------------------------------------------\n",
    "dem_shape = z_dem.shape\n",
    "points = np.column_stack((dem_lon.ravel(), dem_lat.ravel()))\n",
    "tree = cKDTree(points)\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Define Water Level Observations\n",
    "# --------------------------------------------------\n",
    "wl_s2 = np.array([\n",
    "    [-94.51333333, 29.51500000, 3.378],\n",
    "    [-94.72500000, 29.35666667, 2.81],\n",
    "    [-94.79333333, 29.31000000, 3.205],\n",
    "    [-94.91666667, 29.48166667, 3.234],\n",
    "    [-94.92020160, 29.44745403, 3.898],\n",
    "    [-94.98500000, 29.68166667, 2.782],\n",
    "    [-95.26500000, 29.72666667, 3.811],\n",
    "    [-94.7149197, 29.86744193, 3.666],\n",
    "    [-94.7743660, 29.9418847, 3.892],\n",
    "    [-94.8182567, 30.05771539, 5.904],\n",
    "    [-94.8507622, 30.4252067, 5.773],\n",
    "    [-94.9857602, 29.97271914, 7.159752],\n",
    "    [-94.9996503, 29.77078197, 5.5626],\n",
    "    [-95.0938189, 29.87633426, 4.422648],\n",
    "    [-95.1246139, 30.14523056, 5.321808],\n",
    "    [-95.1682662, 30.2327137, 5.344058],\n",
    "    [-95.1413198, 29.91633316, 14.71879],\n",
    "    [-95.2339608, 29.93386089, 16.87373],\n",
    "    [-95.2332671, 29.8371695, 11.04595],\n",
    "    [-95.2163230, 29.69467363, 5.827776],\n",
    "    [-95.2291011, 29.65661915, 7.434072],\n",
    "    [-95.1785440, 29.51745517, 4.995672],\n",
    "    [-95.2679907, 29.79328217, 12.11885],\n",
    "    [-95.3068796, 29.9182784, 17.80337],\n",
    "    [-95.3349365, 29.86189143, 18.90979],\n",
    "    [-95.3132696, 29.80883745, 12.89609],\n",
    "    [-95.2910473, 29.74939477, 4.498848],\n",
    "    [-95.2893807, 29.67439687, 7.046976],\n",
    "    [-95.2974366, 29.5968991, 13.01801],\n",
    "    [-95.3680556, 29.79277778, 13.09421],\n",
    "    [-95.3585490, 29.76661676, 9.232392],\n",
    "    [-95.3388889, 29.71416667, 9.162288],\n",
    "    [-95.3230476, 29.37154349, 7.382866],\n",
    "    [-95.4288270, 30.0357753, 8.59536],\n",
    "    [-95.4179936, 29.95688886, 25.44775],\n",
    "    [-95.3971612, 29.77522777, 14.0208],\n",
    "    [-95.4085505, 29.76022829, 9.878568],\n",
    "    [-95.4121620, 29.69717469, 12.5029],\n",
    "    [-95.4460522, 29.61884399, 11.16787],\n",
    "    [-95.5235538, 29.7468959, 16.67256],\n",
    "    [-95.5282765, 29.6727317, 17.24254],\n",
    "    [-95.5577213, 29.76217336, 18.70558],\n",
    "    [-95.5830000, 29.7091197, 18.92503],\n",
    "    [-95.5621664, 29.65662136, 21.717],\n",
    "    [-95.6057782, 29.7618958, 20.59229],\n",
    "    [-95.6466120, 29.86717035, 7.583424],\n",
    "    [-95.6257783, 29.8357824, 31.13227],\n",
    "    [-95.6868912, 29.8307828, 4.440936],\n",
    "    [-94.19281384, 29.68444965,  5.096256 ],\n",
    "    [-94.39030462, 29.59445505,  4.90728  ],\n",
    "    [-94.68690134, 29.77280093,  4.764024 ],\n",
    "    [-94.67528817, 29.60418343,  3.895344 ],\n",
    "    [-94.64808849, 29.46585341,  4.105656 ],\n",
    "    [-94.63418624, 29.45137871,  5.824728 ],\n",
    "    [-94.75107958, 29.3344534,   4.696968 ],\n",
    "    [-94.99329828, 29.71304287,  3.797808 ],\n",
    "    [-94.99889929, 29.62030003,  3.925824 ],\n",
    "    [-95.02471845, 29.55167198,  3.776472 ],\n",
    "    [-94.95779403, 29.50637545,  3.401568 ],\n",
    "    [-94.90529215, 29.3039072,   3.834384 ],\n",
    "    [-94.87779852, 29.23803827,  4.416552 ],\n",
    "    [-95.12832542, 29.59193594,  4.166616 ],\n",
    "    [-95.103909,   29.51331277,  3.21564  ],\n",
    "    [-95.04778292, 29.45666901,  3.21564  ],\n",
    "    [-95.04001319, 29.35584376,  3.176016 ],\n",
    "    [-94.94470485, 29.22085215,  3.770376 ],\n",
    "    [-95.13140589, 29.28667628,  2.25552  ],\n",
    "    [-95.35660191, 29.29667801,  8.071104 ],\n",
    "    [-95.20831237, 29.21195597,  2.2098   ],\n",
    "    [-95.11719144, 29.08613596,  2.883408 ],\n",
    "    [-95.28420906, 29.33635959,  2.828544 ]\n",
    "])\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Convert Water Level Coordinates to DEM CRS\n",
    "# --------------------------------------------------\n",
    "wl_x, wl_y, wl_values = convert_wl_coordinates(wl_s2, crs)\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Align Water Level Points to DEM Grid\n",
    "# --------------------------------------------------\n",
    "aligned_stations = []\n",
    "for orig_x, orig_y, wl_value in zip(wl_x, wl_y, wl_values):\n",
    "    distance, idx = tree.query([orig_x, orig_y])\n",
    "    row, col = np.unravel_index(idx, dem_shape)\n",
    "    snapped_x = dem_lon[row, col]\n",
    "    snapped_y = dem_lat[row, col]\n",
    "    aux_value = z_dem[row, col]\n",
    "    aligned_stations.append([snapped_x, snapped_y, wl_value, aux_value])\n",
    "\n",
    "aligned_stations = np.array(aligned_stations)\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Save Aligned Water Stations to Shapefile\n",
    "# --------------------------------------------------\n",
    "save_aligned_stations_to_shapefile(\n",
    "    aligned_stations=aligned_stations,\n",
    "    output_shapefile=ALIGNED_WATER_STATIONS_SHP,\n",
    "    crs_epsg=DEM_EPSG\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97636d3c-7eec-49ce-ae11-b1e66f401d3e",
   "metadata": {},
   "source": [
    "## Preprocessing files for Coastal Flood Map + Attenuation (CFM+A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "23e3e603-1b65-490a-8890-712758072f53",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loaded seed point: (328373.13, 3247140.13), Elevation: -18.47 m\n",
      "Seed water body coordinates in UTM (EPSG:26915): (328373.13, 3247140.13)\n",
      "Coastline extraction completed in 129.83 seconds.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\as229858\\Videos\\PyFlood\\functions\\preprocessing_attenuation_functions.py:129: UserWarning: Column names longer than 10 characters will be truncated when saved to ESRI Shapefile.\n",
      "  gdf.to_file(output_shapefile)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Coastline shapefile saved as ../output_data\\coastline.shp\n",
      "Processing 449,544,536 valid land points in parallel...\n",
      "Distance computation completed in 193.67 seconds.\n",
      "Minimum distance to coastline: 0.00 meters\n",
      "Maximum distance to coastline: 57754.35 meters\n",
      "Distance raster saved at: ../output_data\\Distance_to_Coastline.tif\n",
      "HWM aligned shapefile saved to: ../output_data\\Aligned_HWM_with_indices.shp\n"
     ]
    }
   ],
   "source": [
    "# Load Postcalibration Functions\n",
    "from functions.preprocessing_attenuation_functions import (\n",
    "    load_seed_point,\n",
    "    coastline_morphological_dilation,\n",
    "    save_coastline_as_shapefile,\n",
    "    calc_distance_to_coast_parallel,\n",
    "    save_distance_raster,\n",
    "    align_hwm_to_dem\n",
    ")\n",
    "\n",
    "# Import configuration constants\n",
    "from config import (\n",
    "    SEED_CSV,\n",
    "    DEM_FILE,\n",
    "    COASTLINE_SHP,\n",
    "    DISTANCE_TO_COAST_TIF,\n",
    "    HWM_INPUT_FILE,\n",
    "    ALIGNED_HWM_SHP,\n",
    "    DEM_EPSG\n",
    ")\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Load Seed Ocean Point from CSV\n",
    "# --------------------------------------------------\n",
    "seed_ocean, seed_elevation = load_seed_point(SEED_CSV)\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Extract Coastline from DEM\n",
    "# --------------------------------------------------\n",
    "coastline_xyz, coastline_pixel_indices = coastline_morphological_dilation(\n",
    "    dem_lon, dem_lat, z_dem, seed_ocean, epsg_code=DEM_EPSG\n",
    ")\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Save Coastline as Shapefile\n",
    "# --------------------------------------------------\n",
    "save_coastline_as_shapefile(\n",
    "    coastline_xyz,\n",
    "    output_shapefile=COASTLINE_SHP,\n",
    "    epsg_code=DEM_EPSG\n",
    ")\n",
    "\n",
    "# --------------------------------------------------\n",
    "# Compute Distance to Coastline\n",
    "# --------------------------------------------------\n",
    "distances = calc_distance_to_coast_parallel(\n",
    "    dem_lon, dem_lat, z_dem, coastline_xyz[:, :2]\n",
    ")\n",
    "\n",
    "# Reshape and Save Distance Raster\n",
    "distances = distances.reshape(z_dem.shape)\n",
    "\n",
    "print(f\"Minimum distance to coastline: {np.nanmin(distances):.2f} meters\")\n",
    "print(f\"Maximum distance to coastline: {np.nanmax(distances):.2f} meters\")\n",
    "\n",
    "save_distance_raster(\n",
    "    distances=distances,\n",
    "    dem_file=DEM_FILE,\n",
    "    output_filename=DISTANCE_TO_COAST_TIF\n",
    ")\n",
    "\n",
    "gdf_aligned, hwm_indices = align_hwm_to_dem(\n",
    "    shapefile_path=HWM_INPUT_FILE,\n",
    "    dem_lon=dem_lon,\n",
    "    dem_lat=dem_lat,\n",
    "    z_dem=z_dem,\n",
    "    crs=crs,\n",
    "    output_shapefile=ALIGNED_HWM_SHP\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b14adefd-d585-4fcc-9708-df565b26792e",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
