# Location Geofencing with MongoDB, Stitch, and Mapbox

>
>
>Please note: This article discusses Stitch. Stitch is now MongoDB Realm.
>All the same features and functionality, now with a new name. Learn more
>here. We will be updating this article
>in due course.
>
>

For a lot of organizations, when it comes to location, geofencing is
often a very desirable or required feature. In case you're unfamiliar, a
geofence can be thought of as a virtual perimeter for a geographic area.
Often, you'll want to know when something enters or exits that geofence
so that you can apply your own business logic. Such logic might include
sending a notification or updating something in your database.

MongoDB supports GeoJSON data and offers quite a few operators that make
working the location data easy.

When it comes to geofencing, why would you want to use a database like
MongoDB rather than defining boundaries directly within your
client-facing application? Sure, it might be easy to define and manage
one or two boundaries, but when you're working at scale, checking to see
if something has exited or entered one of many boundaries could be a
hassle.

In this tutorial, we're going to explore the
$near
and
$geoIntersects
operators within MongoDB to define geofences and see if we're within the
fences. For the visual aspect of things, we're going to make use of
Mapbox for showing our geofences and our
location.

To get an idea of what we're going to build, take a look at the
following animated image:

We're going to implement functionality where a map is displayed and
polygon shapes are rendered based on data from within MongoDB. When we
move the marker around on the map to simulate actual changes in
location, we're going to determine whether or not we've entered or
exited a geofence.

## The Requirements

There are a few moving pieces for this particular tutorial, so it is
important that the prerequisites are met prior to starting:

-   Must have a Mapbox account with an access token generated.
-   Must have a MongoDB Atlas cluster available.

Mapbox is a service, not affiliated with MongoDB. To render a map along
with shapes and markers, an account is necessary. For this example,
everything can be accomplished within the Mapbox free tier.

Because we'll be using MongoDB Stitch in connection with Mapbox, we'll
need to be using MongoDB Atlas.

>
>
>MongoDB Atlas can be used to deploy an M0
>sized cluster of MongoDB for FREE.
>
>

The MongoDB Atlas cluster should have a **location_services** database
with a **geofences** collection.

## Understanding the GeoJSON Data to Represent Fenced Regions

To use the geospatial functionality that MongoDB offers, the data stored
within MongoDB must be valid GeoJSON data. At the end of the day,
GeoJSON is still JSON, which plays very nicely with MongoDB, but there
is a specific schema that must be followed. To learn more about GeoJSON,
visit the specification documentation.

For our example, we're going to be working with Polygon and Point data.
Take the following document model:

``` json
{
    "_id": ObjectId(),
    "name": string,
    "region": {
        "type": string,
        "coordinates": 
            [
                [double]
            ]
        ]
    }
}
```

In the above example, the `region` represents our GeoJSON data and
everything above it such as `name` represents any additional data that
we want to store for the particular document. A realistic example to the
above model might look something like this:

``` json
{
    "_id": ObjectId("5ebdc11ab96302736c790694"),
    "name": "tracy",
    "region": {
        "type": "Polygon",
        "coordinates": [
            [
                [-121.56115581054638, 37.73644193427164],
                [-121.33868266601519, 37.59729761382843],
                [-121.31671000976553, 37.777700170855454],
                [-121.56115581054638, 37.73644193427164]
            ]
        ]
    }
}
```

We're naming any of our possible fenced regions. This could be useful to
a lot of organizations. For example, maybe you're a business with
several franchise locations. You could geofence the location and name it
something like the address, store number, etc.

To get the performance we need from our geospatial data and to be able
to use certain operators, we're going to need to create an index on our
collection. The index looks something like the following:

``` javascript
db.geofences.createIndex({ region: "2dsphere" })
```

The index can be created through Atlas, Compass, and with the CLI. The
goal here is to make sure the `region` field is a `2dsphere` index.

## Configuring MongoDB Stitch for Client-Facing Application Interactions

Rather than creating a backend application to interact with the
database, we're going to make use of MongoDB Stitch. Essentially, the
client-facing application will use the Stitch SDK to authenticate before
interacting with the data.

Within the [MongoDB Cloud, choose to create
a new Stitch application if you don't already have one that you wish to
use. Make sure that the application is using the cluster that has your
geofencing data.

Within the Stitch dashboard, choose the **Rules** tab and create a new
set of permissions for the **geofences** collection. For this particular
example, the **Users can only read all data** permission template is
fine.

Next, we'll want to choose an authentication mechanism. In the **Users**
tab, choose **Providers**, and enable the anonymous authentication
provider. In a more realistic production scenario, you'll likely want to
create geofences that have stricter users and rules design.

Before moving onto actually creating an application, make note of your
**App ID** within Stitch, as it will be necessary for connecting.

## Interacting with the Geofences using Mapbox and MongoDB Geospatial Queries

With all the configuration out of the way, we can move into the fun part
of creating an attractive client-facing application that queries the
geospatial data in MongoDB and renders it on a map.

On your computer, create an **index.html** file with the following
boilerplate code:

``` xml

    
    
    

    
        
        
    

```

In the above HTML, we're importing the Mapbox and MongoDB Stitch SDKs,
and we are defining an HTML container to hold our interactive map.
Interacting with MongoDB and the map will be done in the `