首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在给定坐标和最大距离查询结果的情况下,用平均堆栈Mongoose查找与某个点最近的点。

在给定坐标和最大距离查询结果的情况下,用平均堆栈Mongoose查找与某个点最近的点。
EN

Stack Overflow用户
提问于 2016-06-09 17:54:42
回答 2查看 2.8K关注 0票数 14

我有些日子没能解决的问题,甚至看看相关的堆栈溢出Q/A。

我正在开发一个重用Scotch's Create Stack Google Map App教程由Ahmed Haque编写方法的应用程序。

我正在尝试实现一个应用程序,它使用Google 绘制PointsLineStringsPolygons,这些坐标包含在存储在MongoDB实例中的GeoJson文件中。

我正在使用Mongoose为我的数据构建模式并查询我的MongoDB数据库。

我想找出最近的点,CP到某个点,P0,给定P0's latitude and longitude,给出一个最大半径,distance,用来找到感兴趣的点。

考虑到图像结束,我想要这样做,例如,如果我插入2000 (公里),我的查询将找到距P0最大2000公里的所有点。在本例中,它可能会给我P1和P2。

当我的Mongoose Schema中只有点数时,我才能做到这一点。

我有这个Schema ,只有标记(点)

代码语言:javascript
运行
复制
// Pulls Mongoose dependency for creating schemas
var mongoose    = require('mongoose');
var Schema      = mongoose.Schema;

// Creates a User Schema. 
var MarkerSchema = new Schema({
    username: {type: String, required: true},
    location: {type: [Number], required: true}, // [Long, Lat]
    created_at: {type: Date, default: Date.now},
    updated_at: {type: Date, default: Date.now}
});

// Indexes this schema in 2dsphere format
MarkerSchema.index({location: '2dsphere'});

module.exports = mongoose.model('mean-markers', MarkerSchema);

这是我的Old Query for only Markers**:**

代码语言:javascript
运行
复制
var User = require('./model.js');

app.post('/query/', function(req, res) {

        // Grab all of the query parameters from the body.
        var lat = req.body.latitude;
        var long = req.body.longitude;
        var distance = req.body.distance;
        var reqVerified = req.body.reqVerified;

        // Opens a generic Mongoose Query
        var query = User.find({});

        // ...include filter by Max Distance (converting miles to meters)
        if (distance) {

            // Using MongoDB's geospatial querying features
            query = query.where('location').near({
                center: {
                    type: 'Point',
                    coordinates: [long, lat]
                },

                // Converting meters to miles
                maxDistance: distance * 1609.34,
                spherical: true
            });
        }
});

它真的很好,我能够得到接近的观点。

然后,我将我的Schema更改为更动态,并支持Polylines and Polygons

我可以插入和绘制新的点,多边形和多边形,用下面的Schema**:**

代码语言:javascript
运行
复制
var mongoose = require('mongoose');
var GeoJSON  = require('geojson');
var Schema   = mongoose.Schema;

// Creates a Location Schema.
var LocationSchema = new Schema({
                                    name: {type: String, required: true},
                                    location: {
                                      type: {type : String, required: true},
                                      coordinates : [Schema.Types.Mixed]
                                    },
                                    created_at: {type: Date, default: Date.now},
                                    updated_at: {type: Date, default: Date.now}
});

LocationSchema.index({location: '2dsphere'});
module.exports = mongoose.model('mean-locations', LocationSchema);

这是我的Mongoose Query**:**

代码语言:javascript
运行
复制
var GeoObjects = require('./model.js');

app.post('/query/', function(req, res) {

    // Grab all of the query parameters from the body.
    var lat = req.body.latitude;
    var long = req.body.longitude;
    var distance = req.body.distance;

    var query;

    if (distance) {
        query = GeoObjects.find({'location.type':'Point'})
                    .where('location.coordinates').near({
                      center: {
                        type: 'Point',
                        coordinates: [lat, long]
                      },
                      // Converting meters to miles
                      maxDistance: distance * 1609.34,
                      spherical: true
        });
    }

    // Execute Query and Return the Query Results
    query.exec(function(err, users) {
        if (err)
            res.send(err);
        console.log(users);
        // If no errors, respond with a JSON of all users that meet the criteria
        res.json(users);
    });
});

console.log(users);给了我undefined.

在我的queryCtrl.js中记录查询结果会给出以下错误消息:

name: "MongoError", message: "error processing query: ns=MeanMapApp.mean-locatio…ed error: unable to find index for $geoNear query", waitedMS: 0, ok: 0, errmsg: "error processing query: ns=MeanMapApp.mean-locatio…ed error: unable to find index for $geoNear query"

与略有差异相同:

代码语言:javascript
运行
复制
app.post('/query/', function(req, res) {

    // Grab all of the query parameters from the body.
    var lat = req.body.latitude;
    var long = req.body.longitude;
    var distance = req.body.distance;

    console.log(lat,long,distance);

    var points = GeoObjects.find({'location.type':'Point'});

    var loc = parseFloat(points.location.coordinates);
    console.log(JSON.stringify(loc));

    if (distance) {
        var query = points.near(loc, {
                      center: {
                        type: 'Point',
                        coordinates: [parseFloat(lat), parseFloat(long)]
                      },
                      // Converting meters to miles
                      maxDistance: distance * 1609.34,
                      spherical: true
        });
    }
});

这是一个标记的例子:

代码语言:javascript
运行
复制
{
  "name": "user01",
  "location": {
                "type":"Point",
                "coordinates": [102.0, 0.0]

  }
}

$near运算符如何与距离和maxDistance:一起工作

来自苏格兰人用谷歌地图制作卑鄙的应用(第二部分)

MongoDB搜索参数$near及其相关属性maxDistance和球形,以指定我们要覆盖的范围。我们将查询体的距离乘以1609.34,因为我们希望将用户的输入(以英里为单位)转换为MongoDB期望的单位(以米为单位)。

  1. 为什么我要得到undefined**?**
  2. 这个问题有可能是由我的架构引起的吗?
  3. ,我怎样才能解决这个问题?

如果你想得到一些澄清,只需在下面发表评论。

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-20 18:52:54

我终于解决了这个问题。

本质上,这个问题是由模式引起的,因为2dIndex被引用到了一个错误的字段(type and coordinates)

我使用以下架构进行了求解

代码语言:javascript
运行
复制
var mongoose = require('mongoose');
var GeoJSON  = require('geojson');
var Schema   = mongoose.Schema;

var geoObjects = new Schema({
                               name : {type: String},
                               type: {
                                       type: String,
                                       enum: [
                                               "Point",
                                               "LineString",
                                               "Polygon"
                                             ]
                                      },
                                coordinates: [Number],
                                created_at: {type: Date, default: Date.now},
                                updated_at: {type: Date, default: Date.now}
});

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

geoObjects.index({coordinates: '2dsphere'});

module.exports = mongoose.model('geoObjects', geoObjects);

和下面的查询

代码语言:javascript
运行
复制
app.post('/query/', function(req, res) {

        // Grab all of the query parameters from the body.
        var lat = req.body.latitude;
        var long = req.body.longitude;
        var distance = req.body.distance;

        var query = GeoObjects.find({'type':'Point'});

        // ...include filter by Max Distance 
        if (distance) {

            // Using MongoDB's geospatial querying features. 
            query = query.where('coordinates').near({
                center: {
                    type: 'Point',
                    coordinates: [lat, long]
                },

                // Converting meters to miles
                maxDistance: distance * 1609.34,
                spherical: true
            });
        }

        // Execute Query and Return the Query Results
        query.exec(function(err, geoObjects) {
            if (err)
                res.send(err);

            // If no errors, respond with a JSON 
            res.json(geoObjects);
        });
    });

我希望它能帮到别人!

编辑

我所介绍的模式会给LineStringsPolygons带来一些问题。

以下是允许使用geoQueries的正确模式

linestring-model.js:

代码语言:javascript
运行
复制
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);

polygon-model.js

代码语言:javascript
运行
复制
var mongoose = require('mongoose');
var Schema   = mongoose.Schema;

// Creates a Polygon Schema.
var polygons = new Schema({
    name: {type: String, required : true},
    geo : {
        type : {type: String,
            default: "Polygon"},
        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
polygons.pre('save', function(next){
    now = new Date();
    this.updated_at = now;
    if(!this.created_at) {
        this.created_at = now
    }
    next();
});

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

LineString插入

代码语言:javascript
运行
复制
{  
    "name" : "myLinestring", 
    "geo" : {
        "type" : "LineString", 
        "coordinates" : [
            [
                17.811, 
                12.634
            ], 
            [
                12.039, 
                18.962
            ], 
            [
                15.039, 
                18.962
            ], 
            [
                29.039, 
                18.962
            ]
        ]
    }
}

多边形插入:

代码语言:javascript
运行
复制
{  
    "name" : "Poly", 
    "geo" : {
        "type" : "Polygon", 
        "coordinates" :  [
                           [ 
                             [25.774, -80.190], [18.466, -66.118], 
                             [32.321, -64.757], [25.774, -80.190] 
                           ]
                         ]
    }
}
票数 1
EN

Stack Overflow用户

发布于 2016-06-13 14:31:32

我不明白你所有的代码下面是什么,但我知道一件事:

如果你使用的是谷歌的雷达搜索,你必须考虑到

最大允许半径为50 000米。

看看他们的文档

这意味着,如果你尝试以更高的半径,结果可能是零

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37733030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档