Building a Location-Based REST API with OpenStreetMap, PostGIS, and Spring Boot
Jul 22, 2025
Introduction
Location-based services are a core component of many modern applications — from delivery tracking to finding the nearest point of interest. In this tutorial, I'll walk through building a REST API in Java with Spring Boot, powered by OpenStreetMap (OSM) data stored in PostGIS (a spatial extension for PostgreSQL).
This guide gives you a working foundation for your own geospatial API, capable of handling spatial queries like "find the nearest pharmacy" or "calculate route distance between two coordinates."
Why OpenStreetMap + PostGIS + Spring Boot?
- OpenStreetMap (OSM): Free, community-driven map data.
- PostGIS: Adds spatial capabilities to PostgreSQL, enabling fast spatial queries.
- Spring Boot: Provides a robust and scalable platform for REST API development.
This stack is ideal for building lightweight, performant, and maintainable geospatial services.
Preparing OSM Data with osm2pgsql
First, download regional OSM data from Geofabrik. Then install and run osm2pgsql
to import it into PostgreSQL:
sudo apt install osm2pgsql osm2pgsql -d osmdb -U postgres -H localhost --create --slim -G --hstore --tag-transform-script openstreetmap-carto.lua -C 2000 -S default.style serbia-latest.osm.pbf
This creates planet_osm_point
, planet_osm_line
, planet_osm_polygon
, etc., populated with spatial data.
Setting Up the PostGIS Database
Enable PostGIS extensions in your database:
CREATE EXTENSION postgis; CREATE EXTENSION hstore;
Confirm spatial columns exist, e.g.:
SELECT f_table_name, f_geometry_column, srid, type FROM geometry_columns;
Creating a Spring Boot Project with Spatial Support
Create a Spring Boot app and add the necessary dependencies:
<!-- pom.xml --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-spatial</artifactId> </dependency> </dependencies>
Configure your datasource in application.yml
:
spring: datasource: url: jdbc:postgresql://localhost:5432/osmdb username: postgres password: secret jpa: properties: hibernate.dialect: org.hibernate.spatial.dialect.postgis.PostgisDialect
Implementing Location Queries
Create a JPA entity using org.locationtech.jts.geom.Point
:
@Entity @Table(name = "planet_osm_point") public class OsmPoint { @Id private Long osm_id; private String name; @Column(columnDefinition = "geometry(Point,4326)") private Point way; }
Now add a repository with a custom native query:
@Query("SELECT * FROM planet_osm_point p WHERE ST_DWithin(p.way, ST_SetSRID(ST_MakePoint(:lng, :lat), 4326), :radius) LIMIT 10") List<OsmPoint> findNearby(@Param("lng") double lng, @Param("lat") double lat, @Param("radius") double radius);
Building the REST API Endpoints
@RestController @RequestMapping("/api/pois") public class PoiController { @Autowired private OsmPointRepository repository; @GetMapping("/nearby") public List<OsmPoint> getNearby(@RequestParam double lat, @RequestParam double lng, @RequestParam(defaultValue = "500") double radius) { return repository.findNearby(lng, lat, radius); } }
This endpoint allows querying for points of interest within a radius.
Optimizing with Spatial Indexes
Make sure your spatial columns are indexed:
CREATE INDEX idx_way_point ON planet_osm_point USING GIST (way);
This significantly improves query performance for spatial filters.
Deploying Behind Apache with Reverse Proxy
Use Apache to expose only ports 80/443, proxying Spring Boot:
ProxyPass "/api" "http://localhost:8081/api" ProxyPassReverse "/api" "http://localhost:8081/api"
Then configure UFW to allow only ports 22, 80, 443.
Conclusion and Next Steps
You now have a working foundation for a spatially-aware REST API based on open data. From here, you can:
- Add more endpoints (e.g. routing, isochrones)
- Integrate map front-ends (Leaflet, OpenLayers)
- Use token-based authentication