Geofencing with Javascript #
For this example we will use Node.js. You will need to install Node.js and NPM.
Let's create a new project folder called geofence
:
mkdir geofence
For this code example we'll need Kuzzle's Javascript SDK. To install it, run:
npm install kuzzle-sdk
We can create an index.js
file in the geofence
folder to program our test.
touch index.js
Connect to Kuzzle #
The first thing we need to do is connect to Kuzzle. To do this write the following code:
const {
Kuzzle,
WebSocket
} = require('kuzzle-sdk');
const kuzzle = new Kuzzle(new WebSocket('kuzzle'));
Replace kuzzle
with the IP address or with the name of the Kuzzle server.
Create a Geographical Boundary #
Now that we have established a connection to Kuzzle, we will perform a subscription request that tells Kuzzle that the App wants to be notified anytime a user leaves a geographical boundary.
We define the geographical boundary as follows:
const bigBen = {
lat: 51.510357,
lon: -0.116773
};
// Create a filter that defines the circular area around Big Ben
const filter = {
geoDistance: {
location: bigBen,
distance: '2km'
}
};
This defines a circular boundary centered around Big Ben with a radius of 2km. For more information about the geoDistance
filter click here.
Note that we use the field name location
to store the geopoint we are centered around. This means that Kuzzle will monitor the field named location
for position changes, and so any user location document sent to Kuzzle must also contain this field.
Now the App must request a subscription to the geographical boundary defined in our JSONObject. To ensure that the App only receives a message when the location
changes from inside the boundary to outside the boundary, we need to set the subscription scope to out
, for more scope options click here.
Let's use the subscribe method :
const filter = {exists: {field: 'message'}};
const callback = notification => {
console.log(notification.result._source.message);
};
try {
await kuzzle.realtime.subscribe(
'myindex',
'mycollection',
filter,
callback
);
console.log('subscribe ok');
} catch (error) {
console.error(error.message);
}
We have now programmed the subscription side of the test.
Place the User Inside the Geographical Boundary #
Now let's move on to the publish side of the test. Here we will create a document that represents the user's location, placed inside the circular boundary around Big Ben.
We will use the create method that creates a document containing three fields: firstName
, lastName
and location
.
Let's start by creating the user Ada Lovelace located at Big Ben. Create the Document object as follows:
const bigBen = {
lat: 51.510357,
lon: -0.116773
};
// Create the user's location: they are inside the circular area
const currentLocation = {
firstName: 'Ada',
lastName: 'Lovelace',
location: bigBen
};
Now we create this document in Kuzzle.
const bigBen = {
lat: 51.510357,
lon: -0.116773
};
const filter = {
geoDistance: {
location: bigBen,
distance: '2km'
}
};
const currentLocation = {
firstName: 'Ada',
lastName: 'Lovelace',
location: bigBen
};
try {
// Create the user's location inside the circular area
await kuzzle.document.create(
'myindex',
'mycollection',
currentLocation,
'ada_lovelace'
);
console.log('document created');
} catch (error) {
console.error(error.message);
}
Notice that we have included a document id, this is so that we can easily reference the document later on. We can also leave the id empty and Kuzzle will generate one automatically.
Place the User Outside the Geographical Boundary #
If the document creation is successful we can go ahead and update it to change the user's location to somewhere outside the geographical boundary. Let's move the user to Hyde Park. Since this is an update we need to do it after the first location document is created.
const bigBen = {
lat: 51.510357,
lon: -0.116773
};
const currentLocation = {
firstName: 'Ada',
lastName: 'Lovelace',
location: bigBen
};
const hydePark = {
lat: 11.507268,
lon: -0.165730
};
const newLocation = {location: hydePark};
try {
await kuzzle.document.create(
'myindex',
'mycollection',
currentLocation,
'ada_lovelace'
);
// Update the user's location: now they are outside the circular area
await kuzzle.document.update(
'myindex',
'mycollection',
'ada_lovelace',
newLocation
);
console.log('document updated');
} catch (error) {
console.error(error.message);
}
When the document update request is sent to Kuzzle, it will detect the change in location and send a message to the subscriber, which in this case is our App.
Run the Test #
The full code should look something like this:
const {
Kuzzle,
WebSocket
} = require('kuzzle-sdk');
const kuzzle = new Kuzzle(new WebSocket('kuzzle'));
const bigBen = {
lat: 51.510357,
lon: -0.116773
};
// Create a filter that defines the circular area around Big Ben
const filter = {
geoDistance: {
location: bigBen,
distance: '2km'
}
};
// Create the user's location: they are inside the circular area
const currentLocation = {
firstName: 'Ada',
lastName: 'Lovelace',
location: bigBen
};
const hydePark = {
lat: 11.507268,
lon: -0.165730
};
const newLocation = {location: hydePark};
const run = async () => {
const callback = notification => {
if (notification.scope === 'out') {
console.log('User has left Big Ben');
kuzzle.disconnect();
}
};
try {
await kuzzle.connect();
/* Create a subscription that triggers a notification
when a user enters the circular area */
await kuzzle.realtime.subscribe(
'myindex',
'mycollection',
filter,
callback
);
// Create the user's location inside the circular area
await kuzzle.document.create(
'myindex',
'mycollection',
currentLocation,
'ada_lovelace'
);
// Update the user's location: now they are outside the circular area
await kuzzle.document.update(
'myindex',
'mycollection',
'ada_lovelace',
newLocation
);
} catch (error) {
console.error(error.message);
}
};
run();
Your console should output the following message:
User has entered Big Ben