{ "cells": [ { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Conservative Regridding\n", "=======================\n", "\n", "This tutorial will explain to you the concept of conservative regridding and \n", "how emiproc uses geopandas to perform this operation.\n", "\n", "This tutorial is there solely for educational purposes.\n", "If you use emiproc, you can use the\n", ":func:`emiproc.regrid.remap_inventory`\n", "function to perform conservative regridding on your inventories.\n", "\n", "A good additional source of information on regridding is this article in German [uba_arcgis_2016]_ by the Umweltbundesamt (UBA), which describes a similar approach using ArcGIS." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import geopandas as gpd\n", "from emiproc.grids import RegularGrid\n", "from shapely.geometry import Polygon" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "\n", "# Create some toy data \n", "grid = RegularGrid(nx=3, ny=2, dx=1, dy=1, xmin=0, ymin=0, crs=None)\n", "grid_serie = grid.gdf.geometry\n", "grid_serie.explore()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is a regular grid with 6 squared cells.\n", "We now want to create another grid in this to see how we can to the remapping." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# We \n", "triangle = Polygon([(-1, 1), (1.5, 0), (1.5, 2)])\n", "# We put another polygon on the side \n", "polygon = Polygon([(1.5, 2 ), (1.5, 0), (3, 0), (4, 1), (3, 2)])\n", "serie = gpd.GeoSeries([triangle, polygon])\n", "serie.explore()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Spatial join \n", "\n", "The first step is to genereate find which shapes will intersect shapes from the other grid.\n", "\n", "This can be performed using the `geopandas.overlay` function.\n", "It supports only geodataframes." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
source_indextarget_indexgeometry
000POLYGON ((0.00000 1.00000, 1.00000 1.00000, 1....
110POLYGON ((0.00000 1.40000, 1.00000 1.80000, 1....
220POLYGON ((1.00000 1.00000, 1.50000 1.00000, 1....
321POLYGON ((2.00000 1.00000, 2.00000 0.00000, 1....
430POLYGON ((1.00000 1.80000, 1.50000 2.00000, 1....
531POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1....
641POLYGON ((2.00000 1.00000, 3.00000 1.00000, 3....
751POLYGON ((2.00000 2.00000, 3.00000 2.00000, 3....
\n", "
" ], "text/plain": [ " source_index target_index \\\n", "0 0 0 \n", "1 1 0 \n", "2 2 0 \n", "3 2 1 \n", "4 3 0 \n", "5 3 1 \n", "6 4 1 \n", "7 5 1 \n", "\n", " geometry \n", "0 POLYGON ((0.00000 1.00000, 1.00000 1.00000, 1.... \n", "1 POLYGON ((0.00000 1.40000, 1.00000 1.80000, 1.... \n", "2 POLYGON ((1.00000 1.00000, 1.50000 1.00000, 1.... \n", "3 POLYGON ((2.00000 1.00000, 2.00000 0.00000, 1.... \n", "4 POLYGON ((1.00000 1.80000, 1.50000 2.00000, 1.... \n", "5 POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1.... \n", "6 POLYGON ((2.00000 1.00000, 3.00000 1.00000, 3.... \n", "7 POLYGON ((2.00000 2.00000, 3.00000 2.00000, 3.... " ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "grid_gdf = grid.gdf\n", "grid_gdf['source_index'] = grid_gdf.index\n", "\n", "gdf_out = gpd.GeoDataFrame(geometry=serie)\n", "gdf_out['target_index'] = gdf_out.index\n", "\n", "gdf_overlayed = gpd.overlay(grid_gdf, gdf_out, how='intersection')\n", "gdf_overlayed" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we have the intersections between the two grids. Each line will be a mapping between a cell in the source grid and a cell in the target grid.\n", "\n", "Cell index of the input grid is `source_index`. The column `target_index` is the index of the cell in the target grid.\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiwAAAF2CAYAAABNisPlAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAArQ0lEQVR4nO3dfXBU9b3H8c8GkjiuG2Ih3Q1RkIJICzY8FtcRoUQYqPVGhcaH6RAFWxGugnh9wFsvhHZCsWOgw6BO1YbUzkXp7SVivRDIFa0OCWjaBHCioA2KeVjAYBLNM/zuH162rkkgJyQ5Z3ffr5nf6J79nV++58zO7ofvnt11STICAABwsBi7CwAAADgfAgsAAHA8AgsAAHA8AgsAAHA8AgsAAHA8AgsAAHA8AgsAAHA8AgsAAHC8gXYX0FuGDh2qhoYGu8sAAAAWeDweVVVVnXdeRASWoUOHqrKy0u4yAABAD6SkpJw3tEREYDnbWUlJSaHLAgBAmPB4PKqsrOzWa3dEBJazGhoaCCwAAEQgLroFAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOZymwPPbYY9q/f7/q6+sVCAS0bds2jR49+rz7zZ8/X+Xl5WpqatKBAwc0d+7cDnOysrJUVVWlxsZG7d69W6NGjbJSGgAAiGCWAsv06dO1adMmXXPNNZo1a5ZiY2O1a9cuXXzxxV3u4/f7tWXLFr3wwguaMGGC8vPzlZ+fr7FjxwbnPPLII3rggQe0ePFiTZ06VV9++aUKCgoUHx/f8yMDAAARxfR0DBkyxBhjzLRp07qc89JLL5lXX301ZFtRUZF55plngrerqqrMQw89FLydkJBgmpqazG233datOjwejzHGGI/H0+NjYTAYDAaD0b/Dyuv3BV3DMmjQIElSbW1tl3P8fr8KCwtDthUUFMjv90uSRowYoeTk5JA59fX12rdvX3DON8XFxcnj8YQMAJEpRgN0kbru4gKIDj3+8UOXy6UNGzbo7bff1nvvvdflPJ/Pp0AgELItEAjI5/MF7z+7ras537Ry5UqtXr26p6UDCANuJegyfUc+DdPr1eV2lwNEvQHJR2z9+z0OLJs2bdK4ceN03XXX9WY93bJ27Vrl5OQEb5/9eWoA4S1GA+TVZUrRd5ToGmx3OQAcpEeBZePGjfrxj3+s66+//rxBoaamRl6vN2Sb1+tVTU1N8P5vbjt7u7S0tNM1W1tb1dra2pPSATjQ17spsa44u8sB4ECWr2HZuHGjbrnlFs2cOVNHjx497/yioiKlpaWFbJs1a5aKiookSRUVFaqurg6Z4/F4NHXq1OAcAJEnRgOUrOGarB/K75qty12jCCsAumSpw7Jp0ybdeeedSk9PV0NDQ7BzUldXp+bmZklSXl6eKisr9fjjj0uSfvvb3+rNN9/UihUr9Nprr+n222/X5MmT9fOf/zy47oYNG/SLX/xCR44cUUVFhX75y1+qqqpK+fn5vXSYAJyCbgqAnrAUWJYsWSJJevPNN0O233XXXcrLy5MkDRs2TGfOnAneV1RUpDvvvFO/+tWvlJ2drSNHjujmm28OuVD3ySeflNvt1u9+9zslJibq7bff1pw5c9TS0tLjAwPgHFybAuBCufTV55vDmsfjUX19vRISEtTQ0GB3OQD+X291UwqqynqxKgA90RefErLy+t3jTwkBQGfopgDoCwQWAL2Ca1MA9CUCC4Aeo5sCoL8QWABYRjcFQH8jsADoFropAOxEYAFwTnRTADgBgQVAB3RTADgNgQVAEN0UAE5FYAGiHN0UAOGAwAJEKbopAMIJgQWIInRTAIQrAgsQBeimAAh3BBYgQtFNARBJCCxAhKGbAiASEViACEA3BUCkI7AAYYxuCoBoQWABwgzdFADRiMAChAm6KQCiGYEFcDC6KQDwFQIL4EB0UwAgFIEFcAi6KQDQNQILYDO6KQBwfgQWwAYxGqAkDdXlGkU3BQC6gcAC9CO3EpSiEUrWcH2pBsIKAHQTgQXoY/+8NmWEEl1D/nmHsa8mAAg3BBagj3y9m8K1KQBwYWKs7jBt2jRt375dlZWVMsYoPT39nPNzc3NljOkwDh06FJyzatWqDveXl5dbPxrAZjEaoGQN12TNkN81W8NcVxJWAKAXWO6wuN1ulZWV6fe//722bdt23vnLli3TY4899s8/OHCgysrK9Kc//Slk3qFDh3TDDTcEb7e3t1stDbAN3RQA6FuWA8vOnTu1c+fObs+vr69XfX198HZ6erouvfRS5ebmhsxrb29XIBCwWg5gmy6vTQEA9Lp+v4Zl0aJFKiws1CeffBKy/corr1RlZaWam5tVVFSklStX6tixY52uERcXp/j4+OBtj8fTpzUDX0c3BQD6X78GluTkZM2dO1d33nlnyPZ9+/bprrvu0gcffKDk5GStWrVKb731lsaNG6cvvviiwzorV67U6tWr+6lqgG4KANitXwNLZmamPv/8c+Xn54ds//pbTAcPHtS+ffv08ccfKyMjQ7///e87rLN27Vrl5OQEb3s8HlVWVvZZ3YhedFMAwBn6NbAsXLhQL774otra2s45r66uTocPH9aoUaM6vb+1tVWtra19USJANwUAHKjfAsv06dN15ZVX6oUXXjjvXLfbrZEjR+rFF1/sh8qAr9BNAQDn6tHHmr/e+RgxYoRSU1NVW1urY8eOKTs7WykpKcrMzAzZb9GiRSouLtZ7773XYc3f/OY3evXVV/Xxxx9r6NChysrK0unTp7Vly5YeHBLQfXRTACA8WA4skydP1htvvBG8vX79eknS5s2bdffddys5OVnDhg0L2SchIUHz5s3TsmXLOl3zsssu05YtWzR48GCdOHFCb7/9tq655hqdPHnSanlAt9BNAYDw4lIE/KKJx+NRfX29EhIS1NDQYHc5cCindVM+N5/x44fdVFBVZncJQNQbkHyk19e08vrNbwkh4tFNAYDwR2BBRHJaNwUAcGEILIgodFMAIDIRWBD26KYAQOQjsCBs0U0BgOhBYEFYoZsCANGJwIKwQDcFAKIbgQWORTcFAHAWgQWOQzcFAPBNBBY4At0UAMC5EFhgK7opAIDuILCg39FNAQBYRWBBv6GbAgDoKQIL+hTdFABAbyCwoE/QTQEA9CYCC3oN3RQAQF8hsOCC0U0BAPQ1Agt6hG4KAKA/EVhgCd0UAIAdCCw4L7opAAC7EVjQJbopAACnILAgBN0UAIATEVggiW4KAMDZCCxRjG4KACBcEFiiEN0UAEC4IbBECbopAIBwRmCJcHRTAACRIMbqDtOmTdP27dtVWVkpY4zS09PPOX/69OkyxnQYXq83ZN6SJUtUUVGhpqYmFRcXa8qUKVZLw/+L0QAla7gma4b8rtka5rqSsAIACGuWA4vb7VZZWZmWLl1qab/Ro0fL5/MFx/Hjx4P3ZWRkKCcnR1lZWZo4caLKyspUUFCgpKQkq+VFNbcSNFqpmqYbNdY1hbd+AAARw/JbQjt37tTOnTst/6Hjx4+rrq6u0/tWrFih5557Tps3b5YkLV68WDfeeKMWLlyodevWWf5b0YRrUwAA0cByh6WnSktLVVVVpV27dunaa68Nbo+NjdWkSZNUWFgY3GaMUWFhofx+f6drxcXFyePxhIxoQzcFABBN+jywVFdX695779W8efM0b948HTt2TG+88YYmTJggSRoyZIgGDhyoQCAQsl8gEJDP5+t0zZUrV6q+vj44Kisr+/owHIFrUwAA0arPPyV0+PBhHT58OHi7qKhII0eO1IMPPqgFCxb0aM21a9cqJycneNvj8UR0aOGTPgCAaGfLx5r379+v6667TpJ08uRJtbe3d/jUkNfrVU1NTaf7t7a2qrW1tc/rtBPXpgAA8E/9dg3L140fP17V1dWSpLa2NpWUlCgtLS14v8vlUlpamoqKiuwoz1ZcmwIAQEeWOyxut1ujRo0K3h4xYoRSU1NVW1urY8eOKTs7WykpKcrMzJQkLVu2TBUVFXrvvfd00UUX6Z577tHMmTM1e/bs4Bo5OTnKy8vTu+++q/3792v58uVyu93Kzc3thUN0PropAACcm+XAMnnyZL3xxhvB2+vXr5ckbd68WXfffbeSk5M1bNiw4P1xcXF66qmnlJKSosbGRh04cEA33HBDyBpbt25VUlKS1qxZI5/Pp9LSUs2ZMyfku1oiEdemAADQPS5Jxu4iLpTH41F9fb0SEhLU0NBgdznnRDcFZ31uPlOia7DdZYSFgqoyu0sAot6A5CO9vqaV129+S6if0E0BAKDnCCx9iG4KAAC9g8DSB+imAADQuwgsvYRuCgAAfYfAcoHopgAA0PcILD1ANwUAgP5FYLGAbgoAAPYgsHRDsoYpRd+hmwIAgE0ILN3wXU1WjMuWn10CAACy6ccPAQAArCCwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAxyOwAAAAx7McWKZNm6bt27ersrJSxhilp6efc/4tt9yiXbt26fjx46qrq9PevXs1e/bskDmrVq2SMSZklJeXWy0NAABEKMuBxe12q6ysTEuXLu3W/Ouvv167d+/Wj370I02aNEl79uzRq6++qvHjx4fMO3TokHw+X3Bcd911VksDAAARaqDVHXbu3KmdO3d2e/6DDz4Ycvvf//3flZ6erptuukmlpaXB7e3t7QoEAlbLAQAAUaDfr2FxuVzyeDyqra0N2X7llVeqsrJSH330kf74xz/q8ssv73KNuLg4eTyekAEAACJXvweWf/u3f9Mll1yirVu3Brft27dPd911l+bMmaP77rtPI0aM0FtvvaVLLrmk0zVWrlyp+vr64KisrOyv8gEAgA36NbDccccdWrVqlTIyMnTixIng9p07d+q//uu/dPDgQe3atUs/+tGPlJiYqIyMjE7XWbt2rRISEoIjJSWlvw4BAADYwPI1LD1122236fnnn9dPfvIT/e///u8559bV1enw4cMaNWpUp/e3traqtbW1L8oEAAAO1C8dlttvv125ubm644479D//8z/nne92uzVy5EhVV1f3Q3UAAMDpevSx5tTUVKWmpkqSRowYodTU1OBFstnZ2crLywvOv+OOO/SHP/xBDz30kPbt2yev1yuv16uEhITgnN/85je6/vrrNXz4cPn9fm3btk2nT5/Wli1bLvT4AABABLAcWCZPnqzS0tLgR5LXr1+v0tJSrVmzRpKUnJysYcOGBef//Oc/V2xsrJ5++mnV1NQEx29/+9vgnMsuu0xbtmzRBx98oK1bt+qzzz7TNddco5MnT17g4QEAgEjgkmTsLuJCeTwe1dfXKyEhQQ0NDb2+/kzdqhgXv2KA3vW5+UyJrsF2lxEWCqrK7C4BiHoDko/0+ppWXr95FQYAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5HYAEAAI5nObBMmzZN27dvV2VlpYwxSk9PP+8+06dPV0lJiZqbm3XkyBFlZmZ2mLNkyRJVVFSoqalJxcXFmjJlitXSAABAhLIcWNxut8rKyrR06dJuzb/iiiv02muvac+ePRo/frw2bNig559/XrNnzw7OycjIUE5OjrKysjRx4kSVlZWpoKBASUlJVssDAAARyCXJ9HRnY4xuvvlmvfLKK13O+fWvf60bb7xRV199dXDbli1blJiYqLlz50qSiouL9c477+j+++//qiiXS8eOHdPGjRu1bt2689bh8XhUX1+vhIQENTQ09PRwujRTtyrGxbtn6F2fm8+U6BpsdxlhoaCqzO4SgKg3IPlIr69p5fV7YK//9W/w+/0qLCwM2VZQUKANGzZIkmJjYzVp0iStXbs2eL8xRoWFhfL7/Z2uGRcXp/j4+OBtj8fT+4V/zWm164xx9enfQPQxMmo3bXaXAQBhoc8Di8/nUyAQCNkWCAQ0aNAgXXTRRbr00ks1cODATueMGTOm0zVXrlyp1atX91XJHQzQQDos6HUu49JAV6zdZQBAWAjLV+G1a9cqISEhOFJSUuwuCQAA9KE+77DU1NTI6/WGbPN6vaqrq1Nzc7NOnjyp9vb2TufU1NR0umZra6taW1v7rGYAAOAsfd5hKSoqUlpaWsi2WbNmqaioSJLU1tamkpKSkDkul0tpaWnBOQAAILr16GPNqampSk1NlSSNGDFCqampuvzyyyVJ2dnZysvLC85/9tln9Z3vfEfr1q3TVVddpfvuu08ZGRlav359cE5OTo5+9rOfacGCBRozZoyeeeYZud1u5ebmXujxAQCACGD5LaHJkyfrjTfeCN4+Gzw2b96su+++W8nJyRo2bFjw/qNHj+rGG2/U+vXrtWzZMn366ae65557tGvXruCcrVu3KikpSWvWrJHP51NpaanmzJmj48ePX8ChAQCASHFB38PiFHwPC8IR38PSfXwPC2A/u7+HhVdhAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeD0KLEuWLFFFRYWamppUXFysKVOmdDl3z549MsZ0GH/5y1+Cc3Jzczvcv2PHjp6UBgAAItBAqztkZGQoJydHixcv1r59+7R8+XIVFBToqquu0okTJzrMv/XWWxUXFxe8PXjwYJWVlelPf/pTyLwdO3bo7rvvDt5uaWmxWhoAAIhQljssK1as0HPPPafNmzervLxcixcvVmNjoxYuXNjp/FOnTikQCATHrFmz1NjY2CGwtLS0hMz7/PPPe3RAAAAg8lgKLLGxsZo0aZIKCwuD24wxKiwslN/v79YaixYt0ksvvaTGxsaQ7TNmzFAgEND777+vp59+Wt/61reslAYAACKYpbeEhgwZooEDByoQCIRsDwQCGjNmzHn3nzJliq6++motWrQoZPvOnTv13//936qoqNDIkSOVnZ2tHTt2yO/368yZMx3WiYuLU3x8fPC2x+OxchgAACDMWL6G5UIsWrRIBw4c0DvvvBOy/eWXXw7+/6FDh3TgwAH94x//0IwZM/T66693WGflypVavXp1X5cLAAAcwtJbQidPnlR7e7u8Xm/Idq/Xq5qamnPue/HFF+v222/XCy+8cN6/U1FRoRMnTmjUqFGd3r927VolJCQER0pKSvcPAgAAhB1LgaWtrU0lJSVKS0sLbnO5XEpLS1NRUdE59/3JT36i+Ph4/fGPfzzv30lJSdHgwYNVXV3d6f2tra1qaGgIGQAAIHJZ/pRQTk6Ofvazn2nBggUaM2aMnnnmGbndbuXm5kqS8vLylJ2d3WG/RYsWKT8/X7W1tSHb3W63nnzySU2dOlXDhw/XzJkz9corr+jDDz9UQUFBDw8LAABEEsvXsGzdulVJSUlas2aNfD6fSktLNWfOHB0/flySNGzYsA4Xyo4ePVrTpk3TrFmzOqx3+vRpff/731dmZqYSExNVVVWlXbt26YknnlBra2sPDwsAAEQSlyRjdxEXyuPxqL6+XgkJCX3y9tBM3aoYF79igN71uflMia7BdpcRFgqqyuwuAYh6A5KP9PqaVl6/eRUGAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2ABAACOR2Dphr/rLdWYYzpjzthdCgAAUWmg3QWEg1M6oVM6oVjFa6gZrhSN0MUuj91lAQAQNQgsFrSpRR/rsD7WYV1qkpSi7+jbSlGMi0YVAAB9icDSQ3RdAADoPwSWC0TXBQCAvkdg6UV0XQAA6BsElj5A1wUAgN5FYOljdF0AALhwBJZ+QtcFAICeI7DYgK4LAADWEFhsRNcFAIDu6dEr45IlS1RRUaGmpiYVFxdrypQpXc7NzMyUMSZkNDU1dZiXlZWlqqoqNTY2avfu3Ro1alRPSgtbp3RCh7RPb+k1HTEH1Gga7C4JAADHsBxYMjIylJOTo6ysLE2cOFFlZWUqKChQUlJSl/vU1dXJ5/MFx/Dhw0Puf+SRR/TAAw9o8eLFmjp1qr788ksVFBQoPj7e+hGFubNdl70qUIl5k98wAgBAPQgsK1as0HPPPafNmzervLxcixcvVmNjoxYuXNjlPsYYBQKB4Dh+/HjI/cuXL9evfvUrbd++XQcPHtSCBQs0dOhQ3XzzzZYPKJLQdQEA4CuWAktsbKwmTZqkwsLC4DZjjAoLC+X3+7vc75JLLtHRo0f1ySefKD8/X9/73veC940YMULJyckha9bX12vfvn1drhkXFyePxxMyIhldFwBAtLMUWIYMGaKBAwcqEAiEbA8EAvL5fJ3u88EHH2jhwoVKT0/XT3/6U8XExGjv3r1KSUmRpOB+VtZcuXKl6uvrg6OystLKYYQ1ui4AgGjU5x9HKS4u1osvvqiysjL99a9/1a233qoTJ07o3nvv7fGaa9euVUJCQnCcDT/RhK4LACCaWPpY88mTJ9Xe3i6v1xuy3ev1qqampltrtLe36+9//3vwU0Bn9/vmGl6vV6WlpZ2u0draqtbWViulRzS+1wUAEOksdVja2tpUUlKitLS04DaXy6W0tDQVFRV17w/GxOjqq69WdXW1JKmiokLV1dUha3o8Hk2dOrXba+IrdF0AAJHK8hfH5eTkKC8vT++++67279+v5cuXy+12Kzc3V5KUl5enyspKPf7445KkJ554QsXFxfrwww+VmJiohx9+WMOHD9fzzz8fXHPDhg36xS9+oSNHjqiiokK//OUvVVVVpfz8/N45yihE1wUAEEksB5atW7cqKSlJa9askc/nU2lpqebMmRP8qPKwYcN05sw//1V/6aWX6rnnnpPP59OpU6dUUlKia6+9VuXl5cE5Tz75pNxut373u98pMTFRb7/9tubMmaOWlpZeOMToxrfpAgAigUuSsbuIC+XxeFRfX6+EhAQ1NPCpmfOJVbyGiq6L3T43nynRNdjuMsJCQVWZ3SUAUW9A8pFeX9PK6ze/JRSF6LoAAMINgSXKca0LACAcEFggia4LAMDZCCzogK4LAMBpCCzoEl0XAIBTEFjQLXRdAAB2IrDAErouAAA7EFjQY3RdAAD9hcCCC0bXBQDQ1wgs6FV0XQAAfYHAgj5B1wUA0JsILOhzdF0AABeKwIJ+Q9cFANBTBBbYgq4LAMAKAgtsRdcFANAdBBY4Bl0XAEBXCCxwHLouAIBvIrDA0ei6AAAkAgvCBF0XAIhuBBaEHbouABB9CCwIW3RdACB6EFgQEei6AEBkI7AgotB1AYDIRGBBxKLrAgCRg8CCiEfXBQDCH4EFUYWuCwCEJwILohJdFwAILz16dl6yZIkqKirU1NSk4uJiTZkypcu599xzj/7617+qtrZWtbW12r17d4f5ubm5MsaEjB07dvSkNMCyUzqhQ9qnt/SajpgDajQNdpcEAPgGy4ElIyNDOTk5ysrK0sSJE1VWVqaCggIlJSV1On/GjBnasmWLfvjDH8rv9+vYsWPatWuXhg4dGjJvx44d8vl8wXHHHXf07IiAHjrbddmrApWYN1VjjumMOWN3WQAASS5JxsoOxcXFeuedd3T//fd/tYDLpWPHjmnjxo1at27defePiYnRqVOn9K//+q968cUXJX3VYUlMTNQtt9xi/QgkeTwe1dfXKyEhQQ0N/OsYvSdW8RqqvrnW5XPzmRJdg3t1zUhVUFVmdwlA1BuQfKTX17Ty+m2pwxIbG6tJkyapsLAwuM0Yo8LCQvn9/m6tcfHFFys2Nla1tbUh22fMmKFAIKD3339fTz/9tL71rW91uUZcXJw8Hk/IAPoCXRcAcAZLgWXIkCEaOHCgAoFAyPZAICCfz9etNdatW6eqqqqQ0LNz504tWLBAaWlpevTRRzV9+nTt2LFDMTGdl7dy5UrV19cHR2VlpZXDAHqEa10AwD79+imhRx99VLfffrtmzJihlpaW4PaXX345+P+HDh3SgQMH9I9//EMzZszQ66+/3mGdtWvXKicnJ3jb4/EQWtBv+IQRAPQ/S4Hl5MmTam9vl9frDdnu9XpVU1Nzzn0feughPfbYY7rhhht08ODBc86tqKjQiRMnNGrUqE4DS2trq1pbW62UDvQJvtcFAPqHpX8StrW1qaSkRGlpacFtLpdLaWlpKioq6nK/hx9+WE888YTmzJmjkpKS8/6dlJQUDR48WNXV1VbKA2zDtS4A0LcsvyWUk5OjvLw8vfvuu9q/f7+WL18ut9ut3NxcSVJeXp4qKyv1+OOPS5IeeeQRrVmzRnfeeaeOHj0a7M588cUX+vLLL+V2u7Vq1Sr9+c9/Vk1NjUaOHKknn3xSH374oQoKCnrxUIH+QdcFAHqf5cCydetWJSUlac2aNfL5fCotLdWcOXN0/PhxSdKwYcN05sw//2V53333KT4+Xn/+859D1lm9erWysrJ0+vRpff/731dmZqYSExNVVVWlXbt26YknnuBtH4Q1rnUBgN5j+XtYnIjvYUG4+Pr3urSqle9h6Sa+hwWwn93fw8JvCQH96Otdl0Ql6TJD1wUAuoPAAtjkc53Q51zrAgDdQmABbMa1LgBwfgQWwEH4hBEAdI7AAjgQXRcACEVgARyOrgsAEFiAsEHXBUA0I7AAYYiuC4BoQ2ABwhhdFwDRgsACRAi6LgAiGYEFiDB0XQBEIgILEMHougCIFAQWIArQdQEQ7ggsQJSh6wIgHBFYgChF1wVAOCGwAKDrAsDxCCwAgui6AHAqAguATtF1AeAkBBYA50TXBYATEFgAdBtdFwB2IbAAsIyuC4D+RmABcEHougDoDwQWAL2CrguAvkRgAdDr6LoA6G0EFgB9hq4LgN5CYAHQL+i6ALgQPfpnzpIlS1RRUaGmpiYVFxdrypQp55w/f/58lZeXq6mpSQcOHNDcuXM7zMnKylJVVZUaGxu1e/dujRo1qielAXC4s12XvSpQiXlTNeaYzpgzdpcFwOEsB5aMjAzl5OQoKytLEydOVFlZmQoKCpSUlNTpfL/fry1btuiFF17QhAkTlJ+fr/z8fI0dOzY455FHHtEDDzygxYsXa+rUqfryyy9VUFCg+Pj4nh8ZAMc7pRM6pH16S6/piDmgRtNgd0kAHMolyVjZobi4WO+8847uv//+rxZwuXTs2DFt3LhR69at6zD/pZdektvt1k033RTcVlRUpNLSUt13332SpKqqKj311FN66qmnJEkJCQkKBAK666679PLLL5+3Jo/Ho/r6eiUkJKihgSc8IJxdqo7XuhRUldlcFYAByUd6fU0rr9+WOiyxsbGaNGmSCgsLg9uMMSosLJTf7+90H7/fHzJfkgoKCoLzR4wYoeTk5JA59fX12rdvX5drxsXFyePxhAwAkYGuC4DOWLrodsiQIRo4cKACgUDI9kAgoDFjxnS6j8/n63S+z+cL3n92W1dzvmnlypVavXq1ldIBhJmvf8LoouQ4tanV7pIA2CgsP1u4du1aJSQkBEdKSordJQHoQ4QVAJYCy8mTJ9Xe3i6v1xuy3ev1qqamptN9ampqzjn/7H+trNna2qqGhoaQAQAAIpelwNLW1qaSkhKlpaUFt7lcLqWlpamoqKjTfYqKikLmS9KsWbOC8ysqKlRdXR0yx+PxaOrUqV2uCQAAoo+xMjIyMkxTU5NZsGCBGTNmjHn22WdNbW2t+fa3v20kmby8PJOdnR2c7/f7TWtrq1mxYoW56qqrzKpVq0xLS4sZO3ZscM4jjzxiamtrzU033WTGjRtntm3bZj766CMTHx/frZo8Ho8xxhiPx2PpWBgMBoPBYNg3LL5+W/8DS5cuNUePHjXNzc2muLjY/OAHPwjet2fPHpObmxsyf/78+eb99983zc3N5uDBg2bu3Lkd1szKyjLV1dWmqanJ7N6921x55ZV9dcAMBoPBYDAcMKy8flv+HhYn4ntYAAAIP332PSwAAAB2ILAAAADHI7AAAADHI7AAAADHI7AAAADHI7AAAADHI7AAAADHs/RrzU7n8XjsLgEAAHSTldftiAgsZw+4srLS5koAAIBVHo/nvF8cFxHfdCtJQ4cO7ZNvufV4PKqsrFRKSgrfonsenKvu41x1H+fKGs5X93Guuq8vz5XH41FVVdV550VEh0VStw72QjQ0NPCA7ibOVfdxrrqPc2UN56v7OFfd1xfnqrvrcdEtAABwPAILAABwPALLebS0tGj16tVqaWmxuxTH41x1H+eq+zhX1nC+uo9z1X1OOFcRc9EtAACIXHRYAACA4xFYAACA4xFYAACA4xFYAACA4xFYJC1ZskQVFRVqampScXGxpkyZcs758+fPV3l5uZqamnTgwAHNnTu3nyq1n5VzlZmZKWNMyGhqaurHau0zbdo0bd++XZWVlTLGKD09/bz7TJ8+XSUlJWpubtaRI0eUmZnZD5Xaz+q5mj59eofHlTFGXq+3nyq2z2OPPab9+/ervr5egUBA27Zt0+jRo8+7XzQ+Z/XkXEXrc9bixYtVVlamuro61dXVae/evZozZ84597HjMRX1gSUjI0M5OTnKysrSxIkTVVZWpoKCAiUlJXU63+/3a8uWLXrhhRc0YcIE5efnKz8/X2PHju3nyvuf1XMlSXV1dfL5fMExfPjwfqzYPm63W2VlZVq6dGm35l9xxRV67bXXtGfPHo0fP14bNmzQ888/r9mzZ/dxpfazeq7OGj16dMhj6/jx431UoXNMnz5dmzZt0jXXXKNZs2YpNjZWu3bt0sUXX9zlPtH6nNWTcyVF53PWp59+qscee0yTJk3S5MmT9frrr+uVV17R9773vU7n2/mYMtE8iouLzcaNG4O3XS6X+fTTT82jjz7a6fyXXnrJvPrqqyHbioqKzDPPPGP7sTjtXGVmZppTp07ZXrfdwxhj0tPTzznn17/+tTl48GDIti1btpgdO3bYXr/TztX06dONMcYMGjTI9nrtHkOGDDHGGDNt2rQu50Tzc5bVc8Vz1j/HZ599ZhYuXNjpfXY9pqK6wxIbG6tJkyapsLAwuM0Yo8LCQvn9/k738fv9IfMlqaCgoMv5kaIn50qSLrnkEh09elSffPKJ8vPzu0zs0S5aH1cXorS0VFVVVdq1a5euvfZau8uxxaBBgyRJtbW1Xc7hsfWV7pwrieesmJgY3XbbbXK73SoqKup0jl2PqagOLEOGDNHAgQMVCARCtgcCAfl8vk738fl8luZHip6cqw8++EALFy5Uenq6fvrTnyomJkZ79+5VSkpKf5QcVrp6XA0aNEgXXXSRTVU5U3V1te69917NmzdP8+bN07Fjx/TGG29owoQJdpfWr1wulzZs2KC3335b7733XpfzovU56+u6e66i+Tlr3LhxamhoUEtLi5599lndcsstKi8v73SuXY+piPm1ZjhPcXGxiouLg7f37t2r8vJy3XvvvfqP//gPGytDODt8+LAOHz4cvF1UVKSRI0fqwQcf1IIFC2ysrH9t2rRJ48aN03XXXWd3KY7X3XMVzc9ZH3zwgcaPH69BgwZp/vz5ysvL0/Tp07sMLXaI6g7LyZMn1d7e3uHTBV6vVzU1NZ3uU1NTY2l+pOjJufqm9vZ2/f3vf9eoUaP6osSw1tXjqq6uTs3NzTZVFT72798fVY+rjRs36sc//rF++MMfqrKy8pxzo/U56ywr5+qbouk5q62tTR999JH+9re/6fHHH1dZWZmWLVvW6Vy7HlNRHVja2tpUUlKitLS04DaXy6W0tLQu37srKioKmS9Js2bN6nJ+pOjJufqmmJgYXX311aquru6rMsNWtD6uesv48eOj5nG1ceNG3XLLLZo5c6aOHj163vnR/Niyeq6+KZqfs2JiYhQfH9/pfXY+pmy/GtnOkZGRYZqamsyCBQvMmDFjzLPPPmtqa2vNt7/9bSPJ5OXlmezs7OB8v99vWltbzYoVK8xVV11lVq1aZVpaWszYsWNtPxannasnnnjCzJo1y4wYMcJMmDDB/Od//qdpbGw03/3ud20/lr4ebrfbpKammtTUVGOMMcuXLzepqanm8ssvN5JMdna2ycvLC86/4oorzBdffGHWrVtnrrrqKnPfffeZtrY2M3v2bNuPxWnnatmyZeZf/uVfzMiRI83YsWPN+vXrTXt7u5k5c6btx9LXY9OmTebUqVPm+uuvN16vNzguuuii4Byes3p+rqL1OSs7O9tMmzbNDB8+3IwbN85kZ2eb06dPmxtuuMFpjyn7T5bdY+nSpebo0aOmubnZFBcXmx/84AfB+/bs2WNyc3ND5s+fP9+8//77prm52Rw8eNDMnTvX9mNw4rnKyckJzq2urjZ/+ctfzPjx420/hv4YZz96+01nz09ubq7Zs2dPh33+9re/mebmZvPhhx+azMxM24/Diefq4YcfNkeOHDGNjY3m5MmT5vXXXzczZsyw/Tj6Y3Tl648VnrN6fq6i9Tnr+eefNxUVFaa5udkEAgGze/fuYFhx0mPK9f//AwAA4FhRfQ0LAAAIDwQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeAQWAADgeP8HfdZavpxlpW0AAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "gdf_overlayed.plot('source_index')\n", "gdf_overlayed.plot('target_index')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Weight calculation\n", "\n", "The next step is to calculate the weights for each intersection.\n", "\n", "For that we apply a method that compares the area of the polygon that falls in the target polygon.\n", "\n", "To calculate the area of each intersection, we need to create the intersection polygon." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
source_indextarget_indexgeometryarea_overlayarea_sourceweights
000POLYGON ((0.00000 1.00000, 1.00000 1.00000, 1....0.601.00.60
110POLYGON ((0.00000 1.40000, 1.00000 1.80000, 1....0.601.00.60
220POLYGON ((1.00000 1.00000, 1.50000 1.00000, 1....0.451.00.45
321POLYGON ((2.00000 1.00000, 2.00000 0.00000, 1....0.501.00.50
430POLYGON ((1.00000 1.80000, 1.50000 2.00000, 1....0.451.00.45
531POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1....0.501.00.50
641POLYGON ((2.00000 1.00000, 3.00000 1.00000, 3....1.001.01.00
751POLYGON ((2.00000 2.00000, 3.00000 2.00000, 3....1.001.01.00
\n", "
" ], "text/plain": [ " source_index target_index \\\n", "0 0 0 \n", "1 1 0 \n", "2 2 0 \n", "3 2 1 \n", "4 3 0 \n", "5 3 1 \n", "6 4 1 \n", "7 5 1 \n", "\n", " geometry area_overlay \\\n", "0 POLYGON ((0.00000 1.00000, 1.00000 1.00000, 1.... 0.60 \n", "1 POLYGON ((0.00000 1.40000, 1.00000 1.80000, 1.... 0.60 \n", "2 POLYGON ((1.00000 1.00000, 1.50000 1.00000, 1.... 0.45 \n", "3 POLYGON ((2.00000 1.00000, 2.00000 0.00000, 1.... 0.50 \n", "4 POLYGON ((1.00000 1.80000, 1.50000 2.00000, 1.... 0.45 \n", "5 POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1.... 0.50 \n", "6 POLYGON ((2.00000 1.00000, 3.00000 1.00000, 3.... 1.00 \n", "7 POLYGON ((2.00000 2.00000, 3.00000 2.00000, 3.... 1.00 \n", "\n", " area_source weights \n", "0 1.0 0.60 \n", "1 1.0 0.60 \n", "2 1.0 0.45 \n", "3 1.0 0.50 \n", "4 1.0 0.45 \n", "5 1.0 0.50 \n", "6 1.0 1.00 \n", "7 1.0 1.00 " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gdf_overlayed['area_overlay'] = gdf_overlayed.area\n", "gdf_overlayed['area_source'] = gdf_overlayed['source_index'].map(grid_gdf.area)\n", "gdf_overlayed['weights'] = gdf_overlayed['area_overlay'] / gdf_overlayed['area_source']\n", "gdf_overlayed" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The weight express how much of the source cell is in the target cell.\n", "\n", "If you sum the weights for all intersections of a source cell, you will get 1." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gdf_overlayed.explore('weights')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Remapping data\n", "\n", "The good thing of working with weights, is that you need simply to calculate them once and then you can apply them to any data.\n", "\n", "For this example, we will assign some values to the source grid and remap them to the target grid." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
geometrysource_indexvalue1
0POLYGON ((0.00000 0.00000, 0.00000 1.00000, 1....01
1POLYGON ((0.00000 1.00000, 0.00000 2.00000, 1....11
2POLYGON ((1.00000 0.00000, 1.00000 1.00000, 2....21
3POLYGON ((1.00000 1.00000, 1.00000 2.00000, 2....31
4POLYGON ((2.00000 0.00000, 2.00000 1.00000, 3....41
5POLYGON ((2.00000 1.00000, 2.00000 2.00000, 3....51
\n", "
" ], "text/plain": [ " geometry source_index value1\n", "0 POLYGON ((0.00000 0.00000, 0.00000 1.00000, 1.... 0 1\n", "1 POLYGON ((0.00000 1.00000, 0.00000 2.00000, 1.... 1 1\n", "2 POLYGON ((1.00000 0.00000, 1.00000 1.00000, 2.... 2 1\n", "3 POLYGON ((1.00000 1.00000, 1.00000 2.00000, 2.... 3 1\n", "4 POLYGON ((2.00000 0.00000, 2.00000 1.00000, 3.... 4 1\n", "5 POLYGON ((2.00000 1.00000, 2.00000 2.00000, 3.... 5 1" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Assign values to the grid\n", "import numpy as np\n", "\n", "grid_gdf['value1'] = 1\n", "\n", "grid_gdf" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
source_indextarget_indexgeometryarea_overlayarea_sourceweightsvalue1
000POLYGON ((0.00000 1.00000, 1.00000 1.00000, 1....0.601.00.601
110POLYGON ((0.00000 1.40000, 1.00000 1.80000, 1....0.601.00.601
220POLYGON ((1.00000 1.00000, 1.50000 1.00000, 1....0.451.00.451
321POLYGON ((2.00000 1.00000, 2.00000 0.00000, 1....0.501.00.501
430POLYGON ((1.00000 1.80000, 1.50000 2.00000, 1....0.451.00.451
531POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1....0.501.00.501
641POLYGON ((2.00000 1.00000, 3.00000 1.00000, 3....1.001.01.001
751POLYGON ((2.00000 2.00000, 3.00000 2.00000, 3....1.001.01.001
\n", "
" ], "text/plain": [ " source_index target_index \\\n", "0 0 0 \n", "1 1 0 \n", "2 2 0 \n", "3 2 1 \n", "4 3 0 \n", "5 3 1 \n", "6 4 1 \n", "7 5 1 \n", "\n", " geometry area_overlay \\\n", "0 POLYGON ((0.00000 1.00000, 1.00000 1.00000, 1.... 0.60 \n", "1 POLYGON ((0.00000 1.40000, 1.00000 1.80000, 1.... 0.60 \n", "2 POLYGON ((1.00000 1.00000, 1.50000 1.00000, 1.... 0.45 \n", "3 POLYGON ((2.00000 1.00000, 2.00000 0.00000, 1.... 0.50 \n", "4 POLYGON ((1.00000 1.80000, 1.50000 2.00000, 1.... 0.45 \n", "5 POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1.... 0.50 \n", "6 POLYGON ((2.00000 1.00000, 3.00000 1.00000, 3.... 1.00 \n", "7 POLYGON ((2.00000 2.00000, 3.00000 2.00000, 3.... 1.00 \n", "\n", " area_source weights value1 \n", "0 1.0 0.60 1 \n", "1 1.0 0.60 1 \n", "2 1.0 0.45 1 \n", "3 1.0 0.50 1 \n", "4 1.0 0.45 1 \n", "5 1.0 0.50 1 \n", "6 1.0 1.00 1 \n", "7 1.0 1.00 1 " ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "col = 'value1'\n", "# Expand the input data to multiply it with the weights \n", "gdf_overlayed[col] = grid_gdf.loc[gdf_overlayed['source_index'], col].values\n", "gdf_overlayed\n", "\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
source_indextarget_indexgeometryarea_overlayarea_sourceweightsvalue1
000POLYGON ((0.00000 1.00000, 1.00000 1.00000, 1....0.601.00.600.60
110POLYGON ((0.00000 1.40000, 1.00000 1.80000, 1....0.601.00.600.60
220POLYGON ((1.00000 1.00000, 1.50000 1.00000, 1....0.451.00.450.45
321POLYGON ((2.00000 1.00000, 2.00000 0.00000, 1....0.501.00.500.50
430POLYGON ((1.00000 1.80000, 1.50000 2.00000, 1....0.451.00.450.45
531POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1....0.501.00.500.50
641POLYGON ((2.00000 1.00000, 3.00000 1.00000, 3....1.001.01.001.00
751POLYGON ((2.00000 2.00000, 3.00000 2.00000, 3....1.001.01.001.00
\n", "
" ], "text/plain": [ " source_index target_index \\\n", "0 0 0 \n", "1 1 0 \n", "2 2 0 \n", "3 2 1 \n", "4 3 0 \n", "5 3 1 \n", "6 4 1 \n", "7 5 1 \n", "\n", " geometry area_overlay \\\n", "0 POLYGON ((0.00000 1.00000, 1.00000 1.00000, 1.... 0.60 \n", "1 POLYGON ((0.00000 1.40000, 1.00000 1.80000, 1.... 0.60 \n", "2 POLYGON ((1.00000 1.00000, 1.50000 1.00000, 1.... 0.45 \n", "3 POLYGON ((2.00000 1.00000, 2.00000 0.00000, 1.... 0.50 \n", "4 POLYGON ((1.00000 1.80000, 1.50000 2.00000, 1.... 0.45 \n", "5 POLYGON ((2.00000 2.00000, 2.00000 1.00000, 1.... 0.50 \n", "6 POLYGON ((2.00000 1.00000, 3.00000 1.00000, 3.... 1.00 \n", "7 POLYGON ((2.00000 2.00000, 3.00000 2.00000, 3.... 1.00 \n", "\n", " area_source weights value1 \n", "0 1.0 0.60 0.60 \n", "1 1.0 0.60 0.60 \n", "2 1.0 0.45 0.45 \n", "3 1.0 0.50 0.50 \n", "4 1.0 0.45 0.45 \n", "5 1.0 0.50 0.50 \n", "6 1.0 1.00 1.00 \n", "7 1.0 1.00 1.00 " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Multiply the values by the weights\n", "gdf_overlayed[col] *= gdf_overlayed['weights'] \n", "gdf_overlayed" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
geometrytarget_indexvalue1
0POLYGON ((-1.00000 1.00000, 1.50000 0.00000, 1...02.1
1POLYGON ((1.50000 2.00000, 1.50000 0.00000, 3....13.0
\n", "
" ], "text/plain": [ " geometry target_index value1\n", "0 POLYGON ((-1.00000 1.00000, 1.50000 0.00000, 1... 0 2.1\n", "1 POLYGON ((1.50000 2.00000, 1.50000 0.00000, 3.... 1 3.0" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Sum the values belonging to the same target index\n", "gdf_out[col] = gdf_overlayed.groupby('target_index')[col].sum().values\n", "gdf_out" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can try to have other values and see the results." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "grid_gdf['value2'] = np.arange(len(grid_gdf))\n", "grid_gdf['value3'] = np.arange(len(grid_gdf))**2\n", "\n", "for col in ['value2', 'value3']:\n", " gdf_overlayed[col] = grid_gdf.loc[gdf_overlayed['source_index'], col].values\n", " gdf_overlayed[col] *= gdf_overlayed['weights'] \n", " gdf_out[col] = gdf_overlayed.groupby('target_index')[col].sum().values" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
geometrytarget_indexvalue1value2value3
0POLYGON ((-1.00000 1.00000, 1.50000 0.00000, 1...02.12.856.45
1POLYGON ((1.50000 2.00000, 1.50000 0.00000, 3....13.011.5047.50
\n", "
" ], "text/plain": [ " geometry target_index value1 \\\n", "0 POLYGON ((-1.00000 1.00000, 1.50000 0.00000, 1... 0 2.1 \n", "1 POLYGON ((1.50000 2.00000, 1.50000 0.00000, 3.... 1 3.0 \n", "\n", " value2 value3 \n", "0 2.85 6.45 \n", "1 11.50 47.50 " ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gdf_out" ] } ], "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.12.2" } }, "nbformat": 4, "nbformat_minor": 2 }