Simplifying Geospatial Operations with PostGIS in Node.js

PostGIS, a powerful extension for PostgreSQL, brings geospatial capabilities to the popular relational database. With the postgis Node.js package, developers can easily interface with a PostGIS-enabled PostgreSQL database to perform complex spatial queries and operations. Whether you're building location-based services, map applications, or performing geospatial analysis, this package provides a robust and flexible solution. In this guide, we’ll explore how to install and use the postgis package, diving into its key methods and common use cases.

Suyog Jadhav
4 min readSep 13, 2024
A split image showing GeoJSON data on the left and its corresponding map visualization on the right. The GeoJSON data includes coordinates, and feature types such as ‘Point’, ‘LineString’, and ‘Polygon’. On the right, a map visual displays the geographic features overlaid in their correct positions, providing a clear depiction of how the data is mapped spatially.

Why PostGIS?

PostGIS extends PostgreSQL by adding support for geographic objects, enabling it to handle everything from GPS coordinates to more complex geometric shapes like polygons and lines. It is widely used in Geographic Information Systems (GIS), mapping tools, and location-based services.

For developers working with spatial data, PostGIS offers powerful features such as:

  • Storage of geometric and geographic data (points, lines, polygons, etc.)
  • Efficient spatial querying (distance calculations, bounding boxes, intersection, etc.)
  • Data export in geospatial formats like GeoJSON, Geobuf, and Mapbox Vector Tiles (MVT).

Installing the postgis NPM Package

To get started with postgis in your Node.js project, you need to install both pg (PostgreSQL client) and postgis.

To get started with pg &Postgis, you need to install the package via npm:

npm install pg postgis

Basic Usage

After installing the necessary packages, you can set up the postgis class with your PostgreSQL client to start executing queries. Below is a simple example:

const { Client } = require('pg');
const Postgis = require('postgis');

// Create PostgreSQL client
const client = new Client({
connectionString: 'your_connection_string'
});
client.connect();

// Initialize the PostGIS instance
const postgis = new Postgis(client);

// Example usage to list tables and columns
async function run() {
try {
const tables = await postgis.list_tables({ filter: 'table_type = \'BASE TABLE\'' });
console.log('Tables:', tables);
const columns = await postgis.list_columns('your_table');
console.log('Columns:', columns);
} catch (err) {
console.error('Error:', err);
} finally {
await client.end();
}
}
run();

In this example:

  • We establish a connection to the PostgreSQL database.
  • The list_tables and list_columns methods are used to retrieve metadata from the database.

Key Methods in the postgis Package

The postgis package abstracts common spatial queries and operations into easy-to-use methods. Below is a breakdown of the most important methods:

1. list_tables(options)

Lists all tables in the database with optional filtering.

const tables = await postgis.list_tables({ filter: 'table_type = \'BASE TABLE\'' });

2. list_columns(table)

Retrieves all columns from a specific table.

const columns = await postgis.list_columns('your_table');

3. query_table(table, options)

Queries a table with optional filtering, sorting, and limiting.

const features = await postgis.query_table('your_table', {
columns: 'name, geom',
filter: `"column_name" = 'value'`,
sort: 'name ASC',
limit: 50
});

4. bbox(table, options)

Computes the bounding box (extent) for geometries in a table.

const bbox = await postgis.bbox('your_table', { geom_column: 'geom', srid: 4326 });

5. centroid(table, options)

Calculates the centroid for geometries in a table.

const centroids = await postgis.centroid('your_table', { geom_column: 'geom' });

6. intersect_feature(table_from, table_to, options)

Finds intersecting features between two tables.

const intersections = await postgis.intersect_feature('table1', 'table2', { distance: '10' });

7. intersect_point(table, point, options)

Finds features in a table that intersect with a given point.

const features = await postgis.intersect_point('your_table', '1,1,4326', { distance: '5' });

8. geojson(table, options)

Converts table data to GeoJSON format.

const geojson = await postgis.geojson('your_table', { id_column: 'id' });

9. geobuf(table, options)

Converts features from a table to Geobuf format.

const geojson = await postgis.geobuf('your_table', { columns: 'name, geom' });

10. mvt(table, x, y, z, options)

Generates a Mapbox Vector Tile (MVT) for given tile coordinates.

const mvt = await postgis.mvt('your_table', 1, 2, 3, { columns: 'name, geom' });

11. nearest(table, point, options)

Finds the nearest features to a given point.

const nearest = await postgis.nearest('your_table', '1,1,4326', { limit: 5 });

12. transform_point(point, options)

Transforms a point from one spatial reference system (SRID) to another.

const transformed = await postgis.transform_point('1,1,4326', { srid: 3857 });

Example: Using GeoJSON for Mapping

A common use case is converting spatial data to GeoJSON, which can be used in web mapping libraries like Leaflet or Mapbox. Here’s how you can use the geojson method to fetch features and convert them into GeoJSON:

const geojson = await postgis.geojson('your_table', {
id_column: 'id',
precision: 6,
geom_column: 'geom',
filter: `"column_name" = 'value'`
});
console.log(JSON.stringify(geojson));
A screenshot of a Windows PowerShell terminal displaying the result of running a Node.js script that outputs GeoJSON data. The GeoJSON is of type ‘FeatureCollection’ containing a single feature with a ‘MultiPolygon’ geometry. The coordinates of the MultiPolygon are listed as an array of longitude and latitude pairs.

Error Handling

It’s important to handle errors appropriately when working with databases. The postgis package throws errors when queries fail, so make sure to wrap your code in try-catch blocks.

try {
const result = await postgis.query_table('your_table');
console.log(result);
} catch (err) {
console.error('Error:', err);
}

Conclusion

The postgis package makes it easy for Node.js developers to harness the power of PostGIS for geospatial data management. Whether you're building advanced GIS applications, performing geospatial analysis, or simply handling spatial data in your web app, this package offers a streamlined and efficient solution.

With methods to simplify common spatial queries — like finding bounding boxes, centroids, intersections, and nearest points — postgis allows developers to focus on building features, not writing complex SQL queries.

For more information, check out the NPM package page or the GitHub repository for complete documentation.

--

--

Suyog Jadhav
Suyog Jadhav

Written by Suyog Jadhav

Software Dev. Senior Analyst at Accenture. Expertise in Node.js, PHP, JavaScript, Angular. Passionate about APIs, deployment, and tackling tech challenges. 🚀

No responses yet