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

推荐订阅源

Help Net Security
Help Net Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
SecWiki News
SecWiki News
Webroot Blog
Webroot Blog
AI
AI
S
Secure Thoughts
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Cloudbric
Cloudbric
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
The Exploit Database - CXSecurity.com
Latest news
Latest news
N
News and Events Feed by Topic
Simon Willison's Weblog
Simon Willison's Weblog
Scott Helme
Scott Helme
S
Schneier on Security
H
Hacker News: Front Page
Forbes - Security
Forbes - Security
T
Troy Hunt's Blog
Know Your Adversary
Know Your Adversary
S
Security Affairs
V
Visual Studio Blog
Stack Overflow Blog
Stack Overflow Blog
博客园_首页
腾讯CDC
GbyAI
GbyAI
有赞技术团队
有赞技术团队
Last Week in AI
Last Week in AI
N
News and Events Feed by Topic
WordPress大学
WordPress大学
The Register - Security
The Register - Security
Engineering at Meta
Engineering at Meta
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cisco Talos Blog
Cisco Talos Blog
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
Recent Announcements
Recent Announcements
V
V2EX
S
Securelist
Security Archives - TechRepublic
Security Archives - TechRepublic
B
Blog RSS Feed
PCI Perspectives
PCI Perspectives
Security Latest
Security Latest
I
InfoQ
I
Intezer
L
LangChain Blog
雷峰网
雷峰网
NISL@THU
NISL@THU
博客园 - 【当耐特】
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志

暗无天日

读:AI Agent 安全日志——从可见性与隐私的两难说起 - 暗无天日 AI写作的语言指纹——如何让文字不那么像机器 - 暗无天日 读:50 条 Claude Code 技巧——一个工程经理的六个月使用心得 读:AI 辅助开发为什么让 E2E 测试更有价值 - 暗无天日 读:在Emacs中使用Claude Code(Spacemacs适配版) - 暗无天日 Claude Code 背后的工程哲学——读 Agent Harness Engineering 读:Agent Harness Engineering——AI 智能体不只是模型,还有套件 - 暗无天日 browser-harness:让 AI 直接接管你的浏览器 - 暗无天日 读:Security-First CI/CD —— DevSecOps 自动化实践指南 TIL: 数字小键盘的小数点陷阱与行内算术求值 - 暗无天日 读:Immutability 不是万能药,它是一种权衡 - 暗无天日 Conducty:给 Claude Code 加上项目记忆和并行执行能力 - 暗无天日 读 — GitHub Trending 里的 Claude Code 技能包 读 — Prompt Caching 省钱指南 TIL: Emacs 中那些跟鼠标配合的冷门快捷键 - 暗无天日 读:Anvil——把 Emacs 变成 AI 的工具服务器 读:Emacs 代码折叠终极指南 - 暗无天日 读:Clojure 搭车客指南 - 暗无天日 git推送失败后恢复仓库损坏的完整记录 - 暗无天日 多智能体系统的两个有效模式——以及对 Claude Code 用户的启示 - 暗无天日 用 Org Babel 写 Literate 博文:扩展执行 + 定制导出 proced:Emacs 内置的进程查看器 - 暗无天日 从 proced 定制中学到的 Elisp 模式 读:让 Emacs proced 在 macOS 上显示 CPU 和内存 异步编程的函数着色税 - 暗无天日 链式调用的代价:JavaScript 和 Clojure 的共同教训 - 暗无天日 hyperfine:命令行基准测试工具 - 暗无天日 管道中的变量去哪了?——子 shell 作用域陷阱 - 暗无天日 开源包装器的信任陷阱:四个危险信号 - 暗无天日 程序员愿意为 AI 写文档,却不愿为同事写 - 暗无天日 mktemp: Shell 脚本中临时文件的安全陷阱与最佳实践 - 暗无天日 WSL9x —— 在 Windows 9x 里跑 Linux 内核 6.19 用 ox.el 做你想做的事 —— org-export 高级编程指南 读:Hot-wiring the Lisp Machine —— 用纯 Elisp 构建零依赖的 Org 静态站点生成器 Elisp 性能优化的六个实战教训 - 暗无天日 fcitx5 下 Emacs 无法切换输入法的排查 - 暗无天日 ERT 测试交互命令的三种方式 - 暗无天日 SEM Assistant: 当 Elisp 守护进程遇上 LLM 用 dmsg 给 Elisp 加上结构化调试日志 用 org-habit 追踪非每日习惯 - 暗无天日 Clojure X-Men:当编程语言特性变成超能力 - 暗无天日 TIL: 用 diff-hl 在 fringe 中显示 git 变更 读:llm-test —— 用 LLM agent 驱动 Emacs 测试 TIL: AI 时代的橡皮鸭调试 - 暗无天日 fcitx 启动后键盘输入卡顿的排查 - 暗无天日 TIL: 早期网页的图片热区导航 - 暗无天日 读 Seeing the Whole System 用 Emacs 自动生成每周链接推荐 - 暗无天日 读:ASCII control characters in my terminal 读 What to learn - 暗无天日 Lisp 的括号之痛——一个愚人节玩笑揭开的老伤疤 - 暗无天日 一本书该"线性读"还是"并行读" - 暗无天日 读 How to Monetize a Blog:一篇伪装成变现指南的讽刺文 Python Mock 第三方依赖的四种策略 - 暗无天日 Emacs Lisp 热重载实用指南 - 暗无天日 Prot 的 Emacs 配置哲学 - 暗无天日 TIL: 从直播对谈中学到的三个 Emacs 技巧 - 暗无天日 TIL: 自动使用项目虚拟环境的 Python - 暗无天日 TIL: 让 Help buffer 自动获得焦点 一条命令让本地开发用上 HTTPS —— slim 工具介绍 用 fsck 检查和修复 Linux 文件系统 排查Linux进程"卡死"实战:从strace到gdb全流程 - 暗无天日 PostgreSQL 索引:从基础到你可能不知道的高级用法 - 暗无天日 用 .pdbrc 自定义 Python 调试器 ANSI 转义码的标准化现状 - 暗无天日 终端程序的潜规则 - 暗无天日 PARA Org-mode 测试配置 - 暗无天日 AI越强越辣鸡?控制论说这是必然的 - 暗无天日 AI 越强越需要你盯着——反馈循环实操指南 - 暗无天日 你的AI代理正在偷你的密钥——四种你没想到的泄露通道 - 暗无天日 LLM 在 DevOps 中的三种角色 - 暗无天日 写作风格的反建议 - 暗无天日 反驳本质复杂性——Dan Luu 论为什么《没有银弹》错了 - 暗无天日 文件充满了危险——Dan Luu 谈文件系统的可靠性陷阱 - 暗无天日 AI 时代的 PARA 方法:用 Org-mode 和 AI 打造个人知识管理系统 Linux 数据去重学习笔记 - 暗无天日 创建跨平台 ZIP 文件的隐藏陷阱:Extra Field - 暗无天日 X11 Forwarding 排障指南 - 暗无天日 IP欺骗端口扫描:当别人冒充你去扫描别人 - 暗无天日 Linux 输入栈全景解析:从硬件按键到屏幕响应 - 暗无天日 Unix 系统中那些被埋没的配置开关——以 FontConfig 为例 - 暗无天日 在Linux上限制儿童使用电脑 - 暗无天日 GIF不仅仅是一种图片格式——用GIF流做些奇怪的事 - 暗无天日 Leiningen 学习笔记:Clojure 项目构建与管理从入门到实战配置 - 暗无天日 Google SRE Book 读书笔记 - 暗无天日 yes 管道 head 发生了什么 - 暗无天日 为什么 nohup 在 crontab 中不起作用 Bash中的Indirection与Nameref - 暗无天日 Linux PAM 简介 - 暗无天日 从Linux ISO文件启动计算机 - 暗无天日 用 Bash 打造一个Screen Locker 用GitHub Actions自动构建EGO博客 - 暗无天日 blocking I/O 的作用 - 暗无天日 mobileog 手机端同步提示Error:2 No such file 的解决方法 回收 WSL2 VHDX 文件占用空间 使用 org-mode columnview 生成任务列表 - 暗无天日 Emacs 作为 MPD 客户端 - 暗无天日 移动文件路径却不破坏org file link的方法 - 暗无天日 如何合理的导出help link 成HTML - 暗无天日 笑话理解之Biology - 暗无天日
TIL:DuckDB Spatial——用SQL做地理空间查询 - 暗无天日
lujun9972,Claude Code · 2026-05-31 · via 暗无天日

Mark Litwintschik 在 Reverse Geocoding with Overture Maps 一文中展示了如何用 DuckDB 的 Spatial 扩展处理地理空间数据。说穿了就是给 DuckDB 装个 Spatial 扩展,让 SQL 能处理点、线、多边形这些地理空间数据。

是什么

DuckDB 的 Spatial 扩展提供了地理空间数据类型和函数,让你能用 SQL 直接处理经纬度坐标、多边形边界等空间数据。安装和加载只需要两条命令,

INSTALL spatial;
LOAD spatial;

INSTALL spatial 只需要执行一次——扩展文件会下载到本地扩展目录,不会每次重复下载。 LOAD spatial 则在每次连接中加载扩展。

加载后,DuckDB 就支持了一个核心类型和一批空间函数,

  • 核心类型 GEOMETRY ,点( POINT )、线( LINESTRING )、多边形( POLYGON )等
  • 常用函数ST_Point (创建点)、 ST_Distance (计算距离)、 ST_Intersects (判断是否相交)、 ST_Area (计算面积)、 ST_Centroid (求中心点)、 ST_AsText (转为可读文本)

DuckDB Spatial 默认用经纬度坐标(EPSG:4326), ST_Distance 返回的是 度数 ,不是公里或米。要换算成实际距离得做投影转换,但后文示例只展示函数用法,不涉及投影。

为什么不用专门的 GIS 数据库

如果只是做简单的空间查询,架一个 PostGIS 太重了。DuckDB 的优势在于它是嵌入式数据库,不需要单独部署;用 SQL 接口,不需要学 GIS 专用语言;还能直接读 CSV、Parquet、JSON 中的数据做空间分析,不用先导入。

当然 DuckDB Spatial 不是 PostGIS 的替代品,它不支持空间索引(至少目前不是原生支持的),复杂空间操作也更有限。但对于「这个点在哪个国家」「离我最近的地址是什么」这类逆地理编码场景,它够用了。

怎么做

以下示例使用 Python 操作 DuckDB,需先安装 duckdb 包:

pip install duckdb

示例 1:创建点和计算距离

ST_Point(lon, lat) 创建一个点, ST_Distance(a, b) 计算两个点的距离:

import duckdb

con = duckdb.connect(database=':memory:')
con.sql('INSTALL spatial; LOAD spatial')

res = con.sql("""
    SELECT
        ST_AsText(ST_Point(116.4, 39.9)) AS beijing,
        ST_AsText(ST_Point(121.47, 31.23)) AS shanghai,
        ST_Distance(ST_Point(116.4, 39.9),
                    ST_Point(121.47, 31.23)) AS dist
""").fetchone()

print(f"北京: {res[0]}")
print(f"上海: {res[1]}")
print(f"距离 (度数): {res[2]}")

输出:

北京: POINT (116.4 39.9)
上海: POINT (121.47 31.23)
距离 (度数): 10.043594973912473

ST_AsText 把二进制的几何对象转成可读的 WKT(Well-Known Text)格式。10.04 是度数,不是实际距离——要换算成公里需要做投影转换。

示例 2:判断点是否在多边形内

ST_GeomFromText 从 WKT 字符串创建多边形,然后用 ST_Intersects 判断一个点是否落在多边形范围内:

import duckdb

con = duckdb.connect(database=':memory:')
con.sql('INSTALL spatial; LOAD spatial')

res = con.sql("""
    WITH bounds AS (
        SELECT ST_GeomFromText(
            'POLYGON((115.4 39.4,
                       117.0 39.4,
                       117.0 40.2,
                       115.4 40.2,
                       115.4 39.4))'
        ) AS geom
    )
    SELECT
        ST_Intersects(geom, ST_Point(116.4, 39.9)) AS tiananmen_in_beijing,
        ROUND(ST_Area(geom)::numeric, 2)            AS area_degrees,
        ROUND(ST_X(ST_Centroid(geom)), 1)           AS cx,
        ROUND(ST_Y(ST_Centroid(geom)), 1)           AS cy
    FROM bounds
""").fetchone()

print(f"天安门在北京范围内: {res[0]}")
print(f"多边形面积 (平方度): {res[1]}")
print(f"中心点: POINT ({res[2]} {res[3]})")

输出:

天安门在北京范围内: True
多边形面积 (平方度): 1.28
中心点: POINT (116.2 39.8)

这里用了一个简化的北京边界多边形(115.4°E–117.0°E, 39.4°N–40.2°N)。天安门坐标(116.4, 39.9)确实落在这个范围内。 ST_Area 返回面积(度数²), ST_Centroid 返回多边形的中心点。

示例 3:从 CSV 读数据做最近邻查询

实际场景中,地理数据通常存在文件里。DuckDB 的 read_csv_auto 可以直接加载 CSV,结合空间函数做分析。

先准备一份城市坐标数据:

city,lon,lat
Beijing,116.4,39.9
Shanghai,121.47,31.23
Guangzhou,113.26,23.13
Shenzhen,114.06,22.55
Chengdu,104.07,30.57
Wuhan,114.27,30.58

然后查询离某个点最近的三个城市:

import duckdb

con = duckdb.connect(database=':memory:')
con.sql('INSTALL spatial; LOAD spatial')

res = con.sql("""
    WITH cities AS (
        SELECT city, ST_Point(lon, lat) AS geom
        FROM read_csv_auto('/tmp/cities.csv')
    )
    SELECT city, ST_Distance(geom, ST_Point(113.5, 22.5)) AS dist
    FROM cities
    ORDER BY dist
    LIMIT 3
""").fetchall()

for row in res:
    print(f"{row[0]}: {row[1]:.4f} deg")

输出:

Shenzhen: 0.5622 deg
Guangzhou: 0.6742 deg
Wuhan: 8.1166 deg

查询点 (113.5, 22.5) 大致在珠江口位置。深圳和广州自然最近,武汉远得多。整个过程就一个 CSV 文件加几行 SQL。

总结

DuckDB Spatial 扩展最常用的函数无非是 ST_Point 创建几何对象, ST_Distance 算距离, ST_Intersects 做空间过滤。配合 read_csv_auto 等文件读取函数,不用上 PostGIS 也能搞定常见的地理空间查询任务。

不过 DuckDB Spatial 目前不支持原生空间索引,数据量大时性能会下降。小型数据集和原型验证是它的舒适区。