Skip to content

Commit 4ec9ed8

Browse files
authored
Merge pull request #5 from geographika/gdalg
Add GDALG example
2 parents 8f250de + a993b77 commit 4ec9ed8

File tree

8 files changed

+247
-2
lines changed

8 files changed

+247
-2
lines changed

workshop/content/docs/advanced/arcgis.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ labelsCheckbox.addEventListener('change', (event) => {
183183
--8<-- "arcgis.js"
184184
```
185185
186-
??? Mapfile "stac.map"
186+
??? Mapfile "arcgis.map"
187187
188188
``` scala
189189
--8<-- "arcgis.map"
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Working with GDAL Vector Pipelines
2+
3+
## Overview
4+
5+
MapServer can dynamically run a [GDAL Vector Pipeline](https://gdal.org/en/latest/programs/gdal_vector_pipeline.html), and render its output -
6+
all through a simple Mapfile.
7+
8+
In this workshop we'll use the Tartu roads dataset used in the [Line Styling](../mapfile/lines.md) exercise, dynamically
9+
buffer it using GDAL, and display the result in OpenLayers using a MapServer WMS.
10+
11+
This is a simple example of a pipeline, but additional steps can be chained together to create more complex workflows.
12+
MapServer reads a vector pipeline using the [GDALG: GDAL Streamed Algorithm](https://gdal.org/en/latest/drivers/vector/gdalg.html) driver.
13+
14+
<div class="map">
15+
<iframe src="https://mapserver.github.io/getting-started-with-mapserver-demo/gdalg.html"></iframe>
16+
</div>
17+
18+
## Checking the Pipelines with GDAL
19+
20+
Before configuring MapServer, it is often easier to test your pipelines directly with GDAL, to ensure they run correctly.
21+
Run the commands below to connect to the MapServer Docker container and use GDAL to get information about the pipelines.
22+
23+
```bash
24+
# open a shell inside the MapServer container
25+
docker exec -it mapserver /bin/bash
26+
27+
# check the dataset used in the pipeline
28+
gdal vector info data/osm/roads.fgb
29+
30+
# inspect the a pipeline JSON file included in the container
31+
gdal vector info roads.gdalg.json
32+
33+
# test an inline pipeline using a single-quoted string (recommended)
34+
gdal vector info '{"type": "gdal_streamed_alg","command_line": "gdal vector pipeline ! read /etc/mapserver/data/osm/roads.fgb ! geom buffer --distance=0.0001"}'
35+
36+
# alternatively escape the double quotes
37+
gdal vector info "{\"type\": \"gdal_streamed_alg\",\"command_line\": \"gdal vector pipeline ! read data/osm/roads.fgb ! geom buffer --distance=0.0001\"}"
38+
```
39+
40+
## The Mapfile
41+
42+
### Embedding Pipelines in a Mapfile
43+
44+
The pipeline `LAYER` in this example uses `CONNECTIONTYPE OGR` and includes the GDAL pipeline "inline" - meaning the pipeline is defined
45+
directly in the Mapfile. Our example pipeline looks like this:
46+
47+
```scala
48+
CONNECTION '{"type": "gdal_streamed_alg","command_line": "gdal vector pipeline ! read /etc/mapserver/data/osm/roads.fgb ! geom buffer --distance=0.0001"}'
49+
DATA "0"
50+
```
51+
52+
Key points to note:
53+
54+
- `DATA "0"` tells MapServer to use the first (index 0) layer in the connection. Since the pipeline returns a single dataset, this will correspond
55+
to the buffered roads.
56+
- When using an inline GDAL pipeline, you must provide the absolute path to any datasets used by the pipeline.
57+
- GDAL requires a valid JSON string for the pipeline. All property names and string values must use double quotes.
58+
59+
In a Mapfile, you have two options for embedding JSON:
60+
61+
1. Wrap the JSON string in single quotes (as in the example above) - this is simpler and easier to read or copy/paste.
62+
2. Escape the double quotes using `\"` as in the example below:
63+
64+
```scala
65+
CONNECTION "{\"type\": \"gdal_streamed_alg\",\"command_line\": \"gdal vector pipeline ! read /etc/mapserver/data/osm/roads.fgb ! geom buffer --distance=0.0001\"}"
66+
```
67+
68+
### Referencing Pipelines in a JSON File
69+
70+
MapServer can also reference a JSON file containing a pipeline, which makes it easy to test and reuse the pipeline with GDAL.
71+
By convention GDALG files should use the `.gdalg.json` extension.
72+
73+
```scala
74+
CONNECTION "roads.gdalg.json"
75+
DATA "0"
76+
```
77+
78+
The contents of pipeline JSON file `roads.gdalg.json` are shown below. Notice that the dataset path `data/osm/roads.fgb` is relative to the JSON file.
79+
80+
Using relative paths in a JSON file makes the pipeline more portable, because it can be moved to a different folder or system without changing the dataset paths.
81+
82+
```json
83+
{
84+
"type": "gdal_streamed_alg",
85+
"command_line": "gdal vector pipeline ! read data/osm/roads.fgb ! geom buffer --distance=0.0001"
86+
}
87+
```
88+
89+
### Hatch Styling
90+
91+
Finally, we use a [hatch symbol](https://mapserver.org/mapfile/symbol.html#mapfile-symbol-type) to style the buffered roads.
92+
Hatch symbols allow you to add patterned fills, and you can adjust their angle, width, and size in the [STYLE](https://mapserver.org/mapfile/style.html) block.
93+
94+
```scala
95+
SYMBOL
96+
NAME "hatchsymbol"
97+
TYPE hatch
98+
END
99+
...
100+
LAYER
101+
CLASS
102+
STYLE
103+
SYMBOL "hatchsymbol"
104+
COLOR "#78C8FF"
105+
WIDTH 0.1
106+
ANGLE 45
107+
SIZE 8
108+
END
109+
```
110+
111+
## Code
112+
113+
!!! example
114+
115+
- Direct MapServer request: <http://localhost:7000/?map=/etc/mapserver/gdalg.map&REQUEST=GetMap&SERVICE=WMS&VERSION=1.3.0&FORMAT=image%2Fpng&STYLES=&TRANSPARENT=TRUE&LAYERS=buffered_roads%2Croads&WIDTH=1707&HEIGHT=848&CRS=EPSG%3A3857&BBOX=2974643.6269619283%2C8046226.818245997%2C2976682.478528896%2C8047239.608870775>
116+
- Local OpenLayers example: <http://localhost:7001/gdalg.html>
117+
118+
??? JavaScript "gdalg.js"
119+
120+
``` js
121+
--8<-- "gdalg.js"
122+
```
123+
124+
??? Mapfile "gdalg.map"
125+
126+
``` scala
127+
--8<-- "gdalg.map"
128+
```
129+
130+
## Exercises
131+
132+
1. Switch to using the JSON file - replace the inline GDAL pipeline with `roads.gdalg.json` in your Mapfile.
133+
134+
2. Extend the GDAL pipeline - add another processing step to the pipeline.
135+
Refer to the [GDAL Vector Pipeline documentation](https://gdal.org/en/latest/programs/gdal_vector_pipeline.html) for examples of available operations.
136+
137+
3. Experiment with hatch styling - adjust properties such as `ANGLE` and `SIZE` in your `STYLE` block
138+
to see how the hatch pattern changes.

workshop/content/mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ nav:
3030
- OGC API - Features: outputs/ogcapi-features.md
3131
- Advanced:
3232
- ArcGIS Feature Server: advanced/arcgis.md
33+
- GDAL Pipeline: advanced/gdalg.md
3334
- Vector Symbols: advanced/symbols.md
3435
- Clusters: advanced/clusters.md
3536
- SLD: advanced/sld.md

workshop/exercises/app/gdalg.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/x-icon" href="https://openlayers.org/favicon.ico" />
6+
<link rel="stylesheet" href="node_modules/ol/ol.css">
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8+
<title>GDAL Vector Pipeline</title>
9+
</head>
10+
<body>
11+
<div id="map" style="background-color: #FFFAF0"></div>
12+
<script type="module" src="./js/gdalg.js"></script>
13+
</body>
14+
</html>

workshop/exercises/app/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ <h2>Outputs</h2>
3030
<li><a href="vector-tiles.html">Vector Tiles</a></li>
3131
<li><a href="ogcapi-features.html">OGC API - Features</a></li>
3232
</ul>
33-
<h2>Advanced</h2>
33+
<h2>Advanced</h2>
3434
<ul>
3535
<li><a href="arcgis.html">ArcGIS Feature Server</a></li>
36+
<li><a href="gdalg.html">GDAL Pipelines</a></li>
3637
<li><a href="railways.html">Vector Symbols (Railways)</a></li>
3738
<li><a href="clusters.html">Clusters</a></li>
3839
<li><a href="landuse.html">Landuse</a></li>

workshop/exercises/app/js/gdalg.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import '../css/style.css';
2+
import ImageWMS from 'ol/source/ImageWMS.js';
3+
import Map from 'ol/Map.js';
4+
import View from 'ol/View.js';
5+
import { Image as ImageLayer } from 'ol/layer.js';
6+
7+
const mapserverUrl = import.meta.env.VITE_MAPSERVER_BASE_URL;
8+
const mapfilesPath = import.meta.env.VITE_MAPFILES_PATH;
9+
10+
const layers = [
11+
new ImageLayer({
12+
source: new ImageWMS({
13+
url: mapserverUrl + mapfilesPath + 'gdalg.map&',
14+
params: { 'LAYERS': 'buffered_roads,roads' },
15+
ratio: 1
16+
}),
17+
}),
18+
];
19+
const map = new Map({
20+
layers: layers,
21+
target: 'map',
22+
view: new View({
23+
center: [2975862.75916499, 8046369.8646329],
24+
zoom: 17,
25+
}),
26+
});
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
MAP
2+
NAME "GDALG"
3+
EXTENT 26.668678 58.339241 26.796582 58.409410
4+
SIZE 800 600
5+
IMAGECOLOR "#0A1E50"
6+
PROJECTION
7+
"init=epsg:4326"
8+
END
9+
WEB
10+
METADATA
11+
"ows_enable_request" "*"
12+
"ows_srs" "EPSG:4326 EPSG:3857"
13+
END
14+
END
15+
16+
SYMBOL
17+
NAME "hatchsymbol"
18+
TYPE hatch
19+
END
20+
21+
LAYER
22+
NAME "buffered_roads"
23+
TYPE POLYGON
24+
STATUS OFF
25+
CONNECTIONTYPE OGR
26+
# note we need to use the full path to the dataset using the inline pipeline
27+
CONNECTION '{"type": "gdal_streamed_alg","command_line": "gdal vector pipeline ! read /etc/mapserver/data/osm/roads.fgb ! geom buffer --distance=0.0001"}'
28+
DATA "0"
29+
# CONNECTION "roads.gdalg.json"
30+
# DATA "0"
31+
CLASS
32+
STYLE
33+
COLOR 50 100 180
34+
END
35+
STYLE
36+
SYMBOL "hatchsymbol"
37+
COLOR "#78C8FF"
38+
WIDTH 0.1
39+
ANGLE 45
40+
SIZE 8
41+
END
42+
END
43+
END
44+
45+
# original unbuffered roads dataset
46+
LAYER
47+
NAME "roads"
48+
TYPE LINE
49+
STATUS OFF
50+
CONNECTIONTYPE FLATGEOBUF
51+
DATA "data/osm/roads.fgb"
52+
CLASS
53+
STYLE
54+
WIDTH 0.8
55+
COLOR "#DCF0FF"
56+
END
57+
END
58+
END
59+
60+
END
61+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "gdal_streamed_alg",
3+
"command_line": "gdal vector pipeline ! read data/osm/roads.fgb ! geom buffer --distance=0.0001"
4+
}

0 commit comments

Comments
 (0)