From 6556dccaf693e4048ca5303ac0960d8da759962c Mon Sep 17 00:00:00 2001 From: Chris Rowe Date: Thu, 5 Sep 2024 16:31:57 -0400 Subject: [PATCH] Cog colormap example notebook --- notebooks/tutorial/cog colormap.ipynb | 247 ++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 notebooks/tutorial/cog colormap.ipynb diff --git a/notebooks/tutorial/cog colormap.ipynb b/notebooks/tutorial/cog colormap.ipynb new file mode 100644 index 0000000..5b15f55 --- /dev/null +++ b/notebooks/tutorial/cog colormap.ipynb @@ -0,0 +1,247 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Setup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Setup\n", + "import os\n", + "\n", + "## Data folder\n", + "def file_path_prefix(file_prefix):\n", + " folder = f'./data/{file_prefix}'\n", + " os.makedirs(folder, exist_ok=True)\n", + " return f'{folder}/{file_prefix}'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Inputs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Inputs\n", + "## Name of the area of interest\n", + "aoi_name='Salvador'\n", + "\n", + "## Path to polygon file the area you want data for\n", + "aoi_url = 'https://cities-indicators.s3.eu-west-3.amazonaws.com/data/boundaries/boundary-BRA-Salvador-ADM4union.geojson'\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Get Polygon for AOI" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# load boundary\n", + "import geopandas as gpd\n", + "\n", + "# If you are using an SSO accout, you need to be authenticated first\n", + "# !aws sso login\n", + "aoi_gdf = gpd.read_file(aoi_url, driver='GeoJSON')\n", + "\n", + "aoi_gdf = aoi_gdf.to_crs(epsg=4326)\n", + "\n", + "## Write to file\n", + "\n", + "file_path = f'{file_path_prefix(aoi_name)}-boundary.geojson'\n", + "aoi_gdf.to_file(file_path, driver='GeoJSON')\n", + "print(f'File saved to {file_path}')\n", + "\n", + "\n", + "\n", + "## Get area in km2 of the city rounded to the nearest integer\n", + "aoi_gdf_area = aoi_gdf['geometry'].to_crs(epsg=3857).area/ 10**6 # in km2\n", + "aoi_gdf_area = round(aoi_gdf_area.values[0])\n", + "print(f'Area: {aoi_gdf_area} sqkm')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LULCv2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from city_metrix.layers import SmartSurfaceLULC\n", + "\n", + "aoi_smart_surface_lulc = SmartSurfaceLULC().get_data(aoi_gdf.total_bounds)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from matplotlib.colors import ListedColormap\n", + "from enum import Enum\n", + "\n", + "# Define the lulcPaletteV3\n", + "lulcPaletteV3 = [\n", + " 'b2df8a',\n", + " 'cccccc',\n", + " '808080',\n", + " '33a02c',\n", + " 'a6cee3',\n", + " '000000',\n", + " '493910',\n", + " '5e4915',\n", + " '735a19',\n", + " '886a1e',\n", + " '9d7a23',\n", + " 'b28b27',\n", + " 'f5efba',\n", + " 'c9beb6'\n", + "]\n", + "\n", + "# Define the SsLulcClass Enum\n", + "class SsLulcClass(Enum):\n", + " GREEN_SPACE_OTHER = 1\n", + " BUILT_UP_OTHER = 2\n", + " BARREN = 3\n", + " OPEN_SPACE = 10\n", + " WATER = 20\n", + " ROADS = 30\n", + " NON_CLASSIFIED_BUILDINGS = 40\n", + " RESIDENTIAL_HIGH_SLOPE = 41\n", + " NON_RESIDENTIAL_HIGH_SLOPE = 42\n", + " UNCLASSIFIED_HIGH_SLOPE = 43\n", + " RESIDENTIAL_LOW_SLOPE = 44\n", + " NON_RESIDENTIAL_LOW_SLOPE = 45\n", + " UNCLASSIFIED_LOW_SLOPE = 46\n", + " PARKING = 50\n", + "\n", + "# Create a colormap dictionary\n", + "colormap = {cls.value: f'#{color}' for cls, color in zip(SsLulcClass, lulcPaletteV3)}\n", + "\n", + "# Create a ListedColormap for matplotlib\n", + "cmap = ListedColormap([colormap[key] for key in colormap.keys()])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cmap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Convert hex color codes to RGBA tuples\n", + "def hex_to_rgba(hex_color):\n", + " hex_color = hex_color.lstrip('#')\n", + " return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4)) + (255,)\n", + "\n", + "rgba_colormap = {key: hex_to_rgba(value) for key, value in colormap.items()}\n", + "\n", + "rgba_colormap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rgba_colormap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Save the DataArray with the colormap as a COG\n", + "file_path = f'{file_path_prefix(aoi_name)}-smart_surface_lulc_styled.tif'\n", + "\n", + "aoi_smart_surface_lulc.rio.to_raster(\n", + " file_path,\n", + " driver=\"COG\",\n", + " dtype=\"uint8\",\n", + " compress=\"deflate\")\n", + "\n", + "print(f'File saved to {file_path}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import rasterio\n", + "\n", + "with rasterio.Env():\n", + "\n", + " with rasterio.open(file_path) as src:\n", + " shade = src.read(1)\n", + " meta = src.meta\n", + "\n", + " with rasterio.open(file_path, 'w', **meta) as dst:\n", + " dst.write(shade, indexes=1)\n", + " dst.write_colormap(\n", + " 1, rgba_colormap)\n", + " cmap = dst.colormap(1)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "cities-cif", + "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.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}