Skip to content

Commit a21b4b2

Browse files
committed
geospatial explorer: moved config guide to separate file
1 parent d88c153 commit a21b4b2

File tree

3 files changed

+269
-208
lines changed

3 files changed

+269
-208
lines changed

_quarto.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ website:
7575
text: Linking APEx STAC catalogue with an openEO service
7676
- href: guides/file_formats.qmd
7777
text: File format recommendations
78+
- href: guides/geospatial_explorer_config_guide.md
79+
text: Configuring the Geospatial Explorer
7880
- href: guides/geospatial_explorer_guide.md
7981
text: Using the Geospatial Explorer
8082
- href: guides/project_portal/index.qmd
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
---
2+
title: Configuring the APEx Geospatial Explorer
3+
---
4+
The [APEx Geospatial Explorer](../instantiation/geospatial_explorer.md) is a versatile web application designed to visualize
5+
and interact with geospatial data. It leverages the OpenLayers library to provide a rich set of features for exploring spatial
6+
datasets. The application is highly configurable, allowing users to tailor its functionality and appearance to meet specific
7+
project requirements. This document outlines the configuration options for the APEx Geospatial Explorer, detailing the structure
8+
and properties of the configuration schema.
9+
10+
## Configuration Schema
11+
12+
The service configuration will be based on a schema that provides administrators with the expected structure and
13+
contents of the configuration. Taking this approach enables:
14+
15+
* Automated and dynamic instantiation of the service with differing functionality.
16+
* Configuration validation.
17+
* Definition of a “contract” for easier documentation of features and their configuration.
18+
19+
The sections below briefly outline the structure of the configuration schema and provide a preliminary description of
20+
each field/property within. The schema currently consists of four top-level fields and all properties are written in
21+
camel case.
22+
23+
### Layout - `layout`
24+
25+
An object with properties that modify the elements that the application will render. These properties and elements
26+
relate specifically to non-geospatial layout components, like navigation and footer.
27+
28+
Currently supported properties:
29+
30+
#### Navigation - `navigation`
31+
32+
An object which supports two properties:
33+
34+
* `logo`: A URL string that points to a logo image asset.
35+
* `title`: A string to be used as a title for the application.
36+
37+
### Interface Groups - `interfaceGroups`
38+
39+
An optional array of strings to be used as names/keys. This is currently used to configure the grouping of layer UI
40+
elements, such as the layer cards. This will be expanded in later versions.
41+
42+
### Exclusivity Sets - `exclusivitySets`
43+
44+
An optional array of strings to be used as names/keys. This is currently not in use but is a placeholder for future
45+
work.
46+
47+
### Sources - `sources`
48+
49+
An array of objects. Each object outlines a particular data source to be configured for display within the application,
50+
with properties detailing both the geospatial and user interface configuration.
51+
52+
Currently supported properties within a source object are:
53+
54+
#### Name - `name`
55+
56+
A string that is used to identify layers in both the user interface and OpenLayers state
57+
58+
#### Is Active - `isActive`
59+
60+
A boolean. Determines if a layer is currently shown on the map. Setting this to true will show the layer on the map when
61+
the application loads.
62+
63+
#### Time Frame - `timeframe`
64+
65+
A string that is required to render and control time series layers. It should have a value of either `Days`, `Months`, `Years`.
66+
This will determine the behavior of the UI for layer groups with time series data configured.
67+
68+
* Days: This will allow the selection of every available date within the configure data sources.
69+
* Months: This will only allow a user to select a the year and the month for the configured sources.
70+
* Years: This will allow only a single year to be selected for the dataset.
71+
72+
For the best user experience it's essential to set this correctly for the series of datasets in use.
73+
74+
#### Base Layer - `isBaseLayer`
75+
76+
Optional boolean that determines if the layer should be treated as a base layer. Base layer groups are always active and
77+
cannot be toggled.
78+
79+
#### Swipe Layer - `isSwipeLayer`
80+
81+
Optional boolean that determines if the layer should be treated as a swipe layers. Swipe layer groups are configured much
82+
like any other layer group however the individual sources need to be configured with an additional position property with
83+
a value of either `left` or `right`.
84+
85+
#### Layout - `layout`
86+
87+
An object to determine which interface elements are rendered for the layer. Supports two properties:
88+
89+
##### Layer Card - `layerCard`
90+
91+
An object that will determine if a layer card should be rendered for this layer and what other interface elements should
92+
be rendered within the card. This is currently the main way to interact with a layer within the application. The layer
93+
card can show a toggle for the layer, a selection of buttons or controls for the layer, legends and attribution text.
94+
This currently supports the following properties:
95+
96+
* `toggleable`: A boolean that determines if a toggle switch to enable/disable the layer should be rendered.
97+
* `controls`: An optional object that configures which buttons to render in the layer card for interaction with
98+
the layer. This object can contain:
99+
* `zoomToCenter`: A boolean that renders a button that will zoom the map to the extent of the layer.
100+
* `opacitySlider`: A boolean that renders a button to open or close the opacity slider control for the layer.
101+
* `download`: A URL string that will render a link to the given URL. Used for signposting users to the source data or website.
102+
* `legend`: An optional object that can be configured to show static or dynamic legend elements within the layer card
103+
when active. Contains a `type` property that has a string value of: `swatch`, `image`, `gradient`. Also requires a `url`
104+
property with a string value
105+
if the type is `image`.
106+
107+
##### Interface Group - `interfaceGroup`
108+
109+
An optional string that is used to identify which interface group this layer belongs to.
110+
111+
#### Metadata - `meta`
112+
113+
An object that contains information describing the data source. This is generally used for information that would be used
114+
in multiple places across the application such as: units used to describe data values, the minimum and maximum value for
115+
use in UI/Visualisation calculations, attribution etc.
116+
117+
This currently supports the following properties:
118+
119+
* `attribution`: An optional object to render some text or a link for use with attribution of layer datasets.
120+
* `min`: An integer for the lower limit to use for data values when calculating UI elements such as legends, statistics,\
121+
colour ramps.
122+
* `max`: An integer for the upper limit to use for data values when calculating UI elements such as legends, statistics,\
123+
colour ramps.
124+
* `units`: An optional string that describes the units of any values derived from the data. Used in legends and statistics\
125+
panels.
126+
* `description`: An optional string that describes the dataset.
127+
* `startColor`: A string describing a valid hex or RGB/A colour value. This is used to render colour ramps and legends.
128+
* `categories`: An array of objects that contains a `label` (string) property, a `color` (string) property and a `value`\
129+
(integer) property. Describes classifications within datasets such as land usage. Used to create swatch legends and statistics
130+
visualisation.
131+
132+
#### Data - `data`
133+
134+
An array of objects that configures the data to be displayed in the layer. If the length is more than one a layer group
135+
will be created and all sources will be treated as one layer.
136+
137+
Each object currently supports the following properties:
138+
139+
* `url`: A required URL string that points to the dataset's publicly available resource.
140+
* `format`: A required string that identifies what kind of dataset is requested. This can be one of the following: `wms`,
141+
`wmts`, `cog`, `xyz`, `wfs`, `flatgeobuf`, `stac` or `geojson`.
142+
* `layers`: Only required for sources of format: `wms` and `wmts`. A string that describes the layer to be requested from
143+
the external service.
144+
* `typeName`: Only required for sources of format: `wfs`. A string that describes the type to be requested from the
145+
external service.
146+
* `zIndex`: Optional integer that determines rendering order within the map. It can be used to override the default
147+
rendering of Open Layers.
148+
* `exclusivitySet`: Optional string used to identify a group of other layers that should be disabled when this layer is
149+
enabled. They must share the same string.
150+
* `projection`: Optional EPSG code string that describes the projection of the dataset to Open Layers. If the projection
151+
is supported (and doesn't match the map's configured projection), it will attempt to reproject the data.
152+
* `style`: Open Layers style object that is passed through to the library to modify the rendering of the layer within
153+
the map.
154+
* `normalise`: Only required for sources of format: `cog`. Boolean that configures the map to normalise the raster pixel
155+
values to between 0 and 1. False by default.
156+
* `level`: A required integer for sources of type `statistical`. Ideally starting at 0, this integer describes the hierarchy
157+
of statistical sources. Higher integers should represent more complex and granular vector datasets. Used to provide the
158+
statistics feature UI and maintain performance for large vector datasets.
159+
* `position`: A string of either `left` or `right` that is only required for swipe layer groups. This determines which side
160+
of the swipe control the date will be visualised on.
161+
* `timestamps`: An optional array of Unix timestamps or ISO8601 date strings. This allows the configuration of time series
162+
visualisation within the layer group. If multiple timestamps exist within the layer group and the timeframe property is
163+
set a datepicker/stepper control will be rendered to cycle which layer is visible.
164+
165+
## Example Configurations
166+
167+
Numerous example configurations can be found in the
168+
[APEx Geospatial Explorer Configurations](https://github.com/ESA-APEx/apex_geospatial_explorer_configs) repository on GitHub.
169+
170+
```{python}
171+
#| echo: false
172+
from IPython.display import display, HTML
173+
import requests
174+
175+
examples_api_url = "https://api.github.com/repos/ESA-APEx/apex_geospatial_explorer_configs/contents/examples"
176+
example_base_url = "https://raw.githubusercontent.com/ESA-APEx/apex_geospatial_explorer_configs/main/examples/"
177+
example_gh_base_url = (
178+
"https://github.com/ESA-APEx/apex_geospatial_explorer_configs/tree/main/examples/"
179+
)
180+
response = requests.get(examples_api_url)
181+
examples = response.json()
182+
cards = []
183+
for example in examples:
184+
result_url = example_base_url + example["name"] + "/result.png"
185+
example_url = example_gh_base_url + example["name"]
186+
187+
config_url = example_base_url + example["name"] + "/config.json"
188+
config_response = requests.get(config_url)
189+
config = config_response.json()
190+
title = config["layout"]["navigation"]["title"]
191+
192+
card = f"""
193+
<a href='{example_url}'>
194+
<div class='card' style='width: 300px'">
195+
<p class='card-img-top'>
196+
<img src='{result_url}' class='thumbnail-image card-img' height='150'/>
197+
</p>
198+
<div class='card-body pot-contents'>
199+
<h5 class='card-title listing-title'>{title}</h5>
200+
</div>
201+
</div>
202+
</a>
203+
"""
204+
cards.append(card)
205+
206+
# Join the cards and return the result
207+
208+
card_container = f"""
209+
<div style='display: flex; flex-wrap: wrap; gap: 1rem;'>
210+
{''.join(cards)}
211+
</div></a>
212+
"""
213+
214+
display(HTML(card_container))
215+
216+
```

0 commit comments

Comments
 (0)