What is Geography in PostGIS?
PostGIS provides two primary types to store spatial data: geometry
and geography
. While geometry uses a flat Cartesian plane, geography understands the Earth as a sphere. This makes geography perfect for global-scale data where curvature matters.
If you're working on distances between cities, flight paths, or cross-country analysis, geography
is your best choice for accurate results.
Geometry vs Geography – Key Differences
Feature | Geometry | Geography |
---|---|---|
Projection | Flat (planar) | Spherical (WGS84 ellipsoid) |
Unit of Measure | Depends on SRID (e.g., meters) | Always meters |
Spatial Operations | Fast, but approximate on globe | Accurate over long distances |
Indexing | GIST, KNN | GIST (automatically applied) |
Use Case | Local-scale mapping | Global/national-scale analysis |
Coordinate System | Various SRIDs supported | WGS84 (SRID 4326) only |
Function Support | Full function library | Subset of functions |
Rule of thumb: For city zoning, use geometry. For airline distance between Mumbai and New York, use geography.
Creating Geography Columns
Creating tables with geography columns is straightforward:
CREATE TABLE capitals (
id SERIAL PRIMARY KEY,
name TEXT,
country TEXT,
location GEOGRAPHY(Point, 4326)
);
INSERT INTO capitals (name, country, location) VALUES
('Delhi', 'India', ST_GeogFromText('POINT(77.2090 28.6139)')),
('Paris', 'France', ST_GeogFromText('POINT(2.3522 48.8566)')),
('Tokyo', 'Japan', ST_GeogFromText('POINT(139.6917 35.6895)')),
('New York', 'USA', ST_GeogFromText('POINT(-74.0060 40.7128)')),
('Sydney', 'Australia', ST_GeogFromText('POINT(151.2093 -33.8688)'));
Geography Input Functions
Function | Purpose | Example |
---|---|---|
ST_GeogFromText() |
Create geography from WKT | ST_GeogFromText('POINT(77.21 28.61)') |
ST_MakePoint()::geography |
Create point geography | ST_MakePoint(77.21, 28.61)::geography |
geometry::geography |
Cast geometry to geography | geom_column::geography |
Distance Calculations with Geography
One of the primary advantages of geography is accurate distance calculation:
-- Distance in meters between two capitals
SELECT
a.name AS from_city,
b.name AS to_city,
ROUND(ST_Distance(a.location, b.location)) AS distance_meters,
ROUND(ST_Distance(a.location, b.location) / 1000) AS distance_km
FROM capitals a, capitals b
WHERE a.name = 'Delhi' AND b.name = 'Paris';
Proximity Searches
Use ST_DWithin
for proximity searches with geography:
-- Find capitals within 1000 km of Delhi
SELECT name, country
FROM capitals
WHERE ST_DWithin(
location,
ST_GeogFromText('POINT(77.2090 28.6139)'),
1000000 -- 1000 km in meters
)
AND name != 'Delhi';
-- Find the closest capital to a given point
SELECT name, country,
ROUND(ST_Distance(location, ST_GeogFromText('POINT(0 51.5)'))) AS distance_m
FROM capitals
ORDER BY location <-> ST_GeogFromText('POINT(0 51.5)')
LIMIT 1;
Geography Types Supported
Geography Type | Description | Example Usage |
---|---|---|
Point | Single location | Cities, landmarks, GPS coordinates |
LineString | Connected points | Flight paths, shipping routes |
Polygon | Enclosed areas | Countries, states, large regions |
MultiPoint | Multiple points | Chain stores, global offices |
MultiLineString | Multiple lines | Airline route networks |
MultiPolygon | Multiple polygons | Countries with islands |
Working with Larger Geographic Features
-- Create a table for countries
CREATE TABLE countries (
id SERIAL PRIMARY KEY,
name TEXT,
boundary GEOGRAPHY(MultiPolygon, 4326)
);
-- Example flight routes
CREATE TABLE flight_routes (
id SERIAL PRIMARY KEY,
airline TEXT,
route_name TEXT,
path GEOGRAPHY(LineString, 4326)
);
INSERT INTO flight_routes (airline, route_name, path) VALUES
('Air India', 'Delhi-London',
ST_GeogFromText('LINESTRING(77.2090 28.6139, -0.1276 51.5074)'));
-- Calculate flight distance
SELECT
route_name,
ROUND(ST_Length(path) / 1000) AS distance_km
FROM flight_routes;
Spatial Catalog for Geography
PostGIS tracks geography columns in a dedicated catalog table:
-- View all geography columns in the database
SELECT
f_table_schema,
f_table_name,
f_geography_column,
type,
srid,
coord_dimension
FROM geography_columns;
-- Get detailed information about a specific geography column
SELECT
f_table_name AS table_name,
f_geography_column AS column_name,
type AS geography_type,
coord_dimension AS dimensions
FROM geography_columns
WHERE f_table_name = 'capitals';
Performance Considerations
Indexing Geography Columns
-- Create spatial index (automatically uses GIST)
CREATE INDEX idx_capitals_location ON capitals USING GIST(location);
-- Check index usage
EXPLAIN ANALYZE
SELECT name FROM capitals
WHERE ST_DWithin(location, ST_GeogFromText('POINT(77.21 28.61)'), 500000);
Performance Comparison
Operation | Geometry (Fast) | Geography (Accurate) | Best Use Case |
---|---|---|---|
Distance calculation | Approximate | Precise | Geography for global data |
Area calculation | Projection-dependent | True spherical area | Geography for large areas |
Spatial joins | Very fast | Slower but accurate | Depends on accuracy needs |
Complex operations | Full function support | Limited functions | Geometry for complex analysis |
Limitations and Considerations
Geography Limitations
- Function support: Geography supports fewer functions than geometry (no TINs, curves, or complex topology operations)
- Performance: Spatial joins and complex operations may be slower
- Projection: Cannot use arbitrary projections—only WGS84 (SRID 4326)
- Precision: Limited to spherical calculations (no ellipsoidal refinements for highest precision)
When to Choose Geography vs Geometry
Use Geography When | Use Geometry When |
---|---|
Working with global or continental data | Working with local or city-scale data |
Accuracy over large distances is critical | Performance is more important than precision |
Calculating true distances/areas | Complex spatial operations are needed |
Data spans multiple time zones/countries | Working with projected coordinate systems |
GPS or lat/lon data from global sources | CAD, surveying, or engineering applications |
Real-World Applications
Global Logistics
-- Calculate shipping distances between ports
CREATE TABLE ports (
name TEXT,
country TEXT,
location GEOGRAPHY(Point, 4326)
);
-- Find optimal shipping routes
SELECT
p1.name AS origin,
p2.name AS destination,
ROUND(ST_Distance(p1.location, p2.location) / 1852) AS nautical_miles
FROM ports p1, ports p2
WHERE p1.name != p2.name
ORDER BY ST_Distance(p1.location, p2.location)
LIMIT 10;
Climate Analysis
-- Analyze weather stations within climate zones
CREATE TABLE weather_stations (
id SERIAL PRIMARY KEY,
name TEXT,
location GEOGRAPHY(Point, 4326),
elevation INTEGER
);
-- Find stations within 500km of a reference point
SELECT name, elevation
FROM weather_stations
WHERE ST_DWithin(
location,
ST_GeogFromText('POINT(77.21 28.61)'),
500000
);
Best Practices
- Evaluate your scale: Use geography for global/national analysis, geometry for local projects
- Index geography columns: Always create spatial indexes for better performance
- Validate coordinates: Ensure longitude is between -180 and 180, latitude between -90 and 90
- Consider precision needs: Geography provides good accuracy for most applications
- Test performance: Compare query performance between geography and projected geometry