What is PostGIS and How is it Used?

PostGIS is a PostgreSQL extension that adds embedded support for geospatial data. Instead of just treating latitude and longitude as numbers, databases can work with real spatial objects like points, lines, and areas and answer questions about distance and location. Functions such as nearby search, geofencing, intersection, and overlap are easier to implement and faster to compute on large datasets. Some of the main PostGIS functionalities include:

  • Spatial Data Storage – Save points (places), lines (routes), and polygons directly in PostgreSQL in 2D and 3D shapes.
  • Spatial Indexing – Quickly find things like “nearby places” or “what is inside this area” without having to scan a whole table.
  • Spatial Functions – Determine distance/area, check if shapes intersect, determine if a point is inside a zone, create “inside of X meters” buffers, etc., using already created spatial functions.
  • Geometry Processing – Tools for processing geodata, such as simplification or conversion.
  • Geocoding and Reverse Geocoding – Convert addresses into coordinates and coordinates back to addresses. 

If you use plain PostgreSQL without PostGIS, you can still save latitude/longitude as numbers, but limitations can happen quickly. You would probably end up writing the mathematical code manually, but mistakes can be made pretty easily, and code hard to maintain. Queries like “nearby search” become slow because the database does not have a way to efficiently index and filter locations. More complex operations like point in polygon, intersection, buffer, or overlap become exceptionally hard to implement correctly or request transferring the data into another system. 

Data Representation

Before running any queries, we need to understand how PostGIS saves location data. The main idea is that PostGIS holds shapes (geometries), and each shape has a type and a coordinate system. Because of that, we can showcase those objects on the map and also analyze their interactions to solve real problems later on. 

In practice, these geometry types will cover most of the real-world use cases:

Type What it representsExample use
PointA single locationStore/shop/user location
LinestringA path or routeRoad segment/route trace
PolygonAn areaCity boundary/delivery zone
MultipointA set of points treated as one objectMultiple entrances, sampling points for one site
MultilinestringA set of line stringsRoad split into segments, bus line made of multiple parts
MultipolygonA set of polygonsAn area made of separate pieces (e.g., islands, campus)

SRIDs

 

SRID (Spatial Reference Identifier) is a key attribute that has to be assigned to every spatial object. It tells PostGIS which spatial referent system the coordinates belong to, where the origin point (0,0) is on Earth, and how the coordinates respond to real locations (including scale/units).

 

The most common SRID is WGS84 (SRID 4326), widely used in GPS, Google Maps, and many other map applications. However, many other SRIDs are in use. Some of them are designed for specific regions and can work with better accuracy or practical units for dedicated computing tasks. That is why it is important to always know the SRIDs of all the spatial data entering your system and handle it correctly.

 

Showcasing PostGIS Core Functions


Imagine that we have a trees table with points and a city blocks table with polygons.

-- Enable PostGIS on current instance of PostgreSQL
CREATE EXTENSION IF NOT EXISTS postgis;

-- Points: trees
CREATE TABLE city_trees (
id bigserial PRIMARY KEY,
species text NOT NULL,
planted_year int,
location geometry(Point, 4326) NOT NULL
);

-- Polygons: city blocks
CREATE TABLE city_blocks (
id bigserial PRIMARY KEY,
name text NOT NULL,
boundary geometry(Polygon, 4326) NOT NULL
);

ST_MakePoint + ST_SetSRID

ST_MakePoint(x, y) creates a point geometry from coordinates.

ST_SetSRID(geom, srid) labels that geometry with a SRID (it does not transform coordinates, it just says “these numbers are in SRID 4326”).

-- Create a point for City Hall (lon, lat) as geometry with SRID 4326
SELECT ST_SetSRID(ST_MakePoint(-0.1246, 51.5007), 4326) AS city_hall;

ST_DWithin

Returns “true” if the geometries are within the given limit of one another. It is designed to work well with indexes, meaning it can use a GiST index and avoid scanning everything. 

This query will find everything within 0.003 degrees (roughly 300 meters) of our City Hall.

SELECT
t.id,
t.species,
t.planted_year
FROM city_trees t
WHERE ST_DWithin(
t.location,
ST_SetSRID(ST_MakePoint(-0.1246, 51.5007), 4326),
0.003
);

ST_Distance

Returns the distance between two geospatial objects. It takes two geometry arguments: ST_Distance(geometryA, geometryB)

This query visualizes how far each tree in the trees table is from City Hall:

SELECT
t.species,
ST_Distance(
t.location,
ST_SetSRID(ST_MakePoint(-0.1246, 51.5007), 4326)
) AS distance
FROM city_trees t
ORDER BY distance;

ST_Intersects

ST_Intersects checks whether two geometries touch or overlap. 

Return every city block whose boundary intersects (touches or overlaps) the given search polygon (e.g., construction zone):

SELECT
b.name
FROM city_blocks b
WHERE ST_Intersects(
b.boundary,
ST_GeomFromText('POLYGON((-0.1270 51.5020, -0.1270 51.5050, -0.1180 51.5050, -0.1180 51.5020, -0.1270 51.5020))', 4326)
);

Common Pitfalls and How to Avoid Them

Even though PostGIS is very approachable, a few common mistakes can lead to incorrect results or slow queries. These are the ones most people run into first.

 

Mixing up latitude and longitude

 

PostGIS point creation typically expects coordinates in (x, y) order, which for GPS data means:

x = longitude

y = latitude

Swapping them won’t always throw an error, but your data will simply end up in the wrong place, and “nearby search” results will look random.

 

Missing or incorrect SRID

 

SRID tells PostGIS what coordinate system your data uses. If you forget to set SRID or set the wrong SRID, then spatial operations can become unreliable or fail when combining geometries.

 

Tip: standardize on a single SRID for storage (often 4326) and validate incoming data before saving it.

 

Expecting meter distances from geometry (4326)

 

A frequent mistake: if your data is stored as geometry in SRID 4326, the coordinate units are degrees, not meters. That means ST_Distance does not return meters unless you convert/transform.

 

Tip: If you need distances in meters, you can either use geography for simple calculations or keep your data as geometry and transform it to a meter-based projected SRID (such as 3857). When running distance queries, choose the approach based on your accuracy and performance needs.

 

Forgetting spatial indexes

 

Without a spatial index, PostGIS queries can transform into full table scans as the dataset grows.

 

Tip: add GiST indexes on spatial columns used in filters.

Conclusion

 

Getting used to PostGIS can drastically change how you work with spatial data. Tasks like gaining useful insights, simplifying processes, or making decisions based on location become much easier when a database understands geography. Whether you are implementing backend functionalities that depend on distances and zones or you work with urban planning, environment analysis, or transport, PostGIS can give you a solid and practical toolset. The more you go into it, the more you will see the powerful combination of PostgreSQL + PostGIS for solving spatial problems that maybe were not on your mind at the start. 

Leave a comment

Your email address will not be published. Required fields are marked *