Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 653
AndreaM16 Avatar asked Aug 11 '16 09:08

AndreaM16


1 Answers

You are passing linestring.geo.coordinates in latitute,longitute format to the final query. Mongodb accepts coordinates in the x,y format, hence it has to be longitude,latitude

Updated:

You will need to directly pass the linestring as $geometry.

query = linestrings.where({ geo : { $geoIntersects : 
                   { 
                       $geometry : lineStringbyId.

                    } } });
like image 65
DhruvPathak Avatar answered Oct 20 '22 18:10

DhruvPathak