第10章 - 属性表、数据编辑与字段采集
在 GeoLibre 里,”编辑数据”不是一个按钮,而是四条互不相同、边界清晰的通路:
- 属性表(Attribute table)——改值、加字段、算字段、看统计;
- GeoEditor——在地图上改几何;
- 写回(Save edits)——把上面两者的结果送回文件、PostGIS 表或 ArcGIS 要素服务;
- 字段采集(Field Collection / GPS Tracking)——在野外按表单新增要素。
这四条通路的”可编辑性”由图层类型决定,不由用户角色决定。本章按”读 → 选 → 改 → 写 → 采”的顺序把它讲完,最后给出一份数据质量清单。
说明:本章基于 GeoLibre 3.4。菜单与按钮名保留英文原文。事实来源为
docs/user-guide/attribute-table.md、docs/arcgis-editing.md、docs/user-guide/field-collection.md、docs/user-guide/layers.md、docs/user-guide/map-controls.md与源码apps/geolibre-desktop/src/lib/geometry-measure.ts、packages/core/src/types.ts,以及 i18n 词条apps/geolibre-desktop/src/i18n/locales/en.json的attributeTable/fieldCollection段。
10.1 属性表的入口与可编辑边界
10.1.1 三种打开方式
| 方式 | 路径 | 说明 |
|---|---|---|
| 图层动作 | Layers 面板 → 图层行 … → Open attribute table |
最常用;同时把该图层设为当前图层 |
| 底部面板 | 状态栏上方的属性表区域,展开后左上角有图层选择器 | 未选图层时提示 “- select a layer with attributes” |
| 识别结果 | Identify features 弹窗里的 Edit attributes | 直接跳到该要素所在行并进入编辑模式 |
属性表停靠在窗口底部,可以:
- 拖上边缘调整高度;
- 用工具栏末端的按钮折叠 / 展开 / 关闭;
- 在 Settings → Layout 里控制整个面板是否显示;
- 在窄屏上自动隐藏,按钮只显示图标。
10.1.2 哪些图层能进属性表
| 图层类型 | 属性表 | 可编辑性 |
|---|---|---|
| GeoJSON(本地文件、URL、处理结果) | ✅ | 值可编辑、字段可增删、可写回文件(桌面) |
| Add Data → Vector Layer 图层 | ✅ | 只读(样式由自己的控件管,不进 GeoLibre 图层模型) |
| CZML 图层 | ✅ | 不提供字段管理与写回 |
| DuckDB 图层(SQL 结果、DuckDB 数据源) | ✅ | 值可在内存里改;不支持 Add field / Calculate / Fields / 列菜单 / 属性表单 / Export |
| ArcGIS 要素服务图层 | ✅ | 可编辑,需显式保存回服务(见 10.10) |
| PostGIS / SQL Server 表 | ✅ | 可编辑,保存回表 |
| 栅格、瓦片、点云 | ❌ | 提示 requiresVectorLayer |
这张表最重要的一列是”可编辑性”。它解释了属性表里为什么有些按钮会消失而不是变灰:
Add field、Calculate、Fields 出现在可编辑的 GeoJSON 图层且不在编辑状态时;Explore、Statistics、Charts、Dashboard 在编辑状态下隐藏。
10.1.3 大数据量下的行为
属性表对行做了虚拟化(只渲染可见行),所以几十万行也能流畅滚动。但要记住三件事:
- 没有分页、没有行数上限,代价是全部读进内存;
- 排序、搜索以及各对话框都作用于内存中的每一行,不是当前视口;
- 页脚一直显示”要素数 / 显示数 / 选中数”,用它可以判断”是数据真少,还是被筛选了”。
注意:属性表的虚拟化与 SQL 工作区结果表的”只显示前 500 行”是两套机制,后者见 第11章 SQL 工作区与 DuckDB 空间分析。
10.2 工具栏、导航与选择
10.2.1 工具栏按钮
| 按钮 | 作用 | 何时出现 |
|---|---|---|
| Edit / Save | 打开行内编辑 / 提交修改 | 可编辑图层 |
| Add field | 新增字段 | 可编辑 GeoJSON、非编辑态 |
| Calculate | 打开字段计算器 | 同上 |
| Fields | 显示/隐藏列(Show fields、Show all fields) | 同上 |
| Explore | 打开列浏览器 | 非编辑态 |
| Statistics | 单字段统计 | 非编辑态 |
| Charts | 单/双字段图表 | 非编辑态 |
| Dashboard | 打开 Dashboard 并预选该图层 | 非编辑态 |
| Refresh | 重新读源(本地文件则重读磁盘) | 可刷新图层 |
| Export | 导出图层 | GeoJSON 派生图层 |
| Search attributes… | 按值或 id 过滤行,忽略大小写 | 恒有 |
| Zoom to selection | 选择变化时保持地图框住选区 | 恒有 |
| Show All Features / Show Selected (n) | 全部 / 只看选中 | 恒有 |
| Clear selection | 取消选择 | 恒有 |
Refresh 有一个细节:ArcGIS 图层有未保存编辑时会被禁用——因为刷新会用服务端数据覆盖你还没提交的改动。
10.2.2 导航与显示
| 操作 | 行为 |
|---|---|
| 点列头 | 升序 → 降序(再次点击切换) |
| 拖列边界 | 调整列宽(列宽不随项目保存) |
| 单元格里的 URL | 显示为链接,点击在浏览器打开 |
| 单元格里的对象 | 显示为 JSON 文本;编辑时必须保持合法 JSON |
| 长文本 | 截断显示,悬停可见全文 |
10.2.3 表与地图共享一套选择
属性表与地图共用同一个选择集,任一侧改动另一侧立刻可见:
| 操作 | 效果 |
|---|---|
| 点一行 | 选中该要素 |
Ctrl/Cmd + 点 |
加入或移出选择 |
Shift + 点 |
选择连续区间 |
Shift + Ctrl/Cmd + 点 |
在当前区间上追加 |
| 地图上 Identify 一个要素 | 属性表滚动到对应行 |
10.2.4 按规则选择
手工点选之外,还有规则化通路(也在 Edit 菜单里):
| 命令 | 作用 |
|---|---|
| Select by Expression… | 按表达式选择;Modify current selection by 决定”新建 / 加入 / 移除 / 在选区内再选”;同一对话框也可 Filter layer,把表达式存成图层过滤器 |
| Select by Location… | 按与另一图层的空间关系选择:intersects、within、contains、disjoint |
| Invert Selection / Clear Selection | 反选 / 清空 |
| Zoom to Selection | 缩放到选区 |
| Export Selected Features as Layer | 把选区复制成新图层 |
此外图层的 … 菜单里有 Select features,提供点选、矩形、多边形、手绘、半径五种交互选择;按住 Shift 加选、Alt 减选、Shift+Alt 相交,Esc 取消。
提示:Select by Expression 与 Filter layer 的区别是”临时选择”与”持久过滤”。前者只影响选择集,后者会把不匹配的要素从地图上隐藏(但仍在属性表里)。想临时聚焦用前者,想长期只看一部分用后者。
10.3 字段管理
10.3.1 新增字段
Add field 只问三件事:
| 参数 | 取值 | 说明 |
|---|---|---|
| Field name | 文本 | 建议避开空格与标点,否则表达式里要写 props["field name"] |
| Type | Text / Number / Boolean | 创建后不可更改 |
| Default value | 文本(可空) | 会写入已有要素,不只是新要素 |
警告:字段类型不可变。需要”换类型”时正确做法是新建一个字段,用字段计算器把旧值转换过去,再删掉旧字段——而不是期待某个”修改类型”的入口。
10.3.2 列菜单(每个列头的 …)
| 菜单项 | 行为 |
|---|---|
| Rename field | 就地改名,Enter 保存、Esc 取消;引用该字段的样式与标注会跟着改 |
| Hide field | 隐藏该列(从 Fields 里恢复) |
| Exclude field on export / Include field on export | 保留在表里但不写进导出文件 |
| Move left / Move right | 调整列顺序 |
| Delete field | 从所有要素里删除该字段,需确认、不可撤销,并会清掉引用它的样式与标注 |
隐藏字段、列顺序、导出排除都随项目保存。这意味着”我明明隐藏了这列,换台机器又出来了”通常是因为打开的是另一个工程文件,而不是设置没保存。
10.3.3 只读边界
- DuckDB 图层与 Add Vector Layer 图层没有字段管理(没有 Add field / Calculate / Fields / 列菜单);
- DuckDB 图层要编辑就先 Materialize to editable layer,复制成 GeoJSON 图层;
- 连接进来的字段(Joins)、虚拟字段、编辑器跟踪字段(editor tracking)在表里是只读的。
10.4 字段计算器与表达式
10.4.1 两种计算,别混
GeoLibre 有两类”计算字段”,语义完全不同:
| 类型 | 入口 | 何时重算 | 表达式是否保存 |
|---|---|---|---|
| 字段计算器(Field calculator) | 属性表 Calculate | 只在点 Calculate 那一次 | 不保存 |
| 虚拟字段(Virtual field) | Style 面板 → Virtual fields | 数据变化时自动 | 保存(随项目) |
前者像 QGIS 的字段计算器,是一次性写入;后者像 QGIS 的虚拟字段,是持续派生。
10.4.2 操作步骤
- 点 Calculate;
- Target field 选 Update field(已有字段)或 Create field(输入新名字);
- 选 Output type:Auto (keep computed type)、Text、Number、Boolean;
- 写 Expression:
- 直接写字段名;名字含空格或标点时写
props["field name"]; - 点字段或函数芯片插入;
$index是行号,PI、E可用;
- 直接写字段名;名字含空格或标点时写
- 看实时 Preview:;
- 需要时勾 Only update the selected features;
- 点 Calculate。
10.4.3 函数清单
| 类别 | 函数 |
|---|---|
| 数学 | abs、ceil、floor、sqrt、exp、ln、log10、pow、min、max、round(x, digits) |
| 类型 | toNumber、toString |
| 文本 | upper、lower、trim、length、concat、substr、replace |
| 空值与逻辑 | isNull、coalesce、iif(condition, then, else) |
| 几何 | $length(unit)、$perimeter(unit)、$area(unit) |
几何度量的单位与测量面板完全一致:
| 类别 | 可选单位 |
|---|---|
| 长度 | meters(默认)、kilometers、miles、feet、yards、nautical-miles |
| 面积 | square-meters(默认)、square-kilometers、square-miles、hectares、acres、square-feet |
Geometry: 那一行按图层几何类型只列出适用的度量:点图层没有 Length/Area,线图层没有 Area,面图层三种都有;混合图层列出它实际包含的几何族。
10.4.4 表达式示例
round($area("square-kilometers"), 2)
iif(pop > 100000, "city", "town")
upper(concat(name, " (", state, ")"))
coalesce(ref_name, "未命名")
props["NAME_2"] + " / " + props["NAME_1"]
10.4.5 失败处理
一行表达式失败时:
- 该行结果写成 null(不是 0,也不是空字符串);
- 消息里报告有多少行失败;
- 其余行照常写入。
两条常见的静默错误来源:
- 单位拼错——
$area("hectare")少了 s 会抛错(Unknown area unit),而不是悄悄按平方米算;这是刻意的,因为差 10 000 倍的错误比报错更难查; - 数值被当成文本——
toNumber转换失败得到 null,后续比较可能按文本比较。
提示:
$area/$length的半径来自工程的 Celestial body(ellipsoidId)。月球工程里同一个多边形的面积只有地球的约 7.4%,这不是错误,详见 第09章 坐标系统、投影与测量。
10.5 虚拟字段与属性连接
10.5.1 虚拟字段
虚拟字段用 MapLibre 表达式定义,在数据变化时自动重算。
添加步骤:
- 选中图层,打开 Style 面板;
- 展开 Virtual fields → Add virtual field;
- 填 Field name;
- 写 Expression(MapLibre 表达式语法),例如:
["/", ["get", "pop"], ["get", "area_km2"]]
- 需要时点 Open builder 用表达式构建器;
- 关闭 Apply this virtual field 可以停用而不删除。
在属性表里的表现:只读、以斜体 + 函数图标显示,可以像普通字段一样用于样式、标注、过滤。
注意:虚拟字段的表达式是 MapLibre 表达式,不是字段计算器的表达式。前者是 JSON 数组,后者是类 JavaScript 的文本。把
$area(...)写进虚拟字段不会生效,把["get","pop"]写进字段计算器也不会。
10.5.2 属性连接(Joins)
连接把另一张表的字段接到本图层上,位置在 Style 面板 → Joins。
步骤:
- Add join;
- 选 Join layer(任何带要素的图层,几何被忽略);要连电子表格,先 Choose file 载入 CSV/TSV/TXT/Excel(有 Worksheet 与 Delimiter 选项),它会成为一个表图层;
- 选 Join field(连接表里的键)与 Target field(本图层的键);
- 选 Fields to join(默认除键以外的全部)与可选的 Field name prefix(例如
census_); - Add。
行为约定:
| 约定 | 说明 |
|---|---|
| 左连接 | 所有要素都保留,未匹配的要素在连接字段上为 null |
| 匹配报告 | 每次连接报告匹配了多少要素、连接表里有多少行未匹配 |
| 文本比较 | 键按文本比较,所以 5 能匹配 "5" |
| 空键不匹配 | 空字符串或 null 的键永远不会匹配 |
| 一对一 | 多条连接行共享一个键时,第一条生效 |
| 字段冲突 | 目标图层已有同名字段时,该连接字段被跳过——用前缀避开 |
| 实时 | 任一侧变化会重跑;随项目保存;Apply this join 可停用 |
| 只读 | 连接字段在属性表里只读,要改请改源表 |
需要内连接或一次性永久合并时,用 Processing → GeoLibre Toolbox → Vector → Join → Attribute join,它会写出一个新图层。
提示:连接(Join)适合”临时带一组列进来”。要长期维护的关系型数据,用数据库(PostGIS / DuckDB)在 SQL 里 JOIN,而不是在工程里挂一堆连接。
10.6 列浏览器、字段统计、图表与快速过滤
10.6.1 列浏览器(Column explorer)
Explore 一次剖析所有字段:
| 输出 | 内容 |
|---|---|
| 类型 | 推断出的字段类型 |
| 完整度 | 有值条数 |
| 空值 | null 条数 |
| 唯一值 | 不同值个数 |
| 分布 | 文本字段:最常见值的排行条形图;数值字段:直方图 + min/mean/max |
支持按名字过滤字段列表,Scope 可选”全部要素”或”被过滤的要素”。
它回答的是”这份数据里到底有什么”——一个 90% 为空的字段、一个混进了非数字的”数值”字段,在这里一眼就能看见。在调样式或建过滤条件之前先跑一遍列浏览器,能省掉大量返工。
10.6.2 字段统计
Statistics 针对单个字段,Scope 可选 all / filtered / selected:
| 字段类型 | 指标 |
|---|---|
| 所有字段 | Count、Nulls、Unique |
| 数值字段 | 追加 Non-numeric、Min、Max、Mean、Median、Std dev、Sum |
| 文本字段 | 追加出现频率最高的 5 个值及其计数 |
Copy 把整份摘要放到剪贴板。
10.6.3 图表
Charts 是”看一眼”的临时视图,不往工程里加任何东西:
| 图表 | 选项 | 上限 |
|---|---|---|
| Histogram | 数值字段 + Bins | 1–50 个分箱 |
| Scatter | X axis / Y axis | 2 000 个点 |
| Bar | Category + Aggregate(Count / Sum / Average) | 20 根柱 |
| Line | 数值字段 × 行序 | — |
| Box plot | 数值字段 | — |
| Pie | Category + Aggregate(Count / Sum) | 8 个扇区,其余归为 “(other)” |
全部要素参与计算,Download 可存 PNG 或 SVG。要”随项目保存、彼此交叉过滤”的图表,用 Dashboard 而不是这里。
10.6.4 快速过滤(Quick filters)
快速过滤是点选式过滤,在 Style 面板 → Quick filters → Add a filter… 里按字段添加,一个字段一条:
| 字段类型 | 过滤形式 |
|---|---|
| 分类 | Values 列表(带计数) |
| 数值 | Range 区间 |
| 日期 | 日期区间 |
| 文本 | Text 匹配:contains / starts with / exactly |
警告:快速过滤只影响地图显示,不会收窄属性表,也不改变选择集。要在表里过滤,用 Search attributes… 或 Show Selected。这是最容易误判”数据丢了”的地方。
10.7 编辑值:校验、属性表单与写回
10.7.1 行内编辑
- 点 Edit,单元格变成输入框;
- 改过的单元格高亮;
- 点 Save 提交;旁边的重置按钮丢弃全部未保存修改;
- 存对象的单元格必须是合法 JSON,否则 Save 被阻止(提示
Fix invalid JSON before saving)。
只读的列:连接字段、虚拟字段、编辑器跟踪字段。Edit 在两种情况下不可用:
- 正在编辑几何(提示
Finish geometry editing to edit attributes); - Add Vector Layer 图层(提示
Editing is not available for Add Vector Layer layers)。
10.7.2 属性表单设计器
属性表单决定”每个字段怎么被编辑”,位置在 Style 面板 → Attributes Form,每个字段点 Configure field:
| 设置 | 取值 | 作用 |
|---|---|---|
| Edit widget | Text / Number / Range / Checkbox / Date / Value map(下拉) | 决定编辑控件 |
| Alias | 文本 | 表单里显示的友好名称(表头仍用原名) |
| Required | 布尔 | 必须有值 |
| Value map entries | 每行一条 value 或 value=Label |
下拉选项 |
| Min / Max / Step | 数值 | Number 与 Range 的边界(Step 只对 Range) |
| Constraint expression / Constraint description | MapLibre 表达式 + 提示语 | 值必须满足的条件,以及不满足时显示的话 |
| Visibility expression | MapLibre 表达式 | 仅在表达式为真时显示该字段 |
编辑时这些规则会真正生效:
- 值映射字段变下拉、复选框变勾选框、数值/范围/日期变类型化输入;
- 违规单元格变红并给出原因(例如
A value is required),Save 被阻止直到修好; - 只标记你自己这次编辑引入的问题,历史数据里已存在的违规不会阻止你保存其它改动。
同一套表单也驱动 Field Collection(10.11),所以在这里配好的控件、别名、约束,在野外采集时原样出现。Alias 只用于表单,不用于表头。
10.7.3 写回源
值改完只是”改在内存里的图层”。要落盘/落库,用图层 … 菜单:
| 目标 | 菜单项 | 平台 |
|---|---|---|
| GeoJSON / GeoPackage 文件 | Save edits to source file | 桌面 |
| ArcGIS 要素服务 | Save edits to ArcGIS service | Web + 桌面 |
| PostGIS 表 | Save edits to PostGIS table | 桌面 |
| SQL Server 表 | Save edits to SQL Server table | 桌面 |
撤销:Ctrl/Cmd + Z 撤销已保存的图层改动(在单元格里打字时不触发,交给输入框自己的撤销)。
提示:保存工程(
.geolibre.json)不会把编辑写回源文件或服务。前者只记录工程状态,后者是显式的写回动作。这条边界也是”我改了、也保存了,但 QGIS 打开还是旧数据”的原因。
10.8 几何编辑:GeoEditor
10.8.1 它是插件,不是内置面板
GeoEditor 是一个内置插件(id geo-editor),能力是”GeoJSON 图层的绘制、顶点编辑、捕捉与删除工具”。激活方式:
Plugins → GeoEditor。因为它在地图上放控件,菜单会展开成子菜单:激活 + 位置(top left / top right / bottom left / bottom right)。
10.8.2 三条进入编辑的路径
| 路径 | 行为 |
|---|---|
图层 … → Edit geometry |
把该图层交给 GeoEditor 做顶点级编辑 |
图层 … → Load features into editor… |
把该图层的要素复制进 GeoEditor 的草图(Sketches)图层 |
| Identify 结果 → Edit geometry | 打开编辑器并选中该要素 |
第二条路径的差别很关键:复制意味着原图层不变,改动留在草图里;需要落地时再把草图导出成工程图层。
10.8.3 能力与写回
| 能力 | 说明 |
|---|---|
| 绘制 | 新建点、线、面要素 |
| 顶点编辑 | 拖动、增删顶点 |
| 捕捉(snapping) | 对齐到已有要素的顶点/边 |
| 删除 | 删除要素 |
| 草图导出 | 草图可作为普通工程图层导出,带着它的样式、透明度、可见性 |
| 会话接入 | 插件可读 getEditSessionLayerId、可 startEditSession,并跟随会话状态 |
几何编辑同样是”两段式”:
- 编辑器里 Save —— 只提交到 GeoLibre 的图层;
- 图层
…→ Save edits to source file / Save edits to PostGIS table / Save edits to ArcGIS service —— 才真正写入源。
写回目标支持 GeoPackage、GeoJSON 文件与 PostGIS 表;ArcGIS 要素服务走它自己的一套(10.10)。
10.8.4 引擎与状态限制
| 引擎 | GeoEditor |
|---|---|
| MapLibre | ✅ |
| Mapbox | ✅(含 Sketches) |
| Cesium | ❌ 不激活(插件 engines 只声明 maplibre/mapbox,Cesium 下挂起) |
| ArcGIS | ❌ 置灰,理由:几何编辑器走 MapLibre/Mapbox 的 style API |
状态限制:
- 几何编辑期间属性表 Edit 不可用;
- 属性表编辑期间 Edit geometry 不可用;
- 对图层做
updateGeoJsonLayer时若该图层正在编辑器里,调用返回false且不改任何东西(避免覆盖未保存的编辑); removeLayer会结束该图层的编辑会话且不保存。
警告:编辑会话是”独占”的。给 A 图层开编辑会话时,若 B 图层已有未保存会话,B 会先被保存并结束——所以切换图层编辑前先确认上一个会话的结果是不是你想要的。
10.9 导出
Export 把图层(包含未保存的编辑)写出:
| 格式 | 备注 |
|---|---|
| GeoJSON | 默认,坐标恒为 WGS84 |
| GeoParquet | 列式,带 geo 元数据 |
| GeoPackage | 可直接给 QGIS/ArcGIS |
| KML / KMZ | — |
| Zipped Shapefile | 字段名截断到 10 字符时会警告 |
| CSV | 仅属性,不含几何 |
| Encoded polyline | 仅线图层,精度 5 或 6 |
导出会遵守 Exclude field on export 的设置。同样的格式在 Layers 面板 → Layer actions → Export 里也有;栅格图层在那里的选项是 GeoTIFF (COG) 与 Extract subset…,LiDAR 图层是 LAS / LAZ / COPC。
提示:Shapefile 的 10 字符字段名限制不是 GeoLibre 的选择,而是格式本身的约束(DBF 字段名上限)。要么接受截断,要么改用 GeoPackage/GeoParquet。
10.10 ArcGIS 要素服务编辑
这是全章唯一”有服务端契约”的编辑路径,也是最容易出问题的一条。
10.10.1 三步流程
- Add Data → ArcGIS Layer,选 Feature layer,填服务图层 URL(或门户项目),受保护服务填 access token;
- 在属性表里改属性,或用 Layer actions → Edit geometry 改几何;先结束几何编辑会话;
- Layer actions → Save edits to ArcGIS service。状态里报告 inserted / updated / deleted 的条数,以及逐条失败原因。
在第三步之前,所有改动都只在本地。几何会话里的 Save 与属性表的 Save 都只提交到 GeoLibre;图层行会提示”尚未保存到服务”。写回成功后,新要素会拿到服务分配的 object ID 与服务端计算的字段(面积、长度等)。
10.10.2 什么时候出现这个菜单项
只有服务同时满足以下条件才出现保存动作:
- 声明了支持的编辑操作;
- 提供了字段 schema 与 object ID 字段。
只读的情况:版本化图层、日期时区未知的图层。
M 值(measure)图层是半只读:可以改属性、可以删,但不能新增或改形状——GeoLibre 不能写 M 值,保存时会拒绝。写请求必须走 HTTPS;浏览器部署还要求服务允许跨域。
10.10.3 域、类型与子类型
GeoLibre 直接读图层元数据里的属性域(不额外发请求),并在属性表和保存前应用:
| 元数据 | 编辑器行为 |
|---|---|
| coded-value domain | 变成发布名称的下拉;存储的是代码(整型字段存 1,文本字段存 "1"/"01"/"0" 原样);只读单元格显示名称、悬停显示代码;导出与要素属性保留代码 |
| range domain(整型/浮点) | 变成有界数字输入;边界含端点;整型拒绝小数 |
| 无域的数值字段 | 按数字编辑(空列里输入的值仍按数字保存) |
| type / subtype 字段 | 变成发布类型的下拉;被类型覆盖的域在切换类型时立即改变选项与边界(保存前就生效) |
类型切换不会清空或替换依赖值:不再合规的值保持可见、被标记,必须改正才能保存。只改非类型字段的编辑只校验被改的字段,所以带历史值的旧记录仍可编辑。
设计器里配的 Attributes Form 会被保留:别名、布局、可见性、约束继续生效;它的值映射或边界可以收窄服务的域,但不能放宽。表单隐藏的字段仍然按服务域校验。
无法确定的情况(只有域名没有代码/范围、types[] 与 subtypes[] 互相矛盾、类型字段不在字段列表里、记录的类型代码未发布),GeoLibre 交给服务端校验,并为受影响字段提供普通编辑器;整层性的问题会在属性表工具栏给出提示。
10.10.4 新要素的默认值
用 Edit geometry 画出的新要素会带上服务的创建默认值,只填空着的属性,优先级从具体到一般:
- 类型/子类型字段 ← 该图层唯一模板的类型 → 否则
defaultSubtypeCode→ 否则字段defaultValue; - 其它可编辑字段 ← 该类型模板的原型值 → 否则子类型的
defaultValues→ 否则字段defaultValue。
模板只在无歧义时使用(图层或该类型只发布了一个模板)。有多个模板时一个都不选,只用子类型与字段默认值。服务分配的字段(object ID、global ID、编辑器跟踪、其它只读字段)留给服务端,保存后会回读记录。
复制或分割要素产生的新要素会保留复制的属性、剔除服务分配的值,所以它们能作为 insert 保存。原要素保留身份:形状未变的那个分片,或分割后第一个分片。
警告:企业级地理数据库里,insert 以服务连接的数据库用户身份执行,不是你的 ArcGIS 账号。如果该用户没有分配 object ID 的权限,每次 insert 都会失败并报类似
The EXECUTE permission was denied on the object 'i12_get_ids'——此时 update / delete 仍然成功。GeoLibre 会在保存状态里标出这个原因,并把新要素留在本地。
10.10.5 待处理编辑与刷新
- GeoLibre 保留”实际下载到的要素”的基线;删除只限于基线内,即使加载时用了要素数上限,平移出已下载范围也不会删除服务记录;
- 有未保存编辑或进行中的几何会话时,视口加载与刷新暂停,保存后可恢复;
- update 只发改过的属性;
- insert 成功后立刻拿到 object ID;即使其它操作失败,成功的操作也会从待处理列表移除;
- 然后回查已保存记录,取服务默认值与计算字段;保存期间本地新产生的改动仍留在待处理列表。
响应丢失或残缺时结果不确定。GeoLibre 会封锁该图层的再次保存(重开工程后仍然封锁),避免重复插入一个可能已成功的记录。此时应核对服务状态、把服务作为新图层重新添加,再继续;本地待处理工作要先导出保存。被服务明确拒绝的编辑可以改正后重试。
注意:访问令牌存在活动连接里,不写进工程文件。重开工程或令牌过期后,受保护服务需要重新添加。
10.10.6 附件
服务声明 hasAttachments 时,记录可以带照片、PDF、文档等:
| 操作 | 行为 | 所需能力 |
|---|---|---|
| Download | 以存储时的文件名保存原始字节 | 读 |
| Preview | 内联显示 JPEG/PNG/GIF/WebP/BMP/AVIF;其它类型(含 SVG、PDF、Office)只能下载,所以附件内容不会在 GeoLibre 内执行 | 读 |
| Add files | 一次上传多个,每个文件一个请求、各自报告结果 | Create 或 Update |
| Replace | 上传新内容、保留附件 ID | Update |
| Delete | 确认后删除单个附件 | Update |
附件的改动不进要素的待处理编辑:每次操作立即写服务并回读列表。新要素要等 Save edits to ArcGIS service 给出 object ID 之后才能加附件。附件按”图层 + object ID + 附件 ID”寻址,从不按文件名,所以重名安全。上传响应丢失或中途取消会被报告为”未确认”,重试前先刷新列表以免重复添加。
桌面端单请求上限 64 MiB;版本化图层与 MapServer 图层只能列出与下载附件。附件的文件类型与大小策略由服务决定。
10.10.7 关联记录
服务在元数据里发布关系类(relationships[])时,选中一条已保存记录可以看到关联表的行(例如消防栓的检修记录、地块的评估记录):
- Relationship 下拉选发布的关系,不从字段名或表名推断;
- 行来自
queryRelatedRecords(按 object ID 与 relationship ID),用关联表自己的字段别名、编码值名称与日期显示;超出域的值被标记而不是隐藏或替换; - 服务支持分页(
supportsQueryRelatedPagination)时逐页读完;只截断不分页的服务会提示”列表不完整”; - 返回行若属于别的父记录会被拒绝;选择或关系变化后到达的响应会被丢弃。
可写条件下(关系由本图层出发、一对一或一对多、无中间表、两端都在 FeatureServer、关联表声明可编辑并在自己的 relationships[] 里指明外键):
- Add record / Edit / Delete 直接写关联表的
applyEdits,随后回读; - 新行按关联表自己的创建默认值(模板、子类型、字段默认值)初始化,外键从父记录在发布的键字段上的值取(可能是 global ID 或别的字段,不假定是 object ID),该键只读,把行移到别的父记录会被拒绝;
- 校验用关联表自己的字段类型、可空性、长度、域;
- object ID、global ID、编辑器跟踪等由服务管理的字段只读;行按 object ID 寻址;
- 关联表若声明支持附件,会出现回形针按钮,打开同一个附件对话框(按关联表与该行的 object ID 寻址),允许的操作随关联表自身能力。
浏览只读的情形:多对多、带属性的关系、从子表一侧看的关系、MapServer 图层。
10.10.8 Sign in with ArcGIS
Add Data → ArcGIS Layer 的 Authentication 里选 Sign in with ArcGIS,走 OAuth 2.0 Authorization Code + PKCE,GeoLibre 永远看不到你的密码、MFA 或身份提供方凭据。
| 形态 | 重定向 URI |
|---|---|
| Web | <app URL>/oauth-callback.html(如 https://web.geolibre.app/oauth-callback.html) |
| 桌面 | org.geolibre.desktop:/oauth/callback |
步骤:
- 在门户上注册应用(ArcGIS Online:Content → New item → Developer credentials;Enterprise 同理),并把上面的重定向 URI 加进去;
- Portal URL 留空走 ArcGIS Online,或填组织 URL(
https://myorg.maps.arcgis.com,可走 SSO),或填 Enterprise 门户(https://gis.example.org/portal);企业门户若限制来源,需要加入 GeoLibre 的来源; - 粘贴应用的 client ID,点 Sign in。client ID 不是秘密,按门户记住。
构建变量 VITE_ARCGIS_OAUTH_CLIENT_ID 可预置一个 ArcGIS Online 的 client ID(托管版 web.geolibre.app 就预置了),所以它的用户能跳过第 1 步。该默认值只在注册过该构建重定向 URI 的来源上有效。
会话只存在内存中,同一门户的所有 ArcGIS 图层共享;访问令牌约 30 分钟,用 refresh token 自动续期(包括保存编辑与刷新图层时),续不上会要求重新登录;Sign out 结束会话并吊销 refresh token。会话、令牌、登录选择都不写进工程文件或服务库。矢量瓦片、地图服务、影像服务图层携带添加时的令牌(约半小时),过期后需重新添加。
注意:要浏览门户内容而不是粘服务 URL,用 Plugins → Web Services → ArcGIS Portal,它与上面共用同一次登录。
10.10.9 当前范围
| 支持 | 不支持 |
|---|---|
| 点、多点、线、多线、面、多面 | 版本化服务、M 坐标、未知时区日期、离线同步 |
| Z 启用服务:仅当服务显式启用”有限默认 Z”时 2D 编辑可用该默认值,否则每个顶点都必须给有限 Z | 通过要素编辑新增字段、修改服务管理字段 |
| 基本字段类型、可空性、字符串长度、编码值与范围域(含类型/子类型覆盖的域) | 创建父记录与其关联行同时进行、嵌套关系 |
| object ID 保持不变 | 独立添加的表(关系之外)的附件、批量 queryAttachments、附件关键字与 upload ID |
| 关联记录的浏览、编辑、删除(满足 10.10.7 的条件时) | 远程冲突解决协议:另一个客户端改了同一属性/几何时,由服务决定接受哪次提交 |
实现基于 Esri 的 applyEdits 与附件操作(attachment infos / add / update / delete),关联记录用 queryRelatedRecords。
10.11 GPS 追踪与字段采集
两个工具都在 Controls 菜单,产物都是普通 GeoJSON 图层:随工程保存、进属性表、走常规导出。没有服务端同步或上传步骤。
10.11.1 GPS Tracking
Controls → GPS Tracking…
定位源(Position source) 两选一:
| 选项 | 说明 |
|---|---|
| This device | 浏览器/系统的定位服务,请求高精度;Android/iOS 首次会向系统申请权限。被拒绝时对话框会说明,授权后重试 Start GPS |
| NMEA receiver (serial or Bluetooth) | 外部 GPS/GNSS 接收机。选 Baud rate(4800 / 9600 / 19200 / 38400 / 57600 / 115200,默认 9600 并记住),再 Connect serial 或 Connect Bluetooth;连上后显示设备名与 1,204 sentences · 300 fixes 这样的计数,以及当前定位质量(如 RTK fixed、RTK float、Differential GPS) |
解析的语句是 GGA、RMC、VTG、GSA、GST,任何 talker(GP、GN、GL…)都认;精度优先取 GST,没有则按 HDOP 估算。
注意:NMEA 需要 Chromium 内核(Chrome、Edge)——Web Serial 与 Web Bluetooth 只有它们提供。多数蓝牙 GPS 用经典蓝牙,应在系统设置里配对后作为串口连接;Connect Bluetooth 只用于低功耗(BLE)接收机。
跟随与读数:Start GPS 后地图显示蓝点、有航向时的箭头、精度圆;读数列出精度(±4 m)、Satellites、海拔、km/h 速度、航向度数。Keep map centered on my position(默认开)会随每次定位重新居中,拖动地图即关闭。关闭对话框后地图角落保留一个小面板(坐标、精度、卫星数、速度、轨迹统计、Capture point、跟随开关、Pause/Resume、重开对话框)。
轨迹记录:
- Record track 清空上一条未保存轨迹并开始记录(必要时自动开 GPS);
- Pause 停止记录;Resume 在新段里继续(所以间隙不会被画成直线);
- 有轨迹时显示点数、距离、时长,以及四个动作:
- Save as layer:作为线图层加入工程,命名如
GPS Track 2026-10-04 0930(多段时是 MultiLineString),保留每个顶点的 time、accuracy、卫星数; - Export GPX:GPX 1.1,每段一个
<trkseg>; - Export GeoJSON:同一条轨迹的 GeoJSON;
- Discard:丢弃。
- Save as layer:作为线图层加入工程,命名如
保存与导出都要求至少两个点。
采点:Digitize → Capture point 在当前定位处加点,写入 GPS Points 图层(首次自动创建)。每个点记录 time、accuracy_m、satellites_used、ele、speed_mps、heading_deg。
记录过滤器:
| 过滤器 | 效果 |
|---|---|
| Min distance (m) | 跳过距上一点更近的定位 |
| Min time (s) | 跳过距上一次更短的定位 |
| Max accuracy (m) | 精度差于此值不记录,并在此时禁用 Capture point |
三者默认 0(关闭),并跨会话记住。
警告:未保存的轨迹只在内存里。关闭应用或刷新页面就没了——先 Save as layer 或导出。
10.11.2 Field Collection
Controls → Field Collection… 按自定义表单采集点、线、面观测。
建立采集图层:
- Collection layer 选已有图层,或 New collection layer…;
- 新图层填 Layer name,选 Geometry:Point / Line / Polygon(一个图层只有一种几何);
- 每个属性 Add field:Label、Type(Text / Number / Date / Choice)、Required 勾选、Choice 字段填 Options (comma-separated);
- Create layer。
没有字段的图层只能采”纯位置”观测。属性名由 Label 派生。字段没有默认值。
如果该图层配了属性表单(10.7.2),Field Collection 改用表单:别名、下拉、勾选框、数值/范围/日期控件、条件可见性、约束全部生效。
采集一条观测:
- 点:Use GPS(一次高精度定位,最多等 15 秒,不读 GPS Tracking 里连的 NMEA 接收机)/Pick on map(点击落点,
Esc取消)/Reposition point(移动已落的点); - 线/面:Draw on map 打开底部工具条——点击加点,Add GPS vertex 在当前位置加一个顶点,Undo 撤掉最后一个顶点,Finish(或双击)在顶点数足够后闭合;
- 填表、可选附照片,点 Save point / Save line / Save polygon。必填字段标
*,表单会拒绝空必填、非数字、不在选项内的值。
照片:Photo (optional) → Choose photo… 可附一张或多张,每张上限 2 MB;照片存在要素上,随工程走。
会话行为:Done 结束会话;用 X 或 Esc 关闭只是隐藏——地图上留一个 Open Field Collection 药丸,可继续采集而不用重新配置。采集时显示的 GPS 精度不写入要素;需要逐点精度与卫星数就用 GPS Tracking 的 Capture point。
离线:采集结果保存在工程里,应用加载后无需联网即可采集。出发前用 Project → Offline Basemap… 缓存底图,并在关闭应用前保存工程。
10.12 数据质量清单
编辑类工作最容易在”看起来没问题”的地方出错。下面这份清单按”发现 → 修复 → 验证”组织。
10.12.1 几何质量
| 问题 | 发现工具 | 修复工具 |
|---|---|---|
| 自相交、孔洞在壳外等非法几何 | Check validity | Fix geometries(ST_MakeValid,合法要素原样通过) |
| 重叠、缝隙、自相交、悬挂点 | Check topology rules | Fix topology(吸附近接端点、修悬挂、把点投影到线上;真正孤立的自由端保留) |
两个工具都在 Processing → GeoLibre Toolbox → Vector → Data quality,检出结果会在图上标出违规要素。
10.12.2 属性质量
| 问题 | 检查方式 | 说明 |
|---|---|---|
| 大面积空值 | Explore(null 比例) | 90% 为空的字段通常不该参与符号化 |
| 类型混杂 | Explore(数值字段的 Non-numeric) | 一个非数字值就说明整列被当作文本 |
| 值域越界 | Statistics 的 Min/Max | 与业务规则比对 |
| 重复记录 | Statistics 的 Unique 与 Count 之比较 | 唯一值远小于行数时考虑去重 |
| 键不匹配 | 连接后的”未匹配行”报告 | 空键永不匹配;文本比较,5 与 "5" 相等 |
| 导出后字段丢失 | 列菜单的 Exclude field on export | 导出前逐列确认 |
| Shapefile 字段名截断 | 导出警告 | 10 字符上限 |
10.12.3 编辑一致性
- 谁拥有这份数据——文件、PostGIS 表、还是 ArcGIS 服务?三者的写回动作不同,不能混用;
- 改了但没写回——属性表
Save只提交到图层;写回是单独的菜单项; - 并发编辑——ArcGIS 服务没有远程冲突解决协议,由服务决定接受哪次提交;PostGIS 表靠数据库自身的事务与锁;
- 字段类型不可变——需要换类型就新建字段 + 计算 + 删旧字段;
- 连接与虚拟字段只读——要改就改源表或表达式;
- 编辑会话独占——切换被编辑图层前先结束当前会话并确认保存;
- 未保存轨迹会丢——GPS 轨迹必须先落地。
提示:把”编辑 → 写回 → 重开验证”当成一个固定动作。写回成功不等于数据正确:重开工程或重新添加服务,确认改动真的在那里,是唯一可靠的验证。
10.13 本章小结
- 属性表停靠底部,行做了虚拟化但全部读入内存;无分页、无行上限,排序/搜索/对话框作用于全部行。
- 可编辑性由图层类型决定:GeoJSON 可编辑;DuckDB 图层只能在内存里改值(且无字段操作);Add Vector Layer 与 CZML 只读。
- 表与地图共享选择;规则化选择用 Select by Expression(可顺便存成图层过滤器)与 Select by Location。
- 字段类型创建后不可变;列菜单提供改名、隐藏、导出排除、排序、删除(删除不可撤销)。
- 两种计算字段:字段计算器一次性写入且不保存表达式;虚拟字段用 MapLibre 表达式、自动重算、随项目保存、表里斜体只读。
- 字段计算器的几何度量与测量面板同源(
$length/$perimeter/$area,同一套单位),半径取当前天体。 - 连接是左连接、文本比较、一对一、实时、只读;需要内连接用 Attribute join 写新图层。
- 属性表单决定每个字段的控件、别名、必填、值映射、范围、约束与可见性,并同时驱动 Field Collection;校验只标记本次编辑引入的问题。
- 快速过滤只影响地图显示,不收窄属性表、不改选择——这是”数据丢了”的头号误判来源。
- 编辑分两段:先提交到图层,再显式写回文件/PostGIS/ArcGIS;保存工程不等于写回。
- GeoEditor 是插件(
geo-editor),支持绘制、顶点编辑、捕捉、删除;ArcGIS 引擎下不可用;编辑会话独占。 - ArcGIS 要素服务编辑有服务端契约:域/子类型、创建默认、待处理编辑、附件、关联记录、OAuth 登录,以及”响应不确定时封锁再次保存”。
- 字段采集无服务端同步:GPS Tracking 出轨迹与采点,Field Collection 按表单采点线面;未保存轨迹会丢,照片每张 ≤ 2 MB。
10.14 实践练习
-
字段全流程:加载一个面图层,Add field 新建
area_ha(Number),用 Calculate 写round($area("hectares"), 2);再建一个虚拟字段density,用["/", ["get","pop"], ["get","area_ha"]]。比较两者在属性表里的样式与只读行为,并说明为什么虚拟字段不能写回文件。 -
列浏览器诊断:用 Explore 找出一列”看起来是数字、实际混有非数字”的字段,记录它的 Non-numeric 计数;然后用字段计算器的
toNumber新建一列,比较修复前后的 Statistics 输出。 -
连接与内连接:准备一份 CSV(键 + 两列数值),用 Style → Joins 连到一个面图层,记录”匹配/未匹配”报告;再用 Processing → GeoLibre Toolbox → Vector → Join → Attribute join(inner)生成新图层,比较两条路径在”未匹配要素”上的差别,以及字段是否只读。
-
表单与采集:给一个点图层配置属性表单:一个 Value map 字段(
1=正常、2=异常)、一个 Range 字段(0–100,Step 5)、一个带 Required 的文本字段、一个带 Visibility expression 的字段。然后打开 Controls → Field Collection…,用同一个图层采集一条记录,验证控件、必填与可见性是否都生效。 -
编辑与写回:在桌面版打开一份 GeoPackage 图层,改两个属性、用 Edit geometry 平移一个要素,Save 后执行 Save edits to source file;关闭工程重新打开,确认两处改动都在。再把同一操作在浏览器版做一遍,记录哪一步不可用,并解释原因。
-
ArcGIS 服务的只读判定:添加一个公开的 ArcGIS 要素服务图层,观察
…菜单里是否出现 Save edits to ArcGIS service;再找一个声明了hasAttachments的图层,打开附件对话框,记录 Preview 对图片与 PDF 的不同处理,并说明为什么这样设计。
延伸阅读
- 仓库文档:
docs/user-guide/attribute-table.md、docs/user-guide/field-collection.md、docs/arcgis-editing.md、docs/user-guide/layers.md、docs/user-guide/map-controls.md(Measure / GPS Tracking) - 源码与词条:
apps/geolibre-desktop/src/lib/geometry-measure.ts、packages/core/src/types.ts、apps/geolibre-desktop/src/i18n/locales/en.json(attributeTable、fieldCollection、gps、serviceDomains) - 相关章节:第06章 图层管理与地图控制、第07章 样式符号化与图例、第09章 坐标系统、投影与测量、第11章 SQL 工作区与 DuckDB 空间分析