Algorithm Geohash:使用libgeohash查找邻居

Algorithm Geohash:使用libgeohash查找邻居,algorithm,geolocation,geocoding,geo,geohashing,Algorithm,Geolocation,Geocoding,Geo,Geohashing,在我的应用程序中,我将所有用户的Geohash存储在一个表中,并希望找到使用这些Geohash的用户的邻居 根据我收集的关于Geohash的信息: 在数据库中使用时,Geohash数据的结构有两个 优势。首先,由geohash索引的数据将具有 连续切片中的给定矩形区域(切片数 取决于所需的精度和geohash“故障”的存在 “行”)。这在需要查询的数据库系统中特别有用 在单个索引上比在多个索引上更容易或更快 查询。第二,这个索引结构可以用于 快速而肮脏的近距离搜索-最近的点通常位于 最近的地理哈

在我的应用程序中,我将所有用户的Geohash存储在一个表中,并希望找到使用这些Geohash的用户的邻居

根据我收集的关于Geohash的信息:

在数据库中使用时,Geohash数据的结构有两个 优势。首先,由geohash索引的数据将具有 连续切片中的给定矩形区域(切片数 取决于所需的精度和geohash“故障”的存在 “行”)。这在需要查询的数据库系统中特别有用 在单个索引上比在多个索引上更容易或更快 查询。第二,这个索引结构可以用于 快速而肮脏的近距离搜索-最近的点通常位于 最近的地理哈希

例如,为了查找“sj8101b085”的邻居,我计划通过以下方式搜索哈希:

SELECT * FROM Users WHERE Geohash LIKE 'sj8101b085%'
然后通过逐个减少散列长度来触发相同的查询,即“sj8101b08%”、“sj8101b0%”,等等,直到得到所需数量的邻居。我觉得这就是我所需要做的

但后来我发现了同一篇文章底部提到的这个C库。该库有一个名为
GEOHASH\u get\u nexture
的函数,它为我们提供给定散列的相邻散列。geohash字符串表示地球上的矩形区域。这个函数返回表示相邻矩形的geohash。这意味着我要在递归中运行这个函数(邻居,然后是邻居的邻居等等),直到我得到所需数量的邻居


现在我真的很困惑,我该如何写我的搜索算法?使用第一种方法还是使用第二种方法?

geohash是一个位字符串,其中偶数位表示经度,奇数位表示纬度。例如,经度表示的每一位选择可行区域的一半。初始可行区域为[-180,180],如果经度的第一位为0,则下一个可行区域为[-180,0],如果为1,则为[0,180]。前两位加在一起,选择赤道上方或下方地球的一半,以及本初子午线左侧或右侧地球的一半。您可以将其视为“矩形区域”,正如您在维基百科链接中所称。前四位加在一起,选择北半球或南半球的一半,以及东半球或西半球的一半。等等

链接中显示的geohash ezs42以32为基数,因此每个字符表示geohash的5位。示例哈希为5个字符的含义是geohash为25位,其中13位表示经度,12位表示纬度。这意味着经度被分成13倍的一半,而纬度被分成12倍的一半,geohash同时选择12个纬度范围中的一个和13个纵向范围中的一个。从散列末尾移除的每个字符将从geohash中删除5位;这相当于经度的3个刻度和纬度的2个刻度,反之亦然。否则,它会将你的纵向范围增加8倍,将你的纬度范围增加4倍,反之亦然。查询该geohash将给出相应“矩形”区域内的所有点

我不熟悉libgeohash;然而,从您的描述中,听起来好像您给了它一个geohash,它还给了您一个geohash集合,这些geohash以输入所暗示的粒度表示相邻的“矩形”区域。据推测,如果你用它来寻找最近的邻居,你将需要跟踪那些你访问过的和没有访问过的Geohash,并且你将不得不反复询问邻居,直到你找到你正在寻找的点为止。从视觉上看,这看起来像是从原始“矩形”大小的“矩形”的初始几何散列中展开的扇形。你需要小心,不要简单地考虑在一个相邻区域中找到的第一个点,因为另一个相邻区域可能有一个更靠近查询点的点;也就是说,在搜索最近的查询点的K之前,你需要考虑所有邻居的点(这意味着,例如,你需要在邻居的方法的第二次迭代中寻找最近的K之前,从原始矩形的所有8个邻居的邻居请求和查询点”。

考虑到libgeohash邻居方法,如果您的原始“矩形”很小(比如,英寸乘以英寸),并且您的点足够稀疏,那么您可能需要花费大量的时间,直到您通过这种扇出技术覆盖足够的地球,直到您找到您的点为止。另一方面,使用前缀方法,可能是你的点足够密集,增加4和8倍的范围会考虑大量的要点。在任何一种情况下,如果要查找k个最近的邻居,仍然需要测试所有结果点的距离,以选择其中k个最近的点。最终,您的选择将取决于您的数据;但是,我建议从前缀方法开始,因为它比相邻的“矩形”区域方法简单得多。

公共集GetMoreNeights(int-surroundRange,String-originHash){
public Set<String> getMoreNeighbours(int surroundRange, String originHash){
    int matrixSize = nthOddNumber(surroundRange / 5);
    Set<String> locationSet = new HashSet<>();
    locationSet.add(originHash);
    List<String> tempNbHash = new ArrayList<>();
    for(int i=0; i < matrixSize / 2; i++) {
        if(tempNbHash.isEmpty()) {
        Map<String, Boolean> memo = new HashMap<>();
            Set<String> collection = new HashSet<>();
            locationSet.forEach(loc -> {
                if (!memo.containsKey(loc)) {
                    Collection<? extends CharSequence> neighbors = GeoHashUtils.neighbors(loc);
                    neighbors.forEach(nb -> collection.add(nb.toString()));
                }
                memo.put(loc, true);
            });
            locationSet.addAll(collection);
            tempNbHash.addAll(collection);
        } else {
            Map<String, Boolean> memo = new HashMap<>();
            Set<String> collection = new HashSet<>();
            tempNbHash.forEach(loc -> {
                if (!memo.containsKey(loc)) {
                    Collection<? extends CharSequence> neighbors = GeoHashUtils.neighbors(loc);
                    neighbors.forEach(nb -> collection.add(nb.toString()));
                }
                memo.put(loc, true);
            });
            locationSet.addAll(collection);
            tempNbHash.clear();
            tempNbHash.addAll(collection);
        }
    }
    return locationSet;
}

public int nthOddNumber(int n){
    return (2 * n - 1);
}
int matrixSize=nthOddNumber(环绕范围/5); Set locationSet=new HashSet(); locationSet.add(originHash); List tempNbHash=new ArrayList(); 对于(int i=0;i{ 如果(!备忘录容器(loc)){
Collectionary您是否从Python之类的编程语言与数据库交互?