@webviz/subsurface-viewer 0.0.1-alpha.1 → 0.0.2-alpha.2

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.
Files changed (177) hide show
  1. package/dist/index.d.ts +0 -1
  2. package/dist/index.js +0 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/package.json +5 -2
  5. package/package.json +6 -3
  6. package/dist/DashSubsurfaceViewer.d.ts +0 -56
  7. package/dist/DashSubsurfaceViewer.js +0 -160
  8. package/dist/DashSubsurfaceViewer.js.map +0 -1
  9. package/src/DashSubsurfaceViewer.tsx +0 -270
  10. package/src/SubsurfaceViewer.stories.tsx +0 -449
  11. package/src/SubsurfaceViewer.test.tsx +0 -98
  12. package/src/SubsurfaceViewer.tsx +0 -356
  13. package/src/__snapshots__/SubsurfaceViewer.test.tsx.snap +0 -178
  14. package/src/assets/glTF/north_arrow/scene.bin +0 -0
  15. package/src/assets/glTF/north_arrow/scene.gltf +0 -315
  16. package/src/assets/glTF/north_arrow/textures/Arrow5_baseColor.png +0 -0
  17. package/src/assets/glTF/north_arrow/textures/Arrow5_metallicRoughness.png +0 -0
  18. package/src/assets/glTF/north_arrow/textures/Arrow5_normal.png +0 -0
  19. package/src/components/ColorLegend.test.tsx +0 -32
  20. package/src/components/ColorLegend.tsx +0 -80
  21. package/src/components/ColorLegends.test.tsx +0 -97
  22. package/src/components/ColorLegends.tsx +0 -46
  23. package/src/components/DistanceScale.stories.tsx +0 -28
  24. package/src/components/DistanceScale.test.tsx +0 -36
  25. package/src/components/DistanceScale.tsx +0 -84
  26. package/src/components/InfoCard.test.tsx +0 -110
  27. package/src/components/InfoCard.tsx +0 -263
  28. package/src/components/Map.test.tsx +0 -142
  29. package/src/components/Map.tsx +0 -1435
  30. package/src/components/StatusIndicator.test.tsx +0 -14
  31. package/src/components/StatusIndicator.tsx +0 -38
  32. package/src/components/ViewAnnotation.tsx +0 -16
  33. package/src/components/ViewFooter.test.tsx +0 -12
  34. package/src/components/ViewFooter.tsx +0 -30
  35. package/src/components/__snapshots__/ColorLegends.test.tsx.snap +0 -15
  36. package/src/components/__snapshots__/DistanceScale.test.tsx.snap +0 -33
  37. package/src/components/__snapshots__/InfoCard.test.tsx.snap +0 -561
  38. package/src/components/__snapshots__/Map.test.tsx.snap +0 -119
  39. package/src/components/__snapshots__/StatusIndicator.test.tsx.snap +0 -3
  40. package/src/components/__snapshots__/ViewFooter.test.tsx.snap +0 -7
  41. package/src/components/settings/DrawModeSelector.test.tsx +0 -45
  42. package/src/components/settings/DrawModeSelector.tsx +0 -58
  43. package/src/components/settings/DrawModeSelector_performance.test.tsx +0 -35
  44. package/src/components/settings/LayerProperty.test.tsx +0 -35
  45. package/src/components/settings/LayerProperty.tsx +0 -153
  46. package/src/components/settings/LayerProperty_performance.test.tsx +0 -39
  47. package/src/components/settings/LayerSettingsButton.test.tsx +0 -133
  48. package/src/components/settings/LayerSettingsButton.tsx +0 -95
  49. package/src/components/settings/LayersButton.test.tsx +0 -102
  50. package/src/components/settings/LayersButton.tsx +0 -97
  51. package/src/components/settings/NumericInput.test.tsx +0 -25
  52. package/src/components/settings/NumericInput.tsx +0 -67
  53. package/src/components/settings/Settings.tsx +0 -71
  54. package/src/components/settings/SliderInput.test.tsx +0 -28
  55. package/src/components/settings/SliderInput.tsx +0 -71
  56. package/src/components/settings/ToggleButton.test.tsx +0 -25
  57. package/src/components/settings/ToggleButton.tsx +0 -53
  58. package/src/components/settings/__snapshots__/DrawModeSelector.test.tsx.snap +0 -124
  59. package/src/components/settings/__snapshots__/LayerProperty.test.tsx.snap +0 -124
  60. package/src/components/settings/__snapshots__/LayerSettingsButton.test.tsx.snap +0 -36
  61. package/src/components/settings/__snapshots__/LayersButton.test.tsx.snap +0 -83
  62. package/src/components/settings/__snapshots__/NumericInput.test.tsx.snap +0 -123
  63. package/src/components/settings/__snapshots__/SliderInput.test.tsx.snap +0 -244
  64. package/src/components/settings/__snapshots__/ToggleButton.test.tsx.snap +0 -182
  65. package/src/custom.d.ts +0 -9
  66. package/src/index.ts +0 -5
  67. package/src/inputSchema/ColorTables.json +0 -51
  68. package/src/inputSchema/FaultPolygons.json +0 -80
  69. package/src/inputSchema/Grid.json +0 -39
  70. package/src/inputSchema/PieChart.json +0 -72
  71. package/src/inputSchema/WellLog.json +0 -126
  72. package/src/inputSchema/WellLogTemplate.json +0 -136
  73. package/src/inputSchema/WellLogs.json +0 -5
  74. package/src/inputSchema/Wells.json +0 -106
  75. package/src/inputSchema/schemaValidationUtil.tsx +0 -55
  76. package/src/inputSchema/validator.tsx +0 -72
  77. package/src/inputSchema/wellCompletions.json +0 -108
  78. package/src/layers/BoxSelectionLayer/boxSelectionLayer.stories.tsx +0 -172
  79. package/src/layers/BoxSelectionLayer/boxSelectionLayer.tsx +0 -136
  80. package/src/layers/axes/axes-fragment.glsl.ts +0 -15
  81. package/src/layers/axes/axesLayer.stories.tsx +0 -87
  82. package/src/layers/axes/axesLayer.ts +0 -692
  83. package/src/layers/axes/boxLayer.ts +0 -71
  84. package/src/layers/axes/grid-vertex.glsl.ts +0 -14
  85. package/src/layers/axes2d/axes2DLayer.stories.tsx +0 -150
  86. package/src/layers/axes2d/axes2DLayer.ts +0 -841
  87. package/src/layers/axes2d/font-atlas.png +0 -0
  88. package/src/layers/axes2d/label-fragment.glsl.js +0 -37
  89. package/src/layers/axes2d/label-vertex.glsl.js +0 -20
  90. package/src/layers/axes2d/line-fragment.glsl.js +0 -14
  91. package/src/layers/axes2d/line-vertex.glsl.js +0 -13
  92. package/src/layers/colormap/colormap.fs.glsl.ts +0 -42
  93. package/src/layers/colormap/colormapLayer.ts +0 -247
  94. package/src/layers/drawing/drawingLayer.tsx +0 -256
  95. package/src/layers/fault_polygons/faultPolygonsLayer.ts +0 -54
  96. package/src/layers/grid3d/fragment.fs.glsl.ts +0 -109
  97. package/src/layers/grid3d/fragment_lines.glsl.ts +0 -21
  98. package/src/layers/grid3d/grid3dLayer.stories.tsx +0 -172
  99. package/src/layers/grid3d/grid3dLayer.ts +0 -248
  100. package/src/layers/grid3d/privateLayer.ts +0 -292
  101. package/src/layers/grid3d/vertex.glsl.ts +0 -43
  102. package/src/layers/grid3d/vertex_lines.glsl.ts +0 -15
  103. package/src/layers/grid3d/webworker.ts +0 -173
  104. package/src/layers/hillshading2d/hillshading2d.fs.glsl.ts +0 -62
  105. package/src/layers/hillshading2d/hillshading2dLayer.ts +0 -172
  106. package/src/layers/index.ts +0 -35
  107. package/src/layers/intersection/intersectionView.stories.tsx +0 -294
  108. package/src/layers/intersection/unfoldedGeoJsonLayer.ts +0 -92
  109. package/src/layers/map/fragment.fs.glsl.ts +0 -127
  110. package/src/layers/map/fragment_lines.glsl.ts +0 -21
  111. package/src/layers/map/mapLayer.stories.tsx +0 -1369
  112. package/src/layers/map/mapLayer.ts +0 -470
  113. package/src/layers/map/privateMapLayer.ts +0 -317
  114. package/src/layers/map/vertex.glsl.ts +0 -45
  115. package/src/layers/map/vertex_lines.glsl.ts +0 -15
  116. package/src/layers/map/webworker.ts +0 -479
  117. package/src/layers/northarrow/northArrow.stories.tsx +0 -108
  118. package/src/layers/northarrow/northArrow3DLayer.ts +0 -204
  119. package/src/layers/northarrow/northarrow-fragment.glsl.js +0 -14
  120. package/src/layers/northarrow/northarrow-vertex.glsl.js +0 -13
  121. package/src/layers/piechart/fragment.glsl.js +0 -42
  122. package/src/layers/piechart/pieChartLayer.ts +0 -246
  123. package/src/layers/piechart/vertex.glsl.js +0 -42
  124. package/src/layers/points/pointsLayer.stories.tsx +0 -141
  125. package/src/layers/points/pointsLayer.ts +0 -143
  126. package/src/layers/polylines/polylinesLayer.stories.tsx +0 -144
  127. package/src/layers/polylines/polylinesLayer.ts +0 -263
  128. package/src/layers/selectable_geojson/selectableGeoJsonLayer.ts +0 -25
  129. package/src/layers/shader_modules/decoder.fs.glsl.ts +0 -41
  130. package/src/layers/shader_modules/decoder.ts +0 -46
  131. package/src/layers/shader_modules/index.ts +0 -1
  132. package/src/layers/terrain/map3DLayer.stories.tsx +0 -340
  133. package/src/layers/terrain/map3DLayer.ts +0 -556
  134. package/src/layers/terrain/terrainMapLayer.ts +0 -334
  135. package/src/layers/terrain/terrainmap.fs.glsl.ts +0 -134
  136. package/src/layers/triangle/fragment.fs.glsl.ts +0 -126
  137. package/src/layers/triangle/fragment_lines.glsl.ts +0 -21
  138. package/src/layers/triangle/privateTriangleLayer.ts +0 -203
  139. package/src/layers/triangle/test_data/surfacePoints.ts +0 -4344
  140. package/src/layers/triangle/test_data/surfaceTriangles.ts +0 -7392
  141. package/src/layers/triangle/triangleLayer.stories.tsx +0 -191
  142. package/src/layers/triangle/triangleLayer.ts +0 -273
  143. package/src/layers/triangle/vertex.glsl.ts +0 -35
  144. package/src/layers/triangle/vertex_lines.glsl.ts +0 -15
  145. package/src/layers/triangle/webworker.ts +0 -165
  146. package/src/layers/utils/glsl.d.ts +0 -4
  147. package/src/layers/utils/layerTools.ts +0 -182
  148. package/src/layers/utils/propertyMapTools.ts +0 -43
  149. package/src/layers/wells/utils/spline.ts +0 -318
  150. package/src/layers/wells/wellsLayer.stories.tsx +0 -625
  151. package/src/layers/wells/wellsLayer.ts +0 -1377
  152. package/src/redux/actions.ts +0 -8
  153. package/src/redux/reducer.ts +0 -43
  154. package/src/redux/store.ts +0 -15
  155. package/src/redux/types.ts +0 -114
  156. package/src/storybook/SubsurfaceViewer.stories.jsx +0 -644
  157. package/src/storybook/components/InfoCard.stories.jsx +0 -39
  158. package/src/storybook/components/colorLegends/ContinuousLegend.stories.jsx +0 -32
  159. package/src/storybook/components/colorLegends/DiscreteLegend.stories.jsx +0 -33
  160. package/src/storybook/components/colorLegends/IndividualScaleForMap.stories.jsx +0 -99
  161. package/src/storybook/components/colorLegends/SingleScaleForMap.stories.jsx +0 -120
  162. package/src/storybook/components/settings/LayerSettingsButton.stories.jsx +0 -34
  163. package/src/storybook/components/settings/NumericInput.stories.jsx +0 -17
  164. package/src/storybook/components/settings/ToggleButton.stories.jsx +0 -16
  165. package/src/storybook/schemaValidation/sampleData.js +0 -177
  166. package/src/storybook/schemaValidation/schemaValidation.stories.jsx +0 -91
  167. package/src/test/TestWrapper.tsx +0 -13
  168. package/src/utils/configuration.ts +0 -61
  169. package/src/utils/fit-bounds.js +0 -85
  170. package/src/utils/measurement.ts +0 -61
  171. package/src/utils/northArrow.ts +0 -4
  172. package/src/utils/specExtractor.ts +0 -36
  173. package/src/viewports/index.js +0 -1
  174. package/src/viewports/intersectionViewport.ts +0 -137
  175. package/src/views/index.js +0 -1
  176. package/src/views/intersectionView.ts +0 -38
  177. package/tsconfig.json +0 -7
@@ -1,1435 +0,0 @@
1
- import { JSONConfiguration, JSONConverter } from "@deck.gl/json/typed";
2
- import DeckGL, { DeckGLRef } from "@deck.gl/react/typed";
3
- import {
4
- Color,
5
- Deck,
6
- Layer,
7
- LayersList,
8
- LayerProps,
9
- LayerContext,
10
- View,
11
- Viewport,
12
- PickingInfo,
13
- OrthographicView,
14
- OrbitView,
15
- } from "@deck.gl/core/typed";
16
- import { Feature, FeatureCollection } from "geojson";
17
- import React, { useEffect, useState, useCallback, useRef } from "react";
18
- import JSON_CONVERTER_CONFIG from "../utils/configuration";
19
- import { WellsPickInfo } from "../layers/wells/wellsLayer";
20
- import InfoCard from "./InfoCard";
21
- import DistanceScale from "./DistanceScale";
22
- import StatusIndicator from "./StatusIndicator";
23
- import { colorTablesArray } from "@emerson-eps/color-tables/";
24
- import fitBounds from "../utils/fit-bounds";
25
- import {
26
- validateColorTables,
27
- validateLayers,
28
- } from "../inputSchema/schemaValidationUtil";
29
- import { LayerPickInfo } from "../layers/utils/layerTools";
30
- import { getLayersByType } from "../layers/utils/layerTools";
31
- import { getWellLayerByTypeAndSelectedWells } from "../layers/utils/layerTools";
32
- import { WellsLayer, Axes2DLayer, NorthArrow3DLayer } from "../layers";
33
-
34
- import { isEmpty, isEqual } from "lodash";
35
- import { cloneDeep } from "lodash";
36
-
37
- import { colorTables } from "@emerson-eps/color-tables";
38
- import { getModelMatrixScale } from "../layers/utils/layerTools";
39
- import { OrbitController, OrthographicController } from "@deck.gl/core/typed";
40
- import { MjolnirEvent, MjolnirPointerEvent } from "mjolnir.js";
41
- import IntersectionView from "../views/intersectionView";
42
- import { Unit } from "convert-units";
43
-
44
- type BoundingBox = [number, number, number, number, number, number];
45
- type NumberQuad = [number, number, number, number];
46
-
47
- function addBoundingBoxes(b1: BoundingBox, b2: BoundingBox): BoundingBox {
48
- const boxDefault: BoundingBox = [0, 0, 0, 1, 1, 1];
49
-
50
- if (typeof b1 === "undefined" || typeof b2 === "undefined") {
51
- return boxDefault;
52
- }
53
-
54
- if (isEqual(b1, boxDefault)) {
55
- return b2;
56
- }
57
-
58
- const xmin = Math.min(b1[0], b2[0]);
59
- const ymin = Math.min(b1[1], b2[1]);
60
- const zmin = Math.min(b1[2], b2[2]);
61
-
62
- const xmax = Math.max(b1[3], b2[3]);
63
- const ymax = Math.max(b1[4], b2[4]);
64
- const zmax = Math.max(b1[5], b2[5]);
65
- return [xmin, ymin, zmin, xmax, ymax, zmax];
66
- }
67
-
68
- function boundingBoxCenter(box: BoundingBox): [number, number, number] {
69
- const xmin = box[0];
70
- const ymin = box[1];
71
- const zmin = box[2];
72
-
73
- const xmax = box[3];
74
- const ymax = box[4];
75
- const zmax = box[5];
76
- return [
77
- xmin + 0.5 * (xmax - xmin),
78
- ymin + 0.5 * (ymax - ymin),
79
- zmin + 0.5 * (zmax - zmin),
80
- ];
81
- }
82
-
83
- export type BoundsAccessor = () => [number, number, number, number];
84
-
85
- export type TooltipCallback = (
86
- info: PickingInfo
87
- ) => string | Record<string, unknown> | null;
88
-
89
- export interface ViewportType {
90
- /**
91
- * Viewport id
92
- */
93
- id: string;
94
-
95
- /**
96
- * Viewport name
97
- */
98
- name?: string;
99
-
100
- /**
101
- * If true, displays map in 3D view, default is 2D view (false)
102
- */
103
- show3D?: boolean;
104
-
105
- /**
106
- * Layers to be displayed on viewport
107
- */
108
- layerIds?: string[];
109
-
110
- target?: [number, number];
111
- zoom?: number;
112
- rotationX?: number;
113
- rotationOrbit?: number;
114
- isSync?: boolean;
115
- }
116
-
117
- export interface ViewsType {
118
- /**
119
- * Layout for viewport in specified as [row, column]
120
- */
121
- layout: [number, number];
122
-
123
- /**
124
- * Number of pixels used for the margin in matrix mode.
125
- * Defaults to 0.
126
- */
127
- marginPixels?: number;
128
-
129
- /**
130
- * Show views label
131
- */
132
- showLabel?: boolean;
133
-
134
- /**
135
- * Layers configuration for multiple viewport
136
- */
137
- viewports: ViewportType[];
138
- }
139
-
140
- export interface ViewStateType {
141
- target: number[];
142
- zoom: number;
143
- rotationX: number;
144
- rotationOrbit: number;
145
- }
146
-
147
- interface marginsType {
148
- left: number;
149
- right: number;
150
- top: number;
151
- bottom: number;
152
- }
153
-
154
- export interface DeckGLLayerContext extends LayerContext {
155
- userData: {
156
- setEditedData: (data: Record<string, unknown>) => void;
157
- colorTables: colorTablesArray;
158
- };
159
- }
160
-
161
- export type EventCallback = (event: MapMouseEvent) => void;
162
-
163
- export interface MapProps {
164
- /**
165
- * The ID of this component, used to identify dash components
166
- * in callbacks. The ID needs to be unique across all of the
167
- * components in an app.
168
- */
169
- id: string;
170
-
171
- /**
172
- * Resource dictionary made available in the DeckGL specification as an enum.
173
- * The values can be accessed like this: `"@@#resources.resourceId"`, where
174
- * `resourceId` is the key in the `resources` dict. For more information,
175
- * see the DeckGL documentation on enums in the json spec:
176
- * https://deck.gl/docs/api-reference/json/conversion-reference#enumerations-and-using-the--prefix
177
- */
178
- resources?: Record<string, unknown>;
179
-
180
- /* List of JSON object containing layer specific data.
181
- * Each JSON object will consist of layer type with key as "@@type" and
182
- * layer specific data, if any.
183
- */
184
- layers?: LayersList;
185
-
186
- /**
187
- * Coordinate boundary for the view defined as [left, bottom, right, top].
188
- */
189
- bounds?: [number, number, number, number] | BoundsAccessor;
190
-
191
- /**
192
- * Views configuration for map. If not specified, all the layers will be
193
- * displayed in a single 2D viewport
194
- */
195
- views?: ViewsType;
196
-
197
- /**
198
- * Parameters for the InfoCard component
199
- */
200
- coords?: {
201
- visible?: boolean | null;
202
- multiPicking?: boolean | null;
203
- pickDepth?: number | null;
204
- };
205
-
206
- /**
207
- * Parameters for the Distance Scale component
208
- */
209
- scale?: {
210
- visible?: boolean | null;
211
- incrementValue?: number | null;
212
- widthPerUnit?: number | null;
213
- cssStyle?: Record<string, unknown> | null;
214
- };
215
-
216
- coordinateUnit?: Unit;
217
-
218
- /**
219
- * Parameters to control toolbar
220
- */
221
- toolbar?: {
222
- visible?: boolean | null;
223
- };
224
-
225
- /**
226
- * Prop containing color table data
227
- */
228
- colorTables?: colorTablesArray;
229
-
230
- /**
231
- * Prop containing edited data from layers
232
- */
233
- editedData?: Record<string, unknown>;
234
-
235
- /**
236
- * For reacting to prop changes
237
- */
238
- setEditedData?: (data: Record<string, unknown>) => void;
239
-
240
- /**
241
- * Validate JSON datafile against schema
242
- */
243
- checkDatafileSchema?: boolean;
244
-
245
- /**
246
- * For get mouse events
247
- */
248
- onMouseEvent?: EventCallback;
249
-
250
- getCameraPosition?: (input: ViewStateType) => void;
251
-
252
- /**
253
- * If changed will reset camera to default position.
254
- */
255
- triggerHome?: number;
256
- triggerResetMultipleWells?: number;
257
- selection?: {
258
- well: string | undefined;
259
- selection: [number | undefined, number | undefined] | undefined;
260
- };
261
-
262
- children?: React.ReactNode;
263
-
264
- getTooltip?: TooltipCallback;
265
- cameraPosition?: ViewStateType;
266
- }
267
-
268
- export interface MapMouseEvent {
269
- type: "click" | "hover" | "contextmenu";
270
- infos: PickingInfo[];
271
- // some frequently used values extracted from infos[]:
272
- x?: number;
273
- y?: number;
274
- // Only for one well. Full information is available in infos[]
275
- wellname?: string;
276
- wellcolor?: Color; // well color
277
- md?: number;
278
- tvd?: number;
279
- }
280
-
281
- export function useHoverInfo(): [PickingInfo[], EventCallback] {
282
- const [hoverInfo, setHoverInfo] = React.useState<PickingInfo[]>([]);
283
- const callback = React.useCallback((pickEvent: MapMouseEvent) => {
284
- setHoverInfo(pickEvent.infos);
285
- }, []);
286
- return [hoverInfo, callback];
287
- }
288
-
289
- function defaultTooltip(info: PickingInfo) {
290
- if ((info as WellsPickInfo)?.logName) {
291
- return (info as WellsPickInfo)?.logName;
292
- } else if (info.layer?.id === "drawing-layer") {
293
- return (info as LayerPickInfo).propertyValue?.toFixed(2);
294
- }
295
- const feat = info.object as Feature;
296
- return feat?.properties?.["name"];
297
- }
298
-
299
- function adjustCameraTarget(
300
- viewStates: Record<string, ViewStateType>,
301
- scale: number,
302
- newScale: number
303
- ): Record<string, ViewStateType> {
304
- const vs = cloneDeep(viewStates);
305
- for (const key in vs) {
306
- if (typeof vs[key].target !== "undefined") {
307
- const t = vs[key].target;
308
- const z = newScale * (t[2] / scale);
309
- vs[key].target = [t[0], t[1], z];
310
- }
311
- }
312
- return vs;
313
- }
314
-
315
- const Map: React.FC<MapProps> = ({
316
- id,
317
- layers,
318
- bounds,
319
- views,
320
- coords,
321
- scale,
322
- coordinateUnit,
323
- colorTables,
324
- setEditedData,
325
- checkDatafileSchema,
326
- onMouseEvent,
327
- selection,
328
- children,
329
- getTooltip = defaultTooltip,
330
- cameraPosition,
331
- getCameraPosition,
332
- triggerHome,
333
- triggerResetMultipleWells,
334
- }: MapProps) => {
335
- const isCameraPositionDefined =
336
- typeof cameraPosition !== "undefined" &&
337
- Object.keys(cameraPosition).length !== 0;
338
-
339
- const deckRef = useRef<DeckGLRef>(null);
340
-
341
- const bboxInitial: BoundingBox = [0, 0, 0, 1, 1, 1];
342
-
343
- const boundsInitial = React.useMemo(
344
- () => bounds ?? ([0, 0, 1, 1] as NumberQuad),
345
- [bounds]
346
- );
347
-
348
- // state for views prop of DeckGL component
349
- const [viewsProps, setViewsProps] = useState<ViewportType[]>([]);
350
- const [alteredLayers, setAlteredLayers] = useState<LayersList>([]);
351
-
352
- const [viewPortMargins, setViewPortMargins] = useState<marginsType>({
353
- left: 0,
354
- right: 0,
355
- top: 0,
356
- bottom: 0,
357
- });
358
-
359
- const [didUserChangeCamera, setDidUserChangeCamera] =
360
- useState<boolean>(false);
361
-
362
- const [reportedBoundingBox, setReportedBoundingBox] =
363
- useState<BoundingBox>(bboxInitial);
364
- const [reportedBoundingBoxAcc, setReportedBoundingBoxAcc] =
365
- useState<BoundingBox>(bboxInitial);
366
-
367
- const initialViewState = getViewState(
368
- viewPortMargins,
369
- boundsInitial,
370
- boundingBoxCenter(reportedBoundingBoxAcc),
371
- views,
372
- 0,
373
- deckRef.current?.deck
374
- );
375
-
376
- // Local help function.
377
- const calcDefaultViewStates = useCallback(
378
- (boundingBox: BoundingBox, input?: ViewportType[]) => {
379
- const center = boundingBoxCenter(
380
- boundingBox // note this may include axesLayer
381
- );
382
-
383
- const updatedViewProps = input ? input : viewsProps;
384
-
385
- const isBoundsDefined = typeof bounds !== "undefined";
386
- const viewStateMap = updatedViewProps.map((item, index) => {
387
- const is3D = views?.viewports?.[index]?.show3D ?? false;
388
-
389
- const viewState = isBoundsDefined
390
- ? getViewState(
391
- viewPortMargins,
392
- boundsInitial,
393
- center,
394
- views,
395
- index,
396
- deckRef.current?.deck
397
- )
398
- : getViewState3D(
399
- is3D,
400
- boundingBox,
401
- views?.viewports?.[index].zoom,
402
- deckRef.current?.deck
403
- );
404
-
405
- const minZoom = is3D ? -12 : -12;
406
- const maxZoom = is3D ? +12 : +4;
407
-
408
- return [item.id, { ...viewState, minZoom, maxZoom }];
409
- });
410
-
411
- const tempViewStates = Object.fromEntries(viewStateMap);
412
-
413
- setDidUserChangeCamera(false);
414
- setViewStates(tempViewStates);
415
- },
416
- [bounds, boundsInitial, views, viewPortMargins, viewsProps]
417
- );
418
-
419
- // set initial view state based on supplied bounds and zoom in viewState
420
- const [viewStates, setViewStates] = useState<Record<string, ViewStateType>>(
421
- {
422
- "main-view_2D": cameraPosition ?? ({} as ViewStateType),
423
- }
424
- );
425
- const [firstViewStateId, setFirstViewStatesId] =
426
- useState<string>("main-view_2D");
427
-
428
- useEffect(() => {
429
- let tempViewStates: Record<string, ViewStateType> = {};
430
- if (isCameraPositionDefined) {
431
- tempViewStates = Object.fromEntries(
432
- viewsProps.map((item) => [item.id, cameraPosition])
433
- ) as unknown as Record<string, ViewStateType>;
434
- } else {
435
- const isBoundsDefined = typeof bounds !== "undefined";
436
-
437
- tempViewStates = Object.fromEntries(
438
- viewsProps.map((item, index) => {
439
- let viewState = viewStates[item.id];
440
- if (typeof viewState === "undefined") {
441
- viewState = isBoundsDefined
442
- ? getViewState(
443
- viewPortMargins,
444
- boundsInitial,
445
- boundingBoxCenter(reportedBoundingBoxAcc),
446
- views,
447
- index,
448
- deckRef.current?.deck
449
- )
450
- : getViewState3D(
451
- views?.viewports?.[index]?.show3D ?? false,
452
- reportedBoundingBoxAcc,
453
- views?.viewports?.[index].zoom,
454
- deckRef.current?.deck
455
- );
456
- }
457
-
458
- return [item.id, viewState];
459
- })
460
- );
461
- }
462
- if (viewsProps[0] !== undefined) {
463
- setFirstViewStatesId(viewsProps[0].id);
464
- }
465
- setViewStates(tempViewStates);
466
- // eslint-disable-next-line react-hooks/exhaustive-deps
467
- }, [
468
- boundsInitial,
469
- cameraPosition,
470
- isCameraPositionDefined,
471
- viewPortMargins,
472
- views?.viewports,
473
- viewsProps,
474
- ]);
475
-
476
- // calculate view state on deckgl context load (based on viewport size)
477
- const onLoad = useCallback(() => {
478
- let tempViewStates: Record<string, ViewStateType> = {};
479
- if (isCameraPositionDefined) {
480
- tempViewStates = Object.fromEntries(
481
- viewsProps.map((item) => [item.id, cameraPosition])
482
- ) as unknown as Record<string, ViewStateType>;
483
- } else {
484
- tempViewStates = Object.fromEntries(
485
- viewsProps.map((item, index) => [
486
- item.id,
487
- getViewState(
488
- viewPortMargins,
489
- boundsInitial,
490
- boundingBoxCenter(reportedBoundingBoxAcc),
491
- views,
492
- index,
493
- deckRef.current?.deck
494
- ),
495
- ])
496
- );
497
- if (viewsProps[0] !== undefined) {
498
- setFirstViewStatesId(viewsProps[0].id);
499
- }
500
- setViewStates(tempViewStates);
501
- }
502
- }, [
503
- isCameraPositionDefined,
504
- viewsProps,
505
- cameraPosition,
506
- viewPortMargins,
507
- boundsInitial,
508
- reportedBoundingBoxAcc,
509
- views,
510
- ]);
511
-
512
- useEffect(() => {
513
- if (typeof triggerHome !== "undefined") {
514
- calcDefaultViewStates(reportedBoundingBoxAcc);
515
- }
516
- // eslint-disable-next-line react-hooks/exhaustive-deps
517
- }, [triggerHome]);
518
-
519
- useEffect(() => {
520
- const union_of_reported_bboxes = addBoundingBoxes(
521
- reportedBoundingBoxAcc,
522
- reportedBoundingBox
523
- );
524
- setReportedBoundingBoxAcc(union_of_reported_bboxes);
525
-
526
- // If "bounds" or "cameraPosition" is not defined "viewState" will be
527
- // calculated based on the union of the reported bounding boxes from each layer.
528
- if (!didUserChangeCamera && !isCameraPositionDefined) {
529
- calcDefaultViewStates(union_of_reported_bboxes);
530
- }
531
- // eslint-disable-next-line react-hooks/exhaustive-deps
532
- }, [reportedBoundingBox]);
533
-
534
- // react on bounds prop change
535
- useEffect(() => {
536
- const isBoundsDefined = typeof bounds !== "undefined";
537
-
538
- let tempViewStates: Record<string, ViewStateType> = {};
539
- if (!isCameraPositionDefined) {
540
- tempViewStates = Object.fromEntries(
541
- viewsProps.map((item, index) => [
542
- item.id,
543
- isBoundsDefined
544
- ? getViewState(
545
- viewPortMargins,
546
- boundsInitial,
547
- boundingBoxCenter(reportedBoundingBoxAcc),
548
- views,
549
- index,
550
- deckRef.current?.deck
551
- )
552
- : getViewState3D(
553
- views?.viewports?.[index]?.show3D ?? false,
554
- reportedBoundingBoxAcc,
555
- views?.viewports?.[index].zoom,
556
- deckRef.current?.deck
557
- ),
558
- ])
559
- );
560
- if (viewsProps[0] !== undefined) {
561
- setFirstViewStatesId(viewsProps[0].id);
562
- }
563
- setViewStates(tempViewStates);
564
- }
565
- // eslint-disable-next-line react-hooks/exhaustive-deps
566
- }, [boundsInitial, cameraPosition, views?.viewports, viewsProps]);
567
-
568
- // react on cameraPosition prop change
569
- useEffect(() => {
570
- let tempViewStates: Record<string, ViewStateType> = {};
571
- if (isCameraPositionDefined) {
572
- tempViewStates = Object.fromEntries(
573
- viewsProps.map((item) => [item.id, cameraPosition])
574
- ) as unknown as Record<string, ViewStateType>;
575
- setViewStates(tempViewStates);
576
- if (viewsProps[0] !== undefined) {
577
- setFirstViewStatesId(viewsProps[0].id);
578
- }
579
- }
580
- if (cameraPosition === null) {
581
- tempViewStates = Object.fromEntries(
582
- viewsProps.map((item) => [item.id, initialViewState])
583
- );
584
- setViewStates(tempViewStates);
585
- }
586
- // eslint-disable-next-line react-hooks/exhaustive-deps
587
- }, [cameraPosition, viewsProps]);
588
-
589
- // Used for scaling in z direction using arrow keys.
590
- const [scaleZ, setScaleZ] = useState<number>(1);
591
- const [scaleZUp, setScaleZUp] = useState<number>(1);
592
- const [scaleZDown, setScaleZDown] = useState<number>(1);
593
-
594
- const scaleUpFunction = () => {
595
- setScaleZUp(Math.random());
596
- };
597
-
598
- const scaleDownFunction = () => {
599
- setScaleZDown(Math.random());
600
- };
601
-
602
- useEffect(() => {
603
- const newScaleZ = scaleZ * 1.05;
604
- setScaleZ(newScaleZ);
605
- // Make camera target follow the scaling.
606
- const vs = adjustCameraTarget(viewStates, scaleZ, newScaleZ);
607
- setViewStates(vs);
608
- // eslint-disable-next-line react-hooks/exhaustive-deps
609
- }, [scaleZUp]);
610
-
611
- useEffect(() => {
612
- const newScaleZ = scaleZ * 0.95;
613
- setScaleZ(newScaleZ);
614
- // Make camera target follow the scaling.
615
- const vs = adjustCameraTarget(viewStates, scaleZ, newScaleZ);
616
- setViewStates(vs);
617
- // eslint-disable-next-line react-hooks/exhaustive-deps
618
- }, [scaleZDown]);
619
-
620
- useEffect(() => {
621
- const viewProps = getViews(views) as ViewportType[];
622
-
623
- setViewsProps(viewProps);
624
-
625
- if (!bounds) {
626
- calcDefaultViewStates(reportedBoundingBoxAcc);
627
- }
628
- // eslint-disable-next-line react-hooks/exhaustive-deps
629
- }, [views]);
630
-
631
- useEffect(() => {
632
- if (layers == undefined) return;
633
-
634
- // Margins on the viewport are extracted from a potenial axes2D layer.
635
- const axes2DLayer = layers?.find((e) => {
636
- return e?.constructor === Axes2DLayer;
637
- }) as Axes2DLayer;
638
-
639
- const left =
640
- axes2DLayer && axes2DLayer.props.isLeftRuler
641
- ? axes2DLayer.props.marginH
642
- : 0;
643
- const right =
644
- axes2DLayer && axes2DLayer.props.isRightRuler
645
- ? axes2DLayer.props.marginH
646
- : 0;
647
- const top =
648
- axes2DLayer && axes2DLayer.props.isTopRuler
649
- ? axes2DLayer.props.marginV
650
- : 0;
651
- const bottom =
652
- axes2DLayer && axes2DLayer.props.isBottomRuler
653
- ? axes2DLayer.props.marginV
654
- : 0;
655
-
656
- setViewPortMargins({ left, right, top, bottom });
657
-
658
- const m = getModelMatrixScale(scaleZ);
659
-
660
- const layers_copy = layers.map((item) => {
661
- if (item?.constructor.name === NorthArrow3DLayer.name) return item;
662
-
663
- const layer = item as Layer;
664
-
665
- // Set "modelLayer" matrix to reflect correct z scaling.
666
- const scaledLayer = layer.clone({ modelMatrix: m });
667
-
668
- // Inject "setReportedBoundingBox" function into layer for it to report
669
- // back its respective bounding box.
670
- const boundedLayer = scaledLayer.clone({
671
- setReportedBoundingBox: setReportedBoundingBox,
672
- });
673
-
674
- return boundedLayer ?? scaledLayer;
675
- });
676
-
677
- setAlteredLayers(layers_copy);
678
- }, [scaleZ, layers /*dispatch*/]);
679
-
680
- const [deckGLLayers, setDeckGLLayers] = useState<LayersList>([]);
681
-
682
- useEffect(() => {
683
- setDeckGLLayers(alteredLayers);
684
- }, [alteredLayers]);
685
-
686
- useEffect(() => {
687
- const layers = deckRef.current?.deck?.props.layers;
688
- if (layers) {
689
- const wellslayer = getLayersByType(
690
- layers,
691
- WellsLayer.name
692
- )?.[0] as WellsLayer;
693
-
694
- wellslayer?.setSelection(selection?.well, selection?.selection);
695
- }
696
- }, [selection]);
697
-
698
- // multiple well layers
699
- const [multipleWells, setMultipleWells] = useState<string[]>([]);
700
- const [selectedWell, setSelectedWell] = useState<string>("");
701
- const [shiftHeld, setShiftHeld] = useState(false);
702
-
703
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
704
- function downHandler({ key }: any) {
705
- if (key === "Shift") {
706
- setShiftHeld(true);
707
- }
708
- }
709
-
710
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
711
- function upHandler({ key }: any) {
712
- if (key === "Shift") {
713
- setShiftHeld(false);
714
- }
715
- }
716
-
717
- useEffect(() => {
718
- window.addEventListener("keydown", downHandler);
719
- window.addEventListener("keyup", upHandler);
720
- return () => {
721
- window.removeEventListener("keydown", downHandler);
722
- window.removeEventListener("keyup", upHandler);
723
- };
724
- }, []);
725
-
726
- useEffect(() => {
727
- const layers = deckRef.current?.deck?.props.layers;
728
- if (layers) {
729
- const wellslayer = getWellLayerByTypeAndSelectedWells(
730
- layers,
731
- "WellsLayer",
732
- selectedWell
733
- )?.[0] as WellsLayer;
734
- wellslayer?.setMultiSelection(multipleWells);
735
- }
736
- }, [multipleWells, selectedWell]);
737
-
738
- useEffect(() => {
739
- if (typeof triggerResetMultipleWells !== "undefined") {
740
- setMultipleWells([]);
741
- }
742
- }, [triggerResetMultipleWells]);
743
-
744
- const getPickingInfos = useCallback(
745
- (
746
- pickInfo: PickingInfo,
747
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
748
- event: any
749
- ): PickingInfo[] => {
750
- if (coords?.multiPicking && pickInfo.layer?.context.deck) {
751
- const pickInfos =
752
- pickInfo.layer.context.deck.pickMultipleObjects({
753
- x: event.offsetCenter.x,
754
- y: event.offsetCenter.y,
755
- depth: coords.pickDepth ? coords.pickDepth : undefined,
756
- }) as LayerPickInfo[];
757
- pickInfos.forEach((item) => {
758
- if (item.properties) {
759
- let unit = (
760
- item.sourceLayer?.props
761
- .data as unknown as FeatureCollection & {
762
- unit: string;
763
- }
764
- )?.unit;
765
- if (unit == undefined) unit = " ";
766
- item.properties.forEach((element) => {
767
- if (
768
- element.name.includes("MD") ||
769
- element.name.includes("TVD")
770
- ) {
771
- element.value =
772
- Number(element.value)
773
- .toFixed(2)
774
- .toString() +
775
- " " +
776
- unit;
777
- }
778
- });
779
- }
780
- });
781
- return pickInfos;
782
- }
783
- return [pickInfo];
784
- },
785
- [coords?.multiPicking, coords?.pickDepth]
786
- );
787
-
788
- /**
789
- * call onMouseEvent callback
790
- */
791
- const callOnMouseEvent = useCallback(
792
- (
793
- type: "click" | "hover",
794
- infos: PickingInfo[],
795
- event: MjolnirEvent
796
- ): void => {
797
- if (!onMouseEvent) return;
798
- const ev = handleMouseEvent(type, infos, event);
799
- onMouseEvent(ev);
800
- },
801
- [onMouseEvent]
802
- );
803
-
804
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
805
- const [hoverInfo, setHoverInfo] = useState<any>([]);
806
- const onHover = useCallback(
807
- (pickInfo: PickingInfo, event: MjolnirEvent) => {
808
- const infos = getPickingInfos(pickInfo, event);
809
- setHoverInfo(infos); // for InfoCard pickInfos
810
- callOnMouseEvent?.("hover", infos, event);
811
- },
812
- [callOnMouseEvent, getPickingInfos]
813
- );
814
-
815
- const onClick = useCallback(
816
- (pickInfo: PickingInfo, event: MjolnirEvent) => {
817
- const infos = getPickingInfos(pickInfo, event);
818
- callOnMouseEvent?.("click", infos, event);
819
- },
820
- [callOnMouseEvent, getPickingInfos]
821
- );
822
-
823
- const [isLoaded, setIsLoaded] = useState<boolean>(false);
824
- const onAfterRender = useCallback(() => {
825
- if (deckGLLayers) {
826
- const state = deckGLLayers.every(
827
- (layer) => (layer as Layer).isLoaded
828
- );
829
- setIsLoaded(state);
830
- }
831
- }, [deckGLLayers]);
832
-
833
- // validate layers data
834
- const [errorText, setErrorText] = useState<string>();
835
- useEffect(() => {
836
- const layers = deckRef.current?.deck?.props.layers as Layer[];
837
- // this ensures to validate the schemas only once
838
- if (checkDatafileSchema && layers && isLoaded) {
839
- try {
840
- validateLayers(layers);
841
- colorTables && validateColorTables(colorTables);
842
- } catch (e) {
843
- setErrorText(String(e));
844
- }
845
- } else setErrorText(undefined);
846
- }, [
847
- checkDatafileSchema,
848
- colorTables,
849
- deckRef?.current?.deck?.props.layers,
850
- isLoaded,
851
- ]);
852
-
853
- const layerFilter = useCallback(
854
- (args: { layer: Layer; viewport: Viewport }): boolean => {
855
- // display all the layers if views are not specified correctly
856
- if (!views || !views.viewports || !views.layout) return true;
857
-
858
- const cur_view = views.viewports.find(
859
- ({ id }) => args.viewport.id && id === args.viewport.id
860
- );
861
- if (cur_view?.layerIds && cur_view.layerIds.length > 0) {
862
- const layer_ids = cur_view.layerIds;
863
- return layer_ids.some((layer_id) => {
864
- const t = layer_id === args.layer.id;
865
- return t;
866
- });
867
- } else {
868
- return true;
869
- }
870
- },
871
- [views]
872
- );
873
-
874
- const onViewStateChange = useCallback(
875
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
876
- ({ viewId, viewState }: { viewId: string; viewState: any }) => {
877
- const viewports = views?.viewports || [];
878
- const isSyncIds = viewports
879
- .filter((item) => item.isSync)
880
- .map((item) => item.id);
881
- if (isSyncIds?.includes(viewId)) {
882
- const viewStateTable = views?.viewports
883
- .filter((item) => item.isSync)
884
- .map((item) => [item.id, viewState]);
885
- const tempViewStates = Object.fromEntries(viewStateTable ?? []);
886
- setViewStates((currentViewStates) => ({
887
- ...currentViewStates,
888
- ...tempViewStates,
889
- }));
890
- } else {
891
- setViewStates((currentViewStates) => ({
892
- ...currentViewStates,
893
- [viewId]: viewState,
894
- }));
895
- }
896
- if (getCameraPosition) {
897
- getCameraPosition(viewState);
898
- }
899
- setFirstViewStatesId(viewsProps[0]?.id);
900
- setDidUserChangeCamera(true);
901
- },
902
- [getCameraPosition, views?.viewports, viewsProps]
903
- );
904
-
905
- const deckGLViews = React.useMemo(() => {
906
- return createViews(
907
- views,
908
- scaleUpFunction,
909
- scaleDownFunction,
910
- deckRef.current?.deck
911
- );
912
- // eslint-disable-next-line react-hooks/exhaustive-deps
913
- }, [views, views, deckRef.current?.deck]);
914
-
915
- if (!deckGLViews || isEmpty(deckGLViews) || isEmpty(deckGLLayers))
916
- return null;
917
- return (
918
- <div onContextMenu={(event) => event.preventDefault()}>
919
- <DeckGL
920
- id={id}
921
- viewState={viewStates}
922
- views={deckGLViews}
923
- layerFilter={layerFilter}
924
- layers={deckGLLayers}
925
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
926
- // @ts-expect-error
927
- userData={{
928
- setEditedData: (updated_prop: Record<string, unknown>) => {
929
- setSelectedWell(updated_prop["selectedWell"] as string);
930
- if (
931
- Object.keys(updated_prop).includes("selectedWell")
932
- ) {
933
- if (shiftHeld) {
934
- if (
935
- multipleWells.includes(
936
- updated_prop["selectedWell"] as string
937
- )
938
- ) {
939
- const temp = multipleWells.filter(
940
- (item) =>
941
- item !==
942
- updated_prop["selectedWell"]
943
- );
944
- setMultipleWells(temp);
945
- } else {
946
- const temp = multipleWells.concat(
947
- updated_prop["selectedWell"] as string
948
- );
949
- setMultipleWells(temp);
950
- }
951
- } else {
952
- setMultipleWells([]);
953
- }
954
- }
955
- setEditedData?.(updated_prop);
956
- },
957
- colorTables: colorTables,
958
- }}
959
- getCursor={({ isDragging }): string =>
960
- isDragging ? "grabbing" : "default"
961
- }
962
- getTooltip={getTooltip}
963
- ref={deckRef}
964
- onViewStateChange={onViewStateChange}
965
- onHover={onHover}
966
- onClick={onClick}
967
- onLoad={onLoad}
968
- onAfterRender={onAfterRender}
969
- >
970
- {children}
971
- </DeckGL>
972
- {scale?.visible ? (
973
- <DistanceScale
974
- {...scale}
975
- zoom={
976
- viewStates[firstViewStateId] === undefined
977
- ? -5
978
- : viewStates[firstViewStateId].zoom
979
- }
980
- scaleUnit={coordinateUnit}
981
- style={scale.cssStyle ?? {}}
982
- />
983
- ) : null}
984
- <StatusIndicator layers={deckGLLayers} isLoaded={isLoaded} />
985
- {coords?.visible ? <InfoCard pickInfos={hoverInfo} /> : null}
986
- {errorText && (
987
- <pre
988
- style={{
989
- flex: "0, 0",
990
- color: "rgb(255, 64, 64)",
991
- backgroundColor: "rgb(255, 255, 192)",
992
- }}
993
- >
994
- {errorText}
995
- </pre>
996
- )}
997
- </div>
998
- );
999
- };
1000
-
1001
- Map.defaultProps = {
1002
- coords: {
1003
- visible: true,
1004
- multiPicking: true,
1005
- pickDepth: 10,
1006
- },
1007
- scale: {
1008
- visible: true,
1009
- incrementValue: 100,
1010
- widthPerUnit: 100,
1011
- cssStyle: { top: 10, left: 10 },
1012
- },
1013
- toolbar: {
1014
- visible: false,
1015
- },
1016
- coordinateUnit: "m",
1017
- views: {
1018
- layout: [1, 1],
1019
- showLabel: false,
1020
- viewports: [{ id: "main-view", show3D: false, layerIds: [] }],
1021
- },
1022
- colorTables: colorTables,
1023
- checkDatafileSchema: false,
1024
- };
1025
-
1026
- export default Map;
1027
-
1028
- // ------------- Helper functions ---------- //
1029
-
1030
- // Add the resources as an enum in the Json Configuration and then convert the spec to actual objects.
1031
- // See https://deck.gl/docs/api-reference/json/overview for more details.
1032
- export function jsonToObject(
1033
- data: Record<string, unknown>[] | LayerProps[],
1034
- enums: Record<string, unknown>[] | undefined = undefined
1035
- ): LayersList | View[] {
1036
- if (!data) return [];
1037
-
1038
- const configuration = new JSONConfiguration(JSON_CONVERTER_CONFIG);
1039
- enums?.forEach((enumeration) => {
1040
- if (enumeration) {
1041
- configuration.merge({
1042
- enumerations: {
1043
- ...enumeration,
1044
- },
1045
- });
1046
- }
1047
- });
1048
- const jsonConverter = new JSONConverter({ configuration });
1049
-
1050
- // remove empty data/layer object
1051
- const filtered_data = data.filter(
1052
- (value) => Object.keys(value).length !== 0
1053
- );
1054
- return jsonConverter.convert(filtered_data);
1055
- }
1056
-
1057
- // return viewstate with computed bounds to fit the data in viewport
1058
- function getViewState(
1059
- viewPortMargins: marginsType,
1060
- bounds_accessor: [number, number, number, number] | BoundsAccessor,
1061
- centerOfData: [number, number, number],
1062
- views: ViewsType | undefined,
1063
- viewPortIndex: number,
1064
- deck?: Deck
1065
- ): ViewStateType {
1066
- let bounds = [0, 0, 1, 1];
1067
- if (typeof bounds_accessor == "function") {
1068
- bounds = bounds_accessor();
1069
- } else {
1070
- bounds = bounds_accessor;
1071
- }
1072
-
1073
- let w = bounds[2] - bounds[0]; // right - left
1074
- let h = bounds[3] - bounds[1]; // top - bottom
1075
-
1076
- const z = centerOfData[2];
1077
-
1078
- const fb = fitBounds({ width: w, height: h, bounds });
1079
- let fb_target = [fb.x, fb.y, z];
1080
- let fb_zoom = fb.zoom;
1081
-
1082
- if (deck) {
1083
- // If there are margins/rulers in the viewport (axes2DLayer) we have to account for that.
1084
- // Camera target should be in the middle of viewport minus the rulers.
1085
- const w_bounds = w;
1086
- const h_bounds = h;
1087
-
1088
- const ml = viewPortMargins.left;
1089
- const mr = viewPortMargins.right;
1090
- const mb = viewPortMargins.bottom;
1091
- const mt = viewPortMargins.top;
1092
-
1093
- // Subtract margins.
1094
- const marginH = (ml > 0 ? ml : 0) + (mr > 0 ? mr : 0);
1095
- const marginV = (mb > 0 ? mb : 0) + (mt > 0 ? mt : 0);
1096
-
1097
- w = deck.width - marginH; // width of the viewport minus margin.
1098
- h = deck.height - marginV;
1099
-
1100
- // Special case if matrix views.
1101
- // Use width and heigt for a subview instead of full viewport.
1102
- if (typeof views?.layout !== "undefined") {
1103
- const [nY, nX] = views.layout;
1104
- const isMatrixViews = nX !== 1 || nY !== 1;
1105
- if (isMatrixViews) {
1106
- const mPixels = views?.marginPixels ?? 0;
1107
-
1108
- const w_ = 99.5 / nX; // Using 99.5% of viewport to avoid flickering of deckgl canvas
1109
- const h_ = 99.5 / nY;
1110
-
1111
- const marginHorPercentage =
1112
- 100 * 100 * (mPixels / (w_ * deck.width)); //percentage of sub view
1113
- const marginVerPercentage =
1114
- 100 * 100 * (mPixels / (h_ * deck.height));
1115
-
1116
- const sub_w = (w_ / 100) * deck.width;
1117
- const sub_h = (h_ / 100) * deck.height;
1118
-
1119
- w = sub_w * (1 - 2 * (marginHorPercentage / 100)) - marginH;
1120
- h = sub_h * (1 - 2 * (marginVerPercentage / 100)) - marginV;
1121
- }
1122
- }
1123
-
1124
- const port_aspect = h / w;
1125
- const bounds_aspect = h_bounds / w_bounds;
1126
-
1127
- const m_pr_pixel =
1128
- bounds_aspect > port_aspect ? h_bounds / h : w_bounds / w;
1129
-
1130
- let translate_x = 0;
1131
- if (ml > 0 && mr === 0) {
1132
- // left margin and no right margin
1133
- translate_x = 0.5 * ml * m_pr_pixel;
1134
- } else if (ml === 0 && mr > 0) {
1135
- // no left margin but right margin
1136
- translate_x = -0.5 * mr * m_pr_pixel;
1137
- }
1138
-
1139
- let translate_y = 0;
1140
- if (mb > 0 && mt === 0) {
1141
- translate_y = 0.5 * mb * m_pr_pixel;
1142
- } else if (mb === 0 && mt > 0) {
1143
- translate_y = -0.5 * mt * m_pr_pixel;
1144
- }
1145
-
1146
- const fb = fitBounds({ width: w, height: h, bounds });
1147
- fb_target = [fb.x - translate_x, fb.y - translate_y, z];
1148
- fb_zoom = fb.zoom;
1149
- }
1150
-
1151
- const target = views?.viewports?.[viewPortIndex]?.target;
1152
- const zoom = views?.viewports?.[viewPortIndex]?.zoom;
1153
-
1154
- const target_ = target ?? fb_target;
1155
- const zoom_ = zoom ?? fb_zoom;
1156
-
1157
- const view_state: ViewStateType = {
1158
- target: target_,
1159
- zoom: zoom_,
1160
- rotationX: 90, // look down z -axis
1161
- rotationOrbit: 0,
1162
- };
1163
- return view_state;
1164
- }
1165
-
1166
- ///////////////////////////////////////////////////////////////////////////////////////////
1167
- // return viewstate with computed bounds to fit the data in viewport
1168
- function getViewState3D(
1169
- is3D: boolean,
1170
- bounds: [number, number, number, number, number, number],
1171
- zoom?: number,
1172
- deck?: Deck
1173
- ): ViewStateType {
1174
- const xMin = bounds[0];
1175
- const yMin = bounds[1];
1176
- const zMin = bounds[2];
1177
-
1178
- const xMax = bounds[3];
1179
- const yMax = bounds[4];
1180
- const zMax = bounds[5];
1181
-
1182
- let width = xMax - xMin;
1183
- let height = yMax - yMin;
1184
- if (deck) {
1185
- width = deck.width;
1186
- height = deck.height;
1187
- }
1188
-
1189
- const target = [
1190
- xMin + (xMax - xMin) / 2,
1191
- yMin + (yMax - yMin) / 2,
1192
- is3D ? zMin + (zMax - zMin) / 2 : 0,
1193
- ];
1194
- const bounds2D = [xMin, yMin, xMax, yMax];
1195
- const fitted_bound = fitBounds({
1196
- width,
1197
- height,
1198
- bounds: bounds2D,
1199
- });
1200
- const view_state: ViewStateType = {
1201
- target,
1202
- zoom: zoom ?? fitted_bound.zoom * 1.2,
1203
- rotationX: 45, // look down z -axis at 45 degrees
1204
- rotationOrbit: 0,
1205
- };
1206
- return view_state;
1207
- }
1208
-
1209
- // construct views object for DeckGL component
1210
- function createViews(
1211
- views: ViewsType | undefined,
1212
- scaleUpFunction: { (): void; (): void },
1213
- scaleDownFunction: { (): void; (): void },
1214
- deck?: Deck
1215
- ): View[] {
1216
- // Use modified controller to handle key events.
1217
- class ZScaleOrbitController extends OrbitController {
1218
- handleEvent(event: MjolnirEvent): boolean {
1219
- if (event.type === "keydown" && event.key === "ArrowUp") {
1220
- scaleUpFunction();
1221
- return true;
1222
- } else if (event.type === "keydown" && event.key === "ArrowDown") {
1223
- scaleDownFunction();
1224
- return true;
1225
- }
1226
-
1227
- return super.handleEvent(event);
1228
- }
1229
- }
1230
- const deckgl_views: View[] = [];
1231
-
1232
- const widthViewPort = deck?.width;
1233
- const heightViewPort = deck?.height;
1234
-
1235
- const isDeckDefined =
1236
- typeof widthViewPort !== "undefined" &&
1237
- typeof heightViewPort !== "undefined";
1238
-
1239
- const mPixels = views?.marginPixels ?? 0;
1240
-
1241
- // if props for multiple viewport are not proper, return 2d view
1242
- if (!views || !views.viewports || !views.layout || !isDeckDefined) {
1243
- deckgl_views.push(
1244
- new OrthographicView({
1245
- id: "main",
1246
- controller: { doubleClickZoom: false },
1247
- x: "0%",
1248
- y: "0%",
1249
- width: "100%",
1250
- height: "100%",
1251
- flipY: false,
1252
- far: +99999,
1253
- near: -99999,
1254
- })
1255
- );
1256
- } else {
1257
- let yPos = 0;
1258
- const [nY, nX] = views.layout;
1259
- const w = 99.5 / nX; // Using 99.5% of viewport to avoid flickering of deckgl canvas
1260
- const h = 99.5 / nY;
1261
-
1262
- const singleView = nX === 1 && nY === 1;
1263
-
1264
- const marginHorPercentage = singleView // percentage of sub view
1265
- ? 0
1266
- : 100 * 100 * (mPixels / (w * widthViewPort));
1267
- const marginVerPercentage = singleView
1268
- ? 0
1269
- : 100 * 100 * (mPixels / (h * heightViewPort));
1270
-
1271
- for (let y = 1; y <= nY; y++) {
1272
- let xPos = 0;
1273
- for (let x = 1; x <= nX; x++) {
1274
- if (
1275
- views.viewports == undefined ||
1276
- deckgl_views.length >= views.viewports.length
1277
- ) {
1278
- return deckgl_views;
1279
- }
1280
-
1281
- const currentViewport: ViewportType =
1282
- views.viewports[deckgl_views.length];
1283
-
1284
- const ViewType = currentViewport.show3D
1285
- ? OrbitView
1286
- : currentViewport.id === "intersection_view"
1287
- ? IntersectionView
1288
- : OrthographicView;
1289
-
1290
- const far = 9999;
1291
- const near = currentViewport.show3D ? 0.1 : -9999;
1292
-
1293
- const Controller = currentViewport.show3D
1294
- ? ZScaleOrbitController
1295
- : OrthographicController;
1296
-
1297
- const controller = {
1298
- type: Controller,
1299
- doubleClickZoom: false,
1300
- };
1301
-
1302
- deckgl_views.push(
1303
- new ViewType({
1304
- id: currentViewport.id,
1305
- controller: controller,
1306
-
1307
- x: xPos + marginHorPercentage / nX + "%",
1308
- y: yPos + marginVerPercentage / nY + "%",
1309
-
1310
- width: w * (1 - 2 * (marginHorPercentage / 100)) + "%",
1311
- height: h * (1 - 2 * (marginVerPercentage / 100)) + "%",
1312
-
1313
- flipY: false,
1314
- far,
1315
- near,
1316
- })
1317
- );
1318
- xPos = xPos + w;
1319
- }
1320
- yPos = yPos + h;
1321
- }
1322
- }
1323
- return deckgl_views;
1324
- }
1325
-
1326
- // construct views object for DeckGL component
1327
- function getViews(views: ViewsType | undefined): ViewportType[] {
1328
- const deckgl_views = [];
1329
-
1330
- // if props for multiple viewport are not proper, return 2d view
1331
- if (!views || !views.viewports || !views.layout) {
1332
- deckgl_views.push({
1333
- id: "main",
1334
- });
1335
- } else {
1336
- const [nY, nX] = views.layout;
1337
- for (let y = 1; y <= nY; y++) {
1338
- for (let x = 1; x <= nX; x++) {
1339
- if (
1340
- views.viewports == undefined ||
1341
- deckgl_views.length >= views.viewports.length
1342
- )
1343
- return deckgl_views;
1344
-
1345
- const cur_viewport: ViewportType =
1346
- views.viewports[deckgl_views.length];
1347
-
1348
- deckgl_views.push({
1349
- id: cur_viewport.id,
1350
- });
1351
- }
1352
- }
1353
- }
1354
- return deckgl_views;
1355
- }
1356
-
1357
- function handleMouseEvent(
1358
- type: "click" | "hover",
1359
- infos: PickingInfo[],
1360
- event: MjolnirEvent
1361
- ) {
1362
- const ev: MapMouseEvent = {
1363
- type: type,
1364
- infos: infos,
1365
- };
1366
- if (ev.type === "click") {
1367
- if ((event as MjolnirPointerEvent).rightButton) ev.type = "contextmenu";
1368
- }
1369
- for (const info of infos as LayerPickInfo[]) {
1370
- if (info.coordinate) {
1371
- ev.x = info.coordinate[0];
1372
- ev.y = info.coordinate[1];
1373
- }
1374
- if (info.layer && info.layer.id === "wells-layer") {
1375
- // info.object is Feature or WellLog;
1376
- {
1377
- // try to use Object info (see DeckGL getToolTip callback)
1378
- const feat = info.object as Feature;
1379
- const properties = feat?.properties;
1380
- if (properties) {
1381
- ev.wellname = properties["name"];
1382
- ev.wellcolor = properties["color"];
1383
- }
1384
- }
1385
-
1386
- if (!ev.wellname)
1387
- if (info.object) {
1388
- ev.wellname = info.object.header?.["well"]; // object is WellLog
1389
- }
1390
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1391
- if (info.properties) {
1392
- for (const property of info.properties) {
1393
- if (!ev.wellcolor) ev.wellcolor = property.color;
1394
- let propname = property.name;
1395
- if (propname) {
1396
- const sep = propname.indexOf(" ");
1397
- if (sep >= 0) {
1398
- if (!ev.wellname) {
1399
- ev.wellname = propname.substring(sep + 1);
1400
- }
1401
- propname = propname.substring(0, sep);
1402
- }
1403
- }
1404
- const names_md = [
1405
- "DEPTH",
1406
- "DEPT",
1407
- "MD" /*Measured Depth*/,
1408
- "TDEP" /*"Tool DEPth"*/,
1409
- "MD_RKB" /*Rotary Relly Bushing*/,
1410
- ]; // aliases for MD
1411
- const names_tvd = [
1412
- "TVD" /*True Vertical Depth*/,
1413
- "TVDSS" /*SubSea*/,
1414
- "DVER" /*"VERtical Depth"*/,
1415
- "TVD_MSL" /*below Mean Sea Level*/,
1416
- ]; // aliases for MD
1417
-
1418
- if (names_md.find((name) => name == propname))
1419
- ev.md = parseFloat(property.value as string);
1420
- else if (names_tvd.find((name) => name == propname))
1421
- ev.tvd = parseFloat(property.value as string);
1422
-
1423
- if (
1424
- ev.md !== undefined &&
1425
- ev.tvd !== undefined &&
1426
- ev.wellname !== undefined
1427
- )
1428
- break;
1429
- }
1430
- }
1431
- break;
1432
- }
1433
- }
1434
- return ev;
1435
- }