{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to make spatial joins"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from nes import *\n",
    "import geopandas as gpd\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from copy import copy\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "countries_path = '/esarchive/shapefiles/gadm_country_mask/gadm_country_ISO3166.shp'\n",
    "countries = gpd.read_file(countries_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Read/Create grid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Rotated grid from MONARCH\n",
    "projection='rotated'\n",
    "centre_lat = 51\n",
    "centre_lon = 10\n",
    "west_boundary = -35\n",
    "south_boundary = -27\n",
    "inc_rlat = 2.\n",
    "inc_rlon = 2.\n",
    "\n",
    "nessy = create_nes(comm=None, info=False, projection=projection,\n",
    "                   centre_lat=centre_lat, centre_lon=centre_lon,\n",
    "                   west_boundary=west_boundary, south_boundary=south_boundary,\n",
    "                   inc_rlat=inc_rlat, inc_rlon=inc_rlon)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "shp = nessy.create_shapefile()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 206732 characters]\n",
      "text/plain": [
       "<Figure size 1368x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, figsize=(19, 7))\n",
    "shp.plot(ax=ax, facecolor=\"none\", edgecolor=\"blue\")\n",
    "countries.plot(ax=ax, facecolor=\"none\", edgecolor='black', linewidth=0.3)\n",
    "\n",
    "ax.margins(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Spatial join"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1. Centroid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/gpfs/projects/bsc32/software/suselinux/11/software/jupyterlab/3.0.9-foss-2019b-Python-3.7.4/lib/python3.7/site-packages/ipykernel_launcher.py:4: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n",
      "\n",
      "  after removing the cwd from sys.path.\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 214632 characters]\n",
      "text/plain": [
       "<Figure size 1368x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot\n",
    "\n",
    "centroid_shp = copy(nessy.shapefile)\n",
    "centroid_shp['geometry'] = centroid_shp['geometry'].centroid\n",
    "\n",
    "fig, ax = plt.subplots(1, figsize=(19, 7))\n",
    "shp.plot(ax=ax, facecolor=\"none\", edgecolor=\"blue\")\n",
    "countries.plot(ax=ax, facecolor=\"none\", edgecolor='black', linewidth=0.3)\n",
    "\n",
    "centroid_shp.plot(ax=ax, edgecolor='none', facecolor=\"green\", marker=\".\", markersize=15)\n",
    "\n",
    "ax.margins(0)\n",
    "\n",
    "zoom={'x_min': -15, 'x_max': 55, 'y_min': 25, 'y_max':65}\n",
    "plt.axis([zoom['x_min'], zoom['x_max'], zoom['y_min'], zoom['y_max']])\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 22.2 s, sys: 940 ms, total: 23.1 s\n",
      "Wall time: 25.3 s\n"
     ]
    }
   ],
   "source": [
    "%time nessy.spatial_join(countries_path, method='centroid', var_list='ISO')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 310956 characters]\n",
      "text/plain": [
       "<Figure size 1368x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot results\n",
    "\n",
    "fig, ax = plt.subplots(1, figsize=(19, 7))\n",
    "\n",
    "nessy.shapefile.plot(ax=ax, column='ISO', cmap='gist_rainbow', legend=True, \n",
    "                     legend_kwds={'ncol': 3, 'loc': 'center left'})\n",
    "\n",
    "countries.plot(ax=ax, facecolor=\"none\", edgecolor='black', linewidth=0.3)\n",
    "shp.plot(ax=ax, facecolor=\"none\", edgecolor=\"grey\", linewidth=0.3)\n",
    "centroid_shp.plot(ax=ax, edgecolor='none', facecolor=\"green\", marker=\".\", markersize=15)\n",
    "\n",
    "leg = ax.get_legend()\n",
    "leg.set_bbox_to_anchor((1., 0.5))\n",
    "\n",
    "ax.margins(0)\n",
    "\n",
    "zoom={'x_min': -15, 'x_max': 55, 'y_min': 25, 'y_max':65}\n",
    "plt.axis([zoom['x_min'], zoom['x_max'], zoom['y_min'], zoom['y_max']])\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2. Intersection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "TopologyException: Input geom 1 is invalid: Ring Self-intersection at or near point 10.454459190368652 47.555736541748047 at 10.454459190368652 47.555736541748047\n",
      "TopologyException: Input geom 1 is invalid: Ring Self-intersection at or near point 28.070461273193359 59.298839569091911 at 28.070461273193359 59.298839569091911\n",
      "TopologyException: Input geom 1 is invalid: Ring Self-intersection at or near point 10.917919158935604 36.649631500244254 at 10.917919158935604 36.649631500244254\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 4min 24s, sys: 1.26 s, total: 4min 25s\n",
      "Wall time: 4min 26s\n"
     ]
    }
   ],
   "source": [
    "nessy = create_nes(comm=None, info=False, projection=projection,\n",
    "                   centre_lat=centre_lat, centre_lon=centre_lon,\n",
    "                   west_boundary=west_boundary, south_boundary=south_boundary,\n",
    "                   inc_rlat=inc_rlat, inc_rlon=inc_rlon)\n",
    "\n",
    "%time nessy.spatial_join(countries_path, method='intersection', var_list='ISO')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 290916 characters]\n",
      "text/plain": [
       "<Figure size 1368x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot results\n",
    "\n",
    "fig, ax = plt.subplots(1, figsize=(19, 7))\n",
    "\n",
    "nessy.shapefile.plot(ax=ax, column='ISO', cmap='gist_rainbow', legend=True, \n",
    "                     legend_kwds={'ncol': 3, 'loc': 'center left'})\n",
    "\n",
    "countries.plot(ax=ax, facecolor=\"none\", edgecolor='black', linewidth=0.3)\n",
    "shp.plot(ax=ax, facecolor=\"none\", edgecolor=\"grey\", linewidth=0.3)\n",
    "\n",
    "leg = ax.get_legend()\n",
    "leg.set_bbox_to_anchor((1., 0.5))\n",
    "\n",
    "ax.margins(0)\n",
    "\n",
    "zoom={'x_min': -15, 'x_max': 55, 'y_min': 25, 'y_max':65}\n",
    "plt.axis([zoom['x_min'], zoom['x_max'], zoom['y_min'], zoom['y_max']])\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3. Nearest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/gpfs/projects/bsc32/software/suselinux/11/software/geopandas/0.10.2-foss-2019b-Python-3.7.4/lib/python3.7/site-packages/geopandas/array.py:348: UserWarning: Geometry is in a geographic CRS. Results from 'sjoin_nearest' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n",
      "\n",
      "  stacklevel=stacklevel,\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 1min 54s, sys: 840 ms, total: 1min 55s\n",
      "Wall time: 1min 55s\n"
     ]
    }
   ],
   "source": [
    "nessy = create_nes(comm=None, info=False, projection=projection,\n",
    "                   centre_lat=centre_lat, centre_lon=centre_lon,\n",
    "                   west_boundary=west_boundary, south_boundary=south_boundary,\n",
    "                   inc_rlat=inc_rlat, inc_rlon=inc_rlon)\n",
    "\n",
    "%time nessy.spatial_join(countries_path, method='nearest', var_list='ISO')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 294080 characters]\n",
      "text/plain": [
       "<Figure size 1368x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot results\n",
    "\n",
    "fig, ax = plt.subplots(1, figsize=(19, 7))\n",
    "\n",
    "nessy.shapefile.plot(ax=ax, column='ISO', cmap='gist_rainbow', legend=True, \n",
    "                     legend_kwds={'ncol': 3, 'loc': 'center left'})\n",
    "\n",
    "countries.plot(ax=ax, facecolor=\"none\", edgecolor='black', linewidth=0.3)\n",
    "shp.plot(ax=ax, facecolor=\"none\", edgecolor=\"grey\", linewidth=0.3)\n",
    "\n",
    "leg = ax.get_legend()\n",
    "leg.set_bbox_to_anchor((1., 0.5))\n",
    "\n",
    "ax.margins(0)\n",
    "\n",
    "zoom={'x_min': -15, 'x_max': 55, 'y_min': 25, 'y_max':65}\n",
    "plt.axis([zoom['x_min'], zoom['x_max'], zoom['y_min'], zoom['y_max']])\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Write string data as NetCDF"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "nessy.variables['ISO'] = {'data': nessy.shapefile['ISO'].values.reshape([1, 1, nessy.lat['data'].shape[0], nessy.lon['data'].shape[-1]]),\n",
    "                          'dtype': str,\n",
    "                         }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set the string lenght\n",
    "nessy.set_strlen(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/gpfs/scratch/bsc32/bsc32538/NES_tests/NES/nes/nc_projections/default_nes.py:2444: UserWarning: WARNING!!! Different data types for variable ISO. Input dtype=<class 'str'>. Data dtype=object.\n",
      "  warnings.warn(msg)\n"
     ]
    }
   ],
   "source": [
    "nessy.to_netcdf('spatial_join.nc')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.7.4"
  },
  "vscode": {
   "interpreter": {
    "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
