def fct_buffer(udf_data: UdfData): """Compute buffer of size 10 around features This function creates buffer around all features in the provided feature collection tiles. The resulting geopandas.GeoDataFrame contains the new geometries and a copy of the original attribute data. Args: udf_data (UdfData): The UDF data object that contains raster and vector tiles Returns: This function will not return anything, the UdfData object "udf_data" must be used to store the resulting data. """ fct_list = [] # Iterate over each tile for tile in udf_data.feature_collection_tiles: # Buffer all features gseries = tile.data.buffer(distance=10) # Create a new GeoDataFrame that includes the buffered geometry and the attribute data new_data = tile.data.set_geometry(gseries) # Create the new feature collection tile fct = FeatureCollectionTile(id=tile.id + "_buffer", data=new_data, start_times=tile.start_times, end_times=tile.end_times) fct_list.append(fct) # Insert the new tiles as list of feature collection tiles in the input object. The new tiles will # replace the original input tiles. udf_data.set_feature_collection_tiles(fct_list)
def fct_sampling(udf_data: UdfData): """Sample any number of raster collection tiles with a single feature collection (the first if several are provided) and store the samples values in the input feature collection. Each time-slice of a raster collection is stored as a separate column in the feature collection. Hence, the size of the feature collection attributes is (number_of_raster_tile * number_of_xy_slices) x number_of_features. The number of columns is equal to (number_of_raster_tile * number_of_xy_slices). A single feature collection id stored in the input data object that contains the sample attributes and the original data. Args: udf_data (UdfData): The UDF data object that contains raster and vector tiles Returns: This function will not return anything, the UdfData object "udf_data" must be used to store the resulting data. """ if not udf_data.feature_collection_tiles: raise Exception("A single feature collection is required as input") if len(udf_data.feature_collection_tiles) > 1: raise Exception("The first feature collection will be used for sampling") # Get the first feature collection fct = udf_data.feature_collection_tiles[0] features = fct.data # Iterate over each raster tile for tile in udf_data.raster_collection_tiles: # Compute the number and names of the attribute columns num_slices = len(tile.data) columns = {} column_names = [] for slice in range(num_slices): column_name = tile.id + "_%i"%slice column_names.append(column_name) columns[column_name] = [] # Sample the raster data with each point for feature in features.geometry: # Check if the feature is a point if feature.type == 'Point': x = feature.x y = feature.y values = tile.sample(top=y, left=x) # Store the values in column specific arrays if values: for column_name, value in zip(column_names, values): columns[column_name].append(value) else: for column_name in column_names: columns[column_name].append(math.nan) else: raise Exception("Only points are allowed for sampling") # Attach the sampled attribute data to the GeoDataFrame for column_name in column_names: features[column_name] = columns[column_name] # Create the output feature collection fct = FeatureCollectionTile(id=fct.id + "_sample", data=features, start_times=fct.start_times, end_times=fct.end_times) # Insert the new tiles as list of feature collection tiles in the input object. The new tiles will # replace the original input tiles. udf_data.set_feature_collection_tiles([fct,]) # Remove the raster collection tiles udf_data.del_raster_collection_tiles()