++ Currently, the examples are being reworked after the latest update because GBIF behaves differently now. Find out more ++
This workflow uses the VAT to evaluate the distribution of Calopteryx splendens in dependence of the land use classification from the Ökosystematlas and an temporal aggregation of the average air temperature.
The purpose of this notebook is to demonstrate the capabilities of Geo Engine. Therefore some useful techniques will be shown:
When building your own nested workflow, it is recommended to build it in several steps as shown in this notebook.
Documentation about the operators and how to use them in Python can be found here: https://docs.geoengine.io/operators/intro.html
#Import packages import geoengine as ge import geoengine_openapi_client from datetime import datetime from geoengine.types import RasterBandDescriptor import altair as alt import asyncio import nest_asyncio alt.renderers.enable('default')
RendererRegistry.enable('default')
#Initialize Geo Engine in VAT ge.initialize("https://vat.gfbio.org/api")
#Get the GBIF DataProvider id (Useful for translating the DataProvider name to its id) root_collection = ge.layer_collection() gbif_prov_id = '' for elem in root_collection.items: if elem.name == 'GBIF': gbif_prov_id = str(elem.provider_id) gbif_prov_id
'1c01dbb9-e3ab-f9a2-06f5-228ba4b6bf7a'
This chapter is not needed and only shows that country boundaries are available
#Create workflow to request germany boundary workflow_germany = ge.register_workflow({ "type": "Vector", "operator": { "type": "OgrSource", "params": { "data": "germany", } } }) workflow_germany
2429a993-385f-546f-b4f7-97b3ba4a5adb
#Set time start_time = datetime.strptime( '2010-01-01T12:00:00.000Z', "%Y-%m-%dT%H:%M:%S.%f%z") end_time = datetime.strptime( '2011-01-01T12:00:00.000Z', "%Y-%m-%dT%H:%M:%S.%f%z") #Request the data from Geo Engine into a geopandas dataframe data = workflow_germany.get_dataframe( ge.QueryRectangle( ge.BoundingBox2D(5.852490, 47.271121, 15.022059, 55.065334), ge.TimeInterval(start_time, end_time), resolution=ge.SpatialResolution(0.1, 0.1), srs="EPSG:4326" ) ) #Plot the data data.plot()
<Axes: >
This chapter is not needed and only shows that raster data is also available.
#Create workflow to request the oekosystematlas raster data workflow_oekosystematlas = ge.register_workflow({ "type": "Raster", "operator": { "type": "GdalSource", "params": { "data": "oekosystematlas_detail" } } }) workflow_oekosystematlas
f447601c-0ba1-57c3-9127-b0622f982231
#Request the data from Geo Engine into a xarray dataarray data = workflow_oekosystematlas.get_xarray( ge.QueryRectangle( ge.BoundingBox2D(5.852490, 47.271121, 15.022059, 55.065334), ge.TimeInterval(start_time, end_time), resolution=ge.SpatialResolution(0.1, 0.1), srs="EPSG:4326" ) ) #Plot the data data.plot(vmax=75)
/home/duempelmann/geoengine_env/lib/python3.10/site-packages/owslib/coverage/wcs110.py:85: FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead. elem = self._capabilities.find(self.ns.OWS('ServiceProvider')) or self._capabilities.find(self.ns.OWS('ServiceProvider')) # noqa <matplotlib.collections.QuadMesh at 0x7f4d09e97a60>
#Create workflow to request the average temperature raster data workflow_t_avg = ge.register_workflow({ "type": "Raster", "operator": { "type": "RasterScaling", "params": { "slope": { "type": "constant", "value": 0.1 }, "offset": { "type": "constant", "value": -273.15 }, "outputMeasurement": { "type": "continuous", "measurement": "temperature", "unit": "K/10" }, "scalingMode": "mulSlopeAddOffset" }, "sources": { "raster": { "type": "RasterTypeConversion", "params": { "outputDataType": "F32" }, "sources": { "raster": { "type": "GdalSource", "params": { "data": "mean_daily_air_temperature" } } } } } } }) workflow_t_avg
6393648d-6545-5435-a49e-015ba9dfa92e
#Preparing of the boundaries for the workflow raster stream bbox = ge.QueryRectangle( ge.BoundingBox2D(5.852490, 47.271121, 15.022059, 55.065334), ge.TimeInterval(start_time, end_time), resolution=ge.SpatialResolution(0.1, 0.1), srs="EPSG:4326" )
#Request the data from Geo Engine into a xarray dataarray data = workflow_t_avg.get_xarray( ge.QueryRectangle( ge.BoundingBox2D(5.852490, 47.271121, 15.022059, 55.065334), ge.TimeInterval(start_time, start_time), resolution=ge.SpatialResolution(0.1, 0.1), srs="EPSG:4326" ) ) #Plot the data data.plot(vmin=-3, vmax=3)
/home/duempelmann/geoengine_env/lib/python3.10/site-packages/owslib/coverage/wcs110.py:85: FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead. elem = self._capabilities.find(self.ns.OWS('ServiceProvider')) or self._capabilities.find(self.ns.OWS('ServiceProvider')) # noqa <matplotlib.collections.QuadMesh at 0x7f4d09db8820>
None of the following steps are necessary in theory, as the entire workflow will be projected in the nested request in the end. However, the steps are intended to show the capabilities of Geo Engine and how to logically build nested workflows.
#Create workflow to request Calopteryx splendens occurences workflow_calopteryx_splendens = ge.register_workflow({ "type": "Vector", "operator": { "type": "OgrSource", "params": { "data": f"_:{gbif_prov_id}:`species/Calopteryx splendens`", } } }) workflow_calopteryx_splendens.get_result_descriptor()
Data type: MultiPoint Spatial Reference: EPSG:4326 Columns: scientificname: Column Type: text Measurement: unitless basisofrecord: Column Type: text Measurement: unitless gbifid: Column Type: int Measurement: unitless
#Request the data from Geo Engine into a geopandas dataframe data = workflow_calopteryx_splendens.get_dataframe( ge.QueryRectangle( ge.BoundingBox2D(5.852490, 47.271121, 15.022059, 55.065334), ge.TimeInterval(start_time, end_time), resolution=ge.SpatialResolution(0.1, 0.1), srs="EPSG:4326" ) ) #Plot the data data.plot()
#Create workflow to request Calopteryx splendens occurrences filtered by German border workflow_calopteryx_splendens_cut = ge.register_workflow({ "type": "Vector", "operator": { "type": "PointInPolygonFilter", "params": {}, "sources": { "points": { #Calopteryx splendens ############################### "type": "OgrSource", "params": { "data": f"_:{gbif_prov_id}:`species/Calopteryx splendens`", "attributeProjection": [] } }, ##################################################### "polygons": { #Germany ################################# "type": "OgrSource", "params": { "data": "germany" } } ###################################################### } } }) workflow_calopteryx_splendens_cut
6cf9ef88-8bd3-5904-bc74-f866165b18c3
#Request the data from Geo Engine into a geopandas dataframe data_calopteryx_splendens = workflow_calopteryx_splendens_cut.get_dataframe( ge.QueryRectangle( ge.BoundingBox2D(5.852490, 47.271121, 15.022059, 55.065334), ge.TimeInterval(start_time, end_time), resolution=ge.SpatialResolution(0.1, 0.1), srs="EPSG:4326" ) ) #Plot the data data_calopteryx_splendens.plot()
#Create a workflow to request Calopteryx splendens occurrences filtered by the German border and linked to the Ökosystematlas data. workflow_calopteryx_splendens_cut_join = ge.register_workflow({ "type": "Vector", "operator": { "type": "RasterVectorJoin", "params": { "names": { "type": "names", "values": ["Ökosystematlas", "Avg_Temperature"] }, "temporalAggregation": "none", "featureAggregation": "first", }, "sources": { "vector": { #Calopteryx splendens cut ###################################### "type": "PointInPolygonFilter", "params": {}, "sources": { "points": { "type": "OgrSource", "params": { "data": f"_:{gbif_prov_id}:`species/Calopteryx splendens`", "attributeProjection": [] } }, "polygons": { "type": "OgrSource", "params": { "data": "germany" } } } }, ############################################################## "rasters": [{ #Ökosystematlas ################################### "type": "GdalSource", "params": { "data": "oekosystematlas" } }, ############################################################## { #Average temperature "type": "RasterScaling", "params": { "slope": { "type": "constant", "value": 0.1 }, "offset": { "type": "constant", "value": -273.15 }, "outputMeasurement": { "type": "continuous", "measurement": "temperature", "unit": "K/10" }, "scalingMode": "mulSlopeAddOffset" }, "sources": { "raster": { "type": "RasterTypeConversion", "params": { "outputDataType": "F32" }, "sources": { "raster": { "type": "GdalSource", "params": { "data": "mean_daily_air_temperature" } } } } } }] ############################################################## }, } }) workflow_calopteryx_splendens_cut_join
63c46ba9-3efd-5ddd-b446-c36fad6537e8
#Request the data from Geo Engine into a geopandas dataframe data = workflow_calopteryx_splendens_cut_join.get_dataframe( ge.QueryRectangle( ge.BoundingBox2D(5.852490, 47.271121, 15.022059, 55.065334), ge.TimeInterval(start_time, end_time), resolution=ge.SpatialResolution(0.1, 0.1), srs="EPSG:4326" ), resolve_classifications=True ) #Show the geopandas dataframe data
540 rows × 8 columns
#Create a workflow to request Calopteryx splendens occurrences filtered by the German border and linked to the Ökosystematlas data. workflow_calopteryx_splendens_cut_join = ge.register_workflow({ "type": "Vector", "operator": { "type": "RasterVectorJoin", "params": { "names": { "type": "names", "values": ["Ökosystematlas", "Avg_Temperature"] }, "temporalAggregation": "none", "featureAggregation": "mean", }, "sources": { "vector": { #Calopteryx splendens cut ###################################### "type": "PointInPolygonFilter", "params": {}, "sources": { "points": { "type": "OgrSource", "params": { "data": f"_:{gbif_prov_id}:`species/Calopteryx splendens`", "attributeProjection": [] } }, "polygons": { "type": "OgrSource", "params": { "data": "germany" } } } }, ############################################################## "rasters": [{ #Ökosystematlas ################################### "type": "GdalSource", "params": { "data": "oekosystematlas" } }, ############################################################## { #Average temperature "type": "RasterScaling", "params": { "slope": { "type": "constant", "value": 0.1 }, "offset": { "type": "constant", "value": -273.15 }, "outputMeasurement": { "type": "continuous", "measurement": "temperature", "unit": "K/10" }, "scalingMode": "mulSlopeAddOffset" }, "sources": { "raster": { "type": "RasterTypeConversion", "params": { "outputDataType": "F32" }, "sources": { "raster": { "type": "GdalSource", "params": { "data": "mean_daily_air_temperature" } } } } } }] ############################################################## }, } }) workflow_calopteryx_splendens_cut_join
4f2e830a-9570-5c8f-b2e1-bc433814df82
It can be seen that the Ökosystematlas variable is numerical, while the classes are human-readable encoded in the metadata of the files. This can be adjusted using a class histogram
#Create a workflow to plot Calopteryx splendens occurrences filtered by the German border and merged with the ecosystematlas data as a class histogram. workflow_calopteryx_splendens_full_öko = ge.register_workflow({ "type": "Plot", "operator": { "type": "ClassHistogram", "params": { "columnName": "Ökosystematlas" }, "sources": { "source": { #Calopteryx splendens cut join ##################################### "type": "RasterVectorJoin", "params": { "names": { "type": "names", "values": ["Ökosystematlas", "Avg_Temperature"] }, "temporalAggregation": "none", "featureAggregation": "mean", }, "sources": { "vector": { "type": "PointInPolygonFilter", "params": {}, "sources": { "points": { "type": "OgrSource", "params": { "data": f"_:{gbif_prov_id}:`species/Calopteryx splendens`", "attributeProjection": [] } }, "polygons": { "type": "OgrSource", "params": { "data": "germany" } } } }, "rasters": [{ "type": "GdalSource", "params": { "data": "oekosystematlas" } }, { "type": "RasterScaling", "params": { "slope": { "type": "constant", "value": 0.1 }, "offset": { "type": "constant", "value": -273.15 }, "outputMeasurement": { "type": "continuous", "measurement": "temperature", "unit": "K/10" }, "scalingMode": "mulSlopeAddOffset" }, "sources": { "raster": { "type": "RasterTypeConversion", "params": { "outputDataType": "F32" }, "sources": { "raster": { "type": "GdalSource", "params": { "data": "mean_daily_air_temperature" } } } } } }] } } ###################################################################### } } }) workflow_calopteryx_splendens_full_öko
befec7cb-1b9a-5464-88b0-aa14b6be3077
#Request the plot from Geo Engine plot_calopteryx_splendens = workflow_calopteryx_splendens_full_öko.plot_chart( ge.QueryRectangle( ge.BoundingBox2D(5.852490, 47.271121, 15.022059, 55.065334), ge.TimeInterval(start_time, end_time), resolution=ge.SpatialResolution(0.1, 0.1), srs="EPSG:4326" ) ) #Show the plot alt.Chart.from_dict(plot_calopteryx_splendens.spec)
#Create a workflow to request Calopteryx splendens occurrences filtered by the German border and linked to the Ökosystematlas data. workflow_calopteryx_splendens_full_avg_temp = ge.register_workflow({ "type": "Vector", "operator": { "type": "RasterVectorJoin", "params": { "names": { "type": "names", "values": ["Ökosystematlas", "Avg_Temperature"] }, "temporalAggregation": "none", "featureAggregation": "mean", }, "sources": { "vector": { "type": "PointInPolygonFilter", "params": {}, "sources": { "points": { "type": "OgrSource", "params": { "data": f"_:{gbif_prov_id}:`species/Calopteryx splendens`", "attributeProjection": [] } }, "polygons": { "type": "OgrSource", "params": { "data": "germany" } } } }, "rasters": [{ "type": "GdalSource", "params": { "data": "oekosystematlas" } }, { "type": "RasterScaling", "params": { "slope": { "type": "constant", "value": 0.1 }, "offset": { "type": "constant", "value": -273.15 }, "outputMeasurement": { "type": "continuous", "measurement": "temperature", "unit": "K/10" }, "scalingMode": "mulSlopeAddOffset" }, "sources": { "raster": { "type": "RasterTypeConversion", "params": { "outputDataType": "F32" }, "sources": { "raster": { "type": "GdalSource", "params": { "data": "mean_daily_air_temperature" } } } } } }] }, } }) workflow_calopteryx_splendens_full_avg_temp
#Request the data from Geo Engine into a geopandas dataframe data = workflow_calopteryx_splendens_full_avg_temp.get_dataframe( ge.QueryRectangle( ge.BoundingBox2D(5.852490, 47.271121, 15.022059, 55.065334), ge.TimeInterval(start_time, end_time), resolution=ge.SpatialResolution(0.1, 0.1), srs="EPSG:4326" ) ) #Show the geopandas dataframe data.plot(column='Avg_Temperature', legend=True, legend_kwds={'label': 'Average Temperature'})
In this chapter, some other useful links between Geo Engine and Python are shown.
#Overlay plot with context import geopandas as gpd import matplotlib.pyplot as plt #Request the data from Geo Engine into a xarray dataarray data = workflow_t_avg.get_xarray( ge.QueryRectangle( ge.BoundingBox2D(5.852490, 47.271121, 15.022059, 55.065334), ge.TimeInterval(start_time, start_time), resolution=ge.SpatialResolution(0.1, 0.1), srs="EPSG:4326" ) ) #Plot the data data.plot(vmin=-3, vmax=3) data_calopteryx_splendens.plot(ax=plt.gca(), color='red', markersize=3) plt.show()
/home/duempelmann/geoengine_env/lib/python3.10/site-packages/owslib/coverage/wcs110.py:85: FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead. elem = self._capabilities.find(self.ns.OWS('ServiceProvider')) or self._capabilities.find(self.ns.OWS('ServiceProvider')) # noqa