From e45c8b66f63005a5a3aea36e5ad02e3bddb12178 Mon Sep 17 00:00:00 2001 From: Alba Vilanova Date: Mon, 2 Jan 2023 12:43:54 +0100 Subject: [PATCH 1/3] #4 Create function to_shapefile --- nes/nc_projections/default_nes.py | 106 ++++++- nes/nes_formats/cams_ra_format.py | 5 + .../5.Others/5.3.Create_Shapefiles.ipynb | 275 +++++------------- 3 files changed, 178 insertions(+), 208 deletions(-) diff --git a/nes/nc_projections/default_nes.py b/nes/nc_projections/default_nes.py index 8f03f50..9d6357c 100644 --- a/nes/nc_projections/default_nes.py +++ b/nes/nc_projections/default_nes.py @@ -622,6 +622,7 @@ class Nes(object): def sel(self, hours_start=None, time_min=None, hours_end=None, time_max=None, lev_min=None, lev_max=None, lat_min=None, lat_max=None, lon_min=None, lon_max=None): + loaded_vars = False for var_info in self.variables.values(): if var_info['data'] is not None: @@ -664,6 +665,7 @@ class Nes(object): # New Axis limits self.read_axis_limits = self.get_read_axis_limits() + # Dimensions screening self.time = self._time[self.read_axis_limits['t_min']:self.read_axis_limits['t_max']] self.time_bnds = self._time_bnds @@ -2375,7 +2377,8 @@ class Nes(object): return gdf def write_shapefile(self, path): - """Save spatial geodataframe (shapefile). + """ + Save spatial geodataframe (shapefile). Parameters ---------- @@ -2398,6 +2401,107 @@ class Nes(object): return None + def to_shapefile(self, path, time=None, lev=None, var_list=None): + """ + Create shapefile from NES data. + + 1. Check 2D data is selected + 2. Create grid shapefile + 3. Add variables to shapefile (as independent function) + 4. Write shapefile + + Parameters + ---------- + path : str + Path to the output file. + time : datetime.datetime + Time stamp to select. + lev : int + Vertical level to select. + var_list : list, str + List (or single string) of the variables to be loaded and saved in the shapefile. + """ + + if var_list is None: + var_list = deepcopy(self.variables).keys() + else: + # Transform to list if there is only one element + if isinstance(var_list, str): + var_list = [var_list] + # Check if variable exists + for var_name in var_list: + if var_name not in self.variables.keys(): + raise ValueError('{} does not exist in dataset.'.format(var_name)) + # Skip variables (if desired) + self.keep_vars(var_list) + + # Check if data is 2D + sel_time, sel_lev = False, False + data_list = deepcopy(self.variables) + for var_name in data_list.keys(): + dim = data_list[var_name]['dimensions'] + if len(dim) != 2: + if len(dim) == 4: + sel_time, sel_lev = True, True + elif len(dim) == 3: + if 'time' in dim: + sel_time = True + elif 'lev' in dim: + sel_lev = True + break + + # Select first vertical level (if needed) + if sel_lev: + if lev is None: + msg = 'No vertical level has been specified. The first one will be selected.' + warnings.warn(msg) + self.sel(lev_min=0, lev_max=0) + else: + if lev not in self.lev['data']: + raise ValueError('Level {} is not available. Choose from {}'.format(lev, self.lev['data'])) + self.sel(lev_min=lev, lev_max=lev) + + # Select first time (if needed) + if sel_time: + if time is None: + msg = 'No time has been specified. The first one will be selected.' + warnings.warn(msg) + self.sel(time_min=self.time[0], time_max=self.time[0]) + else: + if time not in self.time: + raise ValueError('Time {} is not available. Choose from {}'.format(time, self.time)) + self.sel(time_min=time, time_max=time) + + # Create shapefile + self.create_shapefile() + + # Add variables to shapefile + self.add_variables_to_shapefile(var_list) + + # Write shapefile + self.write_shapefile(path) + + return None + + def add_variables_to_shapefile(self, var_list): + """ + Add variables data to shapefile. + + var_list : list, str + List (or single string) of the variables to be loaded and saved in the shapefile. + """ + + if var_list: + + # Load data + self.load() + + # Add data (get first and only available time and level) + for var_name in var_list: + self.shapefile[var_name] = self.variables[var_name]['data'][0, 0, :, :].ravel() + + return None + def spatial_join(self, mask, method=None): """ Compute overlay intersection of two GeoPandasDataFrames diff --git a/nes/nes_formats/cams_ra_format.py b/nes/nes_formats/cams_ra_format.py index 86bd49d..ce0c353 100644 --- a/nes/nes_formats/cams_ra_format.py +++ b/nes/nes_formats/cams_ra_format.py @@ -21,11 +21,14 @@ def to_netcdf_cams_ra(self, path): path : str Path to the output netCDF file. """ + if not isinstance(self, nes.LatLonNes): raise TypeError("CAMS Re-Analysis format must have Regular Lat-Lon projection") if '' not in path: raise ValueError("AMS Re-Analysis path must contain '' as pattern; current: '{0}'".format(path)) + orig_path = copy(path) + for i_lev, level in enumerate(self.lev['data']): path = orig_path.replace('', 'l{0}'.format(i_lev)) # Open NetCDF @@ -189,8 +192,10 @@ def create_variables(self, netcdf, i_lev): def date2num(time_array, time_units=None, time_calendar=None): + time_res = [] for aux_time in time_array: time_res.append(float(aux_time.strftime("%Y%m%d")) + (float(aux_time.strftime("%H")) / 24)) time_res = np.array(time_res, dtype=np.float64) + return time_res diff --git a/tutorials/5.Others/5.3.Create_Shapefiles.ipynb b/tutorials/5.Others/5.3.Create_Shapefiles.ipynb index 6fe590d..c2f7ea2 100644 --- a/tutorials/5.Others/5.3.Create_Shapefiles.ipynb +++ b/tutorials/5.Others/5.3.Create_Shapefiles.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# How to create and save shapefiles" + "# How to create shapefiles" ] }, { @@ -14,7 +14,7 @@ "outputs": [], "source": [ "from nes import *\n", - "import xarray as xr" + "import datetime" ] }, { @@ -30,7 +30,7 @@ "metadata": {}, "outputs": [], "source": [ - "grid_path = '/gpfs/scratch/bsc32/bsc32538/original_files/CAMS_MONARCH_d01_2022070412.nc'\n", + "grid_path = '/gpfs/scratch/bsc32/bsc32538/original_files/franco_interp.nc'\n", "grid = open_netcdf(path=grid_path, info=True)" ] }, @@ -45,152 +45,25 @@ "cell_type": "code", "execution_count": 3, "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", - "
geometry
FID
0POLYGON ((-22.16553 16.27358, -22.04224 16.335...
1POLYGON ((-22.04224 16.33554, -21.91879 16.397...
2POLYGON ((-21.91879 16.39727, -21.79523 16.458...
3POLYGON ((-21.79523 16.45880, -21.67145 16.520...
4POLYGON ((-21.67145 16.52011, -21.54755 16.581...
......
168582POLYGON ((87.45258 59.04235, 87.58887 58.92854...
168583POLYGON ((87.58887 58.92854, 87.72452 58.81466...
168584POLYGON ((87.72452 58.81466, 87.85956 58.70073...
168585POLYGON ((87.85956 58.70073, 87.99396 58.58673...
168586POLYGON ((87.99396 58.58673, 88.12778 58.47268...
\n", - "

168587 rows × 1 columns

\n", - "
" - ], - "text/plain": [ - " geometry\n", - "FID \n", - "0 POLYGON ((-22.16553 16.27358, -22.04224 16.335...\n", - "1 POLYGON ((-22.04224 16.33554, -21.91879 16.397...\n", - "2 POLYGON ((-21.91879 16.39727, -21.79523 16.458...\n", - "3 POLYGON ((-21.79523 16.45880, -21.67145 16.520...\n", - "4 POLYGON ((-21.67145 16.52011, -21.54755 16.581...\n", - "... ...\n", - "168582 POLYGON ((87.45258 59.04235, 87.58887 58.92854...\n", - "168583 POLYGON ((87.58887 58.92854, 87.72452 58.81466...\n", - "168584 POLYGON ((87.72452 58.81466, 87.85956 58.70073...\n", - "168585 POLYGON ((87.85956 58.70073, 87.99396 58.58673...\n", - "168586 POLYGON ((87.99396 58.58673, 88.12778 58.47268...\n", - "\n", - "[168587 rows x 1 columns]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "grid.create_shapefile()\n", - "grid.shapefile" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Add data to shapefile" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Rank 000: Loading O3 var (1/1)\n", - "Rank 000: Loaded O3 var ((109, 24, 361, 467))\n" + "Rank 000: Loading sconcno2 var (1/1)\n", + "Rank 000: Loaded sconcno2 var ((1, 1, 115, 165))\n" ] } ], "source": [ - "grid.keep_vars(['O3'])\n", - "grid.load()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# Add data of last timestep\n", - "grid.shapefile['O3'] = grid.variables['O3']['data'][-1, -1, :].ravel()" + "grid.to_shapefile('regular', \n", + " time=datetime.datetime(2019, 1, 1, 10, 0), \n", + " lev=0, var_list=['sconcno2'])" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -215,7 +88,7 @@ " \n", " \n", " geometry\n", - " O3\n", + " sconcno2\n", " \n", " \n", " FID\n", @@ -226,28 +99,28 @@ " \n", " \n", " 0\n", - " POLYGON ((-22.16553 16.27358, -22.04224 16.335...\n", - " 0.037919\n", + " POLYGON ((-11.85000 33.85000, -11.75000 33.850...\n", + " 0.000288\n", " \n", " \n", " 1\n", - " POLYGON ((-22.04224 16.33554, -21.91879 16.397...\n", - " 0.038064\n", + " POLYGON ((-11.75000 33.85000, -11.65000 33.850...\n", + " 0.000271\n", " \n", " \n", " 2\n", - " POLYGON ((-21.91879 16.39727, -21.79523 16.458...\n", - " 0.038086\n", + " POLYGON ((-11.65000 33.85000, -11.55000 33.850...\n", + " 0.000258\n", " \n", " \n", " 3\n", - " POLYGON ((-21.79523 16.45880, -21.67145 16.520...\n", - " 0.038092\n", + " POLYGON ((-11.55000 33.85000, -11.45000 33.850...\n", + " 0.000254\n", " \n", " \n", " 4\n", - " POLYGON ((-21.67145 16.52011, -21.54755 16.581...\n", - " 0.038098\n", + " POLYGON ((-11.45000 33.85000, -11.35000 33.850...\n", + " 0.000262\n", " \n", " \n", " ...\n", @@ -255,54 +128,54 @@ " ...\n", " \n", " \n", - " 168582\n", - " POLYGON ((87.45258 59.04235, 87.58887 58.92854...\n", - " 0.026542\n", + " 18970\n", + " POLYGON ((4.15000 45.25000, 4.25000 45.25000, ...\n", + " 0.003521\n", " \n", " \n", - " 168583\n", - " POLYGON ((87.58887 58.92854, 87.72452 58.81466...\n", - " 0.026310\n", + " 18971\n", + " POLYGON ((4.25000 45.25000, 4.35000 45.25000, ...\n", + " 0.003924\n", " \n", " \n", - " 168584\n", - " POLYGON ((87.72452 58.81466, 87.85956 58.70073...\n", - " 0.027037\n", + " 18972\n", + " POLYGON ((4.35000 45.25000, 4.45000 45.25000, ...\n", + " 0.004454\n", " \n", " \n", - " 168585\n", - " POLYGON ((87.85956 58.70073, 87.99396 58.58673...\n", - " 0.027271\n", + " 18973\n", + " POLYGON ((4.45000 45.25000, 4.55000 45.25000, ...\n", + " 0.004619\n", " \n", " \n", - " 168586\n", - " POLYGON ((87.99396 58.58673, 88.12778 58.47268...\n", - " 0.026327\n", + " 18974\n", + " POLYGON ((4.55000 45.25000, 4.65000 45.25000, ...\n", + " 0.004712\n", " \n", " \n", "\n", - "

168587 rows × 2 columns

\n", + "

18975 rows × 2 columns

\n", "" ], "text/plain": [ - " geometry O3\n", - "FID \n", - "0 POLYGON ((-22.16553 16.27358, -22.04224 16.335... 0.037919\n", - "1 POLYGON ((-22.04224 16.33554, -21.91879 16.397... 0.038064\n", - "2 POLYGON ((-21.91879 16.39727, -21.79523 16.458... 0.038086\n", - "3 POLYGON ((-21.79523 16.45880, -21.67145 16.520... 0.038092\n", - "4 POLYGON ((-21.67145 16.52011, -21.54755 16.581... 0.038098\n", - "... ... ...\n", - "168582 POLYGON ((87.45258 59.04235, 87.58887 58.92854... 0.026542\n", - "168583 POLYGON ((87.58887 58.92854, 87.72452 58.81466... 0.026310\n", - "168584 POLYGON ((87.72452 58.81466, 87.85956 58.70073... 0.027037\n", - "168585 POLYGON ((87.85956 58.70073, 87.99396 58.58673... 0.027271\n", - "168586 POLYGON ((87.99396 58.58673, 88.12778 58.47268... 0.026327\n", + " geometry sconcno2\n", + "FID \n", + "0 POLYGON ((-11.85000 33.85000, -11.75000 33.850... 0.000288\n", + "1 POLYGON ((-11.75000 33.85000, -11.65000 33.850... 0.000271\n", + "2 POLYGON ((-11.65000 33.85000, -11.55000 33.850... 0.000258\n", + "3 POLYGON ((-11.55000 33.85000, -11.45000 33.850... 0.000254\n", + "4 POLYGON ((-11.45000 33.85000, -11.35000 33.850... 0.000262\n", + "... ... ...\n", + "18970 POLYGON ((4.15000 45.25000, 4.25000 45.25000, ... 0.003521\n", + "18971 POLYGON ((4.25000 45.25000, 4.35000 45.25000, ... 0.003924\n", + "18972 POLYGON ((4.35000 45.25000, 4.45000 45.25000, ... 0.004454\n", + "18973 POLYGON ((4.45000 45.25000, 4.55000 45.25000, ... 0.004619\n", + "18974 POLYGON ((4.55000 45.25000, 4.65000 45.25000, ... 0.004712\n", "\n", - "[168587 rows x 2 columns]" + "[18975 rows x 2 columns]" ] }, - "execution_count": 6, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -311,22 +184,6 @@ "grid.shapefile" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Save shapefile" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "grid.write_shapefile('rotated_1')" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -343,7 +200,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -361,7 +218,16 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "grid.to_shapefile('rotated')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -460,24 +326,14 @@ "[95121 rows x 1 columns]" ] }, - "execution_count": 9, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "grid.create_shapefile()\n", "grid.shapefile" ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "grid.write_shapefile('rotated_2')" - ] } ], "metadata": { @@ -497,6 +353,11 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.4" + }, + "vscode": { + "interpreter": { + "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" + } } }, "nbformat": 4, -- GitLab From 792004becb2febc28a60c16ff7e9b82098d0e51a Mon Sep 17 00:00:00 2001 From: Alba Vilanova Date: Mon, 2 Jan 2023 14:15:19 +0100 Subject: [PATCH 2/3] Create function from_shapefile --- nes/__init__.py | 2 +- nes/create_nes.py | 43 +++++++++++++-- nes/nc_projections/default_nes.py | 87 +++++++------------------------ 3 files changed, 59 insertions(+), 73 deletions(-) diff --git a/nes/__init__.py b/nes/__init__.py index a15e5c1..5cdf04d 100644 --- a/nes/__init__.py +++ b/nes/__init__.py @@ -2,5 +2,5 @@ __date__ = "2022-11-24" __version__ = "1.0.0" from .load_nes import open_netcdf, concatenate_netcdfs -from .create_nes import create_nes +from .create_nes import create_nes, from_shapefile from .nc_projections import * diff --git a/nes/create_nes.py b/nes/create_nes.py index 41c4288..a4e484f 100644 --- a/nes/create_nes.py +++ b/nes/create_nes.py @@ -3,6 +3,7 @@ import warnings from netCDF4 import num2date from mpi4py import MPI +import geopandas as gpd from .nc_projections import * @@ -71,9 +72,9 @@ def create_nes(comm=None, info=False, projection=None, parallel_method='Y', bala for var in required_vars: if var not in kwargs_list: - msg = 'WARNING!!! ' - msg += 'Variable {0} has not been defined.'.format(var) - warnings.warn(msg) + msg = 'Variable {0} has not been defined. '.format(var) + msg += 'For a {} projection, it is necessary to define {}'.format(projection, required_vars) + raise ValueError(msg) if projection is None: if parallel_method == 'Y': @@ -109,4 +110,38 @@ def create_nes(comm=None, info=False, projection=None, parallel_method='Y', bala raise NotImplementedError(projection) return nessy - \ No newline at end of file + + +def from_shapefile(path, method=None, **kwargs): + """ + Create NES from shapefile data. + + 1. Create NES grid. + 2. Create shapefile for grid. + 3. Read shapefile from mask. + 4. Spatial join to add shapefile variables to NES variables. + + Parameters + ---------- + path : str + Path to shapefile. + kwargs : + Projection and projection dependent parameters to create it from scratch. + + method : str + Overlay method. Accepted values: ['nearest', 'intersection', None]. + """ + + # Create NES + nessy = create_nes(comm=None, info=False, **kwargs) + + # Create shapefile for grid + nessy.create_shapefile() + + # Read shapefile + mask = gpd.read_file(path) + + # Make spatial join + nessy.spatial_join(mask, method=method) + + return nessy diff --git a/nes/nc_projections/default_nes.py b/nes/nc_projections/default_nes.py index 9d6357c..55703a0 100644 --- a/nes/nc_projections/default_nes.py +++ b/nes/nc_projections/default_nes.py @@ -19,7 +19,7 @@ import datetime from ..interpolation import vertical_interpolation from ..interpolation import horizontal_interpolation from ..nes_formats import to_netcdf_cams_ra - +from ..nc_projections import * class Nes(object): """ @@ -2405,10 +2405,10 @@ class Nes(object): """ Create shapefile from NES data. - 1. Check 2D data is selected - 2. Create grid shapefile - 3. Add variables to shapefile (as independent function) - 4. Write shapefile + 1. Check 2D data is selected. + 2. Create grid shapefile. + 3. Add variables to shapefile (as independent function). + 4. Write shapefile. Parameters ---------- @@ -2492,7 +2492,7 @@ class Nes(object): """ if var_list: - + # Load data self.load() @@ -2504,7 +2504,7 @@ class Nes(object): def spatial_join(self, mask, method=None): """ - Compute overlay intersection of two GeoPandasDataFrames + Compute overlay intersection of two GeoPandasDataFrames. Parameters ---------- @@ -2517,17 +2517,19 @@ class Nes(object): # Nearest centroids to the mask polygons if method == 'nearest': - # Get centroids of shapefile to mask + # Make copy shapefile_aux = deepcopy(self.shapefile) - shapefile_aux.geometry = self.shapefile.centroid + + # Get centroids of shapefile to mask + shapefile_aux.geometry = shapefile_aux.centroid # Calculate spatial joint by distance - shapefile_aux = gpd.sjoin_nearest(shapefile_aux, mask.to_crs(self.shapefile.crs), distance_col='distance') + shapefile_aux = gpd.sjoin_nearest(shapefile_aux, mask.to_crs(shapefile_aux.crs), distance_col='distance') # Get data from closest shapes to centroids del shapefile_aux['geometry'], shapefile_aux['index_right'] self.shapefile.loc[shapefile_aux.index, shapefile_aux.columns] = shapefile_aux - + # Intersect the areas of the mask polygons, outside of the mask there will be NaN elif method == 'intersection': @@ -2557,72 +2559,21 @@ class Nes(object): # Centroids that fall on the mask polygons, outside of the mask there will be NaN elif method is None: - # Get centroids of shapefile to mask + # Make copy shapefile_aux = deepcopy(self.shapefile) - shapefile_aux.geometry = self.shapefile.centroid + + # Get centroids of shapefile to mask + shapefile_aux.geometry = shapefile_aux.centroid # Calculate spatial joint - shapefile_aux = gpd.sjoin(shapefile_aux, mask.to_crs(self.shapefile.crs)) - + shapefile_aux = gpd.sjoin(shapefile_aux, mask.to_crs(shapefile_aux.crs)) + # Get data from shapes where there are centroids, rest will be NaN del shapefile_aux['geometry'], shapefile_aux['index_right'] self.shapefile.loc[shapefile_aux.index, shapefile_aux.columns] = shapefile_aux return None - @staticmethod - def spatial_overlays(df1, df2, how='intersection'): - """ - Compute overlay intersection of two GeoPandasDataFrames df1 and df2 - - https://github.com/geopandas/geopandas/issues/400 - - :param df1: GeoDataFrame - :param df2: GeoDataFrame - :param how: Operation to do - :return: GeoDataFrame - """ - from functools import reduce - - df1 = df1.copy() - df2 = df2.copy() - df1['geometry'] = df1.geometry.buffer(0) - df2['geometry'] = df2.geometry.buffer(0) - if how == 'intersection': - # Spatial Index to create intersections - spatial_index = df2.sindex - df1['bbox'] = df1.geometry.apply(lambda x: x.bounds) - df1['histreg'] = df1.bbox.apply(lambda x: list(spatial_index.intersection(x))) - pairs = df1['histreg'].to_dict() - nei = [] - for i, j in pairs.items(): - for k in j: - nei.append([i, k]) - pairs = pd.DataFrame(nei, columns=['idx1', 'idx2']) - pairs = pairs.merge(df1, left_on='idx1', right_index=True) - pairs = pairs.merge(df2, left_on='idx2', right_index=True, suffixes=['_1', '_2']) - pairs['geometry'] = pairs.apply(lambda x: (x['geometry_1'].intersection(x['geometry_2'])).buffer(0), axis=1) - - pairs.drop(columns=['geometry_1', 'geometry_2', 'histreg', 'bbox'], inplace=True) - pairs = gpd.GeoDataFrame(pairs, columns=pairs.columns, crs=df1.crs) - pairs = pairs.loc[~pairs.geometry.is_empty] - - return_value = pairs - elif how == 'difference': - spatial_index = df2.sindex - df1['bbox'] = df1.geometry.apply(lambda x: x.bounds) - df1['histreg'] = df1.bbox.apply(lambda x: list(spatial_index.intersection(x))) - df1['new_g'] = df1.apply(lambda x: reduce(lambda x, y: x.difference(y).buffer(0), - [x.geometry] + list(df2.iloc[x.histreg].geometry)), axis=1) - df1.geometry = df1.new_g - df1 = df1.loc[~df1.geometry.is_empty].copy() - df1.drop(['bbox', 'histreg', 'new_g'], axis=1, inplace=True) - return_value = df1 - else: - raise NotImplementedError(how) - - return return_value - def __gather_data_py_object(self): """ Gather all the variable data into the MPI rank 0 to perform a serial write. -- GitLab From 0fd03b9d1ad27f87c6bf6f17f029566fe2d12a62 Mon Sep 17 00:00:00 2001 From: Alba Vilanova Date: Mon, 2 Jan 2023 14:19:32 +0100 Subject: [PATCH 3/3] Update spatial joins tutorial --- tutorials/5.Others/5.3.Create_Shapefiles.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/5.Others/5.3.Create_Shapefiles.ipynb b/tutorials/5.Others/5.3.Create_Shapefiles.ipynb index c2f7ea2..a45e7a7 100644 --- a/tutorials/5.Others/5.3.Create_Shapefiles.ipynb +++ b/tutorials/5.Others/5.3.Create_Shapefiles.ipynb @@ -352,7 +352,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.4" + "version": "3.6.8" }, "vscode": { "interpreter": { -- GitLab