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

推荐订阅源

S
Schneier on Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Threat Research - Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
A
Arctic Wolf
Security Latest
Security Latest
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Troy Hunt's Blog
Latest news
Latest news
Help Net Security
Help Net Security
S
Security Affairs
Webroot Blog
Webroot Blog
The Hacker News
The Hacker News
AI
AI
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Tor Project blog
Forbes - Security
Forbes - Security
Google DeepMind News
Google DeepMind News
AWS News Blog
AWS News Blog
Attack and Defense Labs
Attack and Defense Labs
P
Proofpoint News Feed
www.infosecurity-magazine.com
www.infosecurity-magazine.com
H
Help Net Security
L
Lohrmann on Cybersecurity
S
SegmentFault 最新的问题
Google Online Security Blog
Google Online Security Blog
MongoDB | Blog
MongoDB | Blog
Cyberwarzone
Cyberwarzone
The Last Watchdog
The Last Watchdog
S
Securelist
N
News and Events Feed by Topic
S
Secure Thoughts
F
Fortinet All Blogs
博客园_首页
C
Cybersecurity and Infrastructure Security Agency CISA
量子位
M
MIT News - Artificial intelligence
F
Full Disclosure
T
The Blog of Author Tim Ferriss
T
Tailwind CSS Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Microsoft Security Blog
Microsoft Security Blog
I
InfoQ
P
Privacy International News Feed
L
LangChain Blog
Know Your Adversary
Know Your Adversary
C
CERT Recently Published Vulnerability Notes

BlogFinder

日常漫步 Vol.24 之漫步前山河 - 雅余 周报 #1-聊聊本周的收获 - Edwin's Blog 我的OpenCode必装插件与Skill Write Something 掌中之物未必在掌握之中 · CRIVU PiliNara,一个更顺手的 PiliPlus 分支 「NekoEcho」:做一个必有回响的猫娘主题博客 2026-05 书影音总结 简化博客主题 - 安迪 我第一次发布 npm 包 拾花小记#45:中考前的二三事 – 小改学习志 黛西花园5月游 #18 枇杷又熟了的五月月报 一些奇奇怪怪的需求?word仿方正书版的几个小操作 - Xiobb's Blog 0419 御温泉之旅 修复了一些bug,网站基本上趋于稳定了 - 新锐博客 又回到四十年前 如何定义成功 迷鹿屋2026已重新上线 科技冰火两重天+一周回顾 ${title} 热度退了,我反而用得更深了-咕咚同学 我到底该不该换个域名? 随身WIFI折腾记 - 安迪 博客撰写体验提升——hexo pro插件 为什么不用相机把屏幕上的接关密码拍下来? 国清寺与天台山 – Ouroboros ★★★★☆《挽救计划》——久违的经济上行感 - Davidの3号基地 删除右键“打开方式”里多余选项 第三周刊_No.53|一切都会被支付两次 安卓APP通话记录与录音上传踩坑记录 - 子舒的博客 天量下跌 inBox 笔记 2.3.8,把工具栏交给了你-咕咚同学 我把小龙虾搬到了微信-咕咚同学 安好 - 响石潭 Compound Engineering Plugin:让每个工程单元都比上一个更容易 MOSS-TTS Family:开源高质量语音与声音生成模型家族深度解析 Crawl4AI:专为 LLM 设计的开源 Web 爬虫与数据抓取工具 Build Your Own X:从零实现你最喜欢的技术——程序员进阶的终极资源清单 Anthropic Skills:用文件夹教 Claude 专业技能的开源框架 1年的去月球(下) - 梅之夏 欢迎回来。 简单讲讲 ASN.1 与 OID DTV - 直播聚合客户端 5.22-5.27 – 不兴江 还没去过鸭川 – 不兴江 张晶晶同学三刷林志颖 关于我 – 不兴江 爱与嫉妒 – 不兴江 港股被持续做空 备案码花了四百块-咕咚同学 一句话生成封面:我给公众号做了4种风格的AI封面生成技能 「官」方認證 再谈费曼学习法 2026-05-28T00:34:11+08:00 2026-05-28T00:28:45+08:00 离谱的英语学习指南:基于AI的英语进阶系统方法论 iii:零集成架构的后端统一运行时 Claude Code Harness:让 Claude Code 工作有迹可循的工程化框架 Heretic:全自动移除大语言模型审查机制的开源工具 MarkItDown:微软开源的万能文档转 Markdown 利器 Harness:让 Claude Code 秒变多智能体协作工厂 这段时间尽折腾AI Agent了,确实极大地提高了效率 近期动态:两个新站点正式上线啦 误判解除!zhouayuan.com 腾讯安全申诉成功 - 周阿源|玩具设计・插画日常・生活随笔 Ralph:让 AI 编码工具自主循环跑完所有 PRD 任务的量产神器 全都违法 – 个人工作记录 关于zhouayuan.com被误判 “含违规信息” 的说明与申诉记录 - 周阿源|玩具设计・插画日常・生活随笔 小米 MiMo v2.5 Pro 白嫖 最大的人间清醒,兜里有钱,但是不花。 夜晚靓歌(12):于文文现场solo - 王志勇的Blog 今日插画:风扬起的倔强 - 周阿源|玩具设计・插画日常・生活随笔 回门习俗 独立网卡 - 忘记了回忆 500亿入股人工智能企业 从命令行到桌面智能体-咕咚同学 第一性原理读书笔记 行者微评论223-加班の守株待兔-博客|政治与时事-风雨行者 ZOZO开源物理接触求解器:GPU加速的可扩展仿真引擎 OpenStock:开源股票市场交易平台技术深度解析 MoneyPrinterTurbo:基于AI的全自动短视频生成工具深度解析 Claude-Mem:为 Claude Code 构建的持久化记忆压缩系统 Twenty:可代码化定制的企业级开源 CRM 平台技术深度解析 2026-05-26T22:59:17+08:00 企业级开源大模型部署平台 GPUStack 实战教程 1年的去月球(上) - 梅之夏 Sevalla - 静态网站托管服务 不用翻墙、不用注册、不用月费,普通人也能用上 Claude Code 装修灯具要注意⚠️ 黄梅天先锋 - 游子微博 公安备案顺利办结,站点备案全部完成 - 周阿源|玩具设计・插画日常・生活随笔 第三次兑换天猫超市卡了宗宗酱-三维狐少儿编程 Don't think, feel. - Rolen's Blog 人这一辈子,到底图个什么 博客迁移 - Edwin's Blog 情感赛道写作模板 再现本轮行情的典型特征 裁员与平常心-咕咚同学 别让“偷懒”,成为隐私泄露的破绽 片刻 - Jdeal | Life is like a Design.
TIL:DuckDB Spatial——用SQL做地理空间查询 - 暗无天日
lujun9972,Claude Code · 2026-05-31 · via BlogFinder

目录

  • 是什么
  • 为什么不用专门的 GIS 数据库
  • 怎么做
    • 示例 1:创建点和计算距离
    • 示例 2:判断点是否在多边形内
    • 示例 3:从 CSV 读数据做最近邻查询
  • 总结

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 包:

示例 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 目前不支持原生空间索引,数据量大时性能会下降。小型数据集和原型验证是它的舒适区。