Filter locations in an area of X km

Asked

Viewed 546 times

13

I am trying to set up a small project where I have a list of locations and can filter them according to a x km amount. Ex: Filter all places within a 5km radius of my current location.

I have a Json with some places in my city and when I try to make a 2km filter the Json returns blank, but if I step 50km as parameter all data is returned. I am not able to identify where I am missing.

Follows excerpt from the code:

var mongoose = require('mongoose');
var Location = mongoose.model('Location');

// create an export function to encapsulate the controller's methods
module.exports = {
  index: function(req, res, next) {
    res.json(200, {
      status: 'Location API is running.',
    });
  },
  findLocation: function(req, res, next) {
    var limit = req.query.limit || 10;

    // get the max distance or set it to 8 kilometers
    var maxDistance = req.query.distance || 8;

    // we need to convert the distance to radians
    // the raduis of Earth is approximately 6371 kilometers
    maxDistance /= 6371;

    // get coordinates [ <longitude> , <latitude> ]
    var coords = [];
    coords[0] = req.query.longitude || 0;
    coords[1] = req.query.latitude || 0;

    // find a location
    Location.find({
      loc: {
        $near: coords,
        $maxDistance: maxDistance
      }
    }).limit(limit).exec(function(err, locations) {
      if (err) {
        return res.json(500, err);
      }
      res.json(200, locations);
    });
  }
};

That’s the Json that I’m using:

[
  {
    "name": "Igreja Matriz",
    "loc": [
      -49.974762,
      -23.160631

    ]
  },
  {
    "name": "Prefeitura Jacarezinho",
    "loc": [
      -49.973597,
      -23.159745
    ]
  },
  {
    "name": "Lotérica",
    "loc": [
      -49.980461,
      -23.164231
    ]
  }
]

I pass the parameters by QueryString thus: http://localhost:3000/api/locations?longitude=-49.978440&latitude=-23.169557&distance=2

Console and result: inserir a descrição da imagem aqui

How I get the desired result?

  • That one maxDistance /= 6371 is not a resquicio of formula Haversine? Because in mongodb you will not use radians

  • Did you set the coordinates to index your Collection? If so, what type of index did you use? Make sure you use the getIndexes() method in your seat collection on the Mongo console

  • @Lfziron I don’t know if it’s the index I’m thinking of, but if it is 2d.

  • @user1576978 I’m dividing by 111.12 now, I got more precision, but I have a margin of error of about 100 meters

  • 1

    @Techies this error is acceptable depending on the scale on which you are working and the geographical coordinate system. If you want greater precision, you should work with the UTM projection system. That way the reported radius will actually be in meters.

  • @Marcellobenigno understood, so this margin of error is normal the way my project is?

  • @Techies is yes!

  • @Marcellobenigno if you want to elaborate a question to explain about I will mark it as correct.

Show 3 more comments

1 answer

5


The error in question is acceptable in view of the working scale and the reference system used. An alternative to increase the accuracy of the radius, if its study area fits in a spindle, would be to use the UTM projection system. That way the reported lightning will actually be in meters.

You can also use a geographic database, such as Postgresql/Postgis, which solves this type of situation easily. Your query would work as follows:

-- para um raio de 50 km = 50.000 m:
SELECT ST_Buffer(geom::geography,50000) AS geom
FROM nome_tabela
WHERE condicao;

I’ll give you some links on the subject:

Postgis - Geometry or Geography find points Within Distance in meters

Postgis: extraction of measurements in tables with geographical coordinates

Postgis - When to use Geography Data type over Geometry data type

I hope I’ve cooperated :)

  • Works only for Postgresql. Know something in PHP, with Mysql?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.