Integrate Spring Boot and PostGIS to manage spatial data

Nourreddine HOUARI
4 min readJul 18, 2021

--

In this post, I will show you how we can manage spatial data using Spring Boot and PostGIS.

Spatial data are useful when we would like to develop Geographic Information System or any application that needs to deal with a Map.

What is PostGIS?

PostGIS is an extension of Postgres to help you manage spatial data. PostGIS provides the types (Point, Line, Polygon) and a set of useful functions to manipulate those data. In this tutorial, I will be using the ST_DistanceSphere function to get all the cities within a given distance from a point. You can refer to PostGIS documentation to know more about the available functions: http://www.postgis.org/docs/ST_Distance_Sphere.html

These functions can be used in your SQL queries like any other SQL function.

Let’s jump to the code and write our app !

Run PostGIS

For this tutorial, we will need to install PostGIS database.

We will use Docker and docker-compose command line to run PostGIS.

docker-compose up -d

The docker-compose.yaml is provided in the git repository.

Create a Spring Boot project

The fastest way to create a new project is to use Spring Initialzr website.

On the right, you will have to select all the dependencies that you would like to include in your project and click “Generate” to get the ZIP file containing your project.

Spring Boot initializr

Configure Spring Boot

Unzip the archive, go to the root folder of the new project and use your favorite IDE to edit the code.

  1. Configure the datasource and PostGIS dialect in the src/main/resources/application.yaml file
server:
port: 8980
spring:
# Database configuration
datasource:
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5435}/${DB_NAME:postgis}
username: ${DB_USER:postgis}
password: ${DB_PASSWORD:postgis
# JPA configuration
jpa:
# PotGIS configuration
database-platform: org.hibernate.spatial.dialect.postgis.PostgisDialect
hibernate:
ddl-auto: update
show-sql: true
database: postgresql

2. Add hibernate spatial support to your project

<dependency>
<groupId>com.bedatadriven</groupId>
<artifactId>jackson-datatype-jts</artifactId>
<version>${jackson.jts.version}</version>
</dependency>
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts-core</artifactId>
<version>${jts.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>${hibernate.version}</version>
</dependency>

Notes: I had to downgrade hibernate spatial version due to some recent changes in the jts-core library. See more here: https://stackoverflow.com/questions/48946230/java-io-streamcorruptedexception-invalid-stream-header-30313031

3. Build

mvn clean install

Importing Spatial data

We will be using some OpenSource representing US cities with their population and elevation.

https://github.com/giswqs/data/blob/main/us/us_cities.geojson

The data is in GeoJSON format and needs to be imported to PostGIS.

We can use the ogr2ogr command line to import GeoJSON to our database but I will show you another way using a more friendly tool called QGIS.

QGIS is a user friendly Open Source Geographic Information System (GIS) licensed under the GNU General Public License. QGIS is an official project of the Open Source Geospatial Foundation (OSGeo)

1. Open GeoJSON file
2. Export the data to PostGIS database
3. Check the new table and data

Now that we have our new data in PostGIS, we can start to code our Spring Boot application.

Serialisation/Deserialisation of JTS data types

Add the JTS module for Serialisation/DeSerialisation of geometries. You can add this bean in a separate @Congiguration or directly in your application.

Add JTS module

Spatial Entity

Create the entity with the PostGIS geometry attribute. This entity will do the mapping between the java attributes and the database table and columns.

JPA entity
Note: The ` are used to tell Postgres to be case sensitive for the column name. If you don’t add them, the query will fail because JPA will look at the column name in lowercase.

Repository

The repository will be the simplest as possible and will find cities around a point within a given distance in meter.

Controller

The controller exposes 2 endpoints:

City controller

Run the project

mvn spring-boot:run
  • http://localhost:8980/city?page=1&size=10 to fetch the cities in a page
  • http://localhost:8980/city/lat/lon/distance to get the cities around a geographical position
JSON result

That’s it!

I hope you learnt something new in this tutorial. You can find the git repository here: https://github.com/nouhouari/spring-boot-postgis

Happy learning!

Where to go from here?

  • Add geographical index to speed up the query time
  • Use specification to mix spatial and non spatial column in the query

References

--

--

Nourreddine HOUARI
Nourreddine HOUARI

Responses (3)