Go go-geom 怎样计算几何对象的坐标包围盒
使用 go-geom 计算几何对象的坐标包围盒,核心是调用 g.Bounds(),确认 IsEmpty() 为假后,再读取各维度的 Min 与 Max。二维 XY 对象的常用顺序是 [minX, minY, maxX, maxY]。这个范围与坐标轴平行,适合表达视图范围或作粗筛选。
例如,一条配送线路已经用平面坐标表示,需要给地图视图提供覆盖范围。这里先解决四个极值的取得,不加入空间索引、投影转换或最小旋转矩形算法。示例固定依赖 v1.6.1,该标签的 go.mod 声明 Go 1.22;选定版本是为了让接口依据明确,不表示它是最新版本。
项目官方仓库:https://github.com/twpayne/go-geom
先用四个极值描述二维范围
LineString 表示折线,XY 规定两个坐标分量的含义;Bounds 保存各维最小值与最大值。维度0对应X,维度1对应Y。因此,X极值来自 Min(0)、Max(0),Y极值来自 Min(1)、Max(1)。IsEmpty 则是范围对象的空状态判断。接口定义可见包文档的 Bounds 部分。

| 取值 | 含义 |
|---|---|
| Min(0) | 全部坐标中的最小X |
| Min(1) | 全部坐标中的最小Y |
| Max(0) | 全部坐标中的最大X |
| Max(1) | 全部坐标中的最大Y |
把有效折线转换成四个数
在新建的示例目录中初始化模块并固定依赖;已有项目跳过初始化。以下是供读者运行的示例,不是本文实际运行记录。
# 新示例目录初始化;已有 go.mod 的项目不再执行这一行 go mod init example.com/geometrybox # 使用与本文依据一致的依赖标签 go get github.com/twpayne/go-geom@v1.6.1 # 把下方完整程序保存为 main.go 后执行 go run .
函数刻意只接收 *geom.LineString,把输入限制在二维有限坐标折线。SetCoords 的错误用于发现坐标分量数不合布局的问题;数值是否有限由示例另外处理,不把这些责任都交给包围盒方法。
package main
import (
"fmt"
"log"
"math"
"github.com/twpayne/go-geom"
)
// lineBoxXY 只接收二维折线,拒绝非有限坐标和空范围。
func lineBoxXY(line *geom.LineString) ([4]float64, error) {
var box [4]float64
if line == nil {
return box, fmt.Errorf("折线不能为空指针")
}
if line.Layout() != geom.XY {
return box, fmt.Errorf("需要 XY 布局,实际为 %v", line.Layout())
}
for i, value := range line.FlatCoords() {
if math.IsNaN(value) || math.IsInf(value, 0) {
return box, fmt.Errorf("坐标分量 %d 不是有限数", i)
}
}
bounds := line.Bounds()
// 空对象没有可以交给视图使用的有限极值。
if bounds.IsEmpty() {
return box, fmt.Errorf("折线没有坐标")
}
box = [4]float64{
bounds.Min(0), bounds.Min(1),
bounds.Max(0), bounds.Max(1),
}
return box, nil
}
func main() {
// 示例使用同一平面坐标系中的三个 XY 点。
line, err := geom.NewLineString(geom.XY).SetCoords([]geom.Coord{
{12, 8}, {-4, 17}, {7, -3},
})
if err != nil {
log.Fatal(err)
}
box, err := lineBoxXY(line)
if err != nil {
log.Fatal(err)
}
fmt.Printf("minX=%g minY=%g maxX=%g maxY=%g\n",
box[0], box[1], box[2], box[3])
}
按给出的三个点手工推算,X范围为-4至12,Y范围为-3至17。由此可预期程序打印下列文字;这组数值是示例推导,未在本轮执行程序。
minX=-4 minY=-3 maxX=12 maxY=17
空范围和零宽、零高不是一回事
新建但尚未扩展的范围没有有效坐标。v1.6.1 的实现用正无穷初始化最小值、负无穷初始化最大值,并通过极值关系判断空状态。所以先判断空,再向外提供数字;不要把没有坐标的范围序列化成正常视图参数。依据:固定标签的 bounds.go。
一个有效点的最小值和最大值可以相等;一条竖直折线的X跨度也可以为零。这类范围不等于没有数据。如果视图需要最小显示宽度,应由调用方按业务单位增加留白,不要把零跨度当空对象丢弃。对于 NaN 或无穷值,示例入口直接返回错误,避免让异常值进入后续矩形计算。
多条折线如何合并范围
几条折线共享一个范围时,可以创建 geom.NewBounds(geom.XY),再用 Extend 扩展。此处的折线集合必须满足XY布局、同一坐标系、有限坐标三项输入约束;Extend 关联的是已有范围及待包含的几何,合并Bounds保留所有有效坐标的极值。

// 以下片段放在 main 内,接在已经创建 line 的代码之后。
other, err := geom.NewLineString(geom.XY).SetCoords([]geom.Coord{
{20, 5}, {22, 11},
})
if err != nil {
log.Fatal(err)
}
combined := geom.NewBounds(geom.XY)
for _, item := range []*geom.LineString{line, other} {
// 复用上面的输入约束;空折线在本例中直接跳过。
if item == nil {
log.Fatal("待合并折线不能为空指针")
}
if item.Empty() {
continue
}
if _, err := lineBoxXY(item); err != nil {
log.Fatal(err)
}
combined.Extend(item)
}
if combined.IsEmpty() {
log.Fatal("没有可用的几何坐标")
}
fmt.Printf("合并范围:[%g,%g,%g,%g]\n",
combined.Min(0), combined.Min(1),
combined.Max(0), combined.Max(1))
把追加折线的两个点纳入计算后,预期合并范围为 [-4,-3,22,17]。这个扩展会修改 combined;如果需要保留旧范围供另一处使用,应先复制范围对象,不要只复制指针变量。
应用到其他几何时注意什么
包提供统一的几何接口,Point、Polygon等类型也可取得各自的Bounds。这里的辅助函数只针对折线,替换类型时要重新安排输入约束,不能把函数签名直接当通用处理器。普通几何的坐标存储和范围计算关系可参考项目的几何基础实现。
布局与坐标系分开看。XY只说明有X、Y分量;同为XY不代表单位和投影相同。设置SRID也不能替代实际坐标转换。经纬度数据直接取极值,是输入数值的矩形范围;跨越经度接缝时,它未必是视觉上最紧的地理覆盖区域。
多维输入先明确要哪一层范围。XYZ多了高度,XYM第三个分量是M而非高度;如果只要地图二维范围,就明确读取前两维并单独制定输入策略。不要默认维度2始终代表Z。布局及维度含义见项目的 Layout 定义。
相关问题
包围盒重叠就意味着原几何相交吗?
不能据此作精确相交结论。矩形范围适合粗筛,原始几何的形状仍需另行判断。
Bounds是不是面积最小的旋转矩形?
不是。这里按坐标轴逐维取得极值,没有搜索矩形旋转角度。
几何坐标改了,之前保存的范围会自动变吗?
不要依赖这种联动。需要新范围时重新调用几何对象的Bounds;缓存范围的失效由调用方管理。对视图参数而言,先确认输入,再判断空状态,最后读取四个极值,是最容易维护的一种写法。
Go go-geom 怎样用平铺坐标构造二维折线
- 上一篇
- Go go-geom 怎样用平铺坐标构造二维折线
- 下一篇
- Redis LFU频率计数为什么不等于精确访问次数
-
- Golang · Go教程 | 37分钟前 |
- Go go-shp 怎样把点数据写成Shapefile
- 371浏览 收藏
-
- Golang · Go教程 | 38分钟前 | Go教程 · Go DBF Shapefile go-shp ReadAttribute
- Go go-shp 怎样读取DBF属性字段
- 301浏览 收藏
-
- Golang · Go教程 | 47分钟前 | go · Go go-geom Polygon LinearRing 外环 内环
- Go go-geom 怎样为多边形添加外环与内环
- 287浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go go-geom 怎样用平铺坐标构造二维折线
- 134浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go groot 怎样把ROOT对象写入新文件
- 121浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go groot 怎样列出ROOT文件中的对象键
- 445浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go fitsio 怎样向FITS表追加一条结构化记录
- 464浏览 收藏
-
- Golang · Go教程 | 2小时前 |
- Go jsonschema 怎样从内存注册被引用的 Schema
- 337浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 801次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 792次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 879次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 849次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 680次使用
-
- Java 性能优化上线清单:从定位、改造到灰度发布
- 2026-06-11 860浏览
-
- Spring Boot 压测验证:Gatling、JMeter 与性能回归门禁
- 2026-06-11 843浏览
-
- Java NMT 非堆内存排查:Direct Buffer、线程栈与 Metaspace 分析
- 2026-06-11 826浏览
-
- Spring Boot 容器内存优化:JVM 堆、非堆与 MaxRAMPercentage
- 2026-06-11 809浏览
-
- Tomcat 连接与线程参数调优:maxThreads、acceptCount 与 KeepAlive
- 2026-06-11 792浏览

