DEV Community

Cover image for Sharing Geospatial Data with OGC API, pygeoapi and MongoDB
Joana Simoes
Joana Simoes

Posted on

Sharing Geospatial Data with OGC API, pygeoapi and MongoDB

Geospatial data can be defined as any dataset which has a location tag attached to it, i.e.: a pair of coordinates which allows us to position it precisely at the surface of the earth. In this post we are going to describe how we can make geospatial data available on the web, trough a RESTfull API, so that ourselves or others can do something with it, for instance creating a map. If it is true you can create a map using a static file, using an API has numerous advantages like scalability, reliability and updatability. In order to do this, we will use three things: a dataset, a standard and a stack of Free and Open Source Software (FOSS).

Dataset

In this tutorial we will share a dataset with local shops and products in the city of Barcelona, kindly provided by sawcer.

record from sawcer dataset

Each record describes characteristics of the shop such as name, address, website, which products are sold (e.g.: Gluten free donut) and, last but not the least, its location as a point geometry, with x,y coordinates.

Standard

Standards are the glue in the server-client architecture. The Open Geospatial Consortium(OGC) is a member organisation, which publishes standards to ensure the maximum degree of interoperability between geospatial data and services. In practice interoperability would mean that you could write a client application that talks to any server, without knowing any details about that server's implementation.
In this tutorial we will use the OGC API Features standard, which was designed for sharing feature data over the web (if you are wondering what a feature is, you can check out this article). These are some of its main traits, which make it very convenient to use:

  • Modular
  • RESTfull
  • Recommended encodings (e.g.: GeoJSON, HTML)
  • Use of OpenAPI

Software Stack

In order to publish the dataset using the OGC API Features standard, we need a software which implements the standard. In this tutorial we will use pygeoapi, which is a python server implementation, released under a FOSS (MIT) license. pygeoapi needs a backend to store the data. For that we will use the MongoDB document oriented database. In order to make deployment easier, the complete stack was virtualised into a set of docker containers, and orchestrated using docker-compose.

Software stack

Putting it all together

In order to publish the dataset, you can clone this repository. If you navigate to the docker/examples/mongo folder, you will find this docker-composition:

version: '3.3'

services:
  pygeoapi:
    image: geopython/pygeoapi:latest

    container_name: pygeoapi_mongo

    entrypoint:
      - /mongo-entrypoint.sh

    ports:
      - 5000:80

    volumes:
      - ./pygeoapi/docker.config.yml:/pygeoapi/local.config.yml
      - ./pygeoapi/mongo-entrypoint.sh:/mongo-entrypoint.sh
      - ./pygeoapi/wait-for-mongo.sh:/wait-for-mongo.sh
    links:
      - mongo
    depends_on:
      - mongo

  mongo:
    image: mongo
    container_name: mongo
    ports:
      - 27017:27017
    volumes:
      - ./docker-entrypoint-initdb.d/add_data.sh:/docker-entrypoint-initdb.d/add_data.sh:ro
      - ./mongo_data/:/mongo_data
    environment:
        MONGO_INITDB_DATABASE: sawcer

  mongo-express:
    image: mongo-express
    restart: always
    container_name: mongo_express
    links:
      - mongo
    depends_on:
      - mongo
    ports:
      - 8081:8081
mongodb://root:example@mongo:27017/


volumes:
  mongo_data: {}

Enter fullscreen mode Exit fullscreen mode

Here is what happens behind the scenes, when you type docker-compose up:

  1. The mongo container starts, a database is initialised and the data is injected into a collection. The data is pulled from a GeoJSON file in the mongo_data folder. If you are trying this with your own data, it is worth to mention that mongo ingests the features array, without the outer element. You can transform a regular GeoJSON file into MongoDB-consumable JSON, using the jq command-line utility: jq --compact-output ".features" shops-orig.geojson > shops.geojson
  2. Once the database is live, the pygeoapi container starts. The configuration of the service is on this file, which is mounted by the container. In particular, this bit is where the sawcer dataset is exposed from the MongoDB backend:
    sawcer:
        type: collection
        title: Shops and Products 
        description: SEARCH & FIND & SHARE where to get ingredients in local shops
        keywords:
            - cases
        links:
            - type: text/html
              rel: canonical
              title: information
              href: https://www.sawcer.com/
              hreflang: en-US
        extents:
            spatial:
                bbox: [-180, -90, 180, 90]
                crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
            temporal:
                begin: 2011-11-11
                end: null  # or empty
        providers:
            - type: feature
              name: MongoDB
              data: mongodb://mongo:27017/sawcer
              collection: shops
Enter fullscreen mode Exit fullscreen mode

At this stage, the pygeoapi is running on port 5000: http://localhost:5000. You can access the sawcer dataset at: http://localhost:5000/collections/sawcer
You can retrieve the collection items at:
http://localhost:5000/collections/sawcer/items
The default response is in html, but you can change it using the f (format) parameter. The server supports both, JSON and JSON-LD encodings. For instance:
http://localhost:5000/collections/sawcer/items?f=jsonld
You can access one particular item, using its id:
http://localhost:5000/collections/sawcer/items/61afae9fc6bf8d516533620f

Collection item

If you want to explore the MongoDB collection, you can use the provided mongo-express user interface, running on port 8081: http://localhost:8081

What's next

Making your geospatial dataset available on the web using a standard, unlocks a world of possibilities. It means that many existing (or future) client applications will be able to read your data, out-of-the-box. For instance, anyone can use QGIS, Esri ArcGIS, React-leaflet, OpenLayers or Python OWSlib to pull your data and analyse it, or create products or services on top of it.

OGC API Features on QGIS

You can explore a live deployment of this dataset, at this endpoint:
https://features.byteroad.net/collections/sawcer
On this OpenAPI document, you can try all the available endpoints:
https://features.byteroad.net/openapi?f=html

Discussion (0)