October 22, 2024
Summary: In this tutorial, you will learn some basics of PostGIS.
Table of Contents
Introduction
PostGIS is one of the most powerful extensions for PostgreSQL and it can turn a database into a GIS (Geographic Information System).
For this tutorial, we’ve loaded a data bundle of 2020 New York City Census data. This data is also part of the PostGIS.net tutorial if you’d like to dig in deeper there.
This tutorial has quite a bit of data and takes a sec to load so be a little patient.
Finding single points
SELECT name, ST_AsText(geom)
FROM nyc_subway_stations
LIMIT 10;
Calculating area
In square meters
SELECT ST_Area(geom)
FROM nyc_neighborhoods
WHERE name = 'West Village';
Calculating length
SELECT ST_Length(geom)
FROM nyc_streets
WHERE name = 'Columbus Cir';
What is the length of streets in New York City, summarized by type?
SELECT type, Sum(ST_Length(geom)) AS length
FROM nyc_streets
GROUP BY type
ORDER BY length DESC;
The SRID
When transforming coordinate data (such as with ST_GeomFromText()
) you need a standardized way of transforming from latitude/longitude to internal representations. PostGIS comes with a spatial_ref_sys
spatial reference table upon installation that contains the most common spatial references, standardized across GIS offerings. In this case we are using the id of 26918
which is a common projection for projections centered around North America.
Extrapolating from a point
Find the point
SELECT name, ST_AsText(geom)
FROM nyc_subway_stations
WHERE name = 'Broad St';
name | st_astext
----------+--------------------------------------------
Broad St | POINT(583571.9059213118 4506714.341192182)
(1 row)
Find the district and borough name for that point.
SELECT name, boroname
FROM nyc_neighborhoods
WHERE ST_Intersects(geom, ST_GeomFromText('POINT(583571 4506714)',26918));
Spatial Joins
SELECT
subways.name AS subway_name,
neighborhoods.name AS neighborhood_name,
neighborhoods.boroname AS borough
FROM nyc_neighborhoods AS neighborhoods
JOIN nyc_subway_stations AS subways
ON ST_Contains(neighborhoods.geom, subways.geom)
WHERE subways.name = 'Broad St';
Distance
From one point to another
SELECT ST_Distance(a.geom, b.geom)
FROM nyc_streets a, nyc_streets b
WHERE a.name = 'Columbus Cir'
AND b.name = 'Atlantic Commons';
Or distance to find something close. For example the streets with 10 meters of the Broad Street station (distance from a point).
SELECT name
FROM nyc_streets
WHERE ST_DWithin(
geom,
ST_GeomFromText('POINT(583571 4506714)', 26918),
10
);
Want to go further and test QGIS or more postgis queries, see Basic PostGIS Queries with Geospatial Data.