1
- import type { LayerProps , PickingInfo } from "@deck.gl/core" ;
2
- import { project32 } from "@deck.gl/core" ;
3
1
import type { BitmapLayerPickingInfo , BitmapLayerProps } from "@deck.gl/layers" ;
4
2
import { BitmapLayer } from "@deck.gl/layers" ;
3
+ import type { colorTablesArray } from "@emerson-eps/color-tables/" ;
4
+ import { getRgbData } from "@emerson-eps/color-tables" ;
5
5
import type { Color , LayerProps , PickingInfo } from "@deck.gl/core" ;
6
6
import { project32 } from "@deck.gl/core" ;
7
7
import type {
@@ -18,6 +18,7 @@ import type { ContinuousLegendDataType } from "../../components/ColorLegend";
18
18
import type { ShaderModule } from "@luma.gl/shadertools" ;
19
19
import type { Model } from "@luma.gl/engine" ;
20
20
import type { Texture } from "@luma.gl/core" ;
21
+ import * as png from "@vivaxy/png" ;
21
22
22
23
function getImageData (
23
24
colorMapName : string ,
@@ -108,6 +109,10 @@ export interface ColormapLayerProps
108
109
*/
109
110
colorMapClampColor : Color | undefined | boolean ;
110
111
112
+ // If set will calculate contour lines and hillshading based on this map instead.
113
+ // Default undefined.
114
+ heightMapUrl : string ;
115
+
111
116
// Non public properties:
112
117
reportBoundingBox ?: React . Dispatch < ReportBoundingBoxAction > ;
113
118
}
@@ -133,9 +138,69 @@ const defaultProps = {
133
138
hillshading : false ,
134
139
contourReferencePoint : 0 ,
135
140
contourInterval : 50 , // 50 meter by default
141
+
142
+ propertiesUrl : "" ,
136
143
} ;
137
144
138
145
export default class ColormapLayer extends BitmapLayer < ColormapLayerProps > {
146
+ initializeState ( ) : void {
147
+ super . initializeState ( ) ;
148
+
149
+ const createPropertyTexture = async ( ) => {
150
+ const response = await fetch ( this . props . heightMapUrl ) ;
151
+ if ( ! response . ok ) {
152
+ console . error ( "Could not load " , this . props . heightMapUrl ) ;
153
+ } else {
154
+ const blob = await response . blob ( ) ;
155
+ const contentType = response . headers . get ( "content-type" ) ;
156
+ const isPng = contentType === "image/png" ;
157
+ if ( isPng ) {
158
+ const heightMapTexture = await new Promise ( ( resolve ) => {
159
+ const fileReader = new FileReader ( ) ;
160
+ fileReader . readAsArrayBuffer ( blob ) ;
161
+ fileReader . onload = ( ) => {
162
+ const arrayBuffer = fileReader . result ;
163
+ const imgData = png . decode (
164
+ arrayBuffer as ArrayBuffer
165
+ ) ;
166
+ const w = imgData . width ;
167
+ const h = imgData . height ;
168
+
169
+ const data = imgData . data ; // array of int's
170
+ const n = data . length ;
171
+ const buffer = new ArrayBuffer ( n ) ;
172
+ const view = new DataView ( buffer ) ;
173
+ for ( let i = 0 ; i < n ; i ++ ) {
174
+ view . setUint8 ( i , data [ i ] ) ;
175
+ }
176
+
177
+ const array = new Uint8Array ( buffer ) ;
178
+ const propertyTexture =
179
+ this . context . device . createTexture ( {
180
+ sampler : {
181
+ addressModeU : "clamp-to-edge" ,
182
+ addressModeV : "clamp-to-edge" ,
183
+ minFilter : "linear" ,
184
+ magFilter : "linear" ,
185
+ } ,
186
+ width : w ,
187
+ height : h ,
188
+ format : "rgba8unorm" ,
189
+ data : array as Uint8Array ,
190
+ } ) ;
191
+ resolve ( propertyTexture ) ;
192
+ } ;
193
+ } ) ;
194
+ this . setState ( {
195
+ ...this . state ,
196
+ heightMapTexture,
197
+ } ) ;
198
+ }
199
+ }
200
+ } ;
201
+ createPropertyTexture ( ) ;
202
+ }
203
+
139
204
setShaderModuleProps (
140
205
...props : Parameters < Model [ "shaderInputs" ] [ "setProps" ] >
141
206
) : void {
@@ -181,7 +246,7 @@ export default class ColormapLayer extends BitmapLayer<ColormapLayerProps> {
181
246
const colorMapRangeMin = this . props . colorMapRange ?. [ 0 ] ?? valueRangeMin ;
182
247
const colorMapRangeMax = this . props . colorMapRange ?. [ 1 ] ?? valueRangeMax ;
183
248
184
- const colormap = this . context . device . createTexture ( {
249
+ const colormapTexture = this . context . device . createTexture ( {
185
250
width : 256 ,
186
251
height : 1 ,
187
252
format : "rgb8unorm-webgl" ,
@@ -192,7 +257,29 @@ export default class ColormapLayer extends BitmapLayer<ColormapLayerProps> {
192
257
) ,
193
258
} ) ;
194
259
195
- this . state . model ?. setBindings ( { colormap } ) ;
260
+ // eslint-disable-next-line
261
+ // @ts -ignore
262
+ let heightMapTexture = this . state . heightMapTexture ;
263
+ const isHeightMapTextureDefined =
264
+ typeof heightMapTexture !== "undefined" ;
265
+
266
+ if ( ! isHeightMapTextureDefined ) {
267
+ // Create a dummy texture
268
+ heightMapTexture = this . context . device . createTexture ( {
269
+ sampler : {
270
+ addressModeU : "clamp-to-edge" ,
271
+ addressModeV : "clamp-to-edge" ,
272
+ minFilter : "linear" ,
273
+ magFilter : "linear" ,
274
+ } ,
275
+ width : 1 ,
276
+ height : 1 ,
277
+ format : "rgba8unorm" ,
278
+ data : new Uint8Array ( [ 1 , 1 , 1 , 1 ] ) ,
279
+ } ) ;
280
+ }
281
+
282
+ this . state . model ?. setBindings ( { colormapTexture, heightMapTexture } ) ;
196
283
197
284
const bitmapResolution = this . props . image
198
285
? [
@@ -236,6 +323,7 @@ export default class ColormapLayer extends BitmapLayer<ColormapLayerProps> {
236
323
isClampColor,
237
324
colorMapClampColor,
238
325
isColorMapClampColorTransparent,
326
+ isHeightMapTextureDefined,
239
327
rgbScaler : this . props . valueDecoder . rgbScaler ,
240
328
floatScaler : this . props . valueDecoder . floatScaler ,
241
329
offset : this . props . valueDecoder . offset ,
@@ -320,6 +408,7 @@ uniform mapUniforms {
320
408
bool isClampColor;
321
409
vec3 colorMapClampColor;
322
410
bool isColorMapClampColorTransparent;
411
+ bool isHeightMapTextureDefined;
323
412
vec3 rgbScaler; // r, g and b multipliers
324
413
float floatScaler; // value multiplier
325
414
float offset; // translation of the r, g, b sum
@@ -352,6 +441,7 @@ type Map2DUniformsType = {
352
441
isClampColor : boolean ;
353
442
colorMapClampColor : [ number , number , number ] ;
354
443
isColorMapClampColorTransparent : boolean ;
444
+ isHeightMapTextureDefined : boolean ;
355
445
rgbScaler : [ number , number , number ] ;
356
446
floatScaler : number ;
357
447
offset : number ;
@@ -376,6 +466,7 @@ const map2DUniforms = {
376
466
isClampColor : "u32" ,
377
467
colorMapClampColor : "vec3<f32>" ,
378
468
isColorMapClampColorTransparent : "u32" ,
469
+ isHeightMapTextureDefined : "u32" ,
379
470
rgbScaler : "vec3<f32>" ,
380
471
floatScaler : "f32" ,
381
472
offset : "f32" ,
0 commit comments