惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
有赞技术团队
有赞技术团队
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
爱范儿
爱范儿
Vercel News
Vercel News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Y
Y Combinator Blog
Blog — PlanetScale
Blog — PlanetScale
D
DataBreaches.Net
美团技术团队
Microsoft Security Blog
Microsoft Security Blog
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
GbyAI
GbyAI
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
The Cloudflare Blog
宝玉的分享
宝玉的分享
V
V2EX
Microsoft Azure Blog
Microsoft Azure Blog

Jiajun的技术笔记

你好,2026! TiDB 源码阅读(六):TiDB Coprocessor 源码解析 性能优化的核心思想 TiDB 源码阅读(五):索引 TiDB 源码阅读(四):AST、逻辑计划、物理计划 CockroachDB Serverless Architecture podman 无故退出 Cursor Control-L (CTRL-L) Keyboard Shortcuts in Terminal Replace docker with podman Using xmonad with xfce4 A RC script for freebsd frpc 自己动手写一个k8s controller AI 会取代你的(编程)岗位吗? 自建DERP服务器提升Tailscale连接速度(使用Nginx转发) 自动升级Docker容器 再读《程序员修炼之道-从小工到专家》 让浏览器下载文件 再读《软件随想录》/《黑客与画家》/《软技能》 HTTP 压力测试中的 Coordinated Omission 2的补码 编程语言中的 context 是什么? flutter macOS 构建出错 Flatpak 使用小记 Golang CAS 操作是怎么实现的 PostgreSQL 当MQ来使用 Clash 结合 工作VPN 的网络设计 使用 PostgreSQL 搭建 JuiceFS PostgreSQL 配置优化和日志分析 有GitHub Copilot?那就可以搭建你的ChatGPT4服务 窗口函数的使用(以PG为例)
使用geohash完成地理距离计算
Jiajun Huang · 2017-12-27 · via Jiajun的技术笔记

geohash的原理是使用二分法,把当前的经度和纬度和最大最小的经度纬度进行无限二分,在一边则为0,否则为1,这样就可以定位 到地球上的每一个点了。然后把经度放在偶数位,纬度放在奇数位,组成一个01010101串。如果想变得更容易传输,可以用某种 方式进行hash,例如 base32, base64 等。

下面是一个简单的实现。to_geohash 实现经度和纬度转换成010101串,similarity比较两个01010串的前面有多少个相同的字符。 不过,to_geohash 有更高效的位运算实现,但是可读性不好,不容易懂,就不放出来了。

def to_geohash(longitude, latitude, length=30):
    '''longitude 经度(在地图上竖着的线),latitude纬度(在地图上横着的线)'''
    minLat, maxLat = -90.0, 90.0
    minLng, maxLng = -180.0, 180.0
    result = 0

    for i in range(length):
        if i % 2 == 0:  # 偶数,设置longitude
            mid = (minLng + maxLng) / 2
            if longitude < mid:
                result <<= 1  # push 0
                maxLng = mid
            else:
                result = result << 1 | 1  # push 1
                minLng = mid
        else:
            mid = (minLat + maxLat) / 2
            if latitude < mid:
                result <<= 1
                maxLat = mid
            else:
                result = result << 1 | 1
                minLat = mid

    return str(bin(result))[2:]


def similarity(a, b):
    """比较a和b两个字符串前length位有多少位相同"""
    result = 0
    length = max(len(a), len(b))
    a = a.ljust(length, '0')
    b = b.ljust(length, '0')

    for i in range(length):
        if a[i] == b[i]:
            result += 1
        else:
            break

    return result