Skip to content
Snippets Groups Projects
lib_era5_land_pixel.py 42.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
        # Get input raster spatial reference and epsg code to reproject shapefile in the same spatial reference
    
    
        # Open shapefile with geopandas and reproject its geometry
        shapefile = gpd.read_file(shapefile)
        shapefile['geometry'] = shapefile['geometry'].to_crs(target_epsg)
    
        # Get no data value
    
        progress_bar = tqdm(total = len(shapefile.index), desc='Extracting zonal statistics', unit=' polygons')
    
    
        # Loop on the individual polygons in the shapefile geometry
        for index, row in shapefile.iterrows():
            
            # Get the feature geometry as a shapely object
            geom = row.geometry
            
            # id number of the current parcel geometry
            id = index + 1
            
            # Get land cover
            LC = row.LC
            
            # Crop the raster using the bounding box
            try:
    
                masked_raster, _ = mask(raster_dataset, [geom], crop = True)
    
            except:
                print('\nShapefile bounds are not contained in weather dataset bounds.\n\nExiting script.')
                return None
            
            # Mask the raster using the geometry
    
            masked_raster, _ = mask(raster_dataset, [geom], crop = True)
    
            
            # Replace the nodata values with nan
            masked_raster = masked_raster.astype(np.float32)
            masked_raster[masked_raster == nodata] = np.NaN
            
            # Calculate the zonal statistics
    
            mean = np.nanmean(masked_raster, axis = (1,2))
            
            # Add statistics to output list
            raster_stats.extend([[dates[i], id, mean[i], LC] for i in range(nbands)])
    
            
            # Update progress bar
            progress_bar.update(1)
        
        # Close dataset and progress bar
    
    
    
    def extract_weather_dataframe(rain_path: str, ET0_path: str, shapefile: str, config_file: str, save_path: str) -> None:
        """
        Extract a weather dataframe for each variable (Rain, ET0) and merge them in one
        dataframe. This dataframe is saved as ``csv`` file.
    
        Arguments
        =========
    
    
        1. rain_path: ``str``
    
        2. ET0_path: ``str``
    
        3. shapefile: ``str``
    
        4. config_file: ``str``
    
        5. save_path: ``str``
    
            save path for weather dataframe
    
        Returns
        =======
    
        ``None``
        """
        
        # Generate arguments for multiprocessing
        args = [(rain_path, shapefile, config_file), (ET0_path, shapefile, config_file)]
        
        print('\nStarting weather data extraction on two cores..\n')
        
        # Extract weather values for both weather varialbes
        with Pool(2) as p:
    
        
        # Collect results in a single dataframe
        weather_dataframe = pd.DataFrame(results[0], columns = ['date', 'id', 'Rain', 'LC'])
        weather_dataframe['ET0'] = pd.DataFrame(results[1], columns = ['date', 'id', 'ET0', 'LC'])['ET0']
        
        # Reorder columns
        weather_dataframe = weather_dataframe.reindex(columns = ['date', 'id', 'Rain', 'ET0', 'LC'])
        
        # Format datatypes
        weather_dataframe['Rain'] = np.round(weather_dataframe['Rain']).astype(int)
        weather_dataframe['ET0'] = np.round(weather_dataframe['ET0']).astype(int)
        
        # Change date type
        weather_dataframe['date'] = pd.to_datetime(weather_dataframe['date'])
        
        # Save dataframe to csv
        weather_dataframe.to_csv(save_path, index = False)
        
        return None