Back to blog

Automating Geospatial Tasks with GeoServer and Python

During my work at Airbus as a Deep Learning Scientist, I had to automate geospatial tasks for some projects, like the extraction of image tiles from a GeoServer WMS/WCS service, ingestion of large satellite imagery, and more. In this article, I will show you how to automate these tasks using Python only.

By:arthurdjn
Date:
4 min read

geoserver-py banner

Context

Geospatial data come in various formats and sizes, and it can be challenging to manage them. Among the tools available to manage geospatial data, GeoServer is a popular open-source server software that allows users to share, edit and serve geospatial data. GeoServer supports various data formats, including vector data formats such as ESRI Shapefile, and raster data formats such as GeoTIFF.

However, there are no official Python client to interact with GeoServer. To automate geospatial tasks with GeoServer, I created a Python library called geoserver-py.

Introducing GeoServer-Py

Why?

The goal of geoserver-py is to provide a simple and efficient way to interact with GeoServer using Python. The library is designed to follow the REST API of GeoServer without abstracting it too much. This allows users to have full control over the requests and responses.

Features

This library comes with the following features:

Automating Geospatial Tasks

In this section, I will show you how to automate geospatial tasks using geoserver-py. First, you will have to install the library using pip:

Tip

You may want to create a virtual environment before installing the library.

pip install geoserver-py

Connecting to GeoServer

First, you will need to connect to your GeoServer instance. Here is how you can do it:

from geoserver import GeoServer

# Connect to the GeoServer instance
geoserver = GeoServer(
  service_url="http://localhost:8080/geoserver", 
  username="admin", 
  password="geoserver"
)

Because this library depends on requests, you can pass additional parameters such as timeout or proxies to the GeoServer class, as you would do with requests.

Managing Workspaces

First, you may find it convenient to manage your workspaces. Here is how you can create a new workspace:

# Using JSON
geoserver.create_workspace(body={"workspace": {"name": "my_workspace"}})

# ...or XML
geoserver.create_workspace(body="<workspace><name>my_workspace</name></workspace>")

To facilitate the management of workspaces, you can also list, update, or delete them:

# List all workspaces
geoserver.get_workspaces()

# Update a workspace
geoserver.update_workspace(name="demo", body={"workspace": {"name": "demo_v2"}})

# Delete a workspace
geoserver.delete_workspace(name="demo")

Managing Data Stores

There are different ways to create / add data in a GeoServer instance. You can either upload directly your data (from a local file, external URL, PostGIS, etc.) or create a new data store from a data already present in the GeoServer instance (e.g. you can reference a file that is already present in the data directory of the geoserver).

# If the store already exists, it will be overwritten
geoserver.upload_data_store("buildings.shp", name="buildings", workspace="demo")

# If the `name` parameter is not provided, the name of the store will be the same as the file name
geoserver.upload_data_store("buildings.shp", workspace="demo")

You can also create a data store from a PostGIS database:

body = """
<dataStore>
    <name>postgis</name>
    <description>PostGIS connection</description>
    <connectionParameters>
        <entry key="host">postgis</entry>
        <entry key="port">5432</entry>
        <entry key="database">db</entry>
        <entry key="user">admin</entry>
        <entry key="passwd">postgres</entry>
        <entry key="dbtype">postgis</entry>
        <entry key="schema">public</entry>
        <entry key="Expose primary keys">true</entry>
        <entry key="Loose bbox">true</entry>
        <entry key="Estimated extends">true</entry>
        <entry key="fetch size">1000</entry>
        <entry key="Max open prepared statements">50</entry>
        <entry key="preparedStatements">false</entry>
        <entry key="validate connections">true</entry>
        <entry key="validate connections on borrow">true</entry>
        <entry key="validate connections on return">true</entry>
        <entry key="Connection timeout">20</entry>
        <entry key="Eviction run periodicity">3600</entry>
        <entry key="Min evictable idle time">300</entry>
        <entry key="Max active">50</entry>
        <entry key="Max idle">10</entry>
        <entry key="Max wait">10000</entry>
        <entry key="Test on borrow">true</entry>
        <entry key="Test while idle">true</entry>
        <entry key="Time between eviction runs">60000</entry>
    </connectionParameters>
</dataStore>
"""


geoserver.create_data_store(body=body, workspace="demo")

And of course you can list, update, or delete data stores:

# List all data stores
geoserver.get_data_stores(workspace="demo")

# Delete a data store
geoserver.delete_data_store(name="buildings", workspace="demo")

Managing Coverage Stores

Coverage stores are a type of data store that contains raster data. You can create a coverage store from a GeoTIFF file:

geoserver.upload_coverage_store("image.tif", format="geotiff", workspace="demo")

You can also list, update, or delete coverage stores:

# List all coverage stores
geoserver.get_coverage_stores(workspace="demo")

# Delete a coverage store
geoserver.delete_coverage_store(name="image", workspace="demo")

More Examples

Check out the rest of the examples in the documentation! You will find examples on how to manage layers, styles, and more.

Did you enjoy this post?