ol 7.5.1 → 8.0.0-dev.1692053484481
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DataTile.d.ts +2 -2
- package/DataTile.d.ts.map +1 -1
- package/DataTile.js +3 -2
- package/Image.d.ts +139 -40
- package/Image.d.ts.map +1 -1
- package/Image.js +194 -96
- package/ImageCanvas.d.ts +2 -2
- package/ImageCanvas.d.ts.map +1 -1
- package/ImageCanvas.js +2 -2
- package/Object.d.ts +7 -0
- package/Object.d.ts.map +1 -1
- package/Object.js +8 -0
- package/dist/ol.js +2 -2
- package/dist/ol.js.map +1 -1
- package/expr/cpu.d.ts +71 -0
- package/expr/cpu.d.ts.map +1 -0
- package/expr/cpu.js +312 -0
- package/expr/expression.d.ts +97 -0
- package/expr/expression.d.ts.map +1 -0
- package/expr/expression.js +373 -0
- package/has.d.ts +5 -0
- package/has.d.ts.map +1 -1
- package/has.js +6 -0
- package/index.d.ts +1 -2
- package/index.js +1 -1
- package/layer/Base.d.ts +12 -8
- package/layer/Base.d.ts.map +1 -1
- package/layer/Base.js +12 -8
- package/layer/BaseVector.d.ts.map +1 -1
- package/layer/BaseVector.js +67 -33
- package/layer/Heatmap.d.ts.map +1 -1
- package/layer/Heatmap.js +16 -55
- package/layer/Layer.d.ts +2 -2
- package/layer/Layer.d.ts.map +1 -1
- package/layer/Layer.js +1 -1
- package/layer/WebGLPoints.d.ts +7 -12
- package/layer/WebGLPoints.d.ts.map +1 -1
- package/layer/WebGLPoints.js +7 -12
- package/package.json +1 -1
- package/render/Feature.d.ts +8 -0
- package/render/Feature.d.ts.map +1 -1
- package/render/Feature.js +9 -0
- package/render/canvas/Immediate.d.ts.map +1 -1
- package/render/canvas/Immediate.js +5 -3
- package/render/canvas/TextBuilder.js +2 -2
- package/render/canvas/style.d.ts +69 -0
- package/render/canvas/style.d.ts.map +1 -0
- package/render/canvas/style.js +1192 -0
- package/render/canvas.js +1 -1
- package/render/webgl/VectorStyleRenderer.d.ts.map +1 -1
- package/render/webgl/VectorStyleRenderer.js +4 -0
- package/renderer/Layer.d.ts +2 -2
- package/renderer/Layer.d.ts.map +1 -1
- package/renderer/Layer.js +1 -1
- package/renderer/canvas/ImageLayer.d.ts +4 -4
- package/renderer/canvas/ImageLayer.d.ts.map +1 -1
- package/renderer/canvas/ImageLayer.js +17 -12
- package/renderer/canvas/Layer.d.ts +2 -2
- package/renderer/canvas/Layer.d.ts.map +1 -1
- package/renderer/canvas/Layer.js +1 -1
- package/renderer/canvas/VectorImageLayer.d.ts.map +1 -1
- package/renderer/canvas/VectorImageLayer.js +3 -2
- package/renderer/webgl/VectorLayer.d.ts +1 -2
- package/renderer/webgl/VectorLayer.d.ts.map +1 -1
- package/reproj/Image.d.ts +5 -5
- package/reproj/Image.d.ts.map +1 -1
- package/reproj/Image.js +6 -6
- package/reproj.d.ts +2 -2
- package/reproj.d.ts.map +1 -1
- package/reproj.js +1 -1
- package/resolution.d.ts +13 -0
- package/resolution.d.ts.map +1 -0
- package/resolution.js +18 -0
- package/source/Image.d.ts +44 -7
- package/source/Image.d.ts.map +1 -1
- package/source/Image.js +97 -8
- package/source/ImageArcGISRest.d.ts +0 -23
- package/source/ImageArcGISRest.d.ts.map +1 -1
- package/source/ImageArcGISRest.js +18 -120
- package/source/ImageMapGuide.d.ts +0 -24
- package/source/ImageMapGuide.d.ts.map +1 -1
- package/source/ImageMapGuide.js +21 -113
- package/source/ImageStatic.d.ts +2 -27
- package/source/ImageStatic.d.ts.map +1 -1
- package/source/ImageStatic.js +20 -70
- package/source/ImageWMS.d.ts +2 -46
- package/source/ImageWMS.d.ts.map +1 -1
- package/source/ImageWMS.js +43 -201
- package/source/{Stamen.d.ts → StadiaMaps.d.ts} +17 -7
- package/source/StadiaMaps.d.ts.map +1 -0
- package/source/{Stamen.js → StadiaMaps.js} +85 -38
- package/source/TileArcGISRest.d.ts.map +1 -1
- package/source/TileArcGISRest.js +11 -22
- package/source/TileWMS.d.ts +0 -1
- package/source/TileWMS.d.ts.map +1 -1
- package/source/TileWMS.js +43 -106
- package/source/arcgisRest.d.ts +88 -0
- package/source/arcgisRest.d.ts.map +1 -0
- package/source/arcgisRest.js +131 -0
- package/source/common.d.ts +5 -0
- package/source/common.d.ts.map +1 -1
- package/source/common.js +6 -0
- package/source/mapguide.d.ts +52 -0
- package/source/mapguide.d.ts.map +1 -0
- package/source/mapguide.js +116 -0
- package/source/static.d.ts +45 -0
- package/source/static.d.ts.map +1 -0
- package/source/static.js +44 -0
- package/source/wms.d.ts +109 -1
- package/source/wms.d.ts.map +1 -1
- package/source/wms.js +170 -0
- package/source.d.ts +5 -1
- package/source.d.ts.map +1 -1
- package/source.js +5 -1
- package/style/flat.d.ts +332 -173
- package/style/flat.d.ts.map +1 -1
- package/style/flat.js +176 -248
- package/style/literal.d.ts +27 -72
- package/style/literal.d.ts.map +1 -1
- package/style/literal.js +14 -35
- package/util.d.ts.map +1 -1
- package/util.js +1 -1
- package/webgl/Helper.d.ts +7 -2
- package/webgl/Helper.d.ts.map +1 -1
- package/webgl/Helper.js +16 -27
- package/webgl/ShaderBuilder.d.ts +4 -14
- package/webgl/ShaderBuilder.d.ts.map +1 -1
- package/webgl/ShaderBuilder.js +72 -72
- package/webgl/styleparser.d.ts +3 -9
- package/webgl/styleparser.d.ts.map +1 -1
- package/webgl/styleparser.js +503 -88
- package/ImageBase.d.ts +0 -65
- package/ImageBase.d.ts.map +0 -1
- package/ImageBase.js +0 -98
- package/source/Stamen.d.ts.map +0 -1
package/webgl/styleparser.js
CHANGED
|
@@ -5,33 +5,13 @@
|
|
|
5
5
|
import {ShaderBuilder} from './ShaderBuilder.js';
|
|
6
6
|
import {
|
|
7
7
|
ValueTypes,
|
|
8
|
+
arrayToGlsl,
|
|
8
9
|
expressionToGlsl,
|
|
9
10
|
getStringNumberEquivalent,
|
|
10
11
|
uniformNameForVariable,
|
|
11
12
|
} from '../style/expressions.js';
|
|
12
13
|
import {asArray} from '../color.js';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @param {import('../style/literal.js').SymbolType} type Symbol type
|
|
16
|
-
* @param {string} sizeExpressionGlsl Size expression
|
|
17
|
-
* @return {string} The GLSL opacity function
|
|
18
|
-
*/
|
|
19
|
-
export function getSymbolOpacityGlslFunction(type, sizeExpressionGlsl) {
|
|
20
|
-
switch (type) {
|
|
21
|
-
case 'square':
|
|
22
|
-
case 'image':
|
|
23
|
-
return '1.0';
|
|
24
|
-
// taken from https://thebookofshaders.com/07/
|
|
25
|
-
case 'circle':
|
|
26
|
-
return `(1.0-smoothstep(1.-4./${sizeExpressionGlsl},1.,dot(v_quadCoord-.5,v_quadCoord-.5)*4.))`;
|
|
27
|
-
case 'triangle':
|
|
28
|
-
const st = '(v_quadCoord*2.-1.)';
|
|
29
|
-
const a = `(atan(${st}.x,${st}.y))`;
|
|
30
|
-
return `(1.0-smoothstep(.5-3./${sizeExpressionGlsl},.5,cos(floor(.5+${a}/2.094395102)*2.094395102-${a})*length(${st})))`;
|
|
31
|
-
default:
|
|
32
|
-
throw new Error(`Unexpected symbol type: ${type}`);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
14
|
+
import {getUid} from '../util.js';
|
|
35
15
|
|
|
36
16
|
/**
|
|
37
17
|
* Packs all components of a color into a two-floats array
|
|
@@ -83,102 +63,531 @@ function getGlslTypeFromType(type) {
|
|
|
83
63
|
}
|
|
84
64
|
|
|
85
65
|
/**
|
|
86
|
-
* @param {import("../style/literal").LiteralStyle} style Style
|
|
66
|
+
* @param {import("../style/literal.js").LiteralStyle} style Style
|
|
67
|
+
* @param {ShaderBuilder} builder Shader builder
|
|
68
|
+
* @param {import("../style/expressions.js").ParsingContext} vertContext Vertex shader parsing context
|
|
69
|
+
* @param {'shape-'|'circle-'|'icon-'} prefix Properties prefix
|
|
70
|
+
*/
|
|
71
|
+
function parseCommonSymbolProperties(style, builder, vertContext, prefix) {
|
|
72
|
+
let radius;
|
|
73
|
+
if (`${prefix}radius` in style && prefix !== 'icon-') {
|
|
74
|
+
radius = expressionToGlsl(
|
|
75
|
+
vertContext,
|
|
76
|
+
style[`${prefix}radius`],
|
|
77
|
+
ValueTypes.NUMBER
|
|
78
|
+
);
|
|
79
|
+
} else if (`${prefix}radius1` in style && prefix === 'shape-') {
|
|
80
|
+
radius = expressionToGlsl(
|
|
81
|
+
vertContext,
|
|
82
|
+
style[`${prefix}radius1`],
|
|
83
|
+
ValueTypes.NUMBER
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
if (radius !== undefined) {
|
|
87
|
+
if (`${prefix}stroke-width` in style) {
|
|
88
|
+
radius = `(${radius} + ${expressionToGlsl(
|
|
89
|
+
vertContext,
|
|
90
|
+
style[`${prefix}stroke-width`],
|
|
91
|
+
ValueTypes.NUMBER
|
|
92
|
+
)} * 0.5)`;
|
|
93
|
+
}
|
|
94
|
+
builder.setSymbolSizeExpression(`vec2(${radius} * 2. + 0.5)`); // adding some padding for antialiasing
|
|
95
|
+
}
|
|
96
|
+
if (`${prefix}scale` in style) {
|
|
97
|
+
const scale = expressionToGlsl(
|
|
98
|
+
vertContext,
|
|
99
|
+
style[`${prefix}scale`],
|
|
100
|
+
ValueTypes.NUMBER | ValueTypes.NUMBER_ARRAY
|
|
101
|
+
);
|
|
102
|
+
builder.setSymbolSizeExpression(
|
|
103
|
+
`${builder.getSymbolSizeExpression()} * ${scale}`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
if (`${prefix}displacement` in style) {
|
|
107
|
+
builder.setSymbolOffsetExpression(
|
|
108
|
+
expressionToGlsl(
|
|
109
|
+
vertContext,
|
|
110
|
+
style[`${prefix}displacement`],
|
|
111
|
+
ValueTypes.NUMBER_ARRAY
|
|
112
|
+
)
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
if (`${prefix}rotation` in style) {
|
|
116
|
+
builder.setSymbolRotationExpression(
|
|
117
|
+
expressionToGlsl(
|
|
118
|
+
vertContext,
|
|
119
|
+
style[`${prefix}rotation`],
|
|
120
|
+
ValueTypes.NUMBER
|
|
121
|
+
)
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
if (`${prefix}rotate-with-view` in style) {
|
|
125
|
+
builder.setSymbolRotateWithView(!!style[`${prefix}rotate-with-view`]);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @param {string} distanceField The distance field expression
|
|
131
|
+
* @param {string|null} fillColor The fill color expression; null if no fill
|
|
132
|
+
* @param {string|null} strokeColor The stroke color expression; null if no stroke
|
|
133
|
+
* @param {string|null} strokeWidth The stroke width expression; null if no stroke
|
|
134
|
+
* @param {string|null} opacity The opacity expression; null if no stroke
|
|
135
|
+
* @return {string} The final color expression, based on the distance field and given params
|
|
136
|
+
*/
|
|
137
|
+
function getColorFromDistanceField(
|
|
138
|
+
distanceField,
|
|
139
|
+
fillColor,
|
|
140
|
+
strokeColor,
|
|
141
|
+
strokeWidth,
|
|
142
|
+
opacity
|
|
143
|
+
) {
|
|
144
|
+
let color = 'vec4(0.)';
|
|
145
|
+
if (fillColor !== null) {
|
|
146
|
+
color = fillColor;
|
|
147
|
+
}
|
|
148
|
+
if (strokeColor !== null && strokeWidth !== null) {
|
|
149
|
+
const strokeFillRatio = `smoothstep(-${strokeWidth} + 0.63, -${strokeWidth} - 0.58, ${distanceField})`;
|
|
150
|
+
color = `mix(${strokeColor}, ${color}, ${strokeFillRatio})`;
|
|
151
|
+
}
|
|
152
|
+
const shapeOpacity = `(1.0 - smoothstep(-0.63, 0.58, ${distanceField}))`;
|
|
153
|
+
let result = `${color} * ${shapeOpacity}`;
|
|
154
|
+
if (opacity !== null) {
|
|
155
|
+
result = `${result} * ${opacity}`;
|
|
156
|
+
}
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* @param {import("../style/literal.js").LiteralStyle} style Style
|
|
87
162
|
* @param {ShaderBuilder} builder Shader builder
|
|
88
163
|
* @param {Object<string,import("../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
89
164
|
* @param {import("../style/expressions.js").ParsingContext} vertContext Vertex shader parsing context
|
|
90
165
|
* @param {import("../style/expressions.js").ParsingContext} fragContext Fragment shader parsing context
|
|
91
166
|
*/
|
|
92
|
-
function
|
|
167
|
+
function parseCircleProperties(
|
|
93
168
|
style,
|
|
94
169
|
builder,
|
|
95
170
|
uniforms,
|
|
96
171
|
vertContext,
|
|
97
172
|
fragContext
|
|
98
173
|
) {
|
|
99
|
-
|
|
100
|
-
|
|
174
|
+
// this function takes in screen coordinates in pixels and returns the signed distance field
|
|
175
|
+
// (0 on the boundary, negative inside the circle, positive outside, values in pixels)
|
|
176
|
+
fragContext.functions[
|
|
177
|
+
'circleDistanceField'
|
|
178
|
+
] = `float circleDistanceField(vec2 point, float radius) {
|
|
179
|
+
return length(point) - radius;
|
|
180
|
+
}`;
|
|
181
|
+
|
|
182
|
+
parseCommonSymbolProperties(style, builder, vertContext, 'circle-');
|
|
183
|
+
|
|
184
|
+
// OPACITY
|
|
185
|
+
let opacity = null;
|
|
186
|
+
if ('circle-opacity' in style) {
|
|
187
|
+
opacity = expressionToGlsl(
|
|
188
|
+
fragContext,
|
|
189
|
+
style['circle-opacity'],
|
|
190
|
+
ValueTypes.NUMBER
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// SCALE
|
|
195
|
+
let currentPoint = 'coordsPx';
|
|
196
|
+
if ('circle-scale' in style) {
|
|
197
|
+
const scale = expressionToGlsl(
|
|
198
|
+
fragContext,
|
|
199
|
+
style['circle-scale'],
|
|
200
|
+
ValueTypes.NUMBER | ValueTypes.NUMBER_ARRAY
|
|
201
|
+
);
|
|
202
|
+
currentPoint = `coordsPx / ${scale}`;
|
|
101
203
|
}
|
|
102
204
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const parsedColor = expressionToGlsl(fragContext, color, ValueTypes.COLOR);
|
|
108
|
-
const parsedOpacity = expressionToGlsl(
|
|
205
|
+
// FILL COLOR
|
|
206
|
+
let fillColor = null;
|
|
207
|
+
if ('circle-fill-color' in style) {
|
|
208
|
+
fillColor = expressionToGlsl(
|
|
109
209
|
fragContext,
|
|
110
|
-
|
|
210
|
+
style['circle-fill-color'],
|
|
211
|
+
ValueTypes.COLOR
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// STROKE COLOR
|
|
216
|
+
let strokeColor = null;
|
|
217
|
+
if ('circle-stroke-color' in style) {
|
|
218
|
+
strokeColor = expressionToGlsl(
|
|
219
|
+
fragContext,
|
|
220
|
+
style['circle-stroke-color'],
|
|
221
|
+
ValueTypes.COLOR
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// RADIUS
|
|
226
|
+
let radius = expressionToGlsl(
|
|
227
|
+
fragContext,
|
|
228
|
+
style['circle-radius'],
|
|
229
|
+
ValueTypes.NUMBER
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// STROKE WIDTH
|
|
233
|
+
let strokeWidth = null;
|
|
234
|
+
if ('circle-stroke-width' in style) {
|
|
235
|
+
strokeWidth = expressionToGlsl(
|
|
236
|
+
fragContext,
|
|
237
|
+
style['circle-stroke-width'],
|
|
111
238
|
ValueTypes.NUMBER
|
|
112
239
|
);
|
|
113
|
-
|
|
114
|
-
|
|
240
|
+
radius = `(${radius} + ${strokeWidth} * 0.5)`;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// FINAL COLOR
|
|
244
|
+
const distanceField = `circleDistanceField(${currentPoint}, ${radius})`;
|
|
245
|
+
const colorExpression = getColorFromDistanceField(
|
|
246
|
+
distanceField,
|
|
247
|
+
fillColor,
|
|
248
|
+
strokeColor,
|
|
249
|
+
strokeWidth,
|
|
250
|
+
opacity
|
|
251
|
+
);
|
|
252
|
+
builder.setSymbolColorExpression(colorExpression);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @param {import("../style/literal.js").LiteralStyle} style Style
|
|
257
|
+
* @param {ShaderBuilder} builder Shader builder
|
|
258
|
+
* @param {Object<string,import("../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
259
|
+
* @param {import("../style/expressions.js").ParsingContext} vertContext Vertex shader parsing context
|
|
260
|
+
* @param {import("../style/expressions.js").ParsingContext} fragContext Fragment shader parsing context
|
|
261
|
+
*/
|
|
262
|
+
function parseShapeProperties(
|
|
263
|
+
style,
|
|
264
|
+
builder,
|
|
265
|
+
uniforms,
|
|
266
|
+
vertContext,
|
|
267
|
+
fragContext
|
|
268
|
+
) {
|
|
269
|
+
fragContext.functions['PI'] = 'const float PI = 3.141592653589793238;';
|
|
270
|
+
fragContext.functions['TWO_PI'] = 'const float TWO_PI = 2.0 * PI;';
|
|
271
|
+
fragContext.functions['round'] = `float round(float v) {
|
|
272
|
+
return sign(v) * floor(abs(v) + 0.5);
|
|
273
|
+
}`;
|
|
274
|
+
|
|
275
|
+
// these functions take in screen coordinates in pixels and returns the signed distance field
|
|
276
|
+
// (0 on the boundary, negative inside the circle, positive outside, values in pixels)
|
|
277
|
+
// inspired by https://github.com/zranger1/PixelblazePatterns/blob/master/Toolkit/sdf2d.md#n-sided-regular-polygon
|
|
278
|
+
fragContext.functions[
|
|
279
|
+
'starDistanceField'
|
|
280
|
+
] = `float starDistanceField(vec2 point, float numPoints, float radiusIn, float radiusOut, float angle) {
|
|
281
|
+
float startAngle = -PI * 0.5 + angle; // tip starts upwards and rotates clockwise with angle
|
|
282
|
+
float c = cos(startAngle);
|
|
283
|
+
float s = sin(startAngle);
|
|
284
|
+
vec2 pointRotated = vec2(c * point.x - s * point.y, s * point.x + c * point.y);
|
|
285
|
+
float alpha = TWO_PI / numPoints; // the angle of one sector
|
|
286
|
+
float beta = atan(pointRotated.y, pointRotated.x);
|
|
287
|
+
float gamma = round(beta / alpha) * alpha; // angle in sector
|
|
288
|
+
c = cos(-gamma);
|
|
289
|
+
s = sin(-gamma);
|
|
290
|
+
vec2 inSector = vec2(c * pointRotated.x - s * pointRotated.y, abs(s * pointRotated.x + c * pointRotated.y));
|
|
291
|
+
vec2 tipToPoint = inSector + vec2(-radiusOut, 0.);
|
|
292
|
+
vec2 edgeNormal = vec2(radiusIn * sin(alpha * 0.5), -radiusIn * cos(alpha * 0.5) + radiusOut);
|
|
293
|
+
return dot(normalize(edgeNormal), tipToPoint);
|
|
294
|
+
}`;
|
|
295
|
+
fragContext.functions[
|
|
296
|
+
'regularDistanceField'
|
|
297
|
+
] = `float regularDistanceField(vec2 point, float numPoints, float radius, float angle) {
|
|
298
|
+
float startAngle = -PI * 0.5 + angle; // tip starts upwards and rotates clockwise with angle
|
|
299
|
+
float c = cos(startAngle);
|
|
300
|
+
float s = sin(startAngle);
|
|
301
|
+
vec2 pointRotated = vec2(c * point.x - s * point.y, s * point.x + c * point.y);
|
|
302
|
+
float alpha = TWO_PI / numPoints; // the angle of one sector
|
|
303
|
+
float radiusIn = radius * cos(PI / numPoints);
|
|
304
|
+
float beta = atan(pointRotated.y, pointRotated.x);
|
|
305
|
+
float gamma = round((beta - alpha * 0.5) / alpha) * alpha + alpha * 0.5; // angle in sector from mid
|
|
306
|
+
c = cos(-gamma);
|
|
307
|
+
s = sin(-gamma);
|
|
308
|
+
vec2 inSector = vec2(c * pointRotated.x - s * pointRotated.y, abs(s * pointRotated.x + c * pointRotated.y));
|
|
309
|
+
return inSector.x - radiusIn;
|
|
310
|
+
}`;
|
|
311
|
+
|
|
312
|
+
parseCommonSymbolProperties(style, builder, vertContext, 'shape-');
|
|
313
|
+
|
|
314
|
+
// OPACITY
|
|
315
|
+
let opacity = null;
|
|
316
|
+
if ('shape-opacity' in style) {
|
|
317
|
+
opacity = expressionToGlsl(
|
|
318
|
+
fragContext,
|
|
319
|
+
style['shape-opacity'],
|
|
320
|
+
ValueTypes.NUMBER
|
|
115
321
|
);
|
|
116
322
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
323
|
+
|
|
324
|
+
// SCALE
|
|
325
|
+
let currentPoint = 'coordsPx';
|
|
326
|
+
if ('shape-scale' in style) {
|
|
327
|
+
const scale = expressionToGlsl(
|
|
328
|
+
fragContext,
|
|
329
|
+
style['shape-scale'],
|
|
330
|
+
ValueTypes.NUMBER | ValueTypes.NUMBER_ARRAY
|
|
331
|
+
);
|
|
332
|
+
currentPoint = `coordsPx / ${scale}`;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// FILL COLOR
|
|
336
|
+
let fillColor = null;
|
|
337
|
+
if ('shape-fill-color' in style) {
|
|
338
|
+
fillColor = expressionToGlsl(
|
|
339
|
+
fragContext,
|
|
340
|
+
style['shape-fill-color'],
|
|
341
|
+
ValueTypes.COLOR
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// STROKE COLOR
|
|
346
|
+
let strokeColor = null;
|
|
347
|
+
if ('shape-stroke-color' in style) {
|
|
348
|
+
strokeColor = expressionToGlsl(
|
|
349
|
+
fragContext,
|
|
350
|
+
style['shape-stroke-color'],
|
|
351
|
+
ValueTypes.COLOR
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// STROKE WIDTH
|
|
356
|
+
let strokeWidth = null;
|
|
357
|
+
if ('shape-stroke-width' in style) {
|
|
358
|
+
strokeWidth = expressionToGlsl(
|
|
359
|
+
fragContext,
|
|
360
|
+
style['shape-stroke-width'],
|
|
361
|
+
ValueTypes.NUMBER
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// SHAPE TYPE
|
|
366
|
+
const numPoints = expressionToGlsl(
|
|
367
|
+
fragContext,
|
|
368
|
+
style['shape-points'],
|
|
369
|
+
ValueTypes.NUMBER
|
|
370
|
+
);
|
|
371
|
+
let angle = '0.';
|
|
372
|
+
if ('shape-angle' in style) {
|
|
373
|
+
angle = expressionToGlsl(
|
|
374
|
+
fragContext,
|
|
375
|
+
style['shape-angle'],
|
|
376
|
+
ValueTypes.NUMBER
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
let shapeField;
|
|
380
|
+
if ('shape-radius' in style) {
|
|
381
|
+
let radius = expressionToGlsl(
|
|
382
|
+
fragContext,
|
|
383
|
+
style['shape-radius'],
|
|
384
|
+
ValueTypes.NUMBER
|
|
385
|
+
);
|
|
386
|
+
if (strokeWidth !== null) {
|
|
387
|
+
radius = `${radius} + ${strokeWidth} * 0.5`;
|
|
138
388
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
389
|
+
shapeField = `regularDistanceField(${currentPoint}, ${numPoints}, ${radius}, ${angle})`;
|
|
390
|
+
} else {
|
|
391
|
+
let radiusOuter = expressionToGlsl(
|
|
392
|
+
fragContext,
|
|
393
|
+
style['shape-radius1'],
|
|
394
|
+
ValueTypes.NUMBER
|
|
142
395
|
);
|
|
143
|
-
|
|
144
|
-
|
|
396
|
+
let radiusInner = expressionToGlsl(
|
|
397
|
+
fragContext,
|
|
398
|
+
style['shape-radius2'],
|
|
399
|
+
ValueTypes.NUMBER
|
|
145
400
|
);
|
|
401
|
+
if (strokeWidth !== null) {
|
|
402
|
+
radiusOuter = `${radiusOuter} + ${strokeWidth} * 0.5`;
|
|
403
|
+
radiusInner = `${radiusInner} + ${strokeWidth} * 0.5`;
|
|
404
|
+
}
|
|
405
|
+
shapeField = `starDistanceField(${currentPoint}, ${numPoints}, ${radiusInner}, ${radiusOuter}, ${angle})`;
|
|
146
406
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
407
|
+
|
|
408
|
+
// FINAL COLOR
|
|
409
|
+
const colorExpression = getColorFromDistanceField(
|
|
410
|
+
shapeField,
|
|
411
|
+
fillColor,
|
|
412
|
+
strokeColor,
|
|
413
|
+
strokeWidth,
|
|
414
|
+
opacity
|
|
415
|
+
);
|
|
416
|
+
builder.setSymbolColorExpression(colorExpression);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* @param {import("../style/literal.js").LiteralStyle} style Style
|
|
421
|
+
* @param {ShaderBuilder} builder Shader builder
|
|
422
|
+
* @param {Object<string,import("../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
423
|
+
* @param {import("../style/expressions.js").ParsingContext} vertContext Vertex shader parsing context
|
|
424
|
+
* @param {import("../style/expressions.js").ParsingContext} fragContext Fragment shader parsing context
|
|
425
|
+
*/
|
|
426
|
+
function parseIconProperties(
|
|
427
|
+
style,
|
|
428
|
+
builder,
|
|
429
|
+
uniforms,
|
|
430
|
+
vertContext,
|
|
431
|
+
fragContext
|
|
432
|
+
) {
|
|
433
|
+
fragContext.functions[
|
|
434
|
+
'samplePremultiplied'
|
|
435
|
+
] = `vec4 samplePremultiplied(sampler2D sampler, vec2 texCoord) {
|
|
436
|
+
vec4 color = texture2D(sampler, texCoord);
|
|
437
|
+
return vec4(color.rgb * color.a, color.a);
|
|
438
|
+
}`;
|
|
439
|
+
|
|
440
|
+
// COLOR
|
|
441
|
+
let color = 'vec4(1.0)';
|
|
442
|
+
if ('icon-color' in style) {
|
|
443
|
+
color = expressionToGlsl(
|
|
444
|
+
fragContext,
|
|
445
|
+
style['icon-color'],
|
|
446
|
+
ValueTypes.COLOR
|
|
153
447
|
);
|
|
154
|
-
builder.setSymbolSizeExpression(`vec2(${parsedSize})`);
|
|
155
448
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
449
|
+
|
|
450
|
+
// OPACITY
|
|
451
|
+
if ('icon-opacity' in style) {
|
|
452
|
+
color = `${color} * ${expressionToGlsl(
|
|
453
|
+
fragContext,
|
|
454
|
+
style['icon-opacity'],
|
|
455
|
+
ValueTypes.NUMBER
|
|
456
|
+
)}`;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// IMAGE & SIZE
|
|
460
|
+
let image;
|
|
461
|
+
let size;
|
|
462
|
+
const textureId = getUid(style);
|
|
463
|
+
if ('icon-src' in style) {
|
|
464
|
+
image = new Image();
|
|
465
|
+
image.crossOrigin =
|
|
466
|
+
style['icon-cross-origin'] === undefined
|
|
467
|
+
? 'anonymous'
|
|
468
|
+
: style['icon-cross-origin'];
|
|
469
|
+
image.src = style['icon-src'];
|
|
470
|
+
// the size is provided asynchronously using a uniform
|
|
471
|
+
uniforms[`u_texture${textureId}_size`] = () => {
|
|
472
|
+
return image.complete ? [image.width, image.height] : [0, 0];
|
|
473
|
+
};
|
|
474
|
+
size = `u_texture${textureId}_size`;
|
|
475
|
+
builder.addUniform(`vec2 u_texture${textureId}_size`);
|
|
476
|
+
} else {
|
|
477
|
+
image = style['icon-img'];
|
|
478
|
+
const imgSize = style['icon-img-size'];
|
|
479
|
+
size = arrayToGlsl(imgSize);
|
|
480
|
+
}
|
|
481
|
+
uniforms[`u_texture${textureId}`] = image;
|
|
482
|
+
builder
|
|
483
|
+
.addUniform(`sampler2D u_texture${textureId}`)
|
|
484
|
+
.setSymbolColorExpression(
|
|
485
|
+
`${color} * samplePremultiplied(u_texture${textureId}, v_texCoord)`
|
|
486
|
+
)
|
|
487
|
+
.setSymbolSizeExpression(size);
|
|
488
|
+
|
|
489
|
+
// override size if width/height were specified
|
|
490
|
+
if ('icon-width' in style && 'icon-height' in style) {
|
|
491
|
+
builder.setSymbolSizeExpression(
|
|
492
|
+
`vec2(${expressionToGlsl(
|
|
159
493
|
vertContext,
|
|
160
|
-
|
|
161
|
-
ValueTypes.
|
|
162
|
-
)
|
|
494
|
+
style['icon-width'],
|
|
495
|
+
ValueTypes.NUMBER
|
|
496
|
+
)}, ${expressionToGlsl(
|
|
497
|
+
vertContext,
|
|
498
|
+
style['icon-height'],
|
|
499
|
+
ValueTypes.NUMBER
|
|
500
|
+
)})`
|
|
163
501
|
);
|
|
164
502
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
503
|
+
|
|
504
|
+
// tex coord
|
|
505
|
+
if ('icon-offset' in style && 'icon-size' in style) {
|
|
506
|
+
let offset = expressionToGlsl(
|
|
507
|
+
vertContext,
|
|
508
|
+
style['icon-offset'],
|
|
509
|
+
ValueTypes.NUMBER_ARRAY
|
|
168
510
|
);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
511
|
+
const sampleSize = expressionToGlsl(
|
|
512
|
+
vertContext,
|
|
513
|
+
style['icon-size'],
|
|
514
|
+
ValueTypes.NUMBER_ARRAY
|
|
515
|
+
);
|
|
516
|
+
const fullsize = builder.getSymbolSizeExpression();
|
|
517
|
+
builder.setSymbolSizeExpression(sampleSize);
|
|
518
|
+
|
|
519
|
+
if ('icon-offset-origin' in style) {
|
|
520
|
+
switch (style['icon-offset-origin']) {
|
|
521
|
+
case 'top-right':
|
|
522
|
+
offset = `vec2(v_quadSizePx.x, 0.) + ${sampleSize} * vec2(-1., 0.) + ${offset} * vec2(-1., 1.)`;
|
|
523
|
+
break;
|
|
524
|
+
case 'bottom-left':
|
|
525
|
+
offset = `vec2(0., v_quadSizePx.y) + ${sampleSize} * vec2(0., -1.) + ${offset} * vec2(1., -1.)`;
|
|
526
|
+
break;
|
|
527
|
+
case 'bottom-right':
|
|
528
|
+
offset = `v_quadSizePx - ${sampleSize} - ${offset}`;
|
|
529
|
+
break;
|
|
530
|
+
default: // pass
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
builder.setTextureCoordinateExpression(
|
|
534
|
+
`(vec4((${offset}).xyxy) + vec4(0., 0., ${sampleSize})) / (${fullsize}).xyxy`
|
|
173
535
|
);
|
|
174
536
|
}
|
|
175
|
-
|
|
176
|
-
|
|
537
|
+
|
|
538
|
+
parseCommonSymbolProperties(style, builder, vertContext, 'icon-');
|
|
539
|
+
|
|
540
|
+
if ('icon-anchor' in style) {
|
|
541
|
+
const anchor = expressionToGlsl(
|
|
542
|
+
vertContext,
|
|
543
|
+
style['icon-anchor'],
|
|
544
|
+
ValueTypes.NUMBER_ARRAY
|
|
545
|
+
);
|
|
546
|
+
let scale = `1.0`;
|
|
547
|
+
if (`icon-scale` in style) {
|
|
548
|
+
scale = expressionToGlsl(
|
|
549
|
+
vertContext,
|
|
550
|
+
style[`icon-scale`],
|
|
551
|
+
ValueTypes.NUMBER | ValueTypes.NUMBER_ARRAY
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
let shiftPx;
|
|
555
|
+
if (
|
|
556
|
+
style['icon-anchor-x-units'] === 'pixels' &&
|
|
557
|
+
style['icon-anchor-y-units'] === 'pixels'
|
|
558
|
+
) {
|
|
559
|
+
shiftPx = `${anchor} * ${scale}`;
|
|
560
|
+
} else if (style['icon-anchor-x-units'] === 'pixels') {
|
|
561
|
+
shiftPx = `${anchor} * vec2(vec2(${scale}).x, v_quadSizePx.y)`;
|
|
562
|
+
} else if (style['icon-anchor-y-units'] === 'pixels') {
|
|
563
|
+
shiftPx = `${anchor} * vec2(v_quadSizePx.x, vec2(${scale}).x)`;
|
|
564
|
+
} else {
|
|
565
|
+
shiftPx = `${anchor} * v_quadSizePx`;
|
|
566
|
+
}
|
|
567
|
+
// default origin is top-left
|
|
568
|
+
let offsetPx = `v_quadSizePx * vec2(0.5, -0.5) + ${shiftPx} * vec2(-1., 1.)`;
|
|
569
|
+
if ('icon-anchor-origin' in style) {
|
|
570
|
+
switch (style['icon-anchor-origin']) {
|
|
571
|
+
case 'top-right':
|
|
572
|
+
offsetPx = `v_quadSizePx * -0.5 + ${shiftPx}`;
|
|
573
|
+
break;
|
|
574
|
+
case 'bottom-left':
|
|
575
|
+
offsetPx = `v_quadSizePx * 0.5 - ${shiftPx}`;
|
|
576
|
+
break;
|
|
577
|
+
case 'bottom-right':
|
|
578
|
+
offsetPx = `v_quadSizePx * vec2(-0.5, 0.5) + ${shiftPx} * vec2(1., -1.)`;
|
|
579
|
+
break;
|
|
580
|
+
default: // pass
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
builder.setSymbolOffsetExpression(
|
|
584
|
+
`${builder.getSymbolOffsetExpression()} + ${offsetPx}`
|
|
585
|
+
);
|
|
177
586
|
}
|
|
178
587
|
}
|
|
179
588
|
|
|
180
589
|
/**
|
|
181
|
-
* @param {import("../style/literal").LiteralStyle} style Style
|
|
590
|
+
* @param {import("../style/literal.js").LiteralStyle} style Style
|
|
182
591
|
* @param {ShaderBuilder} builder Shader Builder
|
|
183
592
|
* @param {Object<string,import("../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
184
593
|
* @param {import("../style/expressions.js").ParsingContext} vertContext Vertex shader parsing context
|
|
@@ -205,7 +614,7 @@ function parseStrokeProperties(
|
|
|
205
614
|
}
|
|
206
615
|
|
|
207
616
|
/**
|
|
208
|
-
* @param {import("../style/literal").LiteralStyle} style Style
|
|
617
|
+
* @param {import("../style/literal.js").LiteralStyle} style Style
|
|
209
618
|
* @param {ShaderBuilder} builder Shader Builder
|
|
210
619
|
* @param {Object<string,import("../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
211
620
|
* @param {import("../style/expressions.js").ParsingContext} vertContext Vertex shader parsing context
|
|
@@ -233,14 +642,14 @@ function parseFillProperties(
|
|
|
233
642
|
*/
|
|
234
643
|
|
|
235
644
|
/**
|
|
236
|
-
* Parses a {@link import("../style/literal").LiteralStyle} object and returns a {@link ShaderBuilder}
|
|
645
|
+
* Parses a {@link import("../style/literal.js").LiteralStyle} object and returns a {@link ShaderBuilder}
|
|
237
646
|
* object that has been configured according to the given style, as well as `attributes` and `uniforms`
|
|
238
647
|
* arrays to be fed to the `WebGLPointsRenderer` class.
|
|
239
648
|
*
|
|
240
649
|
* Also returns `uniforms` and `attributes` properties as expected by the
|
|
241
650
|
* {@link module:ol/renderer/webgl/PointsLayer~WebGLPointsLayerRenderer}.
|
|
242
651
|
*
|
|
243
|
-
* @param {import("../style/literal").LiteralStyle} style Literal style.
|
|
652
|
+
* @param {import("../style/literal.js").LiteralStyle} style Literal style.
|
|
244
653
|
* @return {StyleParseResult} Result containing shader params, attributes and uniforms.
|
|
245
654
|
*/
|
|
246
655
|
export function parseLiteralStyle(style) {
|
|
@@ -273,7 +682,13 @@ export function parseLiteralStyle(style) {
|
|
|
273
682
|
/** @type {Object<string,import("../webgl/Helper").UniformValue>} */
|
|
274
683
|
const uniforms = {};
|
|
275
684
|
|
|
276
|
-
|
|
685
|
+
if ('icon-src' in style || 'icon-img' in style) {
|
|
686
|
+
parseIconProperties(style, builder, uniforms, vertContext, fragContext);
|
|
687
|
+
} else if ('shape-points' in style) {
|
|
688
|
+
parseShapeProperties(style, builder, uniforms, vertContext, fragContext);
|
|
689
|
+
} else if ('circle-radius' in style) {
|
|
690
|
+
parseCircleProperties(style, builder, uniforms, vertContext, fragContext);
|
|
691
|
+
}
|
|
277
692
|
parseStrokeProperties(style, builder, uniforms, vertContext, fragContext);
|
|
278
693
|
parseFillProperties(style, builder, uniforms, vertContext, fragContext);
|
|
279
694
|
|