diff --git a/doc/errors/index.md b/doc/errors/index.md
index 4608ed7e6a..d4deea08cf 100644
--- a/doc/errors/index.md
+++ b/doc/errors/index.md
@@ -241,10 +241,6 @@ Support for the `OES_element_index_uint` WebGL extension is mandatory for WebGL
Layer opacity must be a number.
-### 65
-
-A symbol literal representation must be defined on the style supplied to a `WebGLPointsLayer` instance.
-
### 66
`forEachFeatureAtCoordinate` cannot be used on a WebGL layer if the hit detection logic has not been enabled.
diff --git a/examples/webgl-points-layer.html b/examples/webgl-points-layer.html
index ebf30b754c..e411f88116 100644
--- a/examples/webgl-points-layer.html
+++ b/examples/webgl-points-layer.html
@@ -24,15 +24,13 @@ experimental: true
Choose a predefined style from the list below or edit it as JSON manually.
- Predefined styles
Icons
Triangles, color related to population
Circles, size related to population
-
- ✓ style is valid
-
-
- ✗ style not yet valid...
+
+ ✓ style is valid
+ ✗ style not yet valid...
+
diff --git a/examples/webgl-points-layer.js b/examples/webgl-points-layer.js
index a625c1ba0a..18c7ba4c30 100644
--- a/examples/webgl-points-layer.js
+++ b/examples/webgl-points-layer.js
@@ -46,8 +46,6 @@ const predefinedStyles = {
}
}
};
-let literalStyle = predefinedStyles['circles'];
-let pointsLayer;
const map = new Map({
layers: [
@@ -62,45 +60,57 @@ const map = new Map({
})
});
-const editor = document.getElementById('style-editor');
-editor.value = JSON.stringify(literalStyle, null, 2);
-
-function refreshLayer() {
- if (pointsLayer) {
- map.removeLayer(pointsLayer);
- }
+let literalStyle;
+let pointsLayer;
+function refreshLayer(newStyle) {
+ const previousLayer = pointsLayer;
pointsLayer = new WebGLPointsLayer({
source: vectorSource,
- style: literalStyle
+ style: newStyle
});
map.addLayer(pointsLayer);
+
+ if (previousLayer) {
+ map.removeLayer(previousLayer);
+ }
+ literalStyle = newStyle;
}
-function setStyleStatus(valid) {
- document.getElementById('style-valid').style.display = valid ? 'initial' : 'none';
- document.getElementById('style-invalid').style.display = !valid ? 'initial' : 'none';
+const spanValid = document.getElementById('style-valid');
+const spanInvalid = document.getElementById('style-invalid');
+function setStyleStatus(errorMsg) {
+ const isError = typeof errorMsg === 'string';
+ spanValid.style.display = errorMsg === null ? 'initial' : 'none';
+ spanInvalid.firstElementChild.innerText = isError ? errorMsg : '';
+ spanInvalid.style.display = isError ? 'initial' : 'none';
}
+const editor = document.getElementById('style-editor');
editor.addEventListener('input', function() {
const textStyle = editor.value;
- if (JSON.stringify(JSON.parse(textStyle)) === JSON.stringify(literalStyle)) {
- return;
- }
-
try {
- literalStyle = JSON.parse(textStyle);
- refreshLayer();
- setStyleStatus(true);
+ const newLiteralStyle = JSON.parse(textStyle);
+ if (JSON.stringify(newLiteralStyle) !== JSON.stringify(literalStyle)) {
+ refreshLayer(newLiteralStyle);
+ }
+ setStyleStatus(null);
} catch (e) {
- setStyleStatus(false);
+ setStyleStatus(e.message);
}
});
-refreshLayer();
const select = document.getElementById('style-select');
-select.addEventListener('change', function() {
+select.value = 'circles';
+function onSelectChange() {
const style = select.value;
- literalStyle = predefinedStyles[style];
- editor.value = JSON.stringify(literalStyle, null, 2);
- refreshLayer();
-});
+ const newLiteralStyle = predefinedStyles[style];
+ editor.value = JSON.stringify(newLiteralStyle, null, 2);
+ try {
+ refreshLayer(newLiteralStyle);
+ setStyleStatus();
+ } catch (e) {
+ setStyleStatus(e.message);
+ }
+}
+onSelectChange();
+select.addEventListener('change', onSelectChange);
diff --git a/src/ol/layer/WebGLPoints.js b/src/ol/layer/WebGLPoints.js
index b778c56898..f5b375f163 100644
--- a/src/ol/layer/WebGLPoints.js
+++ b/src/ol/layer/WebGLPoints.js
@@ -4,7 +4,6 @@
import {assign} from '../obj.js';
import WebGLPointsLayerRenderer from '../renderer/webgl/PointsLayer.js';
import {getSymbolFragmentShader, getSymbolVertexShader, parseSymbolStyle} from '../webgl/ShaderBuilder.js';
-import {assert} from '../asserts.js';
import Layer from './Layer.js';
@@ -72,24 +71,21 @@ class WebGLPointsLayer extends Layer {
super(baseOptions);
/**
- * @type {import('../style/LiteralStyle.js').LiteralStyle}
+ * @private
+ * @type {import('../webgl/ShaderBuilder.js').StyleParseResult}
*/
- this.style = options.style;
-
- assert(this.style.symbol !== undefined, 65);
+ this.parseResult_ = parseSymbolStyle(options.style.symbol);
}
/**
* @inheritDoc
*/
createRenderer() {
- const parseResult = parseSymbolStyle(this.style.symbol);
-
return new WebGLPointsLayerRenderer(this, {
- vertexShader: getSymbolVertexShader(parseResult.params),
- fragmentShader: getSymbolFragmentShader(parseResult.params),
- uniforms: parseResult.uniforms,
- attributes: parseResult.attributes
+ vertexShader: getSymbolVertexShader(this.parseResult_.params),
+ fragmentShader: getSymbolFragmentShader(this.parseResult_.params),
+ uniforms: this.parseResult_.uniforms,
+ attributes: this.parseResult_.attributes
});
}
}