@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.
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/package.json +5 -2
- package/package.json +6 -3
- package/dist/DashSubsurfaceViewer.d.ts +0 -56
- package/dist/DashSubsurfaceViewer.js +0 -160
- package/dist/DashSubsurfaceViewer.js.map +0 -1
- package/src/DashSubsurfaceViewer.tsx +0 -270
- package/src/SubsurfaceViewer.stories.tsx +0 -449
- package/src/SubsurfaceViewer.test.tsx +0 -98
- package/src/SubsurfaceViewer.tsx +0 -356
- package/src/__snapshots__/SubsurfaceViewer.test.tsx.snap +0 -178
- package/src/assets/glTF/north_arrow/scene.bin +0 -0
- package/src/assets/glTF/north_arrow/scene.gltf +0 -315
- package/src/assets/glTF/north_arrow/textures/Arrow5_baseColor.png +0 -0
- package/src/assets/glTF/north_arrow/textures/Arrow5_metallicRoughness.png +0 -0
- package/src/assets/glTF/north_arrow/textures/Arrow5_normal.png +0 -0
- package/src/components/ColorLegend.test.tsx +0 -32
- package/src/components/ColorLegend.tsx +0 -80
- package/src/components/ColorLegends.test.tsx +0 -97
- package/src/components/ColorLegends.tsx +0 -46
- package/src/components/DistanceScale.stories.tsx +0 -28
- package/src/components/DistanceScale.test.tsx +0 -36
- package/src/components/DistanceScale.tsx +0 -84
- package/src/components/InfoCard.test.tsx +0 -110
- package/src/components/InfoCard.tsx +0 -263
- package/src/components/Map.test.tsx +0 -142
- package/src/components/Map.tsx +0 -1435
- package/src/components/StatusIndicator.test.tsx +0 -14
- package/src/components/StatusIndicator.tsx +0 -38
- package/src/components/ViewAnnotation.tsx +0 -16
- package/src/components/ViewFooter.test.tsx +0 -12
- package/src/components/ViewFooter.tsx +0 -30
- package/src/components/__snapshots__/ColorLegends.test.tsx.snap +0 -15
- package/src/components/__snapshots__/DistanceScale.test.tsx.snap +0 -33
- package/src/components/__snapshots__/InfoCard.test.tsx.snap +0 -561
- package/src/components/__snapshots__/Map.test.tsx.snap +0 -119
- package/src/components/__snapshots__/StatusIndicator.test.tsx.snap +0 -3
- package/src/components/__snapshots__/ViewFooter.test.tsx.snap +0 -7
- package/src/components/settings/DrawModeSelector.test.tsx +0 -45
- package/src/components/settings/DrawModeSelector.tsx +0 -58
- package/src/components/settings/DrawModeSelector_performance.test.tsx +0 -35
- package/src/components/settings/LayerProperty.test.tsx +0 -35
- package/src/components/settings/LayerProperty.tsx +0 -153
- package/src/components/settings/LayerProperty_performance.test.tsx +0 -39
- package/src/components/settings/LayerSettingsButton.test.tsx +0 -133
- package/src/components/settings/LayerSettingsButton.tsx +0 -95
- package/src/components/settings/LayersButton.test.tsx +0 -102
- package/src/components/settings/LayersButton.tsx +0 -97
- package/src/components/settings/NumericInput.test.tsx +0 -25
- package/src/components/settings/NumericInput.tsx +0 -67
- package/src/components/settings/Settings.tsx +0 -71
- package/src/components/settings/SliderInput.test.tsx +0 -28
- package/src/components/settings/SliderInput.tsx +0 -71
- package/src/components/settings/ToggleButton.test.tsx +0 -25
- package/src/components/settings/ToggleButton.tsx +0 -53
- package/src/components/settings/__snapshots__/DrawModeSelector.test.tsx.snap +0 -124
- package/src/components/settings/__snapshots__/LayerProperty.test.tsx.snap +0 -124
- package/src/components/settings/__snapshots__/LayerSettingsButton.test.tsx.snap +0 -36
- package/src/components/settings/__snapshots__/LayersButton.test.tsx.snap +0 -83
- package/src/components/settings/__snapshots__/NumericInput.test.tsx.snap +0 -123
- package/src/components/settings/__snapshots__/SliderInput.test.tsx.snap +0 -244
- package/src/components/settings/__snapshots__/ToggleButton.test.tsx.snap +0 -182
- package/src/custom.d.ts +0 -9
- package/src/index.ts +0 -5
- package/src/inputSchema/ColorTables.json +0 -51
- package/src/inputSchema/FaultPolygons.json +0 -80
- package/src/inputSchema/Grid.json +0 -39
- package/src/inputSchema/PieChart.json +0 -72
- package/src/inputSchema/WellLog.json +0 -126
- package/src/inputSchema/WellLogTemplate.json +0 -136
- package/src/inputSchema/WellLogs.json +0 -5
- package/src/inputSchema/Wells.json +0 -106
- package/src/inputSchema/schemaValidationUtil.tsx +0 -55
- package/src/inputSchema/validator.tsx +0 -72
- package/src/inputSchema/wellCompletions.json +0 -108
- package/src/layers/BoxSelectionLayer/boxSelectionLayer.stories.tsx +0 -172
- package/src/layers/BoxSelectionLayer/boxSelectionLayer.tsx +0 -136
- package/src/layers/axes/axes-fragment.glsl.ts +0 -15
- package/src/layers/axes/axesLayer.stories.tsx +0 -87
- package/src/layers/axes/axesLayer.ts +0 -692
- package/src/layers/axes/boxLayer.ts +0 -71
- package/src/layers/axes/grid-vertex.glsl.ts +0 -14
- package/src/layers/axes2d/axes2DLayer.stories.tsx +0 -150
- package/src/layers/axes2d/axes2DLayer.ts +0 -841
- package/src/layers/axes2d/font-atlas.png +0 -0
- package/src/layers/axes2d/label-fragment.glsl.js +0 -37
- package/src/layers/axes2d/label-vertex.glsl.js +0 -20
- package/src/layers/axes2d/line-fragment.glsl.js +0 -14
- package/src/layers/axes2d/line-vertex.glsl.js +0 -13
- package/src/layers/colormap/colormap.fs.glsl.ts +0 -42
- package/src/layers/colormap/colormapLayer.ts +0 -247
- package/src/layers/drawing/drawingLayer.tsx +0 -256
- package/src/layers/fault_polygons/faultPolygonsLayer.ts +0 -54
- package/src/layers/grid3d/fragment.fs.glsl.ts +0 -109
- package/src/layers/grid3d/fragment_lines.glsl.ts +0 -21
- package/src/layers/grid3d/grid3dLayer.stories.tsx +0 -172
- package/src/layers/grid3d/grid3dLayer.ts +0 -248
- package/src/layers/grid3d/privateLayer.ts +0 -292
- package/src/layers/grid3d/vertex.glsl.ts +0 -43
- package/src/layers/grid3d/vertex_lines.glsl.ts +0 -15
- package/src/layers/grid3d/webworker.ts +0 -173
- package/src/layers/hillshading2d/hillshading2d.fs.glsl.ts +0 -62
- package/src/layers/hillshading2d/hillshading2dLayer.ts +0 -172
- package/src/layers/index.ts +0 -35
- package/src/layers/intersection/intersectionView.stories.tsx +0 -294
- package/src/layers/intersection/unfoldedGeoJsonLayer.ts +0 -92
- package/src/layers/map/fragment.fs.glsl.ts +0 -127
- package/src/layers/map/fragment_lines.glsl.ts +0 -21
- package/src/layers/map/mapLayer.stories.tsx +0 -1369
- package/src/layers/map/mapLayer.ts +0 -470
- package/src/layers/map/privateMapLayer.ts +0 -317
- package/src/layers/map/vertex.glsl.ts +0 -45
- package/src/layers/map/vertex_lines.glsl.ts +0 -15
- package/src/layers/map/webworker.ts +0 -479
- package/src/layers/northarrow/northArrow.stories.tsx +0 -108
- package/src/layers/northarrow/northArrow3DLayer.ts +0 -204
- package/src/layers/northarrow/northarrow-fragment.glsl.js +0 -14
- package/src/layers/northarrow/northarrow-vertex.glsl.js +0 -13
- package/src/layers/piechart/fragment.glsl.js +0 -42
- package/src/layers/piechart/pieChartLayer.ts +0 -246
- package/src/layers/piechart/vertex.glsl.js +0 -42
- package/src/layers/points/pointsLayer.stories.tsx +0 -141
- package/src/layers/points/pointsLayer.ts +0 -143
- package/src/layers/polylines/polylinesLayer.stories.tsx +0 -144
- package/src/layers/polylines/polylinesLayer.ts +0 -263
- package/src/layers/selectable_geojson/selectableGeoJsonLayer.ts +0 -25
- package/src/layers/shader_modules/decoder.fs.glsl.ts +0 -41
- package/src/layers/shader_modules/decoder.ts +0 -46
- package/src/layers/shader_modules/index.ts +0 -1
- package/src/layers/terrain/map3DLayer.stories.tsx +0 -340
- package/src/layers/terrain/map3DLayer.ts +0 -556
- package/src/layers/terrain/terrainMapLayer.ts +0 -334
- package/src/layers/terrain/terrainmap.fs.glsl.ts +0 -134
- package/src/layers/triangle/fragment.fs.glsl.ts +0 -126
- package/src/layers/triangle/fragment_lines.glsl.ts +0 -21
- package/src/layers/triangle/privateTriangleLayer.ts +0 -203
- package/src/layers/triangle/test_data/surfacePoints.ts +0 -4344
- package/src/layers/triangle/test_data/surfaceTriangles.ts +0 -7392
- package/src/layers/triangle/triangleLayer.stories.tsx +0 -191
- package/src/layers/triangle/triangleLayer.ts +0 -273
- package/src/layers/triangle/vertex.glsl.ts +0 -35
- package/src/layers/triangle/vertex_lines.glsl.ts +0 -15
- package/src/layers/triangle/webworker.ts +0 -165
- package/src/layers/utils/glsl.d.ts +0 -4
- package/src/layers/utils/layerTools.ts +0 -182
- package/src/layers/utils/propertyMapTools.ts +0 -43
- package/src/layers/wells/utils/spline.ts +0 -318
- package/src/layers/wells/wellsLayer.stories.tsx +0 -625
- package/src/layers/wells/wellsLayer.ts +0 -1377
- package/src/redux/actions.ts +0 -8
- package/src/redux/reducer.ts +0 -43
- package/src/redux/store.ts +0 -15
- package/src/redux/types.ts +0 -114
- package/src/storybook/SubsurfaceViewer.stories.jsx +0 -644
- package/src/storybook/components/InfoCard.stories.jsx +0 -39
- package/src/storybook/components/colorLegends/ContinuousLegend.stories.jsx +0 -32
- package/src/storybook/components/colorLegends/DiscreteLegend.stories.jsx +0 -33
- package/src/storybook/components/colorLegends/IndividualScaleForMap.stories.jsx +0 -99
- package/src/storybook/components/colorLegends/SingleScaleForMap.stories.jsx +0 -120
- package/src/storybook/components/settings/LayerSettingsButton.stories.jsx +0 -34
- package/src/storybook/components/settings/NumericInput.stories.jsx +0 -17
- package/src/storybook/components/settings/ToggleButton.stories.jsx +0 -16
- package/src/storybook/schemaValidation/sampleData.js +0 -177
- package/src/storybook/schemaValidation/schemaValidation.stories.jsx +0 -91
- package/src/test/TestWrapper.tsx +0 -13
- package/src/utils/configuration.ts +0 -61
- package/src/utils/fit-bounds.js +0 -85
- package/src/utils/measurement.ts +0 -61
- package/src/utils/northArrow.ts +0 -4
- package/src/utils/specExtractor.ts +0 -36
- package/src/viewports/index.js +0 -1
- package/src/viewports/intersectionViewport.ts +0 -137
- package/src/views/index.js +0 -1
- package/src/views/intersectionView.ts +0 -38
- package/tsconfig.json +0 -7
|
@@ -1,1377 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Layer,
|
|
3
|
-
LayersList,
|
|
4
|
-
LayerData,
|
|
5
|
-
CompositeLayer,
|
|
6
|
-
UpdateParameters,
|
|
7
|
-
PickingInfo,
|
|
8
|
-
OrbitViewport,
|
|
9
|
-
} from "@deck.gl/core/typed";
|
|
10
|
-
import { ExtendedLayerProps, isDrawingEnabled } from "../utils/layerTools";
|
|
11
|
-
import { PathLayer, TextLayer } from "@deck.gl/layers/typed";
|
|
12
|
-
import { Color, Position } from "@deck.gl/core/typed";
|
|
13
|
-
import { PathStyleExtension } from "@deck.gl/extensions/typed";
|
|
14
|
-
import { subtract, distance, dot } from "mathjs";
|
|
15
|
-
import {
|
|
16
|
-
rgbValues,
|
|
17
|
-
colorTablesArray,
|
|
18
|
-
getColors,
|
|
19
|
-
} from "@emerson-eps/color-tables/";
|
|
20
|
-
import {
|
|
21
|
-
Feature,
|
|
22
|
-
GeometryCollection,
|
|
23
|
-
LineString,
|
|
24
|
-
Point,
|
|
25
|
-
FeatureCollection,
|
|
26
|
-
GeoJsonProperties,
|
|
27
|
-
Geometry,
|
|
28
|
-
} from "geojson";
|
|
29
|
-
import {
|
|
30
|
-
LayerPickInfo,
|
|
31
|
-
PropertyDataType,
|
|
32
|
-
createPropertyData,
|
|
33
|
-
} from "../utils/layerTools";
|
|
34
|
-
import { splineRefine, invertPath, GetBoundingBox } from "./utils/spline";
|
|
35
|
-
import { interpolateNumberArray } from "d3";
|
|
36
|
-
import { DeckGLLayerContext } from "../../components/Map";
|
|
37
|
-
import {
|
|
38
|
-
ContinuousLegendDataType,
|
|
39
|
-
DiscreteLegendDataType,
|
|
40
|
-
} from "../../components/ColorLegend";
|
|
41
|
-
import { getLayersById } from "../../layers/utils/layerTools";
|
|
42
|
-
import UnfoldedGeoJsonLayer from "../intersection/unfoldedGeoJsonLayer";
|
|
43
|
-
import GL from "@luma.gl/constants";
|
|
44
|
-
|
|
45
|
-
type StyleAccessorFunction = (
|
|
46
|
-
object: Feature,
|
|
47
|
-
objectInfo?: Record<string, unknown>
|
|
48
|
-
) => StyleData;
|
|
49
|
-
|
|
50
|
-
type NumberPair = [number, number];
|
|
51
|
-
type DashAccessor = boolean | NumberPair | StyleAccessorFunction | undefined;
|
|
52
|
-
type ColorAccessor = Color | StyleAccessorFunction | undefined;
|
|
53
|
-
type SizeAccessor = number | StyleAccessorFunction | undefined;
|
|
54
|
-
type StyleData = NumberPair | Color | number;
|
|
55
|
-
|
|
56
|
-
type LineStyleAccessor = {
|
|
57
|
-
color?: ColorAccessor;
|
|
58
|
-
dash?: DashAccessor;
|
|
59
|
-
width?: SizeAccessor;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
type WellHeadStyleAccessor = {
|
|
63
|
-
color?: ColorAccessor;
|
|
64
|
-
size?: SizeAccessor;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
function onDataLoad(
|
|
68
|
-
data: LayerData<FeatureCollection>,
|
|
69
|
-
context: {
|
|
70
|
-
propName: string;
|
|
71
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
72
|
-
layer: Layer<any>;
|
|
73
|
-
}
|
|
74
|
-
): void {
|
|
75
|
-
const bbox = GetBoundingBox(data as unknown as FeatureCollection);
|
|
76
|
-
if (typeof context.layer.props.setReportedBoundingBox !== "undefined") {
|
|
77
|
-
context.layer.props.setReportedBoundingBox(bbox);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface WellsLayerProps<D> extends ExtendedLayerProps<D> {
|
|
82
|
-
pointRadiusScale: number;
|
|
83
|
-
lineWidthScale: number;
|
|
84
|
-
outline: boolean;
|
|
85
|
-
selectedWell: string;
|
|
86
|
-
logData: string | LogCurveDataType[];
|
|
87
|
-
logName: string;
|
|
88
|
-
logColor: string;
|
|
89
|
-
logrunName: string;
|
|
90
|
-
logRadius: number;
|
|
91
|
-
logCurves: boolean;
|
|
92
|
-
refine: boolean;
|
|
93
|
-
wellHeadStyle: WellHeadStyleAccessor;
|
|
94
|
-
colorMappingFunction: (x: number) => [number, number, number];
|
|
95
|
-
lineStyle: LineStyleAccessor;
|
|
96
|
-
wellNameVisible: boolean;
|
|
97
|
-
wellNameAtTop: boolean;
|
|
98
|
-
wellNameSize: number;
|
|
99
|
-
wellNameColor: Color;
|
|
100
|
-
isLog: boolean;
|
|
101
|
-
depthTest: boolean;
|
|
102
|
-
/** If true means that input z values are interpreted as depths.
|
|
103
|
-
* For example depth of z = 1000 corresponds to -1000 on the z axis. Default true.
|
|
104
|
-
*/
|
|
105
|
-
ZIncreasingDownwards: boolean;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const defaultProps = {
|
|
109
|
-
"@@type": "WellsLayer",
|
|
110
|
-
name: "Wells",
|
|
111
|
-
id: "wells-layer",
|
|
112
|
-
autoHighlight: true,
|
|
113
|
-
opacity: 1,
|
|
114
|
-
lineWidthScale: 1,
|
|
115
|
-
pointRadiusScale: 1,
|
|
116
|
-
lineStyle: { dash: false },
|
|
117
|
-
outline: true,
|
|
118
|
-
logRadius: 10,
|
|
119
|
-
logCurves: true,
|
|
120
|
-
refine: false,
|
|
121
|
-
visible: true,
|
|
122
|
-
wellNameVisible: false,
|
|
123
|
-
wellNameAtTop: false,
|
|
124
|
-
wellNameSize: 14,
|
|
125
|
-
wellNameColor: [0, 0, 0, 255],
|
|
126
|
-
selectedWell: "@@#editedData.selectedWells", // used to get data from deckgl layer
|
|
127
|
-
depthTest: true,
|
|
128
|
-
ZIncreasingDownwards: true,
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
export interface LogCurveDataType {
|
|
132
|
-
header: {
|
|
133
|
-
name: string;
|
|
134
|
-
well: string;
|
|
135
|
-
};
|
|
136
|
-
curves: {
|
|
137
|
-
name: string;
|
|
138
|
-
description: string;
|
|
139
|
-
}[];
|
|
140
|
-
data: number[][];
|
|
141
|
-
metadata_discrete: Record<
|
|
142
|
-
string,
|
|
143
|
-
{
|
|
144
|
-
attributes: unknown;
|
|
145
|
-
objects: Record<string, [Color, number]>;
|
|
146
|
-
}
|
|
147
|
-
>;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export interface WellsPickInfo extends LayerPickInfo {
|
|
151
|
-
featureType?: string;
|
|
152
|
-
logName: string;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function multiply(pair: [number, number], factor: number): [number, number] {
|
|
156
|
-
return [pair[0] * factor, pair[1] * factor];
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const LINE = "line";
|
|
160
|
-
const POINT = "point";
|
|
161
|
-
const DEFAULT_POINT_SIZE = 8;
|
|
162
|
-
const DEFAULT_LINE_WIDTH = 5;
|
|
163
|
-
const DEFAULT_DASH = [5, 5] as NumberPair;
|
|
164
|
-
|
|
165
|
-
function getDashFactor(
|
|
166
|
-
accessor: DashAccessor,
|
|
167
|
-
width_accessor?: number | ((object: Feature) => number),
|
|
168
|
-
offset = 0
|
|
169
|
-
) {
|
|
170
|
-
return (
|
|
171
|
-
object: Feature,
|
|
172
|
-
objectInfo: Record<string, unknown>
|
|
173
|
-
): NumberPair => {
|
|
174
|
-
let width = DEFAULT_LINE_WIDTH;
|
|
175
|
-
if (typeof width_accessor == "function") {
|
|
176
|
-
width = (width_accessor as StyleAccessorFunction)(object) as number;
|
|
177
|
-
} else if (width_accessor as number) {
|
|
178
|
-
width = width_accessor as number;
|
|
179
|
-
}
|
|
180
|
-
const factor = width / (width + offset);
|
|
181
|
-
|
|
182
|
-
let dash: NumberPair = [0, 0];
|
|
183
|
-
if (typeof accessor == "function") {
|
|
184
|
-
dash = (accessor as StyleAccessorFunction)(
|
|
185
|
-
object,
|
|
186
|
-
objectInfo
|
|
187
|
-
) as NumberPair;
|
|
188
|
-
} else if (accessor as NumberPair) dash = accessor as NumberPair;
|
|
189
|
-
else if (accessor) dash = DEFAULT_DASH;
|
|
190
|
-
if (dash.length == 2) {
|
|
191
|
-
return multiply(dash, factor);
|
|
192
|
-
} else {
|
|
193
|
-
return multiply(DEFAULT_DASH, factor);
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
function getColor(accessor: ColorAccessor) {
|
|
199
|
-
if (accessor as Color) {
|
|
200
|
-
return accessor as Color;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return (object: Feature, objectInfo?: Record<string, unknown>): Color => {
|
|
204
|
-
if (typeof accessor === "function") {
|
|
205
|
-
const color = (accessor as StyleAccessorFunction)(
|
|
206
|
-
object,
|
|
207
|
-
objectInfo
|
|
208
|
-
) as Color;
|
|
209
|
-
if (color) {
|
|
210
|
-
return color;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return object.properties?.["color"] as Color;
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
export function getSize(
|
|
218
|
-
type: string,
|
|
219
|
-
accessor: SizeAccessor,
|
|
220
|
-
offset = 0
|
|
221
|
-
): number | ((object: Feature) => number) {
|
|
222
|
-
if (typeof accessor == "function") {
|
|
223
|
-
return (object: Feature): number => {
|
|
224
|
-
return (
|
|
225
|
-
((accessor as StyleAccessorFunction)(object) as number) + offset
|
|
226
|
-
);
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if ((accessor as number) == 0) return 0;
|
|
231
|
-
if ((accessor as number) > 0) return (accessor as number) + offset;
|
|
232
|
-
|
|
233
|
-
if (type == LINE) return DEFAULT_LINE_WIDTH + offset;
|
|
234
|
-
if (type == POINT) return DEFAULT_POINT_SIZE + offset;
|
|
235
|
-
return 0;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export default class WellsLayer extends CompositeLayer<
|
|
239
|
-
WellsLayerProps<FeatureCollection<Geometry, GeoJsonProperties>>
|
|
240
|
-
> {
|
|
241
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
|
242
|
-
onClick(info: WellsPickInfo): boolean {
|
|
243
|
-
// Make selection only when drawing is disabled
|
|
244
|
-
if (isDrawingEnabled(this.context.layerManager)) {
|
|
245
|
-
return false;
|
|
246
|
-
} else {
|
|
247
|
-
this.context.userData.setEditedData({
|
|
248
|
-
selectedWell: (info.object as Feature).properties?.["name"],
|
|
249
|
-
});
|
|
250
|
-
return false; // do not return true to allow DeckGL props.onClick to be called
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
setSelection(
|
|
255
|
-
well: string | undefined,
|
|
256
|
-
_selection?: [number | undefined, number | undefined]
|
|
257
|
-
): void {
|
|
258
|
-
if (this.internalState) {
|
|
259
|
-
this.setState({
|
|
260
|
-
well: well,
|
|
261
|
-
selection: _selection,
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
setMultiSelection(wells: string[] | undefined): void {
|
|
267
|
-
if (this.internalState) {
|
|
268
|
-
this.setState({
|
|
269
|
-
selectedMultiWells: wells,
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
shouldUpdateState({ changeFlags }: UpdateParameters<this>): boolean {
|
|
275
|
-
return (
|
|
276
|
-
changeFlags.viewportChanged ||
|
|
277
|
-
changeFlags.propsOrDataChanged ||
|
|
278
|
-
typeof changeFlags.updateTriggersChanged === "object"
|
|
279
|
-
);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
getLegendData(
|
|
283
|
-
value: LogCurveDataType[]
|
|
284
|
-
): ContinuousLegendDataType | DiscreteLegendDataType | null {
|
|
285
|
-
return getLegendData(
|
|
286
|
-
value,
|
|
287
|
-
"",
|
|
288
|
-
this.props.logName,
|
|
289
|
-
this.props.logColor
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
setLegend(value: LogCurveDataType[]): void {
|
|
294
|
-
this.setState({
|
|
295
|
-
legend: this.getLegendData(value),
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
getLogLayer(): Layer {
|
|
300
|
-
const sub_layers = this.internalState?.subLayers as Layer[];
|
|
301
|
-
const log_layer = getLayersById(sub_layers, "wells-layer-log_curve");
|
|
302
|
-
return (log_layer as Layer[])?.[0];
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
getSelectionLayer(): Layer {
|
|
306
|
-
const sub_layers = this.internalState?.subLayers as Layer[];
|
|
307
|
-
const log_layer = getLayersById(sub_layers, "wells-layer-selection");
|
|
308
|
-
return (log_layer as Layer[])?.[0];
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
getLogCurveData(): LogCurveDataType[] | undefined {
|
|
312
|
-
const log_layer = this.getLogLayer();
|
|
313
|
-
return log_layer?.props.data as LogCurveDataType[];
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
setupLegend(): void {
|
|
317
|
-
const data = this.getLogCurveData();
|
|
318
|
-
if (data) this.setLegend(data);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
renderLayers(): LayersList {
|
|
322
|
-
if (!(this.props.data as unknown as FeatureCollection).features) {
|
|
323
|
-
return [];
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
let data = this.props.data as unknown as FeatureCollection;
|
|
327
|
-
if (!this.props.ZIncreasingDownwards) {
|
|
328
|
-
data = invertPath(data);
|
|
329
|
-
}
|
|
330
|
-
const refine = this.props.refine;
|
|
331
|
-
data = refine
|
|
332
|
-
? splineRefine(data) // smooth well paths.
|
|
333
|
-
: data;
|
|
334
|
-
|
|
335
|
-
const is3d = this.context.viewport.constructor === OrbitViewport;
|
|
336
|
-
const positionFormat = "XYZ";
|
|
337
|
-
const isDashed = !!this.props.lineStyle?.dash;
|
|
338
|
-
|
|
339
|
-
const extensions = [
|
|
340
|
-
new PathStyleExtension({
|
|
341
|
-
dash: isDashed,
|
|
342
|
-
highPrecisionDash: isDashed,
|
|
343
|
-
}),
|
|
344
|
-
];
|
|
345
|
-
|
|
346
|
-
const parameters = {
|
|
347
|
-
[GL.DEPTH_TEST]: this.props.depthTest,
|
|
348
|
-
[GL.POLYGON_OFFSET_FILL]: true,
|
|
349
|
-
};
|
|
350
|
-
|
|
351
|
-
const outline = new UnfoldedGeoJsonLayer(
|
|
352
|
-
this.getSubLayerProps({
|
|
353
|
-
id: "outline",
|
|
354
|
-
data,
|
|
355
|
-
pickable: false,
|
|
356
|
-
stroked: false,
|
|
357
|
-
positionFormat,
|
|
358
|
-
pointRadiusUnits: "pixels",
|
|
359
|
-
lineWidthUnits: "pixels",
|
|
360
|
-
visible: this.props.outline,
|
|
361
|
-
pointRadiusScale: this.props.pointRadiusScale,
|
|
362
|
-
lineWidthScale: this.props.lineWidthScale,
|
|
363
|
-
getLineWidth: getSize(LINE, this.props.lineStyle?.width),
|
|
364
|
-
getPointRadius: getSize(POINT, this.props.wellHeadStyle?.size),
|
|
365
|
-
extensions: extensions,
|
|
366
|
-
getDashArray: getDashFactor(this.props.lineStyle?.dash),
|
|
367
|
-
lineBillboard: true,
|
|
368
|
-
pointBillboard: true,
|
|
369
|
-
parameters,
|
|
370
|
-
})
|
|
371
|
-
);
|
|
372
|
-
|
|
373
|
-
const colors = new UnfoldedGeoJsonLayer(
|
|
374
|
-
this.getSubLayerProps({
|
|
375
|
-
id: "colors",
|
|
376
|
-
data,
|
|
377
|
-
pickable: true,
|
|
378
|
-
stroked: false,
|
|
379
|
-
positionFormat,
|
|
380
|
-
pointRadiusUnits: "pixels",
|
|
381
|
-
lineWidthUnits: "pixels",
|
|
382
|
-
pointRadiusScale: this.props.pointRadiusScale,
|
|
383
|
-
lineWidthScale: this.props.lineWidthScale,
|
|
384
|
-
getLineWidth: getSize(LINE, this.props.lineStyle?.width, -1),
|
|
385
|
-
getPointRadius: getSize(
|
|
386
|
-
POINT,
|
|
387
|
-
this.props.wellHeadStyle?.size,
|
|
388
|
-
-1
|
|
389
|
-
),
|
|
390
|
-
getFillColor: getColor(this.props.wellHeadStyle?.color),
|
|
391
|
-
getLineColor: getColor(this.props.lineStyle?.color),
|
|
392
|
-
extensions: extensions,
|
|
393
|
-
getDashArray: getDashFactor(
|
|
394
|
-
this.props.lineStyle?.dash,
|
|
395
|
-
getSize(LINE, this.props.lineStyle?.width),
|
|
396
|
-
-1
|
|
397
|
-
),
|
|
398
|
-
lineBillboard: true,
|
|
399
|
-
pointBillboard: true,
|
|
400
|
-
parameters,
|
|
401
|
-
})
|
|
402
|
-
);
|
|
403
|
-
|
|
404
|
-
// Highlight the selected well.
|
|
405
|
-
const highlight = new UnfoldedGeoJsonLayer(
|
|
406
|
-
this.getSubLayerProps({
|
|
407
|
-
id: "highlight",
|
|
408
|
-
data: getWellObjectByName(
|
|
409
|
-
data.features,
|
|
410
|
-
this.props.selectedWell
|
|
411
|
-
),
|
|
412
|
-
pickable: false,
|
|
413
|
-
stroked: false,
|
|
414
|
-
positionFormat,
|
|
415
|
-
pointRadiusUnits: "pixels",
|
|
416
|
-
lineWidthUnits: "pixels",
|
|
417
|
-
pointRadiusScale: this.props.pointRadiusScale,
|
|
418
|
-
lineWidthScale: this.props.lineWidthScale,
|
|
419
|
-
getLineWidth: getSize(LINE, this.props.lineStyle?.width, 2),
|
|
420
|
-
getPointRadius: getSize(
|
|
421
|
-
POINT,
|
|
422
|
-
this.props.wellHeadStyle?.size,
|
|
423
|
-
2
|
|
424
|
-
),
|
|
425
|
-
getFillColor: getColor(this.props.wellHeadStyle?.color),
|
|
426
|
-
getLineColor: getColor(this.props.lineStyle?.color),
|
|
427
|
-
parameters,
|
|
428
|
-
})
|
|
429
|
-
);
|
|
430
|
-
|
|
431
|
-
// Highlight the multi selected wells.
|
|
432
|
-
const highlightMultiWells = new UnfoldedGeoJsonLayer(
|
|
433
|
-
this.getSubLayerProps({
|
|
434
|
-
id: "highlight2",
|
|
435
|
-
data: getWellObjectsByName(
|
|
436
|
-
data.features,
|
|
437
|
-
this.state["selectedMultiWells"]
|
|
438
|
-
),
|
|
439
|
-
pickable: false,
|
|
440
|
-
stroked: false,
|
|
441
|
-
positionFormat,
|
|
442
|
-
pointRadiusUnits: "pixels",
|
|
443
|
-
lineWidthUnits: "pixels",
|
|
444
|
-
pointRadiusScale: this.props.pointRadiusScale,
|
|
445
|
-
lineWidthScale: this.props.lineWidthScale,
|
|
446
|
-
getLineWidth: getSize(LINE, this.props.lineStyle?.width, -1),
|
|
447
|
-
getPointRadius: getSize(
|
|
448
|
-
POINT,
|
|
449
|
-
this.props.wellHeadStyle?.size,
|
|
450
|
-
2
|
|
451
|
-
),
|
|
452
|
-
getFillColor: [255, 140, 0],
|
|
453
|
-
getLineColor: [255, 140, 0],
|
|
454
|
-
parameters,
|
|
455
|
-
})
|
|
456
|
-
);
|
|
457
|
-
|
|
458
|
-
const log_layer = new PathLayer<LogCurveDataType>(
|
|
459
|
-
this.getSubLayerProps({
|
|
460
|
-
id: "log_curve",
|
|
461
|
-
data: this.props.logData,
|
|
462
|
-
positionFormat,
|
|
463
|
-
pickable: true,
|
|
464
|
-
widthScale: 10,
|
|
465
|
-
widthMinPixels: 1,
|
|
466
|
-
miterLimit: 100,
|
|
467
|
-
visible: this.props.logCurves,
|
|
468
|
-
getPath: (d: LogCurveDataType): Position[] =>
|
|
469
|
-
getLogPath(
|
|
470
|
-
data.features,
|
|
471
|
-
d,
|
|
472
|
-
this.props.logrunName,
|
|
473
|
-
this.props.lineStyle?.color
|
|
474
|
-
),
|
|
475
|
-
getColor: (d: LogCurveDataType): Color[] =>
|
|
476
|
-
getLogColor(
|
|
477
|
-
d,
|
|
478
|
-
this.props.logrunName,
|
|
479
|
-
this.props.logName,
|
|
480
|
-
this.props.logColor,
|
|
481
|
-
(this.context as DeckGLLayerContext).userData
|
|
482
|
-
.colorTables,
|
|
483
|
-
this.props.colorMappingFunction,
|
|
484
|
-
this.props.isLog
|
|
485
|
-
),
|
|
486
|
-
getWidth: (d: LogCurveDataType): number | number[] =>
|
|
487
|
-
this.props.logRadius ||
|
|
488
|
-
getLogWidth(d, this.props.logrunName, this.props.logName),
|
|
489
|
-
updateTriggers: {
|
|
490
|
-
getColor: [
|
|
491
|
-
this.props.logrunName,
|
|
492
|
-
this.props.logName,
|
|
493
|
-
this.props.logColor,
|
|
494
|
-
(this.context as DeckGLLayerContext).userData
|
|
495
|
-
.colorTables,
|
|
496
|
-
this.props.isLog,
|
|
497
|
-
],
|
|
498
|
-
getWidth: [
|
|
499
|
-
this.props.logrunName,
|
|
500
|
-
this.props.logName,
|
|
501
|
-
this.props.logRadius,
|
|
502
|
-
],
|
|
503
|
-
getPath: [positionFormat],
|
|
504
|
-
},
|
|
505
|
-
onDataLoad: (value: LogCurveDataType[]) => {
|
|
506
|
-
this.setLegend(value);
|
|
507
|
-
},
|
|
508
|
-
parameters,
|
|
509
|
-
})
|
|
510
|
-
);
|
|
511
|
-
|
|
512
|
-
const selection_layer = new PathLayer<LogCurveDataType>(
|
|
513
|
-
this.getSubLayerProps({
|
|
514
|
-
id: "selection",
|
|
515
|
-
data: this.props.logData,
|
|
516
|
-
positionFormat,
|
|
517
|
-
pickable: false,
|
|
518
|
-
widthScale: 10,
|
|
519
|
-
widthMinPixels: 1,
|
|
520
|
-
miterLimit: 100,
|
|
521
|
-
visible: this.props.logCurves,
|
|
522
|
-
getPath: (d: LogCurveDataType): Position[] =>
|
|
523
|
-
getLogPath1(
|
|
524
|
-
data.features,
|
|
525
|
-
d,
|
|
526
|
-
this.state["well"],
|
|
527
|
-
this.state["selection"],
|
|
528
|
-
this.props.logrunName,
|
|
529
|
-
this.props.lineStyle?.color
|
|
530
|
-
),
|
|
531
|
-
getColor: (d: LogCurveDataType): Color[] =>
|
|
532
|
-
getLogColor1(
|
|
533
|
-
data.features,
|
|
534
|
-
d,
|
|
535
|
-
this.state["well"],
|
|
536
|
-
this.state["selection"],
|
|
537
|
-
this.props.logrunName
|
|
538
|
-
),
|
|
539
|
-
getWidth: (d: LogCurveDataType): number | number[] =>
|
|
540
|
-
this.props.logRadius * 1.5 ||
|
|
541
|
-
getLogWidth(d, this.props.logrunName, this.props.logName),
|
|
542
|
-
updateTriggers: {
|
|
543
|
-
getColor: [
|
|
544
|
-
this.props.logrunName,
|
|
545
|
-
this.state["well"],
|
|
546
|
-
this.state["selection"],
|
|
547
|
-
],
|
|
548
|
-
getWidth: [
|
|
549
|
-
this.props.logrunName,
|
|
550
|
-
this.props.logName,
|
|
551
|
-
this.props.logRadius,
|
|
552
|
-
],
|
|
553
|
-
getPath: [
|
|
554
|
-
positionFormat,
|
|
555
|
-
this.props.logrunName,
|
|
556
|
-
this.state["well"],
|
|
557
|
-
this.state["selection"],
|
|
558
|
-
],
|
|
559
|
-
},
|
|
560
|
-
onDataLoad: (value: LogCurveDataType[]) => {
|
|
561
|
-
this.setLegend(value);
|
|
562
|
-
},
|
|
563
|
-
parameters,
|
|
564
|
-
})
|
|
565
|
-
);
|
|
566
|
-
|
|
567
|
-
// well name
|
|
568
|
-
const names = new TextLayer<Feature>(
|
|
569
|
-
this.getSubLayerProps({
|
|
570
|
-
id: "names",
|
|
571
|
-
data: data.features,
|
|
572
|
-
visible: this.props.wellNameVisible,
|
|
573
|
-
getPosition: (d: Feature) =>
|
|
574
|
-
getAnnotationPosition(
|
|
575
|
-
d,
|
|
576
|
-
this.props.wellNameAtTop,
|
|
577
|
-
is3d,
|
|
578
|
-
this.props.lineStyle?.color
|
|
579
|
-
),
|
|
580
|
-
getText: (d: Feature) => d.properties?.["name"],
|
|
581
|
-
getColor: this.props.wellNameColor,
|
|
582
|
-
getAnchor: "start",
|
|
583
|
-
getAlignmentBaseline: "bottom",
|
|
584
|
-
getSize: this.props.wellNameSize,
|
|
585
|
-
parameters,
|
|
586
|
-
})
|
|
587
|
-
);
|
|
588
|
-
|
|
589
|
-
return [
|
|
590
|
-
outline,
|
|
591
|
-
log_layer,
|
|
592
|
-
colors,
|
|
593
|
-
highlight,
|
|
594
|
-
highlightMultiWells,
|
|
595
|
-
selection_layer,
|
|
596
|
-
names,
|
|
597
|
-
];
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
getPickingInfo({ info }: { info: PickingInfo }): WellsPickInfo {
|
|
601
|
-
if (!info.object) return { ...info, properties: [], logName: "" };
|
|
602
|
-
|
|
603
|
-
const coordinate = (info.coordinate || [0, 0, 0]) as Position;
|
|
604
|
-
|
|
605
|
-
let md_property = getMdProperty(
|
|
606
|
-
coordinate,
|
|
607
|
-
info.object as Feature,
|
|
608
|
-
this.props.lineStyle?.color,
|
|
609
|
-
(info as WellsPickInfo).featureType
|
|
610
|
-
);
|
|
611
|
-
if (!md_property) {
|
|
612
|
-
md_property = getLogProperty(
|
|
613
|
-
coordinate,
|
|
614
|
-
(this.props.data as unknown as FeatureCollection).features,
|
|
615
|
-
info.object,
|
|
616
|
-
this.props.logrunName,
|
|
617
|
-
"MD"
|
|
618
|
-
);
|
|
619
|
-
}
|
|
620
|
-
let tvd_property = getTvdProperty(
|
|
621
|
-
coordinate,
|
|
622
|
-
info.object as Feature,
|
|
623
|
-
this.props.lineStyle?.color,
|
|
624
|
-
(info as WellsPickInfo).featureType
|
|
625
|
-
);
|
|
626
|
-
if (!tvd_property) {
|
|
627
|
-
tvd_property = getLogProperty(
|
|
628
|
-
coordinate,
|
|
629
|
-
(this.props.data as unknown as FeatureCollection).features,
|
|
630
|
-
info.object,
|
|
631
|
-
this.props.logrunName,
|
|
632
|
-
"TVD"
|
|
633
|
-
);
|
|
634
|
-
}
|
|
635
|
-
const log_property = getLogProperty(
|
|
636
|
-
coordinate,
|
|
637
|
-
(this.props.data as unknown as FeatureCollection).features,
|
|
638
|
-
info.object,
|
|
639
|
-
this.props.logrunName,
|
|
640
|
-
this.props.logName
|
|
641
|
-
);
|
|
642
|
-
|
|
643
|
-
// Patch for inverting tvd readout to fix issue #830,
|
|
644
|
-
// should make proper fix when handling z increase direction - issue #842
|
|
645
|
-
const inverted_tvd_property = tvd_property && {
|
|
646
|
-
...tvd_property,
|
|
647
|
-
value: (tvd_property?.value as number) * -1,
|
|
648
|
-
};
|
|
649
|
-
|
|
650
|
-
const layer_properties: PropertyDataType[] = [];
|
|
651
|
-
if (md_property) layer_properties.push(md_property);
|
|
652
|
-
if (inverted_tvd_property) layer_properties.push(inverted_tvd_property);
|
|
653
|
-
if (log_property) layer_properties.push(log_property);
|
|
654
|
-
|
|
655
|
-
return {
|
|
656
|
-
...info,
|
|
657
|
-
properties: layer_properties,
|
|
658
|
-
logName: log_property?.name || "",
|
|
659
|
-
};
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
WellsLayer.layerName = "WellsLayer";
|
|
664
|
-
WellsLayer.defaultProps = {
|
|
665
|
-
...defaultProps,
|
|
666
|
-
onDataLoad: (data, context): void => onDataLoad(data, context),
|
|
667
|
-
};
|
|
668
|
-
|
|
669
|
-
//================= Local help functions. ==================
|
|
670
|
-
|
|
671
|
-
function getColumn<D>(data: D[][], col: number): D[] {
|
|
672
|
-
const column: D[] = [];
|
|
673
|
-
for (let i = 0; i < data.length; i++) {
|
|
674
|
-
column.push(data[i][col]);
|
|
675
|
-
}
|
|
676
|
-
return column;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
function getLogMd(d: LogCurveDataType, logrun_name: string): number[] {
|
|
680
|
-
if (!isSelectedLogRun(d, logrun_name)) return [];
|
|
681
|
-
|
|
682
|
-
const names_md = ["DEPTH", "DEPT", "MD", "TDEP", "MD_RKB"]; // aliases for MD
|
|
683
|
-
const log_id = getLogIndexByNames(d, names_md);
|
|
684
|
-
return log_id >= 0 ? getColumn(d.data, log_id) : [];
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
export function getLogValues(
|
|
688
|
-
d: LogCurveDataType,
|
|
689
|
-
logrun_name: string,
|
|
690
|
-
log_name: string
|
|
691
|
-
): number[] {
|
|
692
|
-
if (!isSelectedLogRun(d, logrun_name)) return [];
|
|
693
|
-
|
|
694
|
-
const log_id = getLogIndexByName(d, log_name);
|
|
695
|
-
return log_id >= 0 ? getColumn(d.data, log_id) : [];
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
export function getLogInfo(
|
|
699
|
-
d: LogCurveDataType,
|
|
700
|
-
logrun_name: string,
|
|
701
|
-
log_name: string
|
|
702
|
-
): { name: string; description: string } | undefined {
|
|
703
|
-
if (!isSelectedLogRun(d, logrun_name)) return undefined;
|
|
704
|
-
|
|
705
|
-
const log_id = getLogIndexByName(d, log_name);
|
|
706
|
-
return d.curves[log_id];
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
function getDiscreteLogMetadata(d: LogCurveDataType, log_name: string) {
|
|
710
|
-
return d?.metadata_discrete[log_name];
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
function isSelectedLogRun(d: LogCurveDataType, logrun_name: string): boolean {
|
|
714
|
-
return d.header.name.toLowerCase() === logrun_name.toLowerCase();
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
// return position for well name and icon
|
|
718
|
-
function getAnnotationPosition(
|
|
719
|
-
well_data: Feature,
|
|
720
|
-
name_at_top: boolean,
|
|
721
|
-
view_is_3d: boolean,
|
|
722
|
-
color_accessor: ColorAccessor
|
|
723
|
-
): Position | null {
|
|
724
|
-
if (name_at_top) {
|
|
725
|
-
let top;
|
|
726
|
-
|
|
727
|
-
// Read top position from Point geometry, if not present, read it from LineString geometry
|
|
728
|
-
const well_head = getWellHeadPosition(well_data);
|
|
729
|
-
if (well_data) top = well_head;
|
|
730
|
-
else {
|
|
731
|
-
const trajectory = getTrajectory(well_data, color_accessor);
|
|
732
|
-
top = trajectory?.at(0);
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
// using z=0 for orthographic view to keep label above other other layers
|
|
736
|
-
if (top) return view_is_3d ? top : [top[0], top[1], 0];
|
|
737
|
-
} else {
|
|
738
|
-
let bot;
|
|
739
|
-
// if trajectory is not present, return top position from Point geometry
|
|
740
|
-
const trajectory = getTrajectory(well_data, color_accessor);
|
|
741
|
-
if (trajectory) bot = trajectory?.at(-1);
|
|
742
|
-
else bot = getWellHeadPosition(well_data);
|
|
743
|
-
|
|
744
|
-
// using z=0 for orthographic view to keep label above other other layers
|
|
745
|
-
if (bot) return view_is_3d ? bot : [bot[0], bot[1], 0];
|
|
746
|
-
}
|
|
747
|
-
return null;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
function getWellObjectByName(
|
|
751
|
-
wells_data: Feature[],
|
|
752
|
-
name: string
|
|
753
|
-
): Feature | undefined {
|
|
754
|
-
return wells_data?.find(
|
|
755
|
-
(item) =>
|
|
756
|
-
item.properties?.["name"]?.toLowerCase() === name?.toLowerCase()
|
|
757
|
-
);
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
function getWellObjectsByName(
|
|
761
|
-
wells_data: Feature[],
|
|
762
|
-
name: string[]
|
|
763
|
-
): Feature[] | undefined {
|
|
764
|
-
const res: Feature[] = [];
|
|
765
|
-
for (let i = 0; i < name?.length; i++) {
|
|
766
|
-
wells_data?.find((item) => {
|
|
767
|
-
if (
|
|
768
|
-
item.properties?.["name"]?.toLowerCase() ===
|
|
769
|
-
name[i]?.toLowerCase()
|
|
770
|
-
) {
|
|
771
|
-
res.push(item);
|
|
772
|
-
}
|
|
773
|
-
});
|
|
774
|
-
}
|
|
775
|
-
return res;
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
function getPointGeometry(well_object: Feature): Point {
|
|
779
|
-
return (well_object.geometry as GeometryCollection)?.geometries.find(
|
|
780
|
-
(item: { type: string }) => item.type == "Point"
|
|
781
|
-
) as Point;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
function getLineStringGeometry(well_object: Feature): LineString {
|
|
785
|
-
return (well_object.geometry as GeometryCollection)?.geometries.find(
|
|
786
|
-
(item: { type: string }) => item.type == "LineString"
|
|
787
|
-
) as LineString;
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
// Return well head position from Point Geometry
|
|
791
|
-
function getWellHeadPosition(well_object: Feature): Position {
|
|
792
|
-
return getPointGeometry(well_object)?.coordinates as Position;
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
// return trajectory visibility based on alpha of trajectory color
|
|
796
|
-
function isTrajectoryVisible(
|
|
797
|
-
well_object: Feature,
|
|
798
|
-
color_accessor: ColorAccessor
|
|
799
|
-
): boolean {
|
|
800
|
-
let alpha;
|
|
801
|
-
const accessor = getColor(color_accessor);
|
|
802
|
-
if (typeof accessor === "function") {
|
|
803
|
-
alpha = accessor(well_object)?.[3];
|
|
804
|
-
} else {
|
|
805
|
-
alpha = (accessor as Color)?.[3];
|
|
806
|
-
}
|
|
807
|
-
return alpha !== 0;
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
// Return Trajectory data from LineString Geometry if it's visible (checking trajectory visiblity based on line color)
|
|
811
|
-
function getTrajectory(
|
|
812
|
-
well_object: Feature,
|
|
813
|
-
color_accessor: ColorAccessor
|
|
814
|
-
): Position[] | undefined {
|
|
815
|
-
if (isTrajectoryVisible(well_object, color_accessor))
|
|
816
|
-
return getLineStringGeometry(well_object)?.coordinates as Position[];
|
|
817
|
-
else return undefined;
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
function getWellMds(well_object: Feature): number[] {
|
|
821
|
-
return well_object.properties?.["md"][0];
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
function getNeighboringMdIndices(mds: number[], md: number): number[] {
|
|
825
|
-
const idx = mds.findIndex((x) => x >= md);
|
|
826
|
-
return idx === 0 ? [idx, idx + 1] : [idx - 1, idx];
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
function getPositionByMD(well_xyz: Position[], well_mds: number[], md: number) {
|
|
830
|
-
const [l_idx, h_idx] = getNeighboringMdIndices(well_mds, md);
|
|
831
|
-
const md_low = well_mds[l_idx];
|
|
832
|
-
const md_normalized = (md - md_low) / (well_mds[h_idx] - md_low);
|
|
833
|
-
return interpolateNumberArray(
|
|
834
|
-
well_xyz[l_idx],
|
|
835
|
-
well_xyz[h_idx]
|
|
836
|
-
)(md_normalized);
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
function getLogPath(
|
|
840
|
-
wells_data: Feature[],
|
|
841
|
-
d: LogCurveDataType,
|
|
842
|
-
logrun_name: string,
|
|
843
|
-
trajectory_line_color?: ColorAccessor
|
|
844
|
-
): Position[] {
|
|
845
|
-
const well_object = getWellObjectByName(wells_data, d.header.well);
|
|
846
|
-
if (!well_object) return [];
|
|
847
|
-
|
|
848
|
-
const well_xyz = getTrajectory(well_object, trajectory_line_color);
|
|
849
|
-
const well_mds = getWellMds(well_object);
|
|
850
|
-
|
|
851
|
-
if (
|
|
852
|
-
well_xyz == undefined ||
|
|
853
|
-
well_mds == undefined ||
|
|
854
|
-
well_xyz.length == 0 ||
|
|
855
|
-
well_mds.length == 0
|
|
856
|
-
)
|
|
857
|
-
return [];
|
|
858
|
-
|
|
859
|
-
const log_xyz: Position[] = [];
|
|
860
|
-
const log_mds = getLogMd(d, logrun_name);
|
|
861
|
-
log_mds.forEach((md) => {
|
|
862
|
-
const xyz = getPositionByMD(well_xyz, well_mds, md);
|
|
863
|
-
log_xyz.push(xyz);
|
|
864
|
-
});
|
|
865
|
-
|
|
866
|
-
return log_xyz;
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
function getLogIndexByName(d: LogCurveDataType, log_name: string): number {
|
|
870
|
-
const name = log_name.toLowerCase();
|
|
871
|
-
return d.curves.findIndex((item) => item.name.toLowerCase() === name);
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
function getLogIndexByNames(d: LogCurveDataType, names: string[]): number {
|
|
875
|
-
for (const name of names) {
|
|
876
|
-
const index = getLogIndexByName(d, name);
|
|
877
|
-
if (index >= 0) return index;
|
|
878
|
-
}
|
|
879
|
-
return -1;
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
function getLogColor(
|
|
883
|
-
d: LogCurveDataType,
|
|
884
|
-
logrun_name: string,
|
|
885
|
-
log_name: string,
|
|
886
|
-
logColor: string,
|
|
887
|
-
colorTables: colorTablesArray,
|
|
888
|
-
// eslint-disable-next-line
|
|
889
|
-
colorMappingFunction: any,
|
|
890
|
-
isLog: boolean
|
|
891
|
-
): Color[] {
|
|
892
|
-
const log_data = getLogValues(d, logrun_name, log_name);
|
|
893
|
-
const log_info = getLogInfo(d, logrun_name, log_name);
|
|
894
|
-
if (log_data.length == 0 || log_info == undefined) return [];
|
|
895
|
-
const log_color: Color[] = [];
|
|
896
|
-
if (log_info.description == "continuous") {
|
|
897
|
-
const min = Math.min(...log_data);
|
|
898
|
-
const max = Math.max(...log_data);
|
|
899
|
-
const max_delta = max - min;
|
|
900
|
-
log_data.forEach((value) => {
|
|
901
|
-
const rgb = colorMappingFunction
|
|
902
|
-
? colorMappingFunction((value - min) / max_delta)
|
|
903
|
-
: rgbValues((value - min) / max_delta, logColor, colorTables);
|
|
904
|
-
rgbValues(value - min / max_delta, logColor, colorTables, isLog);
|
|
905
|
-
|
|
906
|
-
if (rgb) {
|
|
907
|
-
if (Array.isArray(rgb)) {
|
|
908
|
-
log_color.push([rgb[0], rgb[1], rgb[2]]);
|
|
909
|
-
} else {
|
|
910
|
-
log_color.push([rgb?.r, rgb?.g, rgb?.b]);
|
|
911
|
-
}
|
|
912
|
-
} else {
|
|
913
|
-
log_color.push([0, 0, 0, 0]); // push transparent for null/undefined log values
|
|
914
|
-
}
|
|
915
|
-
});
|
|
916
|
-
} else {
|
|
917
|
-
// well log data set for ex : H1: Array(2)0: (4) [255, 26, 202, 255] 1: 13
|
|
918
|
-
const log_attributes = getDiscreteLogMetadata(d, log_name)?.objects;
|
|
919
|
-
const logLength = Object.keys(log_attributes).length;
|
|
920
|
-
|
|
921
|
-
// eslint-disable-next-line
|
|
922
|
-
const attributesObject: { [key: string]: any } = {};
|
|
923
|
-
const categorial = true;
|
|
924
|
-
|
|
925
|
-
Object.keys(log_attributes).forEach((key) => {
|
|
926
|
-
// get the point from log_attributes
|
|
927
|
-
const point = log_attributes[key][1];
|
|
928
|
-
const categorialMin = 0;
|
|
929
|
-
const categorialMax = logLength - 1;
|
|
930
|
-
|
|
931
|
-
let rgb;
|
|
932
|
-
if (colorMappingFunction) {
|
|
933
|
-
rgb = colorMappingFunction(
|
|
934
|
-
point,
|
|
935
|
-
categorial,
|
|
936
|
-
categorialMin,
|
|
937
|
-
categorialMax
|
|
938
|
-
);
|
|
939
|
-
} else {
|
|
940
|
-
// if colormap function is not defined
|
|
941
|
-
const arrayOfColors: [number, number, number, number][] =
|
|
942
|
-
getColors(logColor, colorTables, point);
|
|
943
|
-
if (!arrayOfColors.length)
|
|
944
|
-
console.error(
|
|
945
|
-
"Empty or missed '" + logColor + "' color table"
|
|
946
|
-
);
|
|
947
|
-
rgb = arrayOfColors;
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
if (rgb) {
|
|
951
|
-
if (Array.isArray(rgb)) {
|
|
952
|
-
if (rgb.length === 3) {
|
|
953
|
-
attributesObject[key] = [
|
|
954
|
-
[rgb[0], rgb[1], rgb[2]],
|
|
955
|
-
point,
|
|
956
|
-
];
|
|
957
|
-
} else {
|
|
958
|
-
attributesObject[key] = [
|
|
959
|
-
[rgb[1], rgb[2], rgb[3]],
|
|
960
|
-
point,
|
|
961
|
-
];
|
|
962
|
-
}
|
|
963
|
-
} else {
|
|
964
|
-
attributesObject[key] = [[rgb.r, rgb.g, rgb.b], point];
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
});
|
|
968
|
-
log_data.forEach((log_value) => {
|
|
969
|
-
const dl_attrs = Object.entries(attributesObject).find(
|
|
970
|
-
([, value]) => value[1] == log_value
|
|
971
|
-
)?.[1];
|
|
972
|
-
dl_attrs
|
|
973
|
-
? log_color.push(dl_attrs[0])
|
|
974
|
-
: log_color.push([0, 0, 0, 0]); // use transparent for undefined/null log values
|
|
975
|
-
});
|
|
976
|
-
}
|
|
977
|
-
return log_color;
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
function getLogPath1(
|
|
981
|
-
wells_data: Feature[],
|
|
982
|
-
d: LogCurveDataType,
|
|
983
|
-
selectedWell: string | undefined,
|
|
984
|
-
selection: [number | undefined, number | undefined] | undefined,
|
|
985
|
-
logrun_name: string,
|
|
986
|
-
trajectory_line_color?: ColorAccessor
|
|
987
|
-
): Position[] {
|
|
988
|
-
if (!selection || selectedWell !== d.header.well) return [];
|
|
989
|
-
const well_object = getWellObjectByName(wells_data, d.header.well);
|
|
990
|
-
if (!well_object) return [];
|
|
991
|
-
|
|
992
|
-
const well_xyz = getTrajectory(well_object, trajectory_line_color);
|
|
993
|
-
const well_mds = getWellMds(well_object);
|
|
994
|
-
|
|
995
|
-
if (
|
|
996
|
-
well_xyz == undefined ||
|
|
997
|
-
well_mds == undefined ||
|
|
998
|
-
well_xyz.length == 0 ||
|
|
999
|
-
well_mds.length == 0
|
|
1000
|
-
)
|
|
1001
|
-
return [];
|
|
1002
|
-
|
|
1003
|
-
const log_mds = getLogMd(d, logrun_name);
|
|
1004
|
-
if (!log_mds) return [];
|
|
1005
|
-
|
|
1006
|
-
const log_xyz: Position[] = [];
|
|
1007
|
-
|
|
1008
|
-
let md0 = selection[0] as number;
|
|
1009
|
-
if (md0 !== undefined) {
|
|
1010
|
-
let md1 = selection[1];
|
|
1011
|
-
if (md1 == md0) md1 = undefined;
|
|
1012
|
-
const mdFirst = well_mds[0];
|
|
1013
|
-
const mdLast = well_mds[well_mds.length - 1];
|
|
1014
|
-
|
|
1015
|
-
if (md1 !== undefined) {
|
|
1016
|
-
if (md0 > md1) {
|
|
1017
|
-
const tmp: number = md0;
|
|
1018
|
-
md0 = md1;
|
|
1019
|
-
md1 = tmp;
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
const delta = 2;
|
|
1024
|
-
if (md0 - delta > mdFirst) {
|
|
1025
|
-
let xyz = getPositionByMD(well_xyz, well_mds, md0 - delta);
|
|
1026
|
-
log_xyz.push(xyz);
|
|
1027
|
-
xyz = getPositionByMD(well_xyz, well_mds, md0);
|
|
1028
|
-
log_xyz.push(xyz);
|
|
1029
|
-
}
|
|
1030
|
-
if (md1 !== undefined) {
|
|
1031
|
-
const _md1 = md1 as number;
|
|
1032
|
-
let index = 0;
|
|
1033
|
-
well_mds.forEach((md) => {
|
|
1034
|
-
if (md0 <= md && md <= _md1) {
|
|
1035
|
-
const xyz = well_xyz[index];
|
|
1036
|
-
log_xyz.push(xyz);
|
|
1037
|
-
}
|
|
1038
|
-
index++;
|
|
1039
|
-
});
|
|
1040
|
-
if (_md1 + delta < mdLast) {
|
|
1041
|
-
let xyz = getPositionByMD(well_xyz, well_mds, _md1);
|
|
1042
|
-
log_xyz.push(xyz);
|
|
1043
|
-
xyz = getPositionByMD(well_xyz, well_mds, _md1 + delta);
|
|
1044
|
-
log_xyz.push(xyz);
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
return log_xyz;
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
function getLogColor1(
|
|
1052
|
-
wells_data: Feature[],
|
|
1053
|
-
d: LogCurveDataType,
|
|
1054
|
-
selectedWell: string | undefined,
|
|
1055
|
-
selection: [number | undefined, number | undefined] | undefined,
|
|
1056
|
-
logrun_name: string
|
|
1057
|
-
): Color[] {
|
|
1058
|
-
if (!selection || selectedWell !== d.header.well) return [];
|
|
1059
|
-
const well_object = getWellObjectByName(wells_data, d.header.well);
|
|
1060
|
-
if (!well_object) return [];
|
|
1061
|
-
|
|
1062
|
-
const well_mds = getWellMds(well_object);
|
|
1063
|
-
|
|
1064
|
-
const log_mds = getLogMd(d, logrun_name);
|
|
1065
|
-
if (!log_mds || log_mds.length === 0) return [];
|
|
1066
|
-
|
|
1067
|
-
const log_color: Color[] = [];
|
|
1068
|
-
|
|
1069
|
-
let md0 = selection[0] as number;
|
|
1070
|
-
if (md0 !== undefined) {
|
|
1071
|
-
const mdFirst = well_mds[0];
|
|
1072
|
-
const mdLast = well_mds[well_mds.length - 1];
|
|
1073
|
-
let md1 = selection[1];
|
|
1074
|
-
if (md1 == md0) md1 = undefined;
|
|
1075
|
-
let swap = false;
|
|
1076
|
-
if (md1 !== undefined) {
|
|
1077
|
-
if (md0 > md1) {
|
|
1078
|
-
const tmp: number = md0;
|
|
1079
|
-
md0 = md1;
|
|
1080
|
-
md1 = tmp;
|
|
1081
|
-
swap = true;
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
const delta = 2;
|
|
1085
|
-
if (md0 - delta > mdFirst)
|
|
1086
|
-
log_color.push(swap ? [0, 255, 0, 128] : [255, 0, 0, 128]);
|
|
1087
|
-
|
|
1088
|
-
if (md1 !== undefined) {
|
|
1089
|
-
const _md1 = md1 as number;
|
|
1090
|
-
log_color.push([128, 128, 128, 128]);
|
|
1091
|
-
well_mds.forEach((md) => {
|
|
1092
|
-
if (md0 <= md && md <= _md1) {
|
|
1093
|
-
log_color.push([128, 128, 128, 128]);
|
|
1094
|
-
}
|
|
1095
|
-
});
|
|
1096
|
-
|
|
1097
|
-
if (_md1 + delta < mdLast)
|
|
1098
|
-
log_color.push(swap ? [255, 0, 0, 128] : [0, 255, 0, 128]);
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
return log_color;
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
function getLogWidth(
|
|
1105
|
-
d: LogCurveDataType,
|
|
1106
|
-
logrun_name: string,
|
|
1107
|
-
log_name: string
|
|
1108
|
-
): number[] {
|
|
1109
|
-
return getLogValues(d, logrun_name, log_name);
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
function squared_distance(a: Position, b: Position): number {
|
|
1113
|
-
const dx = a[0] - b[0];
|
|
1114
|
-
const dy = a[1] - b[1];
|
|
1115
|
-
return dx * dx + dy * dy;
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
// Return distance between line segment vw and point p
|
|
1119
|
-
function distToSegmentSquared(v: Position, w: Position, p: Position): number {
|
|
1120
|
-
const l2 = squared_distance(v, w);
|
|
1121
|
-
if (l2 == 0) return squared_distance(p, v);
|
|
1122
|
-
let t =
|
|
1123
|
-
((p[0] - v[0]) * (w[0] - v[0]) + (p[1] - v[1]) * (w[1] - v[1])) / l2;
|
|
1124
|
-
t = Math.max(0, Math.min(1, t));
|
|
1125
|
-
return squared_distance(p, [
|
|
1126
|
-
v[0] + t * (w[0] - v[0]),
|
|
1127
|
-
v[1] + t * (w[1] - v[1]),
|
|
1128
|
-
]);
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
// Interpolates point closest to the coords on trajectory
|
|
1132
|
-
function interpolateDataOnTrajectory(
|
|
1133
|
-
coord: Position,
|
|
1134
|
-
data: number[],
|
|
1135
|
-
trajectory: Position[]
|
|
1136
|
-
): number {
|
|
1137
|
-
// if number of data points in less than 1 or
|
|
1138
|
-
// length of data and trajectory are different we cannot interpolate.
|
|
1139
|
-
if (data.length <= 1 || data.length != trajectory.length) return -1;
|
|
1140
|
-
|
|
1141
|
-
// Identify closest well path leg to coord.
|
|
1142
|
-
const segment_index = getSegmentIndex(coord, trajectory);
|
|
1143
|
-
|
|
1144
|
-
const index0 = segment_index;
|
|
1145
|
-
const index1 = index0 + 1;
|
|
1146
|
-
|
|
1147
|
-
// Get the nearest data.
|
|
1148
|
-
const data0 = data[index0];
|
|
1149
|
-
const data1 = data[index1];
|
|
1150
|
-
|
|
1151
|
-
// Get the nearest survey points.
|
|
1152
|
-
const survey0 = trajectory[index0];
|
|
1153
|
-
const survey1 = trajectory[index1];
|
|
1154
|
-
|
|
1155
|
-
const dv = distance(survey0, survey1) as number;
|
|
1156
|
-
if (dv === 0) {
|
|
1157
|
-
return -1;
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
// Calculate the scalar projection onto segment.
|
|
1161
|
-
const v0 = subtract(coord as number[], survey0 as number[]);
|
|
1162
|
-
const v1 = subtract(survey1 as number[], survey0 as number[]);
|
|
1163
|
-
|
|
1164
|
-
// scalar_projection in interval [0,1]
|
|
1165
|
-
const scalar_projection: number =
|
|
1166
|
-
dot(v0 as number[], v1 as number[]) / (dv * dv);
|
|
1167
|
-
|
|
1168
|
-
// Interpolate data.
|
|
1169
|
-
return data0 * (1.0 - scalar_projection) + data1 * scalar_projection;
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
function getMd(
|
|
1173
|
-
coord: Position,
|
|
1174
|
-
feature: Feature,
|
|
1175
|
-
accessor: ColorAccessor
|
|
1176
|
-
): number | null {
|
|
1177
|
-
if (!feature.properties?.["md"]?.[0] || !feature.geometry) return null;
|
|
1178
|
-
|
|
1179
|
-
const measured_depths = feature.properties["md"][0] as number[];
|
|
1180
|
-
const trajectory3D = getTrajectory(feature, accessor);
|
|
1181
|
-
|
|
1182
|
-
if (trajectory3D == undefined) return null;
|
|
1183
|
-
|
|
1184
|
-
let trajectory;
|
|
1185
|
-
// In 2D view coord is of type Position2D and in 3D view it's Position3D,
|
|
1186
|
-
// so use apropriate trajectory for interpolation
|
|
1187
|
-
if (coord.length == 2) {
|
|
1188
|
-
const trajectory2D = trajectory3D.map((v) => {
|
|
1189
|
-
return v.slice(0, 2);
|
|
1190
|
-
}) as Position[];
|
|
1191
|
-
trajectory = trajectory2D;
|
|
1192
|
-
} else {
|
|
1193
|
-
trajectory = trajectory3D;
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
return interpolateDataOnTrajectory(coord, measured_depths, trajectory);
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
function getMdProperty(
|
|
1200
|
-
coord: Position,
|
|
1201
|
-
feature: Feature,
|
|
1202
|
-
accessor: ColorAccessor,
|
|
1203
|
-
featureType: string | undefined
|
|
1204
|
-
): PropertyDataType | null {
|
|
1205
|
-
if (featureType === "points") {
|
|
1206
|
-
return null;
|
|
1207
|
-
}
|
|
1208
|
-
const md = getMd(coord, feature, accessor);
|
|
1209
|
-
if (md != null) {
|
|
1210
|
-
const prop_name = "MD " + feature.properties?.["name"];
|
|
1211
|
-
return createPropertyData(prop_name, md, feature.properties?.["color"]);
|
|
1212
|
-
}
|
|
1213
|
-
return null;
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
function getTvd(
|
|
1217
|
-
coord: Position,
|
|
1218
|
-
feature: Feature,
|
|
1219
|
-
accessor: ColorAccessor
|
|
1220
|
-
): number | null {
|
|
1221
|
-
const trajectory3D = getTrajectory(feature, accessor);
|
|
1222
|
-
|
|
1223
|
-
// if trajectory is not found or if it has a data single point then get tvd from well head
|
|
1224
|
-
if (trajectory3D == undefined || trajectory3D?.length <= 1) {
|
|
1225
|
-
const wellhead_xyz = getWellHeadPosition(feature);
|
|
1226
|
-
return wellhead_xyz?.[2] ?? null;
|
|
1227
|
-
}
|
|
1228
|
-
let trajectory;
|
|
1229
|
-
// For 2D view coord is Position2D and for 3D view it's Position3D
|
|
1230
|
-
if (coord.length == 2) {
|
|
1231
|
-
const trajectory2D = trajectory3D?.map((v) => {
|
|
1232
|
-
return v.slice(0, 2);
|
|
1233
|
-
}) as Position[];
|
|
1234
|
-
trajectory = trajectory2D;
|
|
1235
|
-
} else {
|
|
1236
|
-
trajectory = trajectory3D;
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
const tvds = trajectory3D.map((v) => {
|
|
1240
|
-
return v[2];
|
|
1241
|
-
}) as number[];
|
|
1242
|
-
|
|
1243
|
-
return interpolateDataOnTrajectory(coord, tvds, trajectory);
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
function getTvdProperty(
|
|
1247
|
-
coord: Position,
|
|
1248
|
-
feature: Feature,
|
|
1249
|
-
accessor: ColorAccessor,
|
|
1250
|
-
featureType: string | undefined
|
|
1251
|
-
): PropertyDataType | null {
|
|
1252
|
-
if (featureType === "points") {
|
|
1253
|
-
return null;
|
|
1254
|
-
}
|
|
1255
|
-
const tvd = getTvd(coord, feature, accessor);
|
|
1256
|
-
if (tvd != null) {
|
|
1257
|
-
const prop_name = "TVD " + feature.properties?.["name"];
|
|
1258
|
-
return createPropertyData(
|
|
1259
|
-
prop_name,
|
|
1260
|
-
tvd,
|
|
1261
|
-
feature.properties?.["color"]
|
|
1262
|
-
);
|
|
1263
|
-
}
|
|
1264
|
-
return null;
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
// Identify closest path leg to coord.
|
|
1268
|
-
function getSegmentIndex(coord: Position, path: Position[]): number {
|
|
1269
|
-
let min_d = Number.MAX_VALUE;
|
|
1270
|
-
let segment_index = 0;
|
|
1271
|
-
for (let i = 0; i < path?.length - 1; i++) {
|
|
1272
|
-
const d = distToSegmentSquared(path[i], path[i + 1], coord);
|
|
1273
|
-
if (d > min_d) continue;
|
|
1274
|
-
|
|
1275
|
-
segment_index = i;
|
|
1276
|
-
min_d = d;
|
|
1277
|
-
}
|
|
1278
|
-
return segment_index;
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
// Returns segment index of discrete logs
|
|
1282
|
-
function getLogSegmentIndex(
|
|
1283
|
-
coord: Position,
|
|
1284
|
-
wells_data: Feature[],
|
|
1285
|
-
log_data: LogCurveDataType,
|
|
1286
|
-
logrun_name: string
|
|
1287
|
-
): number {
|
|
1288
|
-
const trajectory = getLogPath(wells_data, log_data, logrun_name);
|
|
1289
|
-
return getSegmentIndex(coord, trajectory);
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
function getLogProperty(
|
|
1293
|
-
coord: Position,
|
|
1294
|
-
wells_data: Feature[],
|
|
1295
|
-
log_data: LogCurveDataType,
|
|
1296
|
-
logrun_name: string,
|
|
1297
|
-
log_name: string
|
|
1298
|
-
): PropertyDataType | null {
|
|
1299
|
-
if (!log_data.data) return null;
|
|
1300
|
-
|
|
1301
|
-
const segment_index = getLogSegmentIndex(
|
|
1302
|
-
coord,
|
|
1303
|
-
wells_data,
|
|
1304
|
-
log_data,
|
|
1305
|
-
logrun_name
|
|
1306
|
-
);
|
|
1307
|
-
let log_value: number | string = getLogValues(
|
|
1308
|
-
log_data,
|
|
1309
|
-
logrun_name,
|
|
1310
|
-
log_name
|
|
1311
|
-
)[segment_index];
|
|
1312
|
-
|
|
1313
|
-
let dl_attrs: [string, [Color, number]] | undefined = undefined;
|
|
1314
|
-
const dl_metadata = getDiscreteLogMetadata(log_data, log_name)?.objects;
|
|
1315
|
-
if (dl_metadata) {
|
|
1316
|
-
dl_attrs = Object.entries(dl_metadata).find(
|
|
1317
|
-
([, value]) => value[1] == log_value
|
|
1318
|
-
);
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
const log = getLogInfo(log_data, logrun_name, log_name)?.name;
|
|
1322
|
-
const prop_name = log + " " + log_data.header.well;
|
|
1323
|
-
log_value = dl_attrs ? dl_attrs[0] + " (" + log_value + ")" : log_value;
|
|
1324
|
-
|
|
1325
|
-
if (log_value) {
|
|
1326
|
-
const well_object = getWellObjectByName(
|
|
1327
|
-
wells_data,
|
|
1328
|
-
log_data.header.well
|
|
1329
|
-
);
|
|
1330
|
-
return createPropertyData(
|
|
1331
|
-
prop_name,
|
|
1332
|
-
log_value,
|
|
1333
|
-
well_object?.properties?.["color"]
|
|
1334
|
-
);
|
|
1335
|
-
} else return null;
|
|
1336
|
-
}
|
|
1337
|
-
|
|
1338
|
-
// Return data required to build welllayer legend
|
|
1339
|
-
function getLegendData(
|
|
1340
|
-
logs: LogCurveDataType[],
|
|
1341
|
-
wellName: string,
|
|
1342
|
-
logName: string,
|
|
1343
|
-
logColor: string
|
|
1344
|
-
): ContinuousLegendDataType | DiscreteLegendDataType | null {
|
|
1345
|
-
if (!logs) return null;
|
|
1346
|
-
const log = wellName
|
|
1347
|
-
? logs.find((log) => log.header.well == wellName)
|
|
1348
|
-
: logs[0];
|
|
1349
|
-
const logInfo = !log
|
|
1350
|
-
? undefined
|
|
1351
|
-
: getLogInfo(log, log.header.name, logName);
|
|
1352
|
-
const title = "Wells / " + logName;
|
|
1353
|
-
if (log && logInfo?.description == "discrete") {
|
|
1354
|
-
const meta = log["metadata_discrete"];
|
|
1355
|
-
const metadataDiscrete = meta[logName].objects;
|
|
1356
|
-
return {
|
|
1357
|
-
title: title,
|
|
1358
|
-
colorName: logColor,
|
|
1359
|
-
discrete: true,
|
|
1360
|
-
metadata: metadataDiscrete,
|
|
1361
|
-
};
|
|
1362
|
-
} else {
|
|
1363
|
-
const minArray: number[] = [];
|
|
1364
|
-
const maxArray: number[] = [];
|
|
1365
|
-
logs.forEach(function (log: LogCurveDataType) {
|
|
1366
|
-
const logValues = getLogValues(log, log.header.name, logName);
|
|
1367
|
-
minArray.push(Math.min(...logValues));
|
|
1368
|
-
maxArray.push(Math.max(...logValues));
|
|
1369
|
-
});
|
|
1370
|
-
return {
|
|
1371
|
-
title: title,
|
|
1372
|
-
colorName: logColor,
|
|
1373
|
-
discrete: false,
|
|
1374
|
-
valueRange: [Math.min(...minArray), Math.max(...maxArray)],
|
|
1375
|
-
};
|
|
1376
|
-
}
|
|
1377
|
-
}
|