Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • 技术文档

  • 算法

  • 工作总结

    • 时区校正
    • 上传下载文件方式总结
    • web异常监控和分析
    • 前端优化指南
    • http缓存机制
    • 静态资源灰度发布
    • 浏览器原理及渲染机制
    • Chrome DevTools 渲染分析实战
    • Layout Thrashing(布局抖动)
    • Composite Layer(合成层)
    • 全局设置滚动条样式好吗?
    • 虚拟列表如何避免Layout和Paint
    • 前端安全知识
    • 安全(同源策略 / CSP / CORS)
    • 浏览器安全模型
    • 从chrome v8 讲安全
    • WebAssembly(Wasm)
    • XSS → JIT → 沙箱逃逸
    • 微前端总结
    • websocket聊天
    • Uni-app基础知识
    • react16高级特性
    • react16基础知识总结
    • vue2常见原理总结
    • vue2基础知识总结
    • webpack优化实践
    • webpack基础应用知识总结
    • Agent Skills是什么?跟MCP Workflow Command Prompt的关系。
    • 从cnn到transformer全解大模型
    • 什么是 Encoder 和 Decoder 结构
    • GPT 为什么能“看懂”问题
    • GPT 是怎么学会数学的
    • GIS 基础三件套
    • GIS必会知识点
    • 100 万点地图怎么渲染?
    • GIS空间索引的实现
      • 一、为什么需要空间索引
      • 二、空间索引核心思想
      • 三、R-Tree(GIS最常见)
        • 插入流程
        • 1 找最合适节点
        • 2 插入叶子节点
        • 3 节点溢出
      • 四、查询流程(核心)
        • 1 从 root 开始
        • 2 如果不相交
        • 3 如果相交
        • 4 到达 leaf
      • 五、QuadTree(地图常用)
      • 六、KD-Tree(最近邻搜索)
      • 七、前端如何实现空间索引
        • rbush
      • 八、GIS 系统真实架构
      • 九、前端真实应用场景
        • 1 点击地图选点
        • 2 框选查询
        • 3 聚合算法
        • 4 碰撞检测
      • 十、空间索引怎么实现?
    • Cesium 从入门到精通:实战指南
    • OpenLayers 从零到精通:2025-2026实战指南
    • Mapbox GL JS 从零到精通:2025-2026实战指南
    • Cesium、OpenLayers 和 Mapbox GL JS 的关系、区别
    • 容器领域必学的黄金组合
    • 小程序笔记
    • 小程序工程模板设计
    • 地图标绘--射线法来计算点在多边形内
  • 实用技巧

  • 收藏夹

  • 技术
  • 工作总结
mamingjuan
2026-03-06
目录

GIS空间索引的实现

# 一、为什么需要空间索引

假设地图有 100 万个点。

如果用户点击地图,需要找:

离鼠标最近的点
1

最简单方式:

遍历所有点
O(n)
1
2

如果:

n = 1000000
1

每次点击都遍历:

1000000 次计算
1

地图就会卡顿。

所以需要:

空间索引(Spatial Index)
1

目标:

O(n) → O(log n)
1

# 二、空间索引核心思想

普通数据库索引:

B-Tree
1

是 一维数据。

但 GIS 数据是:

二维 / 三维
1

例如:

(x, y)
1

所以需要:

多维索引
1

常见结构:

索引 用途
R-Tree GIS 最常见
QuadTree 地图瓦片
KD-Tree 最近邻搜索

# 三、R-Tree(GIS最常见)

R-Tree 是 矩形树。

核心思想:

用矩形包裹对象
1

例如:

        Root
       /    \
    NodeA  NodeB
1
2
3

每个节点是:

MBR
Minimum Bounding Rectangle
1
2

例如:

+--------+
| 点集合 |
+--------+
1
2
3

# 插入流程

假设插入一个点:

P(10,20)
1

步骤:

# 1 找最合适节点

选择 扩展面积最小 的矩形。

例如:

Area increase 最小
1

# 2 插入叶子节点

Leaf
 ├ Point1
 ├ Point2
 └ Point3
1
2
3
4

# 3 节点溢出

如果:

node > maxEntries
1

就:

split
1

拆分节点。


# 四、查询流程(核心)

例如查询:

鼠标附近的点
1

步骤:

# 1 从 root 开始

检查:

query bbox
1

是否和节点矩形相交。


# 2 如果不相交

直接:

skip
1

# 3 如果相交

进入子节点。


# 4 到达 leaf

返回数据。


查询复杂度:

O(log n)
1

而不是:

O(n)
1

# 五、QuadTree(地图常用)

地图系统很常见:

QuadTree
1

原理:

空间递归四分
1

示意:

+--------+
|        |
|   +----+----+
|   |    |    |
|---+----+----|
|   |    |    |
|   +----+----+
1
2
3
4
5
6
7

每个节点分成:

4 个象限
1

优点:

实现简单
1

很多地图:

tile
1

本质就是:

QuadTree
1

# 六、KD-Tree(最近邻搜索)

如果问题是:

找最近的点
1

通常使用:

KD-Tree
1

原理:

交替按 x / y 分割
1

示例:

x < 50
      \
       y < 30
1
2
3

适合:

Nearest Neighbor
1

# 七、前端如何实现空间索引

前端一般不会自己写 R-Tree。

常见库:

# rbush

非常流行。

import RBush from "rbush"

const tree = new RBush()

tree.insert({
  minX: 10,
  minY: 20,
  maxX: 10,
  maxY: 20,
  id: "point1"
})
1
2
3
4
5
6
7
8
9
10
11

查询:

tree.search({
  minX: 0,
  minY: 0,
  maxX: 50,
  maxY: 50
})
1
2
3
4
5
6

复杂度:

O(log n)
1

# 八、GIS 系统真实架构

大型地图系统通常:

前端
 ↓
VectorTile
 ↓
TileServer
 ↓
PostGIS
1
2
3
4
5
6
7

数据库层:

GIST Index
1

例如:

CREATE INDEX idx_geom
ON points
USING GIST(geom)
1
2
3

查询:

ST_Intersects
1

# 九、前端真实应用场景

空间索引常见用途:

# 1 点击地图选点

click → nearest point
1

# 2 框选查询

bbox search
1

# 3 聚合算法

cluster
1

# 4 碰撞检测

例如:

label collision
1

# 十、空间索引怎么实现?

空间索引主要用于优化 GIS 数据查询,因为空间数据是二维或三维的,普通 B-Tree 只能处理一维数据,所以 GIS 通常使用多维索引结构,比如 R-Tree、QuadTree 或 KD-Tree。

其中 R-Tree 是最常见的,它通过 Minimum Bounding Rectangle 对空间对象进行分组,形成层级树结构。查询时只需要遍历与查询范围相交的节点,从而将复杂度从 O(n) 降低到 O(log n)。

在地图系统中,QuadTree 常用于瓦片地图划分,而 KD-Tree 更适合最近邻搜索。

在前端实现中,一般会使用 rbush 这样的库构建 R-Tree 索引,用于快速实现点击选点、框选查询或点位聚合等功能。

上次更新: 2026/03/06, 03:23:20
100 万点地图怎么渲染?
Cesium 从入门到精通:实战指南

← 100 万点地图怎么渲染? Cesium 从入门到精通:实战指南→

Copyright © 2015-2026 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式