经纬志
首页 / 实战手册 / OpenLayers 图层

样式函数漏了 return,一半要素不画

先看结论

按属性给不同颜色的点,结果只有一类点显示,其余全部消失,控制台还报了一个读属性失败的错误。

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

现象

图层里 800 个要素,只有 status 为 alarm 的 120 个能显示, 其余按条件走到另一个分支后消失。控制台报:

Uncaught TypeError: Cannot read properties of undefined (reading 'getType')
    at executeDeclutter (VectorLayer.js:1268)

原因

style 函数必须返回一个 ol.style.Style、 样式数组或 null。分支里只写了条件赋值、没有 return, 函数返回 undefined,渲染器拿到空值后既不能绘制也无法判断, 在开启 declutter 时直接抛出类型错误。

null 是合法的“不渲染”信号,undefined 不是。 两者看起来一样,行为完全不同。

排查过程

把样式函数单独抽出来,用几个典型要素手动调用,看返回值:

var styleFn = layer.getStyleFunction();
features.slice(0, 5).forEach(function (f) {
  var s = styleFn(f, map.getView().getResolution());
  console.log(f.get('status'), s && s.length, s);
});
// alarm 1
// normal undefined    ← 问题所在

解决方案

每个分支都明确返回。需要“不显示”时返回 null,不要什么都不写:

var alarmStyle = new ol.style.Style({
  image: new ol.style.Circle({
    radius: 8,
    fill: new ol.style.Fill({ color: '#e03131' }),
    stroke: new ol.style.Stroke({ color: '#ffffff', width: 1 })
  })
});

var normalStyle = new ol.style.Style({
  image: new ol.style.Circle({
    radius: 5,
    fill: new ol.style.Fill({ color: '#1c7ed6' })
  })
});

var hiddenStyle = null;

function styleFn(feature) {
  var status = feature.get('status');
  if (status === 'alarm') return alarmStyle;
  if (status === 'normal') return normalStyle;
  return hiddenStyle;
}

var layer = new ol.layer.Vector({
  source: source,
  style: styleFn,
  declutter: true
});

样式对象提前建好、循环外复用,不要在每个要素回调里 new ol.style.Style。 要素数量大时,这会让内存与 GC 压力成倍增长:

// 错误:每个要素每次渲染都新建
// style: function (f) { return new ol.style.Style({ ... }); }

// 正确:样式在模块级创建一次
var sharedStyle = new ol.style.Style({
  stroke: new ol.style.Stroke({ color: '#2b8a3e', width: 2 })
});

function lineStyle(feature) {
  var width = feature.get('lanes') >= 4 ? 4 : 2;
  sharedStyle.getStroke().setWidth(width);
  return sharedStyle;
}

验证

所有要素都按状态显示,数量与数据源一致。 控制台不再出现 reading 'getType'。 在 map.getFeaturesAtPixel 中能命中原本“消失”的要素。

返回值三选一:Style、Style[]、null。 写样式函数时把这三个当成函数签名的一部分,能避免大部分“部分要素不显示”的问题。

引用本文

经纬志(2026)。《样式函数漏了 return,一半要素不画》。https://www.jingweizhi.com/cookbook/ol-style-function-undefined.html(访问日期 2026-11-03)。