An Immersive Guide to Geospatial MongoDB Data

Dealing with coordinates can be a huge pain, so why not take the easy way? Instead of wrestling with coordinates in the frontend, push it away to the backend and let mongoDB do the work. Today, we’ll look at dealing with geospatial data in mongoDB or m…

Dealing with coordinates can be a huge pain, so why not take the easy way? Instead of wrestling with coordinates in the frontend, push it away to the backend and let mongoDB do the work. Today, we’ll look at dealing with geospatial data in mongoDB or mongoose. First on our list is GeoJSON.



GeoJSON

It has various data types to make dealing with coordinates easy. Keep in mind that longitude comes before latitude:



1) Point

The simplest of all types, it’s basically a coordinate i.e. a longitude and a latitude:

An image of a point

// A point
{ type: "Point", coordinates: [ 40, 5 ] }


2) LineString

It’s an array of array of coordinates, which will be joined to form a line. It basically consists of an array of points.

An image of linestring

// A linestring
{ type: "LineString", coordinates: [ [ 40, 5 ], [ 41, 6 ] ] }


3) Polygon

It’s a polygon, that’s it! squares, rectangles, hexagons, decagons, quadrilaterals so on. This must be a closed figure(the first point must be the same as the last point, I’m sounding like my maths teacher now ?).

We draw the sides of the polygon using linestrings. Now, to illustrate this better, I’m going to draw a very very simple coordinate grid(don’t worry, nothing complicated).

Screenshot 2021-05-07 at 12.40.50

(I apologize on behalf of my bad designing skills for that crude grid)

Now, let’s draw a simple polygon:

Screenshot 2021-05-07 at 12.45.15

Here’s how we can represent this in code:

{
  type : "Polygon",
  coordinates : [
     [ [ 1 , 2 ] , [ 4 , 4 ] , [ 6 , 3 ] , [ 5 , 1 ], [1, 2] ],
  ]
}

There are a few to notice in this:

  • The nested arrays go 3 levels deep, I’ll get back to this in a minute

  • In the diagram, there are only 4 points but we have written 5 points in our code. This is because the first point and last point overlap in the diagram so it’s not visible. To make this a closed figure and a valid Polygon, we need to specify the last value the same as the first value to tell mongoDB that the figure has ended.

As I promised earlier, I’m going to explain the secret of the nested arrays:

  • The first array holds all the rings(I’ll explain this in a second).

  • The second one holds each ring. Now, what are rings? It’s basically a hole inside the polygon. So, the figure holds the area between the polygons. Here’s a diagram:

Screenshot 2021-05-07 at 12.55.45

The white triangle inside is a ring. The figure contains the area inside the outer polygon but outside the white area( the area shaded in red is contained).

  • Finally, the 3rd array is our old friend, the array of coordinates.

The code for this polygon would look like this:

{
  type : "Polygon",
  coordinates : [
     [ [ 1 , 2 ] , [ 4 , 4 ] , [ 6 , 3 ] , [ 5 , 1 ], [1, 2] ],
     [ [ 3 , 2 ] , [ 5 , 3 ] , [ 4 , 2 ] , [ 3 , 2 ] ],
  ]
}

That was a long (and hopefully not boring) maths lesson. Let’s actually play around with these types and learn about more operators.



$geometry

It holds our geometrical data type (eg: Point, Polygon) and is used in tandem with other operators.

{
  $geometry: {
    type : "Polygon",
    coordinates : [
     [ [ 1 , 2 ] , [ 4 , 4 ] , [ 6 , 3 ] , [ 5 , 1 ], [1, 2] 
    ]
  }
}



$geoIntersects

It checks if the coordinates in a document are intersecting(not necessarily completely inside) the provided geometrical type(It has to be a 2d type i.e. Polygon).


Places.find(
   {
     location: {
       $geoIntersects: {
            $geometry: {
              type : "Polygon",
            coordinates : [
               [ 
                  [ 1 , 2 ] , [ 4 , 4 ] , [ 6 , 3 ] , [ 5 , 1 ], [1, 2] 
               ]
            ]
         }
       }
     }
   }
)



$geoWithin

Checks if the coordinates in a document are completely inside the provided Polygon(single/multi ringed).


Places.find(
   {
     location: {
       $geoWithin: {
            $geometry: {
              type : "Polygon",
            coordinates : [
               [ 
                  [ 1 , 2 ] , [ 4 , 4 ] , [ 6 , 3 ] , [ 5 , 1 ], [1, 2] 
               ]
            ]
         }
       }
     }
   }
)

If you want to do the same thing, but in a circle(i.e. in a particular radius from the coordinates) we use $center. It takes in an array which has two elements. The first is the coordinates for the center and the second is the radius. The format is [[coordinateX, coordinateY], radius]

Places.find(
  {
    location: { $geoWithin: { $center: [ [-74, 40.74], 10 ] }  
  }
);



$near

Fetches all documents which are have a certain distance from a specified coordinate which can be controlled using minimum and maximum lengths. Also, it will sort the documents from nearest to farthest.

Places.find(
   {
     location:
       { $near :
          {
            $geometry: {
              type: "Point",
              coordinates: [ -68, 35 ] 
            },
          }
       }
   }
)

We can optionally specify a $minDistance and $maxDistance.

Places.find(
   {
     location:
       { $near :
          {
            $geometry: {
              type: "Point",
              coordinates: [ -68, 35 ],
              $minDistance: 500,
              $maxDistance: 2000
            },
          }
       }
   }
)



Conclusion

You might be thinking, how is this useful? Well,
Suppose our user is looking for restaurants near him, we can provide all restaurants in a 10 mile radius.

Thanks for reading until here. If you liked the article and learn something today, don’t forget to leave a like and follow me on dev.to!


Print Share Comment Cite Upload Translate
APA
Akash Shyam | Sciencx (2024-03-28T18:07:59+00:00) » An Immersive Guide to Geospatial MongoDB Data. Retrieved from https://www.scien.cx/2021/05/07/an-immersive-guide-to-geospatial-mongodb-data/.
MLA
" » An Immersive Guide to Geospatial MongoDB Data." Akash Shyam | Sciencx - Friday May 7, 2021, https://www.scien.cx/2021/05/07/an-immersive-guide-to-geospatial-mongodb-data/
HARVARD
Akash Shyam | Sciencx Friday May 7, 2021 » An Immersive Guide to Geospatial MongoDB Data., viewed 2024-03-28T18:07:59+00:00,<https://www.scien.cx/2021/05/07/an-immersive-guide-to-geospatial-mongodb-data/>
VANCOUVER
Akash Shyam | Sciencx - » An Immersive Guide to Geospatial MongoDB Data. [Internet]. [Accessed 2024-03-28T18:07:59+00:00]. Available from: https://www.scien.cx/2021/05/07/an-immersive-guide-to-geospatial-mongodb-data/
CHICAGO
" » An Immersive Guide to Geospatial MongoDB Data." Akash Shyam | Sciencx - Accessed 2024-03-28T18:07:59+00:00. https://www.scien.cx/2021/05/07/an-immersive-guide-to-geospatial-mongodb-data/
IEEE
" » An Immersive Guide to Geospatial MongoDB Data." Akash Shyam | Sciencx [Online]. Available: https://www.scien.cx/2021/05/07/an-immersive-guide-to-geospatial-mongodb-data/. [Accessed: 2024-03-28T18:07:59+00:00]
rf:citation
» An Immersive Guide to Geospatial MongoDB Data | Akash Shyam | Sciencx | https://www.scien.cx/2021/05/07/an-immersive-guide-to-geospatial-mongodb-data/ | 2024-03-28T18:07:59+00:00
https://github.com/addpipe/simple-recorderjs-demo