React native 和 firestore:geohash 附近搜索到给定距离,结果错误

问题描述

我需要使用 geohash。我必须检查作为 geohash 的目标位置是否在我作为 geohash 的当前位置的范围(距离)内。它实际上有效,但我注意到了很大的范围差异。所以我写了一个测试器,我不需要我的数据库来向你展示问题。

在 Geotest() 函数中开始读取我已将起始位置定义为经纬度坐标,并编码为 geohash。

然后我以英里为单位输入距离/范围值。

通过两者,我可以计算下地理哈希和上地理哈希。

使用下部和上部 geohash,我可以比较其他地方(在 firestore 中)的 geohash,以检查它们是否在范围内。此时有错误的结果。例如,一个地方在 600 英里的距离内,但在 320 英里处,结果已经在其范围内。错了。

我再次将上限和下限解码为 lat、lon 值,并仅根据坐标(不是 geohash)计算距离以显示差异,并且距离几乎翻了一番。有时它作为因子 2 更高,有时更低。如果我选择不同的距离值,它会有所不同。

在我看来,如果我输入 10 英里的距离,请对范围进行编码并对其进行解码以重新计算它应该保持 10 英里的距离。由于四舍五入,可能会有一些细微的差异,但没有 20.37,这是预期的两倍。

现在的问题是,为什么解码后的距离比以前高了?我是否错过了任何计算?

所以我无法准确检查位置是否在给定的范围内。

我知道在客户端代码中我只能处理坐标,但是这些地方在 firestore 中作为 geohash 给出,我必须直接从那里获取范围内的地方,而无需在客户端进行过滤。所以那不是一个选择,我认为如果我有正确的数学,它可以工作。谢谢。

GeoTester.js:

import geohash from "ngeohash";

export const GeoTester = () => {

    const getdistance = (startLat,startLon,targetLat,targetLon) => {  
        const dLat = (startLat-targetLat) * Math.PI / 180;
        const dLon = (startLon-targetLon) * Math.PI / 180;
    
        const lat1 = targetLat * Math.PI / 180;
        const lat2 = startLat * Math.PI / 180;
    
        const a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
        const c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a)); 
        const d = 6371 * c;
        return d;
    }
    
    const getGeohashRange = (latitude,longitude,distance) => {
        const latDeg = 0.0144927536231884; // degrees latitude per mile
        const lonDeg = 0.0181818181818182; // degrees longitude per mile

        const lowerLat = latitude - latDeg * distance;
        const lowerLon = longitude - lonDeg * distance;

        const upperLat = latitude + latDeg * distance;
        const upperLon = longitude + lonDeg * distance;

        const lowerGeohash = geohash.encode(lowerLat,lowerLon);
        const upperGeohash = geohash.encode(upperLat,upperLon);

        return { lowerGeohash,upperGeohash };
    }
  
    const geoTest = () => {
      const startLat = 52.00991050587265;
      const startLon = 4.708180705155277;
      const startGeohash = geohash.encode(startLat,startLon);
      
      const distance = 10; // miles
      
      const { lowerGeohash,upperGeohash } = getGeohashRange(startLat,distance);
      
      const lowerDecoded = geohash.decode(lowerGeohash);
      const upperDecoded = geohash.decode(upperGeohash);
      
      const distLower = getdistance(startLat,lowerDecoded.latitude,lowerDecoded.longitude);
      const distUpper = getdistance(startLat,upperDecoded.latitude,upperDecoded.longitude);

      const diffLower = (distLower / distance);
      const diffUpper = (distUpper / distance);
      
      console.log('distance and diff lower',distLower,diffLower);
      console.log('distance and diff upper',distUpper,diffUpper);
    }
    
    return {
        geoTest
    };
}

App.js:

import React from 'react';
import {View,Button} from 'react-native';
import {GeoTester} from '../helpers/GeoTester';

const App = () => { 
  const { geoTest } = GeoTester();

  return (
    <View>
      <Button title="Test" onPress={() => geotest()} />
   </View>
  );
}

export default App;

console.log 输出

distance and diff lower 20.374469782722997 2.0374469782722997
distance and diff upper 20.347694449540903 2.0347694449540903

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)