Cloud Native OGC APIs server, written in Go.
This server implements modern OGC APIs such as Common, Tiles, Styles, Features and GeoVolumes in a cloud-native way. It contains a complete implementation of OGC API Features (part 1, 2 and 5). With respect to OGC API Tiles, Styles, GeoVolumes the goal is to keep a narrow focus, meaning complex logic is delegated to other implementations. For example, vector tile hosting may be delegated to a vector tile engine, 3D tile hosting to object storage, raster map hosting to a WMS server, etc.
This application is deliberately not multi-tenant, it exposes an OGC API for one dataset. Want to host multiple datasets? Spin up a separate instance/container.
See OGC APIs listed on https://api.pdok.nl. These are powered by GoKoala.
/items?<property>=<value>) and temporal filtering (/items?datetime=<timestamp>).docker build -t pdok/gokoala .
NAME:
GoKoala - Cloud Native OGC APIs server, written in Go
USAGE:
GoKoala [global options] command [command options] [arguments...]
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--host value bind host for OGC server (default: "0.0.0.0") [$HOST]
--port value bind port for OGC server (default: 8080) [$PORT]
--debug-port value bind port for debug server (disabled by default), do not expose this port publicly (default: -1) [$DEBUG_PORT]
--shutdown-delay value delay (in seconds) before initiating graceful shutdown (e.g. useful in k8s to allow ingress controller to update their endpoints list) (default: 0) [$SHUTDOWN_DELAY]
--config-file value reference to YAML configuration file [$CONFIG_FILE]
--theme-file value reference to a (customized) YAML configuration file for the theme [$THEME_FILE]
--openapi-file value reference to a (customized) OGC OpenAPI spec for the dynamic parts of your OGC API [$OPENAPI_FILE]
--enable-trailing-slash allow API calls to URLs with a trailing slash. (default: false) [$ALLOW_TRAILING_SLASH]
--enable-cors enable Cross-Origin Resource Sharing (CORS) as required by OGC API specs. Disable if you handle CORS elsewhere. (default: false) [$ENABLE_CORS]
--help, -h show help
Example (config-file is mandatory):
docker run -v `pwd`/examples:/examples -p 8080:8080 -it pdok/gokoala --config-file /examples/config_vectortiles.yaml
Now open http://localhost:8080. See examples for more details.
The configuration file consists of a general section and a section
per OGC API building block (tiles, styles, etc). See example configuration
files for details. You can reference environment variables in the
configuration file. For example to use the MY_SERVER env var:
ogcApi:
tiles:
title: My Dataset
tileServer: https://${MY_SERVER}/foo/bar
GoKoala offers some minimal theming options. When running GoKoala, pass an argument of -theme-file to load a custom
theming file. The theme.yaml contains the configurable options (colors, images, extra HTML)
for the theme.
For example:
mytheme and place a customized copy of theme.yaml and additional assets/images in this directory.mytheme as a volume and start GoKoala with the custom theme:docker run -v `pwd`/examples:/examples -v `pwd`/mytheme:/mytheme -p 8080:8080 -it pdok/gokoala \
--config-file /examples/config_vectortiles.yaml --theme-file /mytheme/theme.yaml
GoKoala has a few requirements regarding GeoPackages backing an OGC API Features:
indexRequired: false is specified in the
config.select load_extension('/path/to/mod_spatialite');
alter table "<table>" add minx numeric;
alter table "<table>" add maxx numeric;
alter table "<table>" add miny numeric;
alter table "<table>" add maxy numeric;
update "<table>" set minx = st_minx('geom'), maxx = st_maxx('geom'), miny = st_miny('geom'), maxy = st_maxy('geom');
create index "<table>_spatial_idx" on "<table>"(fid, minx, maxx, miny, maxy);
datetime query param) the temporal fields should be indexed and the spatial index should be expanded to include the temporal fields.create index "<table>_spatial_idx" on "<table>"(fid, minx, maxx, miny, maxy, start_date, end_date);
create index "<table>_temporal_idx" on "<table>"(start_date, end_date);
This is in addition to some of the requirements set forth by the PDOK GeoPackage validator. Some of the requirements stated above can be automatically applied with help of the PDOK GeoPackage optimizer.
When using Cloud-Backed GeoPackages we recommend
a local cache that is able to hold the spatial index, see maxSize in the config.
Likewise, GoKoala has a few requirements regarding PostgreSQL backing an OGC API Features:
indexRequired: false is specified in the
config.datetime query param) the temporal fields should be indexed:create index "<table>_temporal_idx" on "<table>" (start_date, end_date);
GoKoala supports OGC API Features part 5 (schemas). The schema for each collection is automatically derived from the underlying - Geopackage or PostgreSQL - table. Optionally, one can enrich the schema with field/property descriptions.
When using GeoPackages you'll need to add
the GeoPackage schema extension.
This includes adding a gpkg_data_columns table and inserting a description for each field.
When using PostgreSQL you can add a comment on each column. This comment will be used as the field description. For example:
comment on column <table>.<field> is "Some description about this field for the end-user";
GoKoala ships with OGC OpenAPI support out of the box, see OpenAPI
specs for details. You can overwrite or extend
the defaults by providing your own spec using the openapi-file CLI flag.
Health endpoint is available on /health. When the server is configured to serve OGC API Tiles, the health endpoint will check for the presence of a specific tile on the configured tileserver.
When no OGC API Tiles are configured, the health endpoint will simply serve an HTTP 200 when called.
By default, when OGC API Tiles are configured, the checked tile is determined from a fixed lookup table, based on the deepest zoomlevel (i.e., zoomLevelRange.end) of EPSG:28992 (e.g., if the
deepest zoomlevel is 12, the path of the checked tile is /NetherlandsRDNewQuad/12/1462/2288.pbf).
It is possible to override the tile to be checked, both in terms of projection (SRS/CRS) and specific tile path:
ogcApi:
tiles:
healthCheck:
srs: EPSG:3035
tilePath: /EuropeanETRS89_LAEAQuad/14/8237/7303
When specifying a projection other than EPSG:28992, the tilePath must also be specified. When specifying a tilePath, the format to be used is either /{tileMatrixSetId}/{tileMatrix}/{col}/{row}.pbf or
/{tileMatrixSetId}/{tileMatrix}/{row}/{col}.pbf (depending on what order the tile server requires).
Besides the main OGC server GoKoala can also start a debug server. This server
binds to localhost and a different port which you must specify using the
--debug-port flag. You shouldn't expose this port publicly but only access it
through a tunnel/port-forward. The debug server exposes /debug for use by
pprof. For example with --debug-port 9001:
kubectl port-forward gokoala-75f59d57f4-4nd6q 9001:9001go tool pprof http://localhost:9001/debug/pprof/profile?seconds=20go tool pprof http://localhost:9001/debug/pprof/heap?seconds=20go tool pprof -http=":8000" pprofbin <path to pb.gz file>Set LOG_SQL=true environment variable to enable logging of all SQL queries to
stdout for debug purposes. Only applies to OGC API Features with
GeoPackage and/or PostgreSQL data source.
Design principles:
ogc package contains logic per specific OGC API
building block.engine package should contain general logic. ogc may reference
engine.
:warning: The other way around is not allowed!
Make sure SpatiaLite, PROJ, openssl and curl are installed.
Also make sure gcc or similar is available since the application uses cgo.
go build -o gokoala cmd/main.go
./gokoala
To troubleshoot, review the Dockerfile since compilation also happens there.
Optionally set SPATIALITE_LIBRARY_PATH=/path/to/spatialite when SpatiaLite isn't found.
To run all unit tests:
go test -v -race -shuffle=on ./...
Optionally set SPATIALITE_LIBRARY_PATH=/path/to/spatialite when SpatiaLite isn't found.
Some tests make use of Testcontainers so you'll need to have Docker installed.
Install golangci-lint and run golangci-lint run ./... from the root.
GoKoala includes a viewer which is available
as a set of Web Components for embedding in HTML pages.
To use the viewer locally when running GoKoala outside Docker execute: hack/build-local-viewer.sh. This will
build the viewer and add it to the GoKoala assets.
Note this is only required for local development. When running GoKoala in a container this is already being taken care of when building the Docker container image.
Preferences > Editor > File Types select Go Template files and
add the following file patterns:
"*.go.html""*.go.json""*.go.tilejson""*.go.xml"Also:
Preferences > Editor > Code Style > Go > Imports
to goimports to align with VSCode and goimports usage in golangci-lint."*.go.html""*.go.json""*.go.tilejson""*.go.xml"html, json and xml to the list of Go template languages.See our end-to-end tests for details.
Make a pull request...
Contacting the maintainers can be done through the issue tracker.