想象你是一座城市的信息管理员,手上有一本超厚的“居民档案册”。里面记着每个店铺的名字、老板和营业额,却完全不记录它们在哪里。某天有人问你:“火车站 500 米内有哪些餐厅?”你只能把整本册子翻一遍,对着每个店名猜测位置——这就是没有 PostGIS 的 PostgreSQL:数据虽多,却没有“空间方向感”。 现在,给这座数据城市装上 GPS。PostGIS 就是 PostgreSQL 的“空间感官”:从今往后,每条记录都知道自己“住在哪个坐标”,数据库能直接计算两点之间的距离、判断某个片区覆盖了哪些商铺、甚至把结果按“从近到远”排好序。你只需要在地图上画一个圈,答案自己跑出来——不再需要翻遍全城。 这篇文章会带你一步步认识 PostGIS:安装扩展、认识点线面、构建空间索引、使用空间函数与地理查询语法,最后搞定坐标系转换。全程借用“城市地图”这个比喻,让零基础的小白也能建立直觉。

岗位关联

学会 PostGIS,你就让数据库自己“认了路”。无论是做 LBS 位置服务、地图应用,还是为 AI 模型准备空间特征数据,这都是后端工程师与 GIS 开发者绕不开的核心能力。

目录
  1. 可视化演示
  2. 认识空间数据
  3. 安装与配置
  4. 空间索引优化
  5. 空间函数集
  6. 地理查询语法
  7. 坐标系转换
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示PostGIS的核心机制,通过开始/执行/监控/完成四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

PostGIS:Post PostGIS空间扩展概述与数 GiST空间索引与查询加速机制 核心机制可视化 PostGIS整体架构与关键组件

认识空间数据

想象你是一名城市配送中心的调度员,需要在手绘地图上标记送货点。你手边有三种符号:一个小圆点标记“商铺”位置,一条弯折的曲线段标记“送货路线”,一个闭合的线圈定“小区范围”。PostGIS 眼中的空间数据,正是这三种基础图形——点(POINT)、线(LINESTRING)和面(POLYGON)。它们共同构成了地图上一切形状的最小语言。

在普通 PostgreSQL 表里,我们只能存数字、字符串这些“没有形状”的值。PostGIS 则增加了一个名为 geometry(几何体)的特殊类型,让每条记录都能描述一个带坐标的图形对象。例如一个点可以写作 POINT(116.40 39.90)——这代表北京某处的经纬度。对数据库来说,它不再是一行冷冰冰的数字,而是一个“知道自己在哪”的实体。

更复杂的对象由多个坐标组合而成:LINESTRING 由一串坐标点依次连接成线,POLYGON 由首尾相接的闭合环围出区域。PostGIS 还提供 MULTIPOINT、MULTILINESTRING、GEOMETRYCOLLECTION 等集合类型,方便把多个几何塞进同一个字段。存储层面,每个几何对象本质是一串坐标序列,但数据库把它当作完整整体来管理、索引和计算。

回到地图的比喻:点线面就像是绘图员的三种笔尖。有了它们,无论是标记一栋楼、画一条河,还是圈出一片工业园区,数据库都能理解并存储。这正是 PostGIS 空间能力的基石。

P=(x,y)L=⟨P1,P2,…,Pn⟩P = (x, y) \qquad L = \langle P_1, P_2, \ldots, P_n \rangle
这个公式表达了两层意思:一个点由横纵坐标对构成;一条线由一串有序点首尾相连构成。面则可以理解为“首尾闭合的线”围出的区域。
  1. 坐标对(x, y) 表示平面上一个点,x 通常对应经度(横向位置),y 对应纬度(纵向位置),就像地图上的网格交叉点。
    P=(x,y)P = (x, y)
  2. 点序列\langle P_1, P_2, \ldots, P_n \rangle 表示把多个点依次连接起来,得到一条折线,这正是 LINESTRING 的数学模型。
    L=⟨P1,P2,…,Pn⟩L = \langle P_1, P_2, \ldots, P_n \rangle
  3. 闭合即面当折线的最后一个点与第一个点重合,就形成闭合环,闭合环内部围出的区域就是多边形 POLYGON。
    POLYGON≈首尾相接的闭合点序列\text{POLYGON} \approx \text{首尾相接的闭合点序列}

安装与配置

要给城市装上 GPS,光有地图不够,还得先铺设基础设施:信号基站、定位终端、后台服务器。PostGIS 的安装,就是给 PostgreSQL 这座数据城市铺设“空间定位设施”的过程。只有设施到位,后续所有空间功能才有地方运行。

PostGIS 是 PostgreSQL 的扩展(extension)模块,安装分两步走。第一步,在操作系统层面安装 postgis 软件包,等于把 GPS 设备运进城市。第二步,在数据库里执行 CREATE EXTENSION postgis; 完成激活,等于接通电源、把传感器真正挂到当前数据库上。第二步做完,数据库才真正获得空间能力。

激活后,系统会自动创建 spatial_ref_sys 表,里面预置了几百种坐标系定义;geometry、geography 类型以及全部 ST_ 前缀的空间函数立即可用。此时执行 SELECT postgis_version(); 可以查看版本号以及底层依赖库 GEOS、PROJ 的信息,就像查看 GPS 设备的信号强度和固件版本,确认一切正常。

GPS 设施铺设完毕,数据库就“睁开了空间之眼”。接下来要思考的是:如何让它在海量数据中快速找到目标?答案就是空间索引。

postgis_version()↦⟨3.4, GEOS, PROJ⟩\text{postgis\_version}() \mapsto \langle 3.4,\ \text{GEOS},\ \text{PROJ} \rangle
版本号函数返回一个“三元组”,分别代表 PostGIS 本身版本、几何算法引擎版本和投影库版本。它们共同决定你能用哪些空间功能。
  1. 函数调用postgis\_version() 是 PostGIS 提供的一个版本查询函数,相当于设备自检时打印的固件信息。
    postgis_version()\text{postgis\_version}()
  2. 三元组\langle 3.4,\ \text{GEOS},\ \text{PROJ} \rangle 中,3.4 是 PostGIS 版本号,GEOS 负责几何计算,PROJ 负责投影转换——三者各司其职。
    ⟨3.4, GEOS, PROJ⟩\langle 3.4,\ \text{GEOS},\ \text{PROJ} \rangle
  3. 映射关系\mapsto 表示“执行调用就得到结果”,验证安装成功与否,就像 GPS 设备亮起绿灯表示信号正常。
    调用↦结果\text{调用} \mapsto \text{结果}

空间索引优化

假设你要在整座城市里找“离我最近的奶茶店”。没有导航时,只能一条街一条街地敲门问;有导航时,GPS 会先告诉你“你在第三商圈”,然后把目光缩小到附近几个街区。空间索引就是这个导航系统——它让数据库不必翻遍全城。

PostGIS 使用名为 GiST(广义搜索树)的索引结构处理空间数据。它的核心思路是:为每个几何对象“套一个最小的矩形盒子”(bounding box),再把众多盒子按空间位置组织成一棵树。查询时,数据库快速排除掉与搜索区域不相交的盒子,只有可能相关的记录才进入精确计算。这就像先看街区地图,再决定敲哪几家门。

创建空间索引只需一条命令:CREATE INDEX idx_pois_geom ON pois USING GIST (geom);。建好索引后,配合 VACUUM ANALYZE 更新统计信息,查询规划器就能判断何时该走索引、何时该全表扫描。空间索引是性能调优的第一主角,没有它,再快的服务器也会被全表扫描拖垮。

空间索引像导航系统一样,帮数据库把“全城搜索”变成“精准定位”。但索引只是加速工具,真正回答业务问题还需要一套丰富的量算函数——空间函数集。

Cscan=O(n)Cindex=O(log⁡2n)C_{\text{scan}} = O(n) \qquad C_{\text{index}} = O(\log_2 n)
没有索引时,查询成本随记录数 n 线性增长(挨家挨户找);有了 GiST 索引,成本按对数增长(每次砍掉一半搜索空间)。n 越大,差距越惊人。
  1. 扫描成本C_{\text{scan}} = O(n) 表示数据库要把 n 行数据全部检查一遍,就是挨家挨户敲门问路,数据量越大越慢。
    Cscan=O(n)C_{\text{scan}} = O(n)
  2. 索引成本C_{\text{index}} = O(\log_2 n) 表示索引每次将搜索空间对半切开,类似猜数字游戏里“每次排除一半”的二分法。
    Cindex=O(log⁡2n)C_{\text{index}} = O(\log_2 n)
  3. 对比含义当 n=10000 时,无索引约需 10000 次比较,有索引仅需约 14 次。这就是为什么“先缩小到街区再敲门”能快几个数量级。
    104→⌈log⁡2104⌉=1410^4 \to \lceil \log_2 10^4 \rceil = 14

空间函数集

城市管家手里有一整套量算工具:卷尺量两点直线距离,测亩仪算地块面积,区域探测器判断两个地块是否重叠,圆规画一个服务圈。PostGIS 的空间函数集,就是数据库版的城市管家工具箱,每个 ST_ 前缀的函数都是一件趁手的工具。

常用的有五个:ST_Distance(a, b) 返回两个几何体之间的最短距离,ST_Area(a) 计算面对象的面积,ST_Length(a) 计算线对象的长度,ST_Intersects(a, b) 判断两个对象是否相交,ST_Buffer(a, r) 围绕对象画出半径 r 的缓冲区——一个扩大一圈的“服务范围”。比如想找“加油站周围 1 公里内的房子”,可以先对加油站做缓冲区,再和房子做相交判断。

这些函数接受 geometry 类型的参数,返回数字或布尔值。关键在于与索引配合:ST_Intersects、ST_DWithin 这类函数可以直接利用空间索引;而 ST_Distance 只负责计算,通常难以用索引加速。理解“哪些函数走索引、哪些不能”,是编写高性能 GIS 查询的分水岭。

有了卷尺和圆规,管家就能回答“到底有多远”的问题。但真正的业务往往还要组合多个条件——“三公里内、从近到远、只要餐厅”,这就需要地理查询语法的配合。

d(P1,P2)=(x2−x1)2+(y2−y1)2d(P_1, P_2) = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}
这是平面上两点间直线距离的公式。把两点横纵坐标之差分别平方、相加再开根号,就像用卷尺量出直角三角形的斜边。
  1. 坐标差(x_2 - x_1) 是两点横坐标之差,(y_2 - y_1) 是纵坐标之差,相当于直角三角形两条直角边的长度。
    (x2−x1),(y2−y1)(x_2 - x_1), \quad (y_2 - y_1)
  2. 平方和把两个差值分别平方后相加,得到直角三角形两条直角边的平方和,对应勾股定理中的 a² + b²。
    (x2−x1)2+(y2−y1)2(x_2 - x_1)^2 + (y_2 - y_1)^2
  3. 开根号\sqrt{\cdot} 对平方和取平方根,得到斜边长度,即两点的直线距离。
    (x2−x1)2+(y2−y1)2\sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}

地理查询语法

你不必写复杂的程序,只要对地图管家说一句话:“把 3 公里以内的书店都列出来,从近到远排好。” 地理查询语法,就是把这类日常指令翻译成数据库听得懂的 SQL。

最常用的范围查询是 ST_DWithin(a, b, radius)。它专门利用空间索引快速筛出距离小于阈值的记录,相当于“以 b 为圆心画一个半径圈,把圈内的 a 都挑出来”。另一个重要能力是空间连接(Spatial Join):让两张表按空间关系“配对”,例如把商铺表和小区表用 ST_Intersects 连接,即可找出“所有位于小区内部的商铺”。

邻近查询通常这样写:SELECT * FROM pois ORDER BY ST_Distance(geom, :my_location) ASC LIMIT 10;,数据库会返回离你最近的 10 个对象。空间连接与普通 JOIN 的关键差异在于关联条件:普通 JOIN 比较字段值是否相等,空间 JOIN 比较两个几何体的位置关系——距离、包含、相交等。

地理查询语法让你能用一句话调动空间函数和索引。不过在实际项目中还会遇到一个隐蔽的坑——坐标系。同样的经纬度,在不同坐标系下算出的距离可能相差甚远。

ST_DWithin(A,B,ϵ)⟺min⁡a∈A, b∈Bd(a,b)≤ϵ\text{ST\_DWithin}(A, B, \epsilon) \Longleftrightarrow \min_{a \in A,\, b \in B} d(a, b) \le \epsilon
这个公式说明 ST_DWithin 的数学本质:两个几何体上所有点对之间的最小距离,只要不超过给定半径,就判定为“在范围内”。这正是配送员画圈找店的逻辑。
  1. 集合 A 与 BA、B 代表两个几何对象,每个对象内部包含无数个点,如一个多边形区域的边界和内部。
    A,BA, B
  2. 最小距离\min_{a \in A,\, b \in B} d(a, b) 表示遍历 A 上所有点与 B 上所有点,取距离的最小值——这是“两者靠多近”的客观度量。
    min⁡a∈A, b∈Bd(a,b)\min_{a \in A,\, b \in B} d(a, b)
  3. 阈值判定\le \epsilon 说明只要最小距离小于等于半径就返回真,对应 SQL 中 WHERE 子句的过滤条件。
    min⁡d(a,b)≤ϵ\min d(a, b) \le \epsilon

坐标系转换

同样一条街道,不同地图商家画出来的图可能完全不一样:有的用经纬度把地球画成球面弧线,有的展开成方形平面。坐标系就像方言,各说各话,统一之前谁也听不懂谁。PostGIS 必须处理坐标系转换,才能让“方言”互译。

PostGIS 通过 SRID(空间参考标识符)标记每个坐标遵循的规则。最常见的两个坐标系:SRID 4326 是 WGS84 经纬度坐标系,用度表示位置,适合全球定位;SRID 3857 是 Web 墨卡托投影坐标系,把球面摊平成平面,单位是米,适合网页地图。如果直接用 4326 的 geometry 计算距离,得到的结果单位是“度”,而不是米。

ST_Transform(geom, target_srid) 函数能把一个坐标系转换到另一个。比如把 4326 经纬度转成 3857 后再算距离,单位就是米。若需要高精度的球面距离,PostGIS 还提供 geography 类型,直接按地球椭球计算,结果自动以米为单位。选择 geometry 还是 geography,本质是在“计算速度”与“结果精度”之间做权衡。

坐标系转换就像地图的“普通话翻译官”。做完这一步,PostGIS 才能真正说出“用户在 3 公里内”这样精确而可信的答案。

1∘ 经度≈111×cos⁡(φ) 千米1^\circ \text{ 经度} \approx 111 \times \cos(\varphi) \text{ 千米}
这个公式告诉我们:1 度经度在地球上对应的实际距离,会随纬度变化——赤道约 111 公里,到了高纬度会大幅缩短。因此直接用“度”当“米”来算距离,在纬度较高的地区会严重失真。
  1. 111 千米地球赤道上 1 度经度大约对应 111 公里的弧长,这是公式的基准值。
    1∘≈111 km1^\circ \approx 111\ \text{km}
  2. 纬度修正\cos(\varphi) 中的 \varphi 是纬度,余弦值随纬度增大而减小,代表经度线向两极方向逐渐收拢。
    cos⁡(φ)↓(φ↑)\cos(\varphi) \downarrow \quad (\varphi \uparrow)
  3. 实际意义在纬度 60° 处,\cos(60^\circ) = 0.5,1 度经度只剩约 55.5 公里。如果忽略坐标系直接计算,距离误差可能超过一半。
    111×cos⁡(60∘)=55.5 km111 \times \cos(60^\circ) = 55.5\ \text{km}

AI 应用场景

LBS 附近推荐

阶段:特征工程与在线检索

解决的问题:传统做法把区域内所有 POI 拉出来,在应用层逐个算距离再筛选,数据量一大就严重卡顿。用 PostGIS 的 ST_DWithin 配合 GiST 索引,把“找附近”下推到数据库,毫秒级返回候选集。

具体案例:外卖 App 打开首页时,后端收到用户经纬度,执行一条带空间索引的 ST_DWithin 查询,一次性返回 3 公里内营业餐厅的 ID 列表。AI 推荐模型基于这些候选,再做个性化排序与评分。

地理围栏与配送区域分析

阶段:数据加工与规则特征计算

解决的问题:风控和物流场景需要判断用户或车辆是否进入某个多边形区域,纯人工比对效率极低。利用 ST_Intersects、ST_Buffer 可自动完成围栏命中检测。

具体案例:共享单车团队用 PostGIS 保存城市禁停区多边形,每次还车落库时执行 ST_Intersects 判断,命中禁停区就触发调度提醒,避免人工巡检的成本。

空间特征工程

阶段:训练数据准备

解决的问题:房价预测、客流预测等 AI 模型需要“到地铁站距离”“周边 POI 密度”等空间特征。PostGIS 能用 SQL 批量计算这些特征,直接灌入训练表。

具体案例:房价预测模型用 ST_Distance 批量计算每套房到最近学校、医院、公园的距离,再将生成的数值特征送入梯度提升树模型训练,显著提升预测精度。

Python 演示

python59 行
import psycopg2 CONN = dict(host="localhost", port=5432, dbname="gis_demo",            user="postgres", password="postgres")  def main():    conn = psycopg2.connect(**CONN)    conn.autocommit = True    cur = conn.cursor()    cur.execute("CREATE EXTENSION IF NOT EXISTS postgis;")    cur.execute("""        DROP TABLE IF EXISTS pois;        CREATE TABLE pois (            id SERIAL PRIMARY KEY,            name TEXT,            geom geometry(Point, 4326)        );    """)    cur.execute("CREATE INDEX idx_pois_geom ON pois USING GIST (geom);")    data = [        ("地铁站", 116.397, 39.908),        ("咖啡店", 116.390, 39.915),        ("书店", 116.404, 39.901),        ("公园", 116.412, 39.912),    ]    for name, lon, lat in data:        cur.execute(            "INSERT INTO pois (name, geom) VALUES (%s, ST_SetSRID(ST_MakePoint(%s, %s), 4326));",            (name, lon, lat),        )    lon, lat = 116.391, 39.910    cur.execute(        """        SELECT name,               ST_Distance(                   ST_Transform(geom, 3857),                   ST_Transform(ST_SetSRID(ST_MakePoint(%s, %s), 4326), 3857)               ) AS dist_m        FROM pois        WHERE ST_DWithin(                  ST_Transform(geom, 3857),                  ST_Transform(ST_SetSRID(ST_MakePoint(%s, %s), 4326), 3857),                  1500              )        ORDER BY dist_m;        """,        (lon, lat, lon, lat),    )    rows = cur.fetchall()    print("1.5公里内发现:")    for name, dist in rows:        print("  - %s: %.0f 米" % (name, dist))    cur.close()    conn.close()  if __name__ == "__main__":    main()
目的:连接启用了 PostGIS 的 PostgreSQL,建表、插入带经纬度的 POI 点、创建 GiST 空间索引,最后执行“1.5 公里内从近到远”的空间查询,打印距离结果。
  1. cur.execute("CREATE EXTENSION IF NOT EXISTS postgis;")激活空间扩展,相当于给这一数据库实例接通 GPS 电源。
  2. CREATE INDEX idx_pois_geom ON pois USING GIST (geom);为几何字段建立 GiST 索引,让“找附近”查询不用扫全表。
  3. INSERT INTO pois (name, geom) VALUES (%s, ST_SetSRID(ST_MakePoint(%s, %s), 4326));用 ST_MakePoint 从经度纬度生成点,再 ST_SetSRID 标注坐标系为 4326。
  4. ST_Transform(geom, 3857)先把经纬度转成 3857 米制投影,再算距离,结果单位才是米。
  5. ST_DWithin(..., 1500)范围谓词直接走空间索引,只保留 1.5 公里以内的候选点。
  6. ORDER BY dist_m按距离从近到远排序,方便前端直接展示列表。

常见误区

误区初学者在表里加了一个 `geometry` 字段并插入数据后,发现空间查询依然奇慢无比,于是怀疑 PostGIS 根本没用。

正解只加字段不建索引,就像城市只装了门牌号却没装导航系统,找一栋楼仍然得挨家挨户问。必须显式执行 CREATE INDEX ... USING GIST (geom);,数据库才会为空间数据建立高效检索路径。空间字段本身不会自动生成索引。

为何常见:很多人受普通 B-Tree 索引思维的影响,以为主键有了索引就等于所有字段都有索引,忽略了空间数据需要专用的 GiST 索引。

误区有人用 `ST_Distance(a.geom, b.geom)` 算出 0.02,直接当作 20 米写入业务逻辑,结果定位和推荐全乱套。

正解SRID 4326 是经纬度坐标系,单位是“度”而不是“米”。1 度经度在赤道约 111 公里,在纬度 60° 处只有 55 公里。正确做法是转成 3857 等米制投影后再算,或改用 geography 类型获得球面米制距离。

为何常见:日常看到的地图都是平面展开图,让人误以为经纬度可以直接当作平面坐标;没有意识到球面到平面的投影变形。

误区开发者写 `WHERE ST_Distance(geom, :p) < 1000` 来找附近点,发现查询还是慢如蜗牛,于是觉得索引没生效。

正解ST_Distance 是计算函数,只负责算出距离,数据库很难用它反推“哪些点可能近”。正确写法是用 ST_DWithin(geom, :p, 1000) 这类专用范围谓词,它被设计为“先筛后算”,能充分利用 GiST 索引。

为何常见:函数和谓词的区别容易被忽视,大家习惯把“计算结果”直接放进 WHERE,没有理解索引生效需要谓词配合。

误区“反正都是存几何数据,我统一用 geometry 类型就行,省得麻烦。”

正解geometry 按平面欧氏几何计算,速度较快,但结果依赖 SRID 定义的单位;geography 按地球椭球体计算,结果永远以米为单位、精度更高,但计算代价更大。跨大洲航线距离、全球范围搜索应选 geography;局地平面分析选 geometry 更高效。

为何常见:对 SRID 与投影的概念不熟,以为“几何”就是“坐标系无关的图形”,忽略了不同坐标系对计算结果的根本影响。

面试题

Q1. 在 PostgreSQL 中激活 PostGIS 扩展用哪条 SQL?

单选题 · easy

  • A.CREATE EXTENSION postgis;← 正确答案
  • B.INSTALL EXTENSION postgis;
  • C.ENABLE EXTENSION postgis;
  • D.LOAD EXTENSION postgis;

答案:A。PostGIS 是 PostgreSQL 的扩展模块,激活命令固定为 CREATE EXTENSION postgis;。INSTALL/ENABLE/LOAD 都不是 PostgreSQL 原生扩展语法,这是面试中高频的基础题。

Q2. PostGIS 中表示“点”的几何类型是?

单选题 · easy

  • A.POINT← 正确答案
  • B.CIRCLE
  • C.NODE
  • D.ANCHOR

答案:A。PostGIS 的基础几何类型是 POINT(点)、LINESTRING(线)、POLYGON(面)。CIRCLE、NODE、ANCHOR 都不是内置几何类型,选项 C 的 NODE 容易和网络术语混淆,需注意区分。

Q3. PostGIS 空间索引通常使用哪种索引方法?

单选题 · mid

  • A.B-Tree 索引
  • B.Hash 索引
  • C.GiST 索引← 正确答案
  • D.Bitmap 索引

答案:C。空间数据是多维坐标,普通 B-Tree 只能排序一维数值,Hash 索引也不适合范围查询。GiST 是 PostgreSQL 为空间数据设计的广义搜索树,能有效组织 bounding box 并支持 ST_DWithin 等空间谓词快速剪枝。

Q4. 要查询“3 公里内”的附近 POI,推荐使用哪个函数?

单选题 · mid

  • A.ST_Distance
  • B.ST_DWithin← 正确答案
  • C.ST_Area
  • D.ST_Buffer

答案:B。ST_DWithin 是范围谓词,专为空间索引优化的“半径圈内过滤”,效率远高于先 ST_Distance 计算再手动比较。ST_Distance 只负责算距离,ST_Area 算面积,ST_Buffer 生成缓冲区,都不适合做“附近过滤”。

Q5. 关于 PostGIS 空间索引,下列说法正确的是?

多选题 · mid

  • A.用 GiST 索引加速空间查询← 正确答案
  • B.用 B-Tree 索引即可加速
  • C.索引帮助查询快速剪枝← 正确答案
  • D.索引能加速一切查询

答案:AC。GiST 索引通过 bounding box 剪枝大幅减少精确计算量,A 和 C 正确。B-Tree 不擅长多维空间排序;索引并非万能,对非空间条件或函数计算不定式查询也可能失效,D 过于绝对。

Q6. SRID 4326 代表什么坐标系?

单选题 · mid

  • A.WGS84 经纬度坐标系← 正确答案
  • B.北京 54 坐标系
  • C.GCJ02 火星坐标系
  • D.Web 墨卡托投影系

答案:A。SRID 4326 是 WGS84 椭球下的经纬度坐标系,单位是度,GPS 原始输出一般就是它。3857 才是 Web 墨卡托;GCJ02 是国内的加密坐标系,与 PostGIS 标准 SRID 无关。

Q7. 下列哪些操作能提升空间查询性能?

多选题 · hard

  • A.为几何字段建 GiST 索引← 正确答案
  • B.把距离函数写进 SELECT
  • C.用 ST_DWithin 做范围过滤← 正确答案
  • D.依赖主键索引完成空间范围查找

答案:AC。GiST 索引是空间加速的核心,ST_DWithin 能让谓词走索引,两者搭配最快。SELECT 里写 ST_Distance 只是输出计算结果,不参与过滤;主键索引是一维的,无法高效完成二维空间范围查找。

Q8. 对 SRID 4326 的 geometry 执行 ST_Distance,结果单位是什么?

单选题 · hard

  • A.米(meter)
  • B.千米(公里)
  • C.度(degree)← 正确答案
  • D.弧度(radian)

答案:C。4326 的 geometry 是经纬度坐标,ST_Distance 按平面欧氏公式计算,返回单位与输入相同即“度”。想要米制距离,必须先 ST_Transform 到 3857 等投影坐标系,或改用 geography 类型。

Q9. 关于 geography 与 geometry 的描述,正确的是?

单选题 · extreme

  • A.geography 按球面计算且单位是米← 正确答案
  • B.geometry 按球面计算且单位是米
  • C.geography 只支持 POINT 类型
  • D.geometry 不支持 SRID 设定

答案:A。geography 类型把地球当作椭球体计算,距离结果自动以米为单位,适合大范围跨国测量;geometry 按平面计算,单位取决于 SRID。geography 支持多种类型,geometry 同样有 SRID,C、D 均为错误说法。

Q10. 关于 ST_Transform 函数,说法正确的是?

多选题 · mid

  • A.可把 4326 转成 3857← 正确答案
  • B.可把经纬度换算成米制← 正确答案
  • C.可以把文本转成几何
  • D.可以把数字转成布尔

答案:AB。ST_Transform(geom, target_srid) 用于坐标系转换,从 4326 经纬度转到 3857 后单位成为米,A、B 正确。文本转几何是 ST_GeomFromText 的职责;数字转布尔是类型转换函数 ST_AsBoolean 之类,与坐标转换无关。