经纬志
首页 / 实战手册 / 数据加载

DBF 字段名超 10 个字符被截断,前端读 properties 全是 undefined

先看结论

数据表里明明有 population_total,导出的 Shapefile 里只剩 population。

最后验证 2026-11-03 · 多技术栈 · 更新 2026-10-29 · 引用本文

现象

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_namedistrict_n可用,但名字变了
population_totalpopulation可用
population_densitypopulation冲突,被覆盖
area_sqkmarea_sqkm正好 9 字节,未截断

排查过程

  1. 用 ogrinfo -al -so 看导出的字段列表,与源表逐一对比。
  2. 字段数比源表少,说明发生了截断冲突。
  3. 打开 .dbf 的字段描述区(前 32 字节为单位),字段名以 \0 结尾,长度固定 11 字节。
  4. 在前端打印 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 字节
GeoPackage1.2 及以上无实际限制
GeoJSONRFC 7946无限制
GDAL3.6 及以上默认截断,可用 SHAPE_ENCODING 影响字节数
引用本文

经纬志(2026)。《DBF 字段名超 10 个字符被截断,前端读 properties 全是 undefined》。https://www.jingweizhi.com/cookbook/dbf-field-name-limit.html(访问日期 2026-11-03)。