我正在尝试使用geofirestore执行GeoQuery。我想获取给定集合中半径1000以内的所有文档。
这是我的.js文件:
const GeoFirestore = require('geofirestore').GeoFirestore;
const GeoPoint = require('geopoint');
const firebase = require('firebase');
firebase.initializeApp({
projectId : 'my-project-id'
});
module.exports = {
getLocalDocuments: getLocalDocuments
}
async function getLocalDocuments() {
let latitude = 38.9537323;
let longitude = -77.3507578;
let radius = 1000;
// Create a Firestore reference
const firestore = firebase.firestore();
// Create a GeoFirestore reference
const geofirestore = new GeoFirestore(firestore);
// Create a GeoCollection reference
const geocollection = geofirestore.collection('myDocs');
const query = geocollection.near({
center: new GeoPoint(latitude, longitude),
radius
});
// Get query (as Promise)
await query.get().then((value) => {
console.log(`value.docs: ${value.docs}`); // All docs returned by GeoQuery
});
}
调用 getLocalDocuments()函数时,我得到以下堆栈跟踪:
Error: Invalid location: latitude must be a number
at validateLocation (/srv/node_modules/geofirestore/dist/index.cjs.js:567:15)
at validateQueryCriteria (/srv/node_modules/geofirestore/dist/index.cjs.js:600:9)
at GeoCollectionReference.GeoQuery.near (/srv/node_modules/geofirestore/dist/index.cjs.js:1416:9)
at getLocalDocuments (/srv/utils/locationService.js:45:33)
at Object.getLocalDocuments (/srv/utils/locationService.js:58:11)
at buildLocalTPRecipients (/srv/utils/notificationInstructorGenerator.js:370:43)
at notifyTPOfLocalJobsInstructionGenerator (/srv/utils/notificationInstructorGenerator.js:255:32)
at Object.generateNewJobInstructions (/srv/utils/notificationInstructorGenerator.js:98:29)
at handleOnCreate (/srv/db/jobs/onCreate.f.js:20:53)
at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:131:23)
这是 validateLocation 方法:
function validateLocation(location, flag) {
if (flag === void 0) { flag = false; }
var error;
if (!location) {
error = 'GeoPoint must exist';
}
else if (typeof location.latitude === 'undefined') {
error = 'latitude must exist on GeoPoint';
}
else if (typeof location.longitude === 'undefined') {
error = 'longitude must exist on GeoPoint';
}
else {
var latitude = location.latitude;
var longitude = location.longitude;
if (typeof latitude !== 'number' || isNaN(latitude)) {
error = 'latitude must be a number';
}
else if (latitude < -90 || latitude > 90) {
error = 'latitude must be within the range [-90, 90]';
}
else if (typeof longitude !== 'number' || isNaN(longitude)) {
error = 'longitude must be a number';
}
else if (longitude < -180 || longitude > 180) {
error = 'longitude must be within the range [-180, 180]';
}
}
if (typeof error !== 'undefined' && !flag) {
throw new Error('Invalid location: ' + error);
}
else {
return !error;
}
}
有人知道为什么说纬度不是数字吗?我已经检查过isNaN()和其他方法,他们都说那是一个数字。
答案 0 :(得分:0)
问题位于以下代码行的validateLocation
函数内部:
var latitude = location.latitude;
var longitude = location.longitude;
这些行应该是:
var latitude = location.latitude();
var longitude = location.longitude();
由于latitude
和longitude
是getter方法。
.latitude(inRadians)
:返回点的纬度。默认情况下,纬度以度为单位,除非inRadians为真
.longitude(inRadians)
:返回点的经度。默认情况下,经度以度为单位,除非inRadians为真
创建某个特定的GeoPoint
:
var GeoPoint = require('geopoint'),
statueOfLiberty = new GeoPoint(40.689604, -74.04455);
然后是console.log(statueOfLiberty)
,这是预期的输出:
GeoPoint {
_degLat: 40.689604,
_degLon: -74.04455,
_radLat: 0.7101675611326549,
_radLon: -1.2923211906575673
}
此后,要验证上述GeoPoint
,我使用了validateLocation(location, flag)
函数,该函数与您使用的函数相同,并且可以也被发现 here:
function validateLocation(location, flag){
if (flag === void 0) { flag = false; }
var error;
if (!location) {
error = 'GeoPoint must exist';
}
else if (typeof location.latitude === 'undefined') {
error = 'latitude must exist on GeoPoint';
}
else if (typeof location.longitude === 'undefined') {
error = 'longitude must exist on GeoPoint';
}
else {
var latitude = location.latitude;
var longitude = location.longitude;
if (typeof latitude !== 'number' || isNaN(latitude)) {
error = 'latitude must be a number';
}
else if (latitude < -90 || latitude > 90) {
error = 'latitude must be within the range [-90, 90]';
}
else if (typeof longitude !== 'number' || isNaN(longitude)) {
error = 'longitude must be a number';
}
else if (longitude < -180 || longitude > 180) {
error = 'longitude must be within the range [-180, 180]';
}
}
if (typeof error !== 'undefined' && !flag) {
throw new Error('Invalid location: ' + error);
}
else {
return !error;
}
}
在代码中调用函数,如下所示:
validateLocation(statueOfLiberty);
结果与您收到的错误消息没什么不同。
如上所述,当您在validateLocation
函数中使用正确的getter方法调用时,整个故事就会改变:
var latitude = location.latitude();
var longitude = location.longitude();
答案 1 :(得分:0)
因此,您不/不应使用名为“ geopoint”的库。地理位置是Firebase / firestore对象...
const firebase = require('firebase');
const GeoPoint = firebase.firestore.GeoPoint;
进行更改,其他所有内容都应该起作用。