API with NestJS #183. Distance and radius in PostgreSQL with Drizzle ORM

NestJS SQL

This entry is part 183 of 186 in the API with NestJS

PostgreSQL provides many options for working with geographical data, especially with the PostGIS extension. In this article, we’ll explore how to calculate the distance between two coordinates and how to identify locations within a specific radius.

If you want to check out the basics of storing coordinates in PostgreSQL with the Drizzle ORM, check out API with NestJS #182. Storing coordinates in PostgreSQL with Drizzle ORM

Spatial Reference System Identifier

We will use a straightforward database schema that contains a table with locations.

database-schema.ts

Above, we specify the Spatial Reference System Identifier (SRID). This number tells PostGIS how to interpret the coordinates. It specifies one of several coordinate systems used to represent the data.

  • In SRID 4326, the coordinates are defined in latitude and longitude.
  • In SRID 3857, the coordinates are specified in meters on a flat map.

If two sets of coordinates use different SRIDs, they are based on different systems and won’t line up correctly. For example, comparing latitude/longitude directly to flat map coordinates will give incorrect results.

The default SRID in PostGIS is 0, which means the data has no defined coordinate system. It’s good practice to define the SRID for our data explicitly.

Let’s create the SQL migration to add our table to the database.

If you want to know more about migrations with the Drizzle ORM, check out API with NestJS #176. Database migrations with the Drizzle ORM

database-schema.ts

Unfortunately, right now, Drizzle ORM has a bug that causes it to ignore the provided SRID. To deal with that, we have to adjust our migration manually. Let’s also add a line ensuring the PostGIS extension is set up.

database-schema.ts

Calculating the distance between two points

Let’s insert a few locations into our database:

  • Empire State Building in New York
  • Santa Monica Pier in the Los Angeles County
  • Times Square in New York

Let’s calculate the distance between the Empire State Building and the Santa Monica Pier. To do that, we can use the function built into PostgreSQL.

The result is roughly 3960 kilometers (about 2460 miles). What’s crucial is that the function takes into account that Earth is a sphere. To use it with the Drizzle ORM, we need to provide the raw SQL.

locations.service.ts

The Earth is not a perfect sphere

What’s interesting is that assumes that Earth is a perfect sphere. However, this is not the case. To be more precise, we can use the function, which accounts for Earth’s ellipsoidal shape.

By providing we specify the Earth’s shape, using the WGS84 model.

The above query results in roughly 3969 kilometers (about 2466 miles). It is 9 kilometers more than the function returned. If we want to calculate big distances, taking the Earth’s shape into account can give us more precise results.

Getting locations in a certain radius

Another very useful feature is finding locations in a certain radius. To do that, we need to use the function built into PostGIS.

So far, we’ve been using the data type built into PostGIS that treats Earth as a flat 2D plane. However, when combined with functions such as , which we used above, it can calculate distances on a spherical Earth.

Alternatively, PostGIS implements the data type, which automatically accounts for the Earth’s ellipsoidal shape. Unfortunately, the Drizzle ORM does not currently support this type of data. To use the function, we need to convert our data to on the fly.

Above, we find all the locations in a 5-kilometer radius of the Empire State Building in New York.

We can exclude the Empire State Building from our results to receive more meaningful results.

To use with the Drizzle ORM, we need to incorporate raw SQL into our code. Drizzle ORM handles most of the query, while the raw SQL is only used partly in the  clause.

locations.service.ts

Summary

In this article, we learned how to use PostGIS with the Drizzle ORM to calculate the distance between two coordinates and find all locations within a certain radius.

PostgreSQL offers many functionalities for various coordinate calculations thanks to the PostGIS extension. While the integration with Drizzle ORM isn’t perfect, we can work around most problems to get the job done. Assuming that the Drizzle team continues to improve the ORM, it has the potential to become a solid choice for handling spatial data.

Series Navigation<< API with NestJS #182. Storing coordinates in PostgreSQL with Drizzle ORMAPI with NestJS #184. Storing PostGIS Polygons in PostgreSQL with Drizzle ORM >>
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments