DBF 字段名超 10 个字符被截断,前端读 properties 全是 undefined
数据表里明明有 population_total,导出的 Shapefile 里只剩 population。
现象
PostGIS 表有 14 个字段,字段名是 district_name、population_total、
area_sqkm。用 ogr2ogr 导出为 Shapefile 后,
DBF 里只剩 district_n、population、area_sqkm。
前端代码按 feature.properties.population_total 取值,全部得到
undefined,图例数字显示 NaN。
原因
DBF(dBase III/IV)格式规定字段名最长 10 个字节,
其中汉字按编码占 2~3 字节,所以中文名最多 3~5 个字。
超出部分由 GDAL 截断,且不保证唯一:population_total 与
population_density 都会被截成 population,后者直接覆盖前者。
| 原始字段名 | DBF 中 | 是否可用 |
|---|---|---|
| district_name | district_n | 可用,但名字变了 |
| population_total | population | 可用 |
| population_density | population | 冲突,被覆盖 |
| area_sqkm | area_sqkm | 正好 9 字节,未截断 |
排查过程
- 用
ogrinfo -al -so看导出的字段列表,与源表逐一对比。 - 字段数比源表少,说明发生了截断冲突。
- 打开
.dbf的字段描述区(前 32 字节为单位),字段名以\0结尾,长度固定 11 字节。 - 在前端打印
Object.keys(feature.properties),确认实际键名。
ogrinfo -al -so districts.shp | Select-String -Pattern "^[a-z_]+:"
# district_n: String (254.0)
# population: Real (24.15)
# area_sqkm: Real (24.15)
# 少了 population_density
解决方案
导出前把字段名改成 10 字节以内的短名,并在前端做一层映射。 需要长期使用就改用 GeoJSON 或 GeoPackage,它们没有这个限制。
# 方案一:导出时用 SQL 重命名
ogr2ogr -f "ESRI Shapefile" out districts.shp -sql "
SELECT district_name AS d_name,
population_total AS pop_tot,
population_density AS pop_den,
area_sqkm AS area_km2,
geom FROM districts"
# 方案二:直接改用 GeoPackage,字段名不受限
ogr2ogr -f "GPKG" districts.gpkg districts.shp
// 前端加一层别名,兼容历史文件
const ALIAS = { pop_tot: 'population_total', pop_den: 'population_density' };
function readProps(p) {
const out = { ...p };
for (const [k, v] of Object.entries(ALIAS)) if (k in p) out[v] = p[k];
return out;
}
L.geoJSON(fc, {
onEachFeature: (f, layer) => {
const p = readProps(f.properties);
layer.bindPopup(`<b>${p.d_name}</b><br>人口 ${p.population_total}`);
}
});
验证
导出后字段数为 4,与 SQL 中的别名数量一致;
前端 properties.pop_tot 有值,图例不再出现 NaN。
console.assert('pop_tot' in fc.features[0].properties, '字段仍被截断');
console.assert(!Object.keys(fc.features[0].properties).some(k => k.length > 10), '仍有超长字段名');
适用版本
| 格式 / 工具 | 版本 | 字段名长度 |
|---|---|---|
| DBF(Shapefile) | dBase III | 最多 10 字节 |
| GeoPackage | 1.2 及以上 | 无实际限制 |
| GeoJSON | RFC 7946 | 无限制 |
| GDAL | 3.6 及以上 | 默认截断,可用 SHAPE_ENCODING 影响字节数 |
经纬志(2026)。《DBF 字段名超 10 个字符被截断,前端读 properties 全是 undefined》。https://www.jingweizhi.com/cookbook/dbf-field-name-limit.html(访问日期 2026-11-03)。