# Parallel Processing Strategies for Geospatial Data in a Cloud Computing Infrastructure
## 4 Abstracting Platform-Specific Dependencies with openEO
Once processing resources are available in the Kubernetes cluster, the job is started (step 6), and its status is set in the database accordingly (step 7). The workflow can be balanced through a tiling mechanism, where parts of the image (tiles) are distributed to different pods (single instances of a running process in the Kubernetes cluster). When all pods have ended their tasks (step 8), the job status in the database is marked as finished. Results are stored and can be downloaded or visualized (e.g., via a web mapping service) by the user. The workflow in Listing 1, written in Python, follows the specifications of the openEO Python client API [27]. After importing the openEO module (import openee), a connection is set up to the BDAP backend. A data cube is then loaded (load_collection) by specifying the Sentinel-2 collection at level 2A (bottom of atmosphere reflectance) as an argument. Before a data cube is actually created and loaded into the memory, it is first filtered spatially to select the region of interest. It is then filtered temporally (filter_temporal: all acquisitions of the year 2020). Finally, the spectral bands are filtered (filter_bands with B4: red band, B8: near-infrared band, and SCL: scene classification). The NDVI is calculated as the normalized difference between the red and near-infrared bands (ndvi). Vegetated pixels are coded with a value of 4 in the SCL band. All pixels with a different code are masked (mask). The remaining pixels are then spatially aggregated by calculating the mean NDVI value at the parcel level (polyposal_mean_timeseries). The parcels are represented by the polygons in a vector file in GeoJSON format. The aggregated NDVI values are then saved to a vector file (save_result). The client API converts this Python code to a process graph JSON according to the openEO core API. The process graph is sent to the backend (send_job), where the job is executed in batch mode (start_job). ```
1 importopeneo
2 openeoURL=\"[[http://openeo-dev.cidsn.jrc.it:46204](http://openeo-dev.cidsn.jrc.it:46204)]([http://openeo-dev.cidsn.jrc.it:46204](http://openeo-dev.cidsn.jrc.it:46204))\"
3 connection=openeo.connect(openeoURL)
4 datacube=connection.load_collection(\"E0.Copernicus.52.L2A\")
5 datacube=datacube.filter_bbox(west=5.5,south=51.34,east=6.0,north=51.7)
6 datacube=datacube.filter_temporal(start_date=\"2620-01-01\",end_date=\"2021-01-01\",
7)
8 ndvi=datacube.filter_bands([\"B4\",\"B8\",\"SCL\"])
9 ndvi=datacube.ndvi(nir='B8',red='B4')
10 classification=datacube.band(\"SCL\")
11 vegetation_mask=(classification!=4)
12 ndvi=ndvi.mask(vegetation_mask)
13 ndvi=ndvi.polyposal_mean_timeseries('parcels.json')
14 ndvi=ndvi.save_result()
15 job=ndvi.send_job()
16 job.start_job()

Figure 3: Implementation of openEO in the Big Data Analytics Platform. ## 5 Results

Experiments were conducted first for tiling and multi-threading individually. Single-threaded processing without tiling was used as a reference (\(S=1\)) to calculate the speedup. The processing time was 30 min, though times will vary depending on the specifications of the virtual machine and the disk access time to read the imagery from the file system. In this study, the processing time was achieved on a server Intel(R) Xeon(R) CPU E7-8870 v4. Data were accessed from EOS [28], an open-source distributed file system developed at the European Organization for Nuclear Research (CERN). It runs on commodity hardware, and it is mainly focused on low latency, high availability, ease of operation, and low total cost of ownership [28; 29]. The Sentinel-2 image data are stored as regular files in JPEG 2000, a discrete wavelet transform-based compression standard. The cluster can directly access the data storage on the EOS distributed file system via a 10 Gb network. Uncompressing the image data and reading them into memory was performed with the Geospatial Data Abstraction Library (GDAL [30]). The respective processing times for multi-threaded and tiled processing can be obtained by dividing this time with the respective speedup values reported.