@gisatcz/deckgl-geolib 1.11.0-dev.1 → 1.11.0-dev.3

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.
@@ -1,42 +1,88 @@
1
- import { CompositeLayer } from '@deck.gl/core';
2
- import { TileLayer } from '@deck.gl/geo-layers';
1
+ import { CompositeLayer, CompositeLayerProps, DefaultProps, TextureSource, UpdateParameters } from '@deck.gl/core';
2
+ import { _Tile2DHeader as Tile2DHeader, _TileLoadProps as TileLoadProps, GeoBoundingBox, NonGeoBoundingBox, TileLayer, TileLayerProps } from '@deck.gl/geo-layers';
3
3
  import { BitmapLayer } from '@deck.gl/layers';
4
- import { _TerrainExtension as TerrainExtension } from '@deck.gl/extensions';
5
- import CogTiles from '../cogtiles/cogtiles.ts';
4
+ import type { MeshAttributes } from '@loaders.gl/schema';
6
5
  import { GeoImageOptions } from '../geoimage/geoimage.ts';
7
- declare class CogBitmapLayer extends CompositeLayer<any> {
6
+ export type TileBoundingBox = NonGeoBoundingBox | GeoBoundingBox;
7
+ export type ZRange = [minZ: number, maxZ: number];
8
+ export type Bounds = [minX: number, minY: number, maxX: number, maxY: number];
9
+ export type URLTemplate = string | string[] | null;
10
+ export declare const urlType: {
11
+ type: "object";
12
+ value: URLTemplate;
13
+ validate: (value: any, propType: any) => boolean;
14
+ equal: (value1: any, value2: any) => boolean;
15
+ };
16
+ export type ClampToTerrainOptions = {
17
+ terrainDrawMode?: string;
18
+ };
19
+ type MeshAndTexture = [MeshAttributes | null, TextureSource | null];
20
+ /** All properties supported by CogBitmapLayer */
21
+ export type CogBitmapLayerProps = _CogBitmapLayerProps & TileLayerProps<MeshAndTexture> & CompositeLayerProps;
22
+ /** Props added by the CogBitmapLayer */
23
+ type _CogBitmapLayerProps = {
24
+ /** Image url that encodes raster data. * */
25
+ rasterData: URLTemplate;
26
+ /** Bounding box of the bitmap image, [minX, minY, maxX, maxY] in world coordinates. * */
27
+ bounds: Bounds | null;
28
+ /** Whether the rendered texture should be blurred or not - effects minFilter and maxFilter * */
29
+ blurredTexture?: boolean;
30
+ /** Weather visualise the entire image with specified opacity (0-1) * */
31
+ opacity?: number;
32
+ /** Whether the rendered texture should be clamped to terrain * */
33
+ clampToTerrain?: ClampToTerrainOptions | boolean;
34
+ /**
35
+ * TODO
36
+ */
37
+ cogBitmapOptions: GeoImageOptions;
38
+ /**
39
+ * @deprecated Use `loadOptions.terrain.workerUrl` instead
40
+ */
41
+ workerUrl?: string;
42
+ };
43
+ /** Render bitmap texture from cog raster images. */
44
+ export default class CogBitmapLayer<ExtraPropsT extends {} = {}> extends CompositeLayer<ExtraPropsT & Required<_CogBitmapLayerProps & Required<TileLayerProps<MeshAndTexture>>>> {
45
+ static defaultProps: DefaultProps<CogBitmapLayerProps>;
8
46
  static layerName: string;
9
- id: string;
10
- url: string;
11
- static displayName: string;
12
- cogTiles: CogTiles;
13
- tileSize: number;
47
+ rasterUrl: string;
14
48
  minZoom: number;
15
49
  maxZoom: number;
16
- blurredTexture: boolean;
17
- constructor(id: string, url: string, options: GeoImageOptions);
18
- initializeState(): void;
19
- init(url: string): Promise<void>;
50
+ state: {
51
+ isTiled?: boolean;
52
+ terrain?: MeshAttributes;
53
+ zRange?: ZRange | null;
54
+ };
55
+ initializeState(context: any): Promise<void>;
56
+ init(rasterUrl: string): Promise<void>;
57
+ updateState({ props, oldProps }: UpdateParameters<this>): void;
58
+ getTiledBitmapData(tile: TileLoadProps): Promise<TextureSource>;
59
+ renderSubLayers(props: TileLayerProps<TextureSource> & {
60
+ id: string;
61
+ data: TextureSource;
62
+ tile: Tile2DHeader<TextureSource>;
63
+ }): BitmapLayer<{}>;
20
64
  renderLayers(): TileLayer<any, {
21
- id: `${string}-${string}`;
22
- getTileData: (tileData: any) => Promise<string>;
65
+ getTileData: any;
66
+ renderSubLayers: any;
67
+ updateTriggers: {
68
+ getTileData: {
69
+ rasterData: string;
70
+ blurredTexture: boolean;
71
+ opacity: number;
72
+ clampToTerrain: boolean | ClampToTerrainOptions;
73
+ };
74
+ };
75
+ extent: any;
76
+ tileSize: number;
23
77
  minZoom: number;
24
78
  maxZoom: number;
25
- tileSize: number;
26
- maxRequests: 6;
27
- extent: [number, number, number, number];
28
- renderSubLayers: (props: any) => BitmapLayer<{
29
- terrainDrawMode: any;
30
- data: null;
31
- image: any;
32
- bounds: [any, any, any, any];
33
- opacity: number;
34
- textureParameters: {
35
- minFilter: "linear" | "nearest";
36
- magFilter: "linear" | "nearest";
37
- };
38
- extensions: TerrainExtension[];
39
- }>;
79
+ maxRequests: number;
80
+ onTileLoad: (tile: Tile2DHeader<MeshAndTexture>) => void;
81
+ onTileUnload: (tile: Tile2DHeader<MeshAndTexture>) => void;
82
+ onTileError: (err: any, tile?: any) => void;
83
+ maxCacheSize: number;
84
+ maxCacheByteSize: number;
85
+ refinementStrategy: import("node_modules/@deck.gl/geo-layers/dist/tileset-2d/tileset-2d.js").RefinementStrategy;
40
86
  }>;
41
87
  }
42
- export default CogBitmapLayer;
88
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gisatcz/deckgl-geolib",
3
- "version": "1.11.0-dev.1",
3
+ "version": "1.11.0-dev.3",
4
4
  "private": false,
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -1,113 +1,344 @@
1
- import { CompositeLayer } from '@deck.gl/core';
2
- import { TileLayer } from '@deck.gl/geo-layers';
3
- import { BitmapLayer } from '@deck.gl/layers';
1
+ import {CompositeLayer, CompositeLayerProps, DefaultProps, log, TextureSource, UpdateParameters,} from '@deck.gl/core';
2
+ import {
3
+ _Tile2DHeader as Tile2DHeader,
4
+ _TileLoadProps as TileLoadProps,
5
+ GeoBoundingBox,
6
+ NonGeoBoundingBox,
7
+ TileLayer,
8
+ TileLayerProps,
9
+ } from '@deck.gl/geo-layers';
10
+ import {BitmapLayer} from '@deck.gl/layers';
4
11
  import { _TerrainExtension as TerrainExtension } from '@deck.gl/extensions';
5
- import { GL } from '@luma.gl/constants';
12
+ // import { GL } from '@luma.gl/constants';
6
13
  // import GL from '@luma.gl/constants';
7
14
  // GL.GL.CLIP_DISTANCE0_WEBGL
15
+ import type {MeshAttributes} from '@loaders.gl/schema';
8
16
  import CogTiles from '../cogtiles/cogtiles.ts';
9
17
 
10
- import { GeoImageOptions } from '../geoimage/geoimage.ts';
18
+ import {GeoImageOptions} from '../geoimage/geoimage.ts';
19
+ // import { TileBoundingBox, ZRange } from '../cogterrainlayer/CogTerrainLayer.js';
20
+ export type TileBoundingBox = NonGeoBoundingBox | GeoBoundingBox;
21
+
22
+ export type ZRange = [minZ: number, maxZ: number];
11
23
 
12
24
  // let needsRerender: boolean = false;
13
25
  // let extent = [0, 0, 0, 0]
26
+ export type Bounds = [minX: number, minY: number, maxX: number, maxY: number];
14
27
 
15
- class CogBitmapLayer extends CompositeLayer<any> {
16
- static layerName = 'CogBitmapLayer';
28
+ export type URLTemplate = string | string[] | null;
17
29
 
18
- // private _isLoaded: boolean;
30
+ export const urlType = {
31
+ type: 'object' as const,
32
+ value: null as URLTemplate,
33
+ validate: (value, propType) => (propType.optional && value === null)
34
+ || typeof value === 'string'
35
+ || (Array.isArray(value) && value.every((url) => typeof url === 'string')),
36
+ equal: (value1, value2) => {
37
+ if (value1 === value2) {
38
+ return true;
39
+ }
40
+ if (!Array.isArray(value1) || !Array.isArray(value2)) {
41
+ return false;
42
+ }
43
+ const len = value1.length;
44
+ if (len !== value2.length) {
45
+ return false;
46
+ }
47
+ for (let i = 0; i < len; i++) {
48
+ if (value1[i] !== value2[i]) {
49
+ return false;
50
+ }
51
+ }
52
+ return true;
53
+ },
54
+ };
55
+
56
+ export type ClampToTerrainOptions = {
57
+ terrainDrawMode?: string
58
+ }
59
+
60
+ const defaultProps: DefaultProps<CogBitmapLayerProps> = {
61
+ ...TileLayer.defaultProps,
62
+ // Image url that encodes height data
63
+ // elevationData: urlType,
64
+ // Image url to use as texture
65
+ // texture: { ...urlType, optional: true },
66
+ // Martini error tolerance in meters, smaller number -> more detailed mesh
67
+ // meshMaxError: { type: 'number', value: 4.0 },
68
+ // Bounding box of the terrain image, [minX, minY, maxX, maxY] in world coordinates
69
+ bounds: {
70
+ type: 'array', value: null, optional: true, compare: true,
71
+ },
72
+ rasterData: urlType,
73
+ // Color to use if texture is unavailable
74
+ // color: { type: 'color', value: [255, 255, 255] },
75
+ blurredTexture: true,
76
+ opacity: 1,
77
+ clampToTerrain: false,
78
+ // Object to decode height data, from (r, g, b) to height in meters
79
+ // elevationDecoder: {
80
+ // type: 'object',
81
+ // value: {
82
+ // rScaler: 1,
83
+ // gScaler: 0,
84
+ // bScaler: 0,
85
+ // offset: 0,
86
+ // },
87
+ // },
88
+ // Supply url to local terrain worker bundle. Only required if running offline and cannot access CDN.
89
+ workerUrl: '',
90
+ // Same as SimpleMeshLayer wireframe
91
+ // wireframe: false,
92
+ // material: true,
93
+
94
+ // loaders: [TerrainLoader],
95
+ };
96
+
97
+ // Turns array of templates into a single string to work around shallow change
98
+ function urlTemplateToUpdateTrigger(template: URLTemplate): string {
99
+ if (Array.isArray(template)) {
100
+ return template.join(';');
101
+ }
102
+ return template || '';
103
+ }
104
+
105
+ type MeshAndTexture = [MeshAttributes | null, TextureSource | null];
19
106
 
20
- id = '';
107
+ /** All properties supported by CogBitmapLayer */
108
+ export type CogBitmapLayerProps = _CogBitmapLayerProps &
109
+ TileLayerProps<MeshAndTexture> &
110
+ CompositeLayerProps;
21
111
 
22
- url: string;
112
+ /** Props added by the CogBitmapLayer */
113
+ type _CogBitmapLayerProps = {
114
+ /** Image url that encodes raster data. * */
115
+ rasterData: URLTemplate;
23
116
 
24
- static displayName: string;
117
+ /** Bounding box of the bitmap image, [minX, minY, maxX, maxY] in world coordinates. * */
118
+ bounds: Bounds | null;
25
119
 
26
- cogTiles: CogTiles;
120
+ /** Whether the rendered texture should be blurred or not - effects minFilter and maxFilter * */
121
+ blurredTexture?: boolean;
27
122
 
28
- tileSize: number;
123
+ /** Weather visualise the entire image with specified opacity (0-1) * */
124
+ opacity?: number;
125
+
126
+ /** Whether the rendered texture should be clamped to terrain * */
127
+ clampToTerrain?: ClampToTerrainOptions | boolean, // terrainDrawMode: 'drape',
128
+
129
+ /**
130
+ * TODO
131
+ */
132
+ cogBitmapOptions: GeoImageOptions;
133
+
134
+ /**
135
+ * @deprecated Use `loadOptions.terrain.workerUrl` instead
136
+ */
137
+ workerUrl?: string;
138
+ };
139
+
140
+ /** Render bitmap texture from cog raster images. */
141
+ export default class CogBitmapLayer<ExtraPropsT extends {} = {}> extends CompositeLayer<
142
+ ExtraPropsT & Required<_CogBitmapLayerProps & Required<TileLayerProps<MeshAndTexture>>>
143
+ > {
144
+ static defaultProps = defaultProps;
145
+
146
+ static layerName = 'CogBitmapLayer';
147
+
148
+ rasterUrl: string;
29
149
 
30
150
  minZoom: number;
31
151
 
32
152
  maxZoom: number;
33
153
 
34
- blurredTexture: boolean;
35
-
36
- constructor(id:string, url:string, options:GeoImageOptions) {
37
- super({});
38
- this.id = id;
39
- // this.state = {
40
- // initialized: false,
41
- // };
42
- // this._isLoaded = false;
43
- this.cogTiles = new CogTiles(options);
44
- this.blurredTexture = options.blurredTexture;
45
- this.url = url;
46
- // setTimeout(() => {
47
- // this.init(url);
48
- // }, 500);
49
- }
154
+ state!: {
155
+ isTiled?: boolean;
156
+ terrain?: MeshAttributes;
157
+ zRange?: ZRange | null;
158
+ };
159
+
160
+ // private _isLoaded: boolean;
161
+
162
+ // id = '';
163
+
164
+ // url: string;
165
+
166
+ // static displayName: string;
167
+
168
+ // cogTiles: CogTiles;
169
+ //
170
+ // tileSize: number;
171
+ //
172
+ // blurredTexture: boolean;
173
+
174
+ async initializeState(context: any) {
175
+ super.initializeState(context);
50
176
 
51
- initializeState() {
52
- this.state = {
177
+ this.setState({
178
+ bitmapCogTiles: new CogTiles(this.props.cogBitmapOptions),
53
179
  initialized: false,
54
- };
180
+ });
55
181
 
56
- this.init(this.url);
182
+ await this.init(this.rasterUrl);
57
183
  }
58
184
 
59
- async init(url:string) {
60
- const cog = await this.cogTiles.initializeCog(url);
61
- this.setState({ initialized: true });
62
- this.tileSize = this.cogTiles.getTileSize(cog);
63
- const zoomRange = this.cogTiles.getZoomRange(cog);
185
+ async init(rasterUrl: string) {
186
+ const cog = await this.state.bitmapCogTiles.initializeCog(this.props.rasterData);
187
+ // this.tileSize = this.terrainCogTiles.getTileSize(cog);
188
+
189
+ const zoomRange = this.state.bitmapCogTiles.getZoomRange(cog);
64
190
  [this.minZoom, this.maxZoom] = zoomRange;
191
+
192
+ this.setState({ initialized: true });
193
+ }
194
+
195
+ updateState({ props, oldProps }: UpdateParameters<this>): void {
196
+ const rasterDataChanged = props.rasterData !== oldProps.rasterData;
197
+ if (rasterDataChanged) {
198
+ const { rasterData } = props;
199
+ const isTiled = rasterData
200
+ && (Array.isArray(rasterData)
201
+ || (rasterData.includes('{x}') && rasterData.includes('{y}'))) || this.props.isTiled;
202
+ this.setState({ isTiled });
203
+ }
204
+
205
+ // Reloading for single terrain mesh
206
+ const shouldReload = rasterDataChanged
207
+ // || props.meshMaxError !== oldProps.meshMaxError
208
+ // || props.elevationDecoder !== oldProps.elevationDecoder
209
+ || props.bounds !== oldProps.bounds;
210
+
211
+ if (!this.state.isTiled && shouldReload) {
212
+ // When state.isTiled, elevationData cannot be an array
213
+ // const terrain = this.loadTerrain(props as TerrainLoadProps);
214
+ // this.setState({ terrain });
215
+ }
216
+
217
+ // TODO - remove in v9
218
+ // @ts-ignore
219
+ if (props.workerUrl) {
220
+ log.removed('workerUrl', 'loadOptions.terrain.workerUrl')();
221
+ }
222
+ }
223
+
224
+ async getTiledBitmapData(tile: TileLoadProps): Promise<TextureSource> {
225
+ // const {
226
+ // rasterData, fetch,
227
+ // } = this.props;
228
+ const { viewport } = this.context;
229
+ // const dataUrl = getURLFromTemplate(rasterData, tile);
230
+ // const textureUrl = texture && getURLFromTemplate(texture, tile);
231
+
232
+ const { signal } = tile;
233
+ let bottomLeft = [0, 0] as [number, number];
234
+ let topRight = [0, 0] as [number, number];
235
+ if (viewport.isGeospatial) {
236
+ const bbox = tile.bbox as GeoBoundingBox;
237
+
238
+ bottomLeft = viewport.projectFlat([bbox.west, bbox.south]);
239
+ topRight = viewport.projectFlat([bbox.east, bbox.north]);
240
+ } else {
241
+ const bbox = tile.bbox as Exclude<TileBoundingBox, GeoBoundingBox>;
242
+ bottomLeft = [bbox.left, bbox.bottom];
243
+ topRight = [bbox.right, bbox.top];
244
+ }
245
+ const bounds: Bounds = [bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]];
246
+
247
+ // TODO - pass signal to getTile
248
+ // abort request if signal is aborted
249
+ return await this.state.bitmapCogTiles.getTile(
250
+ tile.index.x,
251
+ tile.index.y,
252
+ tile.index.z,
253
+ // bounds,
254
+ // this.props.meshMaxError,
255
+ );
65
256
  }
66
257
 
258
+ renderSubLayers(
259
+ props: TileLayerProps<TextureSource> & {
260
+ id: string;
261
+ data: TextureSource;
262
+ tile: Tile2DHeader<TextureSource>;
263
+ },
264
+ ) {
265
+ const SubLayerClass = this.getSubLayerClass('image', BitmapLayer);
266
+
267
+ const { blurredTexture, opacity,clampToTerrain } = this.props;
268
+
269
+ const data = props.data;
270
+
271
+ if (!data) {
272
+ return null;
273
+ }
274
+
275
+ const {
276
+ bbox: {
277
+ west, south, east, north,
278
+ },
279
+ } = props.tile;
280
+
281
+ return new SubLayerClass({ ...props, tileSize: 256 }, {
282
+ data: null,
283
+ image: data,
284
+ _instanced: false,
285
+ bounds: [west, south, east, north],
286
+ opacity,
287
+ textureParameters: {
288
+ minFilter: blurredTexture ? 'linear' : 'nearest',
289
+ magFilter: blurredTexture ? 'linear' : 'nearest',
290
+ },
291
+ // TODO check if works!!!
292
+ extensions: clampToTerrain ? [new TerrainExtension()] : [],
293
+ ...(clampToTerrain?.terrainDrawMode
294
+ ? { terrainDrawMode: clampToTerrain.terrainDrawMode }
295
+ : {}),
296
+ });
297
+ }
298
+
299
+
67
300
  renderLayers() {
68
- if (this.cogTiles.cog) {
69
- const layer = new TileLayer({
70
- id: `${this.id}-${String(performance.now())}`,
71
- getTileData: (tileData: any) => this.cogTiles.getTile(
72
- tileData.index.x,
73
- tileData.index.y,
74
- tileData.index.z,
75
- ),
301
+ const {
302
+ rasterData,
303
+ blurredTexture,
304
+ opacity,
305
+ clampToTerrain,
306
+ tileSize,
307
+ maxRequests,
308
+ onTileLoad,
309
+ onTileUnload,
310
+ onTileError,
311
+ maxCacheSize,
312
+ maxCacheByteSize,
313
+ refinementStrategy,
314
+ } = this.props;
315
+ if (this.state.isTiled && this.state.initialized){
316
+ return new TileLayer(this.getSubLayerProps({
317
+ id: 'tiles',
318
+ }), {
319
+ getTileData: this.getTiledBitmapData.bind(this),
320
+ renderSubLayers: this.renderSubLayers.bind(this),
321
+ updateTriggers: {
322
+ getTileData: {
323
+ rasterData: urlTemplateToUpdateTrigger(rasterData),
324
+ blurredTexture,
325
+ opacity,
326
+ clampToTerrain,
327
+ },
328
+ },
329
+ extent: this.state.bitmapCogTiles.cog ? this.state.bitmapCogTiles.getBoundsAsLatLon(this.state.bitmapCogTiles.cog) : null,
330
+ tileSize,
76
331
  minZoom: this.minZoom,
77
332
  maxZoom: this.maxZoom,
78
- tileSize: this.tileSize,
79
- maxRequests: 6,
80
- extent: this.cogTiles.cog ? this.cogTiles.getBoundsAsLatLon(this.cogTiles.cog) : null,
81
-
82
- renderSubLayers: (props: any) => {
83
- const {
84
- bbox: {
85
- west, south, east, north,
86
- },
87
- } = props.tile;
88
-
89
- return new BitmapLayer(props, {
90
- data: null,
91
- image: props.data,
92
- bounds: [west, south, east, north],
93
- opacity: 1, // 0.6
94
- textureParameters: {
95
- minFilter: this.blurredTexture ? 'linear' : 'nearest',
96
- magFilter: this.blurredTexture ? 'linear' : 'nearest',
97
- },
98
- extensions: this.cogTiles?.options?.clampToTerrain ? [new TerrainExtension()] : [],
99
- ...(this.cogTiles?.options?.clampToTerrain?.terrainDrawMode
100
- ? { terrainDrawMode: this.cogTiles?.options?.clampToTerrain.terrainDrawMode }
101
- : {}),
102
- });
103
- },
333
+ maxRequests,
334
+ onTileLoad,
335
+ onTileUnload,
336
+ onTileError,
337
+ maxCacheSize,
338
+ maxCacheByteSize,
339
+ refinementStrategy,
104
340
  });
105
- return layer;
106
341
  }
107
342
  return null;
108
343
  }
109
- }
110
-
111
- CogBitmapLayer.displayName = 'CogBitmapLayer';
112
-
113
- export default CogBitmapLayer;
344
+ }