Mongo $ geoWithin Radians

时间:2014-09-18 06:05:32

标签: mongodb geospatial

努力计算圆的弧度使用mongoose / mongodb geoWithin查询。我有用户的位置,我的结果离该用户最远。从这两点我需要计算弧度,这样我就可以围绕该用户进行整圈搜索,从而达到最远的结果。希望这是有道理的。 :)

    //get closest item to user (just because)
    var closestLon = vendorPosts[0].location.long;
    var closestLat = vendorPosts[0].location.lat;

    //get furthest item from user
    var furthestLon = vendorPosts[vendorPosts.length - 1].location.long;
    var furthestLat = vendorPosts[vendorPosts.length - 1].location.lat;

    //User is located here
    var userLat = req.query.lat;
    var userLon = req.query.long;

    //Number of kilometers furthest item is from user
    var maxDistanceKm = getDistanceFromLatLonInKm(userLat, userLon, furthestLat, furthestLon);

    //Attempting to convert to rads but results never appear, is this correct calculation?
    var maxDistanceRadians = maxDistanceKm/6371;

    Model.find({
        $text: { $search: searchterm, $language: 'english' },
        coordinates :
             { $geoWithin :
                 {
                     $center : [ [ userLon, userLat ] , maxDistanceRadians ]
                 }
             }
        } , { score: {
                $meta: "textScore"
            }
        }, function (err, results) {
            ....
        });

使用这些着名的hasrsine formula / utils

    function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
        var R = 6371; // Radius of the earth in miles
        var dLat = deg2rad(lat2-lat1);  // deg2rad below
        var dLon = deg2rad(lon2-lon1);
        var a =
              Math.sin(dLat/2) * Math.sin(dLat/2) +
              Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
              Math.sin(dLon/2) * Math.sin(dLon/2)
            ;
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        var d = R * c; // Distance in km
        return d;
    }

    function deg2rad(deg) {
        return deg * (Math.PI/180)
    }

1 个答案:

答案 0 :(得分:0)

看起来我的答案过于复杂。我已经有一个圆圈的中心点(用户位置),我已经有了离用户最远的项目。从这两点我需要计算半径并插入mongo。

    var furthestitem = vendorPosts[vendorPosts.length - 1];

    var radius = Math.sqrt( Math.pow((userLat-furthestitem.location.lat), 2) + Math.pow((userLong-furthestitem.location.long), 2) )

    PostModel.find({
        $text: { $search: heading, $language: 'english' },
        $or: mongoCategories,
        coordinates :
             { $geoWithin :
                 {
                     $center : [ [ userLong, userLat ] , radius ]
                 }
             }
        } , { score: {
                $meta: "textScore"
            }
        }, function (err, results) {  ...... });