AndreaM16 AndreaM16 - 3 months ago 14
Node.js Question

MEAN & Geospatial queries - Find LineStrings Intersecting on Another One given Its Name

I'm trying to build an application using MEAN but now I'm stuck when trying to

find linestrings intersecting on another one given its name
.

For instance, given the following image,
poly1
and
poly2
should have intersections while
poly3
does not.

enter image description here

Let's suppose
poly1
has the following coordinates and the following
JSON
:

{
"_id" : ObjectId("57ab2107505ab11b1bd8422e"),
"name" : "poly1",
"updated_at" : ISODate("2016-08-10T12:41:43.789+0000"),
"created_at" : ISODate("2016-08-10T12:41:43.780+0000"),
"geo" : {
"coordinates" : [ [14.59, 24.847], [28.477, 15.961] ],
"type" : "LineString"
},
"__v" : NumberInt(0)
}


When I run the query on
MongoChef
I find both
poly1
and
poly2
and I do not find
poly3
like I want:

{
geo :{
$geoIntersects:{
$geometry :{
type: "LineString" ,
coordinates: [ [14.59, 24.847], [28.477, 15.961] ]
}
}
}
}


While, when I run the query on
Mongoose
given a
Polyline Id/name
it does not work

//Given
var linestringById = Linestrings.find({name : lineName});
var linestrings = Linestrings.find({});

//Works
query = linestrings.where({ geo : { $geoIntersects :
{ $geometry :
{ type : 'LineString',
coordinates : [ [27.528, 25.006], [14.063, 15.591] ]
}
} } });

//Does not work
query = linestrings.where({ geo : { $geoIntersects :
{ $geometry :
{ type : 'LineString',
coordinates : linestringById.geo.coordinates
}
} } });
//Also does not work:
query = linestrings.where({ geo : { $geoIntersects :
{ $geometry :
{ type : 'LineString',
coordinates : linestringById
}
} } });


This is the Schema for LineStrings:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// Creates a LineString Schema.
var linestrings = new Schema({
name: {type: String, required : true},
geo : {
type : {type: String, default: "LineString"},
coordinates : Array
},
created_at: {type: Date, default: Date.now},
updated_at: {type: Date, default: Date.now}
});

// Sets the created_at parameter equal to the current time
linestrings.pre('save', function(next){
now = new Date();
this.updated_at = now;
if(!this.created_at) {
this.created_at = now
}
next();
});

linestrings.index({geo : '2dsphere'});
module.exports = mongoose.model('linestrings', linestrings);


This is how I call the query from the front-end QueryController.js

/** Looks for LineStrings intersecting a given linestring **/
vm.polyIntersect = function () {

//Taking name from a form
vm.queryBody = {
name : vm.formData.poly1
};

// Post the queryBody
$http.post('/find-poly-intersection', vm.queryBody)
.success(function(queryResults) {
console.log(queryResults);
})
.error(function(queryResults) {
console.log('Error: no results found '+queryResults));
});
};


This is my Route.js:

/** Requiring Factories **/
var LinestringFactory = require('./factories/linestring.factory.js');

module.exports = function(app) {
// Retrieves JSON records for all linestrings intersecting a given one
app.post('/find-poly-intersection', function(req, res) {
LinestringFactory.findIntersections(req).then( function (linestrings) {
return res.json(linestrings);
}, function (error) {
return res.json(error);
})
});
}


This is my LineString.factory.js:

var Linestrings = require('../models/linestring-model.js');

exports.findIntersections = findIntersections;

/** Finds Linestrings Intersections **/
function findIntersections(req) {
return new Promise( function (resolve, reject) {
var lineName = req.body.name;
var linestringById = Linestrings.find({name : lineName});
var linestrings = Linestrings.find({});

//Check if that certain linestring exists with Lodash
if (_.isEmpty(linestringById) || _.isUndefined(linestringById)
|| _.isNull(linestringById)){
return reject('No Linestrings found for that Name');
} else {

query = linestrings.where({ geo :
{ $geoIntersects : { $geometry :
{ type : 'LineString',
coordinates : linestringById.geo.coordinates}
} } });

query.exec(function (err, intersections) {
if (err){
return reject(err);
}
return resolve(intersections);
});

}, function (error) {
return reject(error);
})
}



console.log
in
QueryController
gives me always
Object {}
for any
linestring name.

This is the Mongoose Log of the query.

I'm making sure of inserting
[lng, lat]
coordinates


Have you any idea on why I can't find any LineString intersecting by Id while I can find them using straight coordinates?

Thanks in advance.

Answer

I finally managed to solve this issue with the following code

/** Finds Linestrings Intersections **/
function findIntersections(req) {
    return new Promise( function (resolve, reject) {
        var lineName = req.body.name;
        Linestrings.findOne({name : lineName}).then( function (linestringById, error) {
            if(error){
                return reject({error : 'LineString not Found'});
            }
                queryIntersections(linestringById).then( function (response) {
                    return resolve(response);
                });
        });
    }, function (error) {
        return reject({error : 'Error while executing promise'});
    });
}

function queryIntersections(linestringById) {
    return new Promise( function (resolve, reject) {
        if (_.isEmpty(linestringById) || _.isUndefined(linestringById) || _.isNull(linestringById)){
            return reject({ error : 'No Linestrings found for that Name'});
        } else {
            query = Linestrings.where( { geo : { $geoIntersects : { $geometry : { type: 'LineString', coordinates: linestringById.geo.coordinates  } } } } );
            queryExec(query).then( function (intersections) {
                return resolve(intersections);
            });
        }
    }, function (error){
       return reject({error : 'Error while executing promise'});
    });
}

The error was caused by the fact that I did not pass correctly linestrings and linestringById objects to the query.

I hope it will help someone.

Comments