Modular OGC API Workflows for Processing and Visualization
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Jacovella-St-Louis, Jerome
A presentation of the new OGC API - Processes - Part 3: Workflows draft specifications, allowing to: - chain nested processes, - refer to external processes and collections accessible via OGC API standards, and - trigger execution of processes through OGC API data delivery specifications (such as OGC API - Features, Tiles, Maps and Coverages). Demonstration of use cases including crop classification, point cloud processing and routing. Overview of the work accomplished during the GeoConnections 2020-2021 project contributing to the development of these specifications, to open standards and to free & open source software, including the development of a new unified OGC API driver in GDAL supporting the execution and visualization of results from these workflows in QGIS. OGC API - Processes - Part 3: Workflows and Chaining is a draft OGC specification allowing to use an OGC API collection or the output of an OGC API process as an input to another process, as well as to trigger the execution of that process via data delivery requests, making the results easily accessible from OGC API clients using the data delivery APIs (e.g. Features, Coverages, Maps, Tiles...). The latest draft specifications are available at:-009.html Financial support for the project provided by GeoConnections, a national collaborative initiative led by Natural Resources Canada. GeoConnections supports the integration and use of the Canadian Geospatial Data Infrastructure (CGDI), an on-line resource that improves the sharing, access and use of open geospatial information.
 Great. Yes, we can see. Great. So I'd like to talk to you about the modular OGC API workflows. So this is a project that we've been leading last year, which ended in March of this year. Basically, it led through the development of a new extension for OGC API processes, and that connects multiple OGC API specifications together. So it was a collaborative project by ourselves and other OGC members, as well as additional to Canadian Research Centre. I apologize, some of the members are not showing right now because of some bugs in open office, so some logos are missing. But the Universes Laval and the Institut de la Science de la recherche scientifique were the two collaborators. We have EOX, we had Rassdamann, we had CubeWorks, CRIM, TheraF. We also have Specialis, we've been working on GDOL as part of this project. We had also Pangea Innovation, and another few that unfortunately is not showing here. So in a nutshell, the idea behind the workflows and training extension provides the ability to chain nested processes, and also to refer to external processes and collections that are accessible via the OGC API standards, and to trigger the execution of process through OGC API delivery, data delivery specification like features, styles, maps, and packages. So if you start from OGC API processes core, what you can add is nested process. So the input to a process can be another process. Also you can describe an input to be an OGC API collection without going into a specific request. So for example, you can just say I'm going to use this collection of data, but you don't have to say, well, this data uses OGC API features, or you don't have to say this uses this specific building, bonding box or this specific resolution, you can leave that up for later. For example, at the time that the client comes and negotiate with content negotiation, and also you can define a workflow in a way that it will work for different areas. So it makes it more reusable by leaving this out of the workflow. And also one thing it could do is you could define a workflow as part of nested processes, and then you could present the workflow as a whole as one process. So that's where the chain input parameter comes in because it would allow you to plug in an input into that workflow that then gets used at a specific place within this workflow. So the idea is that it introduces new execution mode. So instead of only getting an OGC API process score, there's the concept of synchronous and asynchronous execution. So this adds a new concept where instead of actually starting a job right away, you just register the workflow. So you make the server aware that this is what you want to do. And then the way to actually trigger the processing will be by making OGC API data requests, like asking for a specific tile or asking for a specific feature. And that is what will actually trigger the processing. And you don't need to specify output because, again, the output or you negotiate what output you need by simply using the content negotiation. It's actually now in the final version of OGC API processes core, the outputs are optional now. So if you don't specify the output, you will get the default format for all the outputs. So the idea is how this works. It's very simple. So this mode to just register your workflow. So you post your workflow to the process execution endpoint. Now again, as part of this project, we've actually worked a lot with the different OGC API specifications to try to make progress specifically on OGC API processes. And so there was a lot of things changing along the way throughout the project. So at this point, we're finalizing the part three, we need to do some work based on the latest changes in the OGC API processes core. So exactly how you would say I want to execute this as a deferred execution is the mode we call this is still to be determined. But you would post your workflow to the execution endpoint and somehow say that, well, you want to execute it and I want to get back a landing page or I want to get back a collection document as a response. So that's still to be specified. And once you've done this, the next thing you do is you submit your OGC API request, just like you would if it was just a coverages or a features or maps or a tile server. And this is what is going to trigger based on the, for example, if you use the subset parameter in coverages or if you use the V box in maps, it's going to say, well, you're interested in processing this particular area here. So some of the things that were done, so EOX implemented using PyGAPI some processing on the Euro data cube. And one of the things that allowed to do is a generic Python coverage processor. So we would, for example, point to the collection that offers the Sentinel to data product. And then we could say directly by specify a Python function in the workflow document. And so first we pose this. So this one here, you can see if that calculates an NDDI. And after that, this makes, once you post this, the workflow is registered, and then you do OGC API coverages request, and you get back a coverage with these two bands here, the NDDI and the scale value of band four. So basically this allows to do coverage processing in a very flexible manner using familiar tools like Python. And you register this once, and then clients, just regular clients can make data requests. And it's triggered on the fly for the area of interest. And the way they implemented this was actually with TrpeterLab in the back end. So this was an example of the server-side Python NDDI in our Gosis Cartographer client. So another thing that was done as part of the project was ResDemand implemented support for OGC API coverages in ResDemand. So we are also testing retrieving coverages, installing them client-side in our client. This is Sentinel to data from the Euro data cube that is showing in QGIS as part of the new OGC API driver that was the lappist part of this project in GDAL. Then this is again in QGIS showing data coming from both the ResDemand and our HRA Gosis map server using OGC API coverages and I believe that's, yeah, both our coverages. And then we had also another part of the project was experimenting with WCPS, the Web Coverage Processing Service from ResDemand, which was integrated as part of the OGC API. And what we did is we built an adapter that connects the Web Coverage Processing Service, which is this idea of an OGC API processes workflow. So just like the Python example earlier on the Euro data cube, it's actually very similar here, but this is a generic, so this is a process that basically instead of understanding Python, it understands WCPS. It was relaying the processing to the ResDemand service, but you can see it's actually very similar here, but then you have actual WCPS script, which then gets sent to the server. So you can define one process using WCPS, and then once that process is registered, you can reuse it to perform that particular NDVI operation or whichever operation you define. Another topic was doing crop classification. We used the random forest classification algorithm with the scikit-learn library for Python. And again, so we deployed one process that was using this implemented Python code, and then you point to the source data, which will serve as source for the classification, which in this case we used the Sentinel-2 provided by the Euro data cube. And then as you would move around, it would classify the area of interest or the resolution of interest. So when we experimented with it, we used imagery from three different seasons, spring, summer, and fall, and we used a database of known parcel crops so that we actually know what these crops are for the training. And we're going to the next slide. Sorry. My, sorry. That's crashed. All right. I'm having trouble with this. Try this one. We use these slides from, okay. So when you would, so the idea with the crop classification is we could also do a coverage style request. So the OJCPI coverage is as a conformance class for tiles. So you could ask for a specific tile and then you would get the classification coverage as a result. Another example we used was a contour generator. So you can point to a process that generates contours and then you point to an input which can be a coverage and you can specify parameters like the distance between contours, the geometry type, I mean, in max height. And this was one example of that with the worldwide elevation data from SRTM. And this again, together with our 3D visualization client, you can see the contours. Another aspect of the work was focusing on point cloud processing. So we use a data set with over a billion points over Quebec, which was provided by the University Laval. And one of the things we did was trying to extract the building footprints and then from the building footprints doing some extrusion. And so one other aspect that we tested on was actually incorporating the height information to add it to open street map data. So trying to augment the upper street map data with elevation of the buildings from the point cloud. And another aspect here, so this particular, yeah, so this is the one here, so points to the OSM data and it points to the point cloud and then the result is an open street map data set with added elevation. Another aspect of this scenario was trying to find roads which are more accessible by having the minimum change in elevation. So that's some of the screenshot of the point cloud visualization, so it's a fairly large area around Quebec City. And you can see the detail here, looks. So this is the elevation that was added to the open street map buildings. And then this is a nested workflow, which basically tries to render a map, which use our routing engine, which uses a source, the OSM around the DC, Washington DC, the road values. And then it integrates both the rendering of tiles from RGIS online with the roads from our open street map routing engine. This is the route showing on top of the imagery as part of the nested workflow. And then we also work, so 52 North was another of the contributors as part of the project. And another thing we did was integrate their routing engine and we visualized the result directly in QGIS. So we have open street map data coming in as tiles and then the result of the route, all part of the same workflow. And then also the Java PS from 52 North, they also had an NDVI process that we tested with. And basically we tested integrating this as part of our, because at this point, the Java PS server only implemented OGC API processes core. Basically our process map adapter allowed to connect a server that only implements the core and to integrate it within the modular workflow system, where basically you can use coverage or tiles or feature requests to trigger the processing. So the nice thing about workflows is that you can have processing clients that actually don't implement support for processes. All they have to do is make the regular coverage or tiles or feature or map requests. So this is the workflow extension. I think we'll now be more the focus of the OGC API processes standard working group in the future because the processes core is going to the final stage of approval and publication. So we'll be able to focus more on advancing that specification. This probably will be part three of OGC API processes. And we do have support on our map server for this extension if you actually want to play with it and try to write a client for it. Thank you very much. Thank you, Jerome. Fantastic presentation. And it shows that the OGC API processes is in a very mature state indeed. I think we don't have any questions yet, but in the meantime, I would like to ask you, have you seen an interest from the data science machine learning community outside, let's say, the GIS world in using OGC API processes? Oh, yeah, for sure. I think that's what it's for, right? That's the... I think there's a lot of... And I think workflows in particular will enable things... Because the idea with workflows is you don't have to do everything as batch processing anymore. So you can use... It makes it easier to use the latest data available as new satellite imagery comes in, like the new Landsat 9 that was just launched this week says, there's more and more data that's available. If you write a workflow that works with the latest data and the workflows make it easier to share, so you define the science as a workflow and then people can just access it using simple clients like the G.Library and it triggers the processing behind that. So I think it makes it easier. Sure. And in theory, you could use this without any geospatial data, right? Just to process data or not? Just to... Well, in theory, it's not natively... It's possible. Yeah, yeah, yeah, for sure. It's possible. There's nothing inherently geospatial about it, but why it's nice for geospatial is because there's this concept that you can move around and you can zoom in and out. And the nice thing about that is if you define a workflow and you want to test it, and especially if it works at a different scale, you can test it at a specific scale just to get an idea of what things look like. So you tweak your parameters, your inputs, and then as you can zoom in to test it, is this better to get more details? And as you do that, you can, again, tweak the workflow again. You don't have to reprocess the whole thing, right? Like the whole batch or you don't have to... It makes it easier also for the scientists to do it because it's all done ad hoc on the client side. So you don't have to wait for the thing to be deployed and then the batch process to be done is instant feedback of the workflow you want to run. And just very quickly, what would you say were the biggest improvements regarding older standards like WPS, for instance, for this new way of processing? What would be the key highlights for you? The key highlights? Well, I think it's much simpler. Like if you look at the way you make the request, the request is very, very easy, is very simple. And I think the workflows makes it even simpler because clients, they can use the data requests that they know that are already implemented so they can leverage existing clients to do it. It's very easy to... Sorry, I think you're mute. Sorry, yeah, I accidentally mute myself. I was saying that it's more friendly to implementers. Yeah. Okay. I think, Jerome, I think you don't have any questions. Maybe people will come back to you later, but you had a lot of clubs when you finish your presentation. Thank you very much. So thank you. I mean, you can continue the conversation via chat. And we will move to our next presenter. So let's meet.
 Great.  Yes, we can see.  Great.  So I'd like to talk to you about the modular OGC API workflows.  So this is a project that we've been leading last year, which ended in March of this year.  Basically, it led through the development of a new extension for OGC API processes, and  that connects multiple OGC API specifications together.  So it was a collaborative project by ourselves and other OGC members, as well as additional  to Canadian Research Centre.  I apologize, some of the members are not showing right now because of some bugs in  open office, so some logos are missing.  But the Universes Laval and the Institut de la Science de la recherche scientifique  were the two collaborators.  We have EOX, we had Rassdamann, we had CubeWorks, CRIM, TheraF.  We also have Specialis, we've been working on GDOL as part of this project.  We had also Pangea Innovation, and another few that unfortunately is not showing here.  So in a nutshell, the idea behind the workflows and training extension provides the ability  to chain nested processes, and also to refer to external processes and collections that  are accessible via the OGC API standards, and to trigger the execution of process through  OGC API delivery, data delivery specification like features, styles, maps, and packages.  So if you start from OGC API processes core, what you can add is nested process.  So the input to a process can be another process.  Also you can describe an input to be an OGC API collection without going into a specific  request.  So for example, you can just say I'm going to use this collection of data, but you don't  have to say, well, this data uses OGC API features, or you don't have to say this uses  this specific building, bonding box or this specific resolution, you can leave that up  for later.  For example, at the time that the client comes and negotiate with content negotiation, and  also you can define a workflow in a way that it will work for different areas.  So it makes it more reusable by leaving this out of the workflow.  And also one thing it could do is you could define a workflow as part of nested processes,  and then you could present the workflow as a whole as one process.  So that's where the chain input parameter comes in because it would allow you to plug  in an input into that workflow that then gets used at a specific place within this workflow.  So the idea is that it introduces new execution mode.  So instead of only getting an OGC API process score, there's the concept of synchronous and  asynchronous execution.  So this adds a new concept where instead of actually starting a job right away, you just  register the workflow.  So you make the server aware that this is what you want to do.  And then the way to actually trigger the processing will be by making OGC API data requests,  like asking for a specific tile or asking for a specific feature.  And that is what will actually trigger the processing.  And you don't need to specify output because, again, the output or you negotiate what output  you need by simply using the content negotiation.  It's actually now in the final version of OGC API processes core, the outputs are optional  now.  So if you don't specify the output, you will get the default format for all the outputs.  So the idea is how this works.  It's very simple.  So this mode to just register your workflow.  So you post your workflow to the process execution endpoint.  Now again, as part of this project, we've actually worked a lot with the different  OGC API specifications to try to make progress specifically on OGC API processes.  And so there was a lot of things changing along the way throughout the project.  So at this point, we're finalizing the part three, we need to do some work based on the  latest changes in the OGC API processes core.  So exactly how you would say I want to execute this as a deferred execution is the mode we  call this is still to be determined.  But you would post your workflow to the execution endpoint and somehow say that, well, you want  to execute it and I want to get back a landing page or I want to get back a collection document  as a response.  So that's still to be specified.  And once you've done this, the next thing you do is you submit your OGC API request,  just like you would if it was just a coverages or a features or maps or a tile server.  And this is what is going to trigger based on the, for example, if you use the subset  parameter in coverages or if you use the V box in maps, it's going to say, well, you're  interested in processing this particular area here.  So some of the things that were done, so EOX implemented using PyGAPI some processing  on the Euro data cube.  And one of the things that allowed to do is a generic Python coverage processor.  So we would, for example, point to the collection that offers the Sentinel to data product.  And then we could say directly by specify a Python function in the workflow document.  And so first we pose this.  So this one here, you can see if that calculates an NDDI.  And after that, this makes, once you post this, the workflow is registered, and then  you do OGC API coverages request, and you get back a coverage with these two bands here,  the NDDI and the scale value of band four.  So basically this allows to do coverage processing in a very flexible manner using familiar tools  like Python.  And you register this once, and then clients, just regular clients can make data requests.  And it's triggered on the fly for the area of interest.  And the way they implemented this was actually with TrpeterLab in the back end.  So this was an example of the server-side Python NDDI in our Gosis Cartographer client.  So another thing that was done as part of the project was ResDemand implemented support  for OGC API coverages in ResDemand.  So we are also testing retrieving coverages, installing them client-side in our client.  This is Sentinel to data from the Euro data cube that is showing in QGIS as part of the  new OGC API driver that was the lappist part of this project in GDAL.  Then this is again in QGIS showing data coming from both the ResDemand and our HRA Gosis  map server using OGC API coverages and I believe that's, yeah, both our coverages.  And then we had also another part of the project was experimenting with WCPS, the Web Coverage  Processing Service from ResDemand, which was integrated as part of the OGC API.  And what we did is we built an adapter that connects the Web Coverage Processing Service,  which is this idea of an OGC API processes workflow.  So just like the Python example earlier on the Euro data cube, it's actually very similar  here, but this is a generic, so this is a process that basically instead of understanding  Python, it understands WCPS.  It was relaying the processing to the ResDemand service, but you can see it's actually very  similar here, but then you have actual WCPS script, which then gets sent to the server.  So you can define one process using WCPS, and then once that process is registered,  you can reuse it to perform that particular NDVI operation or whichever operation you  define.  Another topic was doing crop classification.  We used the random forest classification algorithm with the scikit-learn library for Python.  And again, so we deployed one process that was using this implemented Python code, and  then you point to the source data, which will serve as source for the classification, which  in this case we used the Sentinel-2 provided by the Euro data cube.  And then as you would move around, it would classify the area of interest or the resolution  of interest.  So when we experimented with it, we used imagery from three different seasons, spring, summer,  and fall, and we used a database of known parcel crops so that we actually know what  these crops are for the training.  And we're going to the next slide.  Sorry.  My, sorry.  That's crashed.  All right.  I'm having trouble with this.  Try this one.  We use these slides from, okay.  So when you would, so the idea with the crop classification is we could also do a coverage  style request.  So the OJCPI coverage is as a conformance class for tiles.  So you could ask for a specific tile and then you would get the classification coverage  as a result.  Another example we used was a contour generator.  So you can point to a process that generates contours and then you point to an input which  can be a coverage and you can specify parameters like the distance between contours, the geometry  type, I mean, in max height.  And this was one example of that with the worldwide elevation data from SRTM.  And this again, together with our 3D visualization client, you can see the contours.  Another aspect of the work was focusing on point cloud processing.  So we use a data set with over a billion points over Quebec, which was provided by the University  Laval.  And one of the things we did was trying to extract the building footprints and then from  the building footprints doing some extrusion.  And so one other aspect that we tested on was actually incorporating the height information  to add it to open street map data.  So trying to augment the upper street map data with elevation of the buildings from  the point cloud.  And another aspect here, so this particular, yeah, so this is the one here, so points to  the OSM data and it points to the point cloud and then the result is an open street map  data set with added elevation.  Another aspect of this scenario was trying to find roads which are more accessible by  having the minimum change in elevation.  So that's some of the screenshot of the point cloud visualization, so it's a fairly large  area around Quebec City.  And you can see the detail here, looks.  So this is the elevation that was added to the open street map buildings.  And then this is a nested workflow, which basically tries to render a map, which use  our routing engine, which uses a source, the OSM around the DC, Washington DC, the road  values.  And then it integrates both the rendering of tiles from RGIS online with the roads from  our open street map routing engine.  This is the route showing on top of the imagery as part of the nested workflow.  And then we also work, so 52 North was another of the contributors as part of the project.  And another thing we did was integrate their routing engine and we visualized the result  directly in QGIS.  So we have open street map data coming in as tiles and then the result of the route,  all part of the same workflow.  And then also the Java PS from 52 North, they also had an NDVI process that we tested with.  And basically we tested integrating this as part of our, because at this point, the Java  PS server only implemented OGC API processes core.  Basically our process map adapter allowed to connect a server that only implements the  core and to integrate it within the modular workflow system, where basically you can use  coverage or tiles or feature requests to trigger the processing.  So the nice thing about workflows is that you can have processing clients that actually  don't implement support for processes.  All they have to do is make the regular coverage or tiles or feature or map requests.  So this is the workflow extension.  I think we'll now be more the focus of the OGC API processes standard working group in  the future because the processes core is going to the final stage of approval and publication.  So we'll be able to focus more on advancing that specification.  This probably will be part three of OGC API processes.  And we do have support on our map server for this extension if you actually want to play  with it and try to write a client for it.  Thank you very much.  Thank you, Jerome.  Fantastic presentation.  And it shows that the OGC API processes is in a very mature state indeed.  I think we don't have any questions yet, but in the meantime, I would like to ask you,  have you seen an interest from the data science machine learning community outside, let's say,  the GIS world in using OGC API processes?  Oh, yeah, for sure.  I think that's what it's for, right?  That's the...  I think there's a lot of...  And I think workflows in particular will enable things...  Because the idea with workflows is you don't have to do everything as batch processing  anymore.  So you can use...  It makes it easier to use the latest data available as new satellite imagery comes in,  like the new Landsat 9 that was just launched this week says, there's more and more data  that's available.  If you write a workflow that works with the latest data and the workflows make it easier  to share, so you define the science as a workflow and then people can just access it using simple  clients like the G.Library and it triggers the processing behind that.  So I think it makes it easier.  Sure.  And in theory, you could use this without any geospatial data, right?  Just to process data or not?  Just to...  Well, in theory, it's not natively...  It's possible.  Yeah, yeah, yeah, for sure.  It's possible.  There's nothing inherently geospatial about it, but why it's nice for geospatial is because  there's this concept that you can move around and you can zoom in and out.  And the nice thing about that is if you define a workflow and you want to test it, and especially  if it works at a different scale, you can test it at a specific scale just to get an  idea of what things look like.  So you tweak your parameters, your inputs, and then as you can zoom in to test it, is  this better to get more details?  And as you do that, you can, again, tweak the workflow again.  You don't have to reprocess the whole thing, right?  Like the whole batch or you don't have to...  It makes it easier also for the scientists to do it because it's all done ad hoc on the  client side.  So you don't have to wait for the thing to be deployed and then the batch process to  be done is instant feedback of the workflow you want to run.  And just very quickly, what would you say were the biggest improvements regarding older  standards like WPS, for instance, for this new way of processing?  What would be the key highlights for you?  The key highlights?  Well, I think it's much simpler.  Like if you look at the way you make the request, the request is very, very easy, is very simple.  And I think the workflows makes it even simpler because clients, they can use the data requests  that they know that are already implemented so they can leverage existing clients to do  it.  It's very easy to...  Sorry, I think you're mute.  Sorry, yeah, I accidentally mute myself.  I was saying that it's more friendly to implementers.  Yeah.  Okay.  I think, Jerome, I think you don't have any questions.  Maybe people will come back to you later, but you had a lot of clubs when you finish  your presentation.  Thank you very much.  So thank you.  I mean, you can continue the conversation via chat.  And we will move to our next presenter.  So let's meet.
FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_0_131.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_132_887.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_888_2303.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_2304_2975.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_2976_7055.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_7056_9551.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_9552_13355.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_13356_15347.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_15348_16535.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_16536_17999.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_18000_18047.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_18048_18095.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_18096_18287.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_18288_18419.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_18420_18467.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_18468_18527.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_18528_20015.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_20016_21767.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_21768_22043.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_22044_24011.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_24012_25427.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_25428_26627.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_26628_26771.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_26772_29939.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_29940_30443.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_30444_30767.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_30768_30983.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_30984_31211.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_31212_31595.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_31596_32867.png FOSS4G_-_Modular_OGC_API_Workflows_for_Processing__IgCFo1IZDFM_32868_33013.png