我有一个问题,即使在查看相关的Stack Overflow Q / A之后,也无法解决。
我正在使用Ahmed Haque方法重用Scotch的“创建MEAN Stack Google Map App教程”开发应用程序。
我试图实现使用的应用程序 谷歌地图API 绘制Points,LineStrings并且Polygons其坐标被包含在 以GeoJSON 存储在一个文件中 的MongoDB 实例。
Points
LineStrings
Polygons
我正在使用Mongoose数据构建架构并查询MongoDB数据库。
Mongoose
MongoDB
我想找到最接近的点CP到一定点数P0 给定P0's latitude and longitude,并给予最大半径 distance用来寻找感兴趣点。
CP
P0
P0's latitude and longitude
distance
给定图像,例如,如果我插入2000(公里),我的查询将找到距P0最大2000公里的所有点。在此示例中,它可能应该给我P1和P2。
当我的积分中只有积分时,我就能做到Mongoose Schema。
Mongoose Schema
我Schema只有标记(点):
Schema
// 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:
Old Query for only Markers
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。
Polylines and Polygons
我可以使用以下命令插入和绘制新的点,折线和多边形Schema:
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:
Mongoose Query
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.
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"
相同,但有一点变化:
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 }); } });
这是标记的示例:
{ "name": "user01", "location": { "type":"Point", "coordinates": [102.0, 0.0] } }
$ near运算符如何与distance和maxDistance一起工作:
摘自Ahmed Haque的Scotch用Google地图制作MEAN应用(第二部分)
MongoDB搜索参数$ near及其相关属性maxDistance和球形,用于指定我们要覆盖的范围。我们将查询正文的距离乘以1609.34,因为我们要获取用户的输入(以英里为单位)并将其转换为MongoDB期望的单位(以米为单位)。
undefined
如果您想得到一些澄清,请在下面发表评论。
提前致谢。
我终于设法解决了这个问题。
本质上,此问题是由模式引起的,因为2dIndex它被指向错误的字段(type and coordinates)。
2dIndex
(type and coordinates)
我使用以下 模式 解决了:
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);
和以下 查询 :
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); }); });
希望对您有所帮助!
编辑
我提出的模式会给LineStringsand 带来一些问题Polygons。
这是允许使用的正确架构 geoQueries
geoQueries
linestring-model.js:
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);
多边形模型
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插入 :
{ "name" : "myLinestring", "geo" : { "type" : "LineString", "coordinates" : [ [ 17.811, 12.634 ], [ 12.039, 18.962 ], [ 15.039, 18.962 ], [ 29.039, 18.962 ] ] } }
多边形插入:
{ "name" : "Poly", "geo" : { "type" : "Polygon", "coordinates" : [ [ [25.774, -80.190], [18.466, -66.118], [32.321, -64.757], [25.774, -80.190] ] ] } }