简体   繁体   中英

How to check if a vehicle entered into geofence or not using geospatial data in NodeJS using mongodb and mongoose?

I've been working on creating geo fences and alerting systems using Node.JS, mongoDB and mongoose framwork.

I've a vehicle with a sensor, which keep on sending the coordinates it travelling through. Now, I need to check whether that vehicle entered into the geofence I've created before.

If the vehicle entered into the fence, I need to send an alert to the admin of the system.

But I got confused on how to check whether the vehicle entered into fence or not using the coordinates provided by the vehicle itself and the fence's coordinates.

Below is the code I've used so far.

Geofences.js Model

const mongoose = require('mongoose');

const FenceSchema = mongoose.Schema({
    fenceId      : {type: String, unique: true, required: false},
    fenceName    : {type: String, required: true},
    geoData      : {type: Object, required: false},
    description  : {type: String, required: false},
    status       : {type: Boolean, required: false, default: true}
},{
    versionKey: false,
    timestamps: true
});

FenceSchema.index({ "geoData": "2dsphere" });

module.exports = mongoose.model("geofences", FenceSchema);

Sample Data For FenceAlerts.js

{
    "_id" : ObjectId("5ef9b89334b4f12f74dd60a1"),
    "fenceName" : "Ram Nagar",
    "description" : "Should alert the admin when anyone enters or leaves through Ram Nagar",
    "geoData" : {
        "coordinates" : [ 
            [ 
                [ 
                    78.4521996974945, 
                    17.4258916749477
                ], 
                [ 
                    78.4533584117889, 
                    17.4262294770614
                ], 
                [ 
                    78.4534442424774, 
                    17.4267617700325
                ], 
                [ 
                    78.4533584117889, 
                    17.4273657159469
                ], 
                [ 
                    78.4528541564941, 
                    17.4279389508985
                ], 
                [ 
                    78.4519529342651, 
                    17.4280822593551
                ], 
                [ 
                    78.4514486789703, 
                    17.4277854059987
                ], 
                [ 
                    78.4511590003967, 
                    17.4269357885517
                ], 
                [ 
                    78.451384305954, 
                    17.4262806591452
                ], 
                [ 
                    78.4521996974945, 
                    17.4258916749477
                ]
            ]
        ],
        "type" : "Polygon"
    }
}

FenceAlerts.js Model

const mongoose = require('mongoose');

const AlertSchema = mongoose.Schema({
    deviceId   : {type: mongoose.Schema.Types.ObjectId, ref: 'templates.devices', required: true},
    fenceId    : {type: mongoose.Schema.Types.ObjectId, ref: 'geofences', required: true},
    status     : {type: Boolean, required: true, default: true},
    alertRule  : {type: String, required: true},
    notifyType : {type: String, enum: ['WARNING','DANGER','EMERGENCY'], defualt: "WARNING"}
},{
    versionKey: false,
    timestamps: true
});

module.exports = mongoose.model("fenceAlerts", AlertSchema);

Sample Data For FenceAlerts.js

{
    "_id" : ObjectId("5efb0082260fca32e8b08bfe"),
    "deviceId" : ObjectId("5ef9f8ffc667822e84ecec9e"), //DeviceName: "VEH-1"
    "fenceId" : ObjectId("5ef9b89334b4f12f74dd60a1"),
    "alertRule" : "Incoming",
    "status" : true,
    "notifyType" : "EMERGENCY"
}

Coordinates being sent by the Vehicle

{
    "_id" : ObjectId("5efb3bcd829b9310c83091de"),
    "latitude" : 40.25,
    "longitude" : 20.69,
    "deviceId" : "VEH-1",
    "entryDayTime" : ISODate("2020-06-30T13:19:09.989Z")
},
{
    "_id" : ObjectId("5efb3bf5fc418a182c76d520"),
    "latitude" : 42.25,
    "longitude" : 21.69,
    "deviceId" : "VEH-1",
    "entryDayTime" : ISODate("2020-06-30T13:19:49.045Z")
},
{
    "_id" : ObjectId("5efb3dd028b6e533a071707e"),
    "latitude" : 52.25,
    "longitude" : 31.69,
    "deviceId" : "VEH-1",
    "entryDayTime" : ISODate("2020-06-30T13:27:44.200Z")
},
{
    "_id" : ObjectId("5efb3e06a78a9538b4c5b8a8"),
    "latitude" : 22.25,
    "longitude" : 15.69,
    "deviceId" : "VEH-1",
    "entryDayTime" : ISODate("2020-06-30T13:28:38.431Z")
},
{
    "_id" : ObjectId("5efb3e4b3e598f386cf88357"),
    "latitude" : 20.25,
    "longitude" : 18.69,
    "deviceId" : "VEH-1",
    "entryDayTime" : ISODate("2020-06-30T13:29:47.391Z")
},
{
    "_id" : ObjectId("5efb46267a00ce41fc466bbe"),
    "latitude" : 80.25,
    "longitude" : 18.69,
    "deviceId" : "VEH-1",
    "entryDayTime" : ISODate("2020-06-30T14:03:18.579Z")
},
{
    "_id" : ObjectId("5efb4670ceeab33c48973d86"),
    "latitude" : 90.25,
    "longitude" : 48.69,
    "deviceId" : "VEH-1",
    "entryDayTime" : ISODate("2020-06-30T14:04:32.951Z")
}

I've been using RabbitMQ and MQTT for continuous transmission of data. So with the every payload being sent by the vehicle, I need to check whether the vehicle is inside the fence or not.

But the actual problem is, how to compare the device location with the fence coordinates?

I've seen $geoWithin but couldn't understand on how to implement in my case. Is there anyway to compare them and return the string like, VEHICLE ENTERED THE FENCE and VEHICLE LEFT THE FENCE ?

Came across this post while researching a solution for a similar requirement. So, not a complete answer but a line of investigation.

MongoDB supports Change Streams, a mechanism to set a watch on a collection, database, or cluster. An aggregation query is configured to report only on changes that meet certain criteria. It avoids having to receive a continuous stream of data on which to perform condition checking.

As noted, there is a query $geoWithin. Therefore, when the vehicle is within the geofence, the condition would be true.

It's possible that a change from true to false, and obviously false to true, could be used to track exit or entry. Query syntax would need to be developed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM