@equinor/esv-intersection 3.1.9 → 4.1.0
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/components/axis.d.ts.map +1 -1
- package/dist/control/ExtendedCurveInterpolator.d.ts.map +1 -1
- package/dist/control/IntersectionReferenceSystem.d.ts.map +1 -1
- package/dist/control/LayerManager.d.ts.map +1 -1
- package/dist/control/MainController.d.ts.map +1 -1
- package/dist/control/ZoomPanHandler.d.ts.map +1 -1
- package/dist/control/overlay.d.ts.map +1 -1
- package/dist/datautils/colortable.d.ts.map +1 -1
- package/dist/datautils/findsample.d.ts.map +1 -1
- package/dist/datautils/picks.d.ts.map +1 -1
- package/dist/datautils/schematicShapeGenerator.d.ts +10 -10
- package/dist/datautils/schematicShapeGenerator.d.ts.map +1 -1
- package/dist/datautils/seismicimage.d.ts.map +1 -1
- package/dist/datautils/surfacedata.d.ts.map +1 -1
- package/dist/datautils/trajectory.d.ts.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +2533 -1570
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/layers/CalloutCanvasLayer.d.ts.map +1 -1
- package/dist/layers/CustomDisplayObjects/ComplexRope.d.ts +2 -3
- package/dist/layers/CustomDisplayObjects/ComplexRope.d.ts.map +1 -1
- package/dist/layers/CustomDisplayObjects/ComplexRopeGeometry.d.ts.map +1 -1
- package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRope.d.ts +3 -4
- package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRope.d.ts.map +1 -1
- package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.d.ts +4 -4
- package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.d.ts.map +1 -1
- package/dist/layers/CustomDisplayObjects/UniformTextureStretchRope.d.ts +3 -4
- package/dist/layers/CustomDisplayObjects/UniformTextureStretchRope.d.ts.map +1 -1
- package/dist/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.d.ts +4 -4
- package/dist/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.d.ts.map +1 -1
- package/dist/layers/GeomodelCanvasLayer.d.ts.map +1 -1
- package/dist/layers/GeomodelLabelsLayer.d.ts.map +1 -1
- package/dist/layers/GeomodelLayerV2.d.ts.map +1 -1
- package/dist/layers/GridLayer.d.ts.map +1 -1
- package/dist/layers/ImageCanvasLayer.d.ts.map +1 -1
- package/dist/layers/ReferenceLineLayer.d.ts.map +1 -1
- package/dist/layers/SchematicLayer.d.ts +6 -6
- package/dist/layers/SchematicLayer.d.ts.map +1 -1
- package/dist/layers/WellborePathLayer.d.ts.map +1 -1
- package/dist/layers/base/CanvasLayer.d.ts.map +1 -1
- package/dist/layers/base/HTMLLayer.d.ts.map +1 -1
- package/dist/layers/base/Layer.d.ts.map +1 -1
- package/dist/layers/base/PixiLayer.d.ts +7 -8
- package/dist/layers/base/PixiLayer.d.ts.map +1 -1
- package/dist/layers/base/SVGLayer.d.ts.map +1 -1
- package/dist/layers/schematicInterfaces.d.ts.map +1 -1
- package/dist/utils/arc-length.d.ts.map +1 -1
- package/dist/utils/root-finder.d.ts.map +1 -1
- package/dist/utils/text.d.ts.map +1 -1
- package/dist/utils/vectorUtils.d.ts +6 -6
- package/dist/utils/vectorUtils.d.ts.map +1 -1
- package/dist/vendor/pixi-dashed-line/index.d.ts +13 -13
- package/dist/vendor/pixi-dashed-line/index.d.ts.map +1 -1
- package/package.json +4 -6
- package/src/components/axis.ts +40 -10
- package/src/control/ExtendedCurveInterpolator.ts +47 -9
- package/src/control/IntersectionReferenceSystem.ts +110 -30
- package/src/control/LayerManager.ts +76 -24
- package/src/control/MainController.ts +37 -8
- package/src/control/ZoomPanHandler.ts +76 -14
- package/src/control/overlay.ts +18 -6
- package/src/datautils/colortable.ts +7 -2
- package/src/datautils/findsample.ts +12 -2
- package/src/datautils/picks.ts +66 -18
- package/src/datautils/schematicShapeGenerator.ts +591 -165
- package/src/datautils/seismicimage.ts +36 -10
- package/src/datautils/surfacedata.ts +119 -40
- package/src/datautils/trajectory.ts +56 -17
- package/src/layers/CalloutCanvasLayer.ts +129 -26
- package/src/layers/CustomDisplayObjects/ComplexRope.ts +11 -13
- package/src/layers/CustomDisplayObjects/ComplexRopeGeometry.ts +14 -13
- package/src/layers/CustomDisplayObjects/FixedWidthSimpleRope.ts +11 -14
- package/src/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.ts +13 -12
- package/src/layers/CustomDisplayObjects/UniformTextureStretchRope.ts +16 -17
- package/src/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.ts +11 -11
- package/src/layers/GeomodelCanvasLayer.ts +10 -3
- package/src/layers/GeomodelLabelsLayer.ts +212 -87
- package/src/layers/GeomodelLayerV2.ts +11 -7
- package/src/layers/GridLayer.ts +14 -3
- package/src/layers/ImageCanvasLayer.ts +17 -3
- package/src/layers/ReferenceLineLayer.ts +31 -9
- package/src/layers/SchematicLayer.ts +533 -173
- package/src/layers/WellborePathLayer.ts +22 -7
- package/src/layers/base/CanvasLayer.ts +18 -4
- package/src/layers/base/HTMLLayer.ts +11 -3
- package/src/layers/base/Layer.ts +10 -2
- package/src/layers/base/PixiLayer.ts +36 -43
- package/src/layers/base/SVGLayer.ts +13 -3
- package/src/layers/schematicInterfaces.ts +16 -6
- package/src/utils/arc-length.ts +31 -5
- package/src/utils/root-finder.ts +32 -4
- package/src/utils/text.ts +34 -7
- package/src/utils/vectorUtils.ts +27 -10
- package/src/vendor/pixi-dashed-line/index.ts +93 -39
|
@@ -16,7 +16,9 @@ export type SeismicInfo = {
|
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
export const getSeismicOptions = (
|
|
19
|
+
export const getSeismicOptions = (
|
|
20
|
+
info: SeismicInfo | null,
|
|
21
|
+
): SeismicCanvasDataOptions => {
|
|
20
22
|
if (!info) {
|
|
21
23
|
return {
|
|
22
24
|
x: 0,
|
|
@@ -40,20 +42,36 @@ export const getSeismicOptions = (info: SeismicInfo | null): SeismicCanvasDataOp
|
|
|
40
42
|
* @param trajectory Wellbore or freehand trajectory
|
|
41
43
|
* @return Key domain and depth information for seismic data
|
|
42
44
|
*/
|
|
43
|
-
export function getSeismicInfo(
|
|
45
|
+
export function getSeismicInfo(
|
|
46
|
+
data: { datapoints: number[][]; yAxisValues: number[] },
|
|
47
|
+
trajectory: number[][],
|
|
48
|
+
): SeismicInfo | null {
|
|
44
49
|
if (!(data && data.datapoints)) {
|
|
45
50
|
return null;
|
|
46
51
|
}
|
|
47
|
-
const minX = trajectory.reduce(
|
|
48
|
-
|
|
52
|
+
const minX = trajectory.reduce(
|
|
53
|
+
(acc: number, val: number[]) => Math.min(acc, val[0]!),
|
|
54
|
+
0,
|
|
55
|
+
);
|
|
56
|
+
const maxX = trajectory.reduce(
|
|
57
|
+
(acc: number, val: number[]) => Math.max(acc, val[0]!),
|
|
58
|
+
0,
|
|
59
|
+
);
|
|
49
60
|
|
|
50
61
|
const minTvdMsl = data.yAxisValues && data.yAxisValues[0]!;
|
|
51
|
-
const maxTvdMsl =
|
|
62
|
+
const maxTvdMsl =
|
|
63
|
+
data.yAxisValues && data.yAxisValues[data.yAxisValues.length - 1]!;
|
|
52
64
|
|
|
53
65
|
// Find value domain
|
|
54
66
|
const dp = data.datapoints || [];
|
|
55
|
-
const min = -dp.reduce(
|
|
56
|
-
|
|
67
|
+
const min = -dp.reduce(
|
|
68
|
+
(val: number, array: number[]) => Math.min(...array, val),
|
|
69
|
+
0,
|
|
70
|
+
);
|
|
71
|
+
const max = dp.reduce(
|
|
72
|
+
(val: number, array: number[]) => Math.max(...array, val),
|
|
73
|
+
0,
|
|
74
|
+
);
|
|
57
75
|
|
|
58
76
|
const absMax = Math.max(Math.abs(min), Math.abs(max));
|
|
59
77
|
|
|
@@ -103,8 +121,14 @@ export async function generateSeismicSliceImage(
|
|
|
103
121
|
}
|
|
104
122
|
const { datapoints: dp } = data;
|
|
105
123
|
|
|
106
|
-
const min =
|
|
107
|
-
|
|
124
|
+
const min =
|
|
125
|
+
options?.seismicMin ||
|
|
126
|
+
options?.seismicRange ||
|
|
127
|
+
dp.reduce((val: number, array: number[]) => Math.min(...array, val), 0);
|
|
128
|
+
const max =
|
|
129
|
+
options?.seismicMax ||
|
|
130
|
+
options?.seismicRange ||
|
|
131
|
+
dp.reduce((val: number, array: number[]) => Math.max(...array, val), 0);
|
|
108
132
|
|
|
109
133
|
const absMax = Math.max(Math.abs(min), Math.abs(max));
|
|
110
134
|
|
|
@@ -131,7 +155,9 @@ export async function generateSeismicSliceImage(
|
|
|
131
155
|
let offset = 0;
|
|
132
156
|
const colorFactor = (colorTableSize - 1) / domain.difference;
|
|
133
157
|
|
|
134
|
-
let pos = options?.isLeftToRight
|
|
158
|
+
let pos = options?.isLeftToRight
|
|
159
|
+
? trajectory[0]?.[0]!
|
|
160
|
+
: trajectory[trajectory.length - 1]?.[0]!;
|
|
135
161
|
|
|
136
162
|
const step = (length / width) * (options?.isLeftToRight ? -1 : 1);
|
|
137
163
|
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { interpolateRgb, quantize } from 'd3-interpolate';
|
|
2
2
|
import { scaleOrdinal } from 'd3-scale';
|
|
3
3
|
import { convertColor } from '../utils/color';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
StratUnit,
|
|
6
|
+
SurfaceMetaAndValues,
|
|
7
|
+
SurfaceLine,
|
|
8
|
+
SurfaceArea,
|
|
9
|
+
SurfaceData,
|
|
10
|
+
} from './interfaces';
|
|
5
11
|
|
|
6
12
|
const TRANSLUCENT_RED = 0x80000000;
|
|
7
13
|
const WHITE = 0xffffffff;
|
|
@@ -48,16 +54,30 @@ interface SurfaceAreaGrouping {
|
|
|
48
54
|
* @param surfaceData - Surfaces meta data with surface values in data section
|
|
49
55
|
* @return Surface areas ready for rendering in geolayer
|
|
50
56
|
*/
|
|
51
|
-
export function generateSurfaceData(
|
|
52
|
-
|
|
57
|
+
export function generateSurfaceData(
|
|
58
|
+
trajectory: number[][],
|
|
59
|
+
stratColumn: StratUnit[],
|
|
60
|
+
surfaceData: SurfaceMetaAndValues[],
|
|
61
|
+
): SurfaceData {
|
|
62
|
+
const filteredSurfaces: SurfaceMetaAndValues[] = surfaceData.filter(
|
|
63
|
+
s => s.data.values,
|
|
64
|
+
);
|
|
53
65
|
const mappedSurfaces = mapSurfaceData(filteredSurfaces);
|
|
54
66
|
|
|
55
67
|
const stratGroups = new Map<string, StratGroup>();
|
|
56
|
-
const stratigraphies = combineSurfacesAndStratColumn(
|
|
68
|
+
const stratigraphies = combineSurfacesAndStratColumn(
|
|
69
|
+
mappedSurfaces,
|
|
70
|
+
stratColumn,
|
|
71
|
+
stratGroups,
|
|
72
|
+
);
|
|
57
73
|
sortStratigraphies(stratigraphies);
|
|
58
74
|
|
|
59
75
|
const lines: SurfaceLine[] = getSurfaceLines(mappedSurfaces, trajectory);
|
|
60
|
-
const surfaceAreas: SurfaceAreaGrouping = generateSurfaceAreas(
|
|
76
|
+
const surfaceAreas: SurfaceAreaGrouping = generateSurfaceAreas(
|
|
77
|
+
trajectory,
|
|
78
|
+
stratigraphies,
|
|
79
|
+
stratColumn,
|
|
80
|
+
);
|
|
61
81
|
|
|
62
82
|
const groups: MappedGroup[] = mapGroups(stratGroups, surfaceAreas);
|
|
63
83
|
const groupAreas: SurfaceArea[] = generateGroupAreas(groups, trajectory);
|
|
@@ -67,7 +87,7 @@ export function generateSurfaceData(trajectory: number[][], stratColumn: StratUn
|
|
|
67
87
|
...groupAreas,
|
|
68
88
|
...Object.values(surfaceAreas)
|
|
69
89
|
.flat()
|
|
70
|
-
.filter(
|
|
90
|
+
.filter(d => !d.exclude),
|
|
71
91
|
];
|
|
72
92
|
|
|
73
93
|
const data = {
|
|
@@ -83,7 +103,10 @@ export function generateSurfaceData(trajectory: number[][], stratColumn: StratUn
|
|
|
83
103
|
* @param mappedSurfaces
|
|
84
104
|
* @param trajectory
|
|
85
105
|
*/
|
|
86
|
-
function getSurfaceLines(
|
|
106
|
+
function getSurfaceLines(
|
|
107
|
+
mappedSurfaces: MappedSurfaces[],
|
|
108
|
+
trajectory: number[][],
|
|
109
|
+
): SurfaceLine[] {
|
|
87
110
|
const lines: SurfaceLine[] = mappedSurfaces
|
|
88
111
|
.filter((d: MappedSurfaces) => d.visualization === 'line')
|
|
89
112
|
.map((l: MappedSurfaces) => ({
|
|
@@ -97,27 +120,40 @@ function getSurfaceLines(mappedSurfaces: MappedSurfaces[], trajectory: number[][
|
|
|
97
120
|
return lines;
|
|
98
121
|
}
|
|
99
122
|
|
|
100
|
-
function generateGroupAreas(
|
|
123
|
+
function generateGroupAreas(
|
|
124
|
+
groups: MappedGroup[],
|
|
125
|
+
trajectory: number[][],
|
|
126
|
+
): SurfaceArea[] {
|
|
101
127
|
const groupAreas = groups.map((g: MappedGroup, i: number) => {
|
|
102
|
-
const next: MappedGroup | null =
|
|
128
|
+
const next: MappedGroup | null =
|
|
129
|
+
i + 1 < groups.length ? groups[i + 1]! : null;
|
|
103
130
|
return {
|
|
104
131
|
id: g.id,
|
|
105
132
|
color: convertColor(g.color),
|
|
106
|
-
data: trajectory.map((p: number[], j: number) => [
|
|
133
|
+
data: trajectory.map((p: number[], j: number) => [
|
|
134
|
+
p[0]!,
|
|
135
|
+
g.top[j]!,
|
|
136
|
+
...(next ? [next.top[j]!] : []),
|
|
137
|
+
]),
|
|
107
138
|
};
|
|
108
139
|
});
|
|
109
140
|
|
|
110
141
|
return groupAreas;
|
|
111
142
|
}
|
|
112
143
|
|
|
113
|
-
function mapGroups(
|
|
144
|
+
function mapGroups(
|
|
145
|
+
stratGroups: Map<string, StratGroup>,
|
|
146
|
+
surfaceAreas: SurfaceAreaGrouping,
|
|
147
|
+
): MappedGroup[] {
|
|
114
148
|
const groups = Array.from(stratGroups.values())
|
|
115
149
|
.sort((a: StratGroup, b: StratGroup) => a.age - b.age)
|
|
116
150
|
.filter((g: StratGroup) => {
|
|
117
151
|
const surfaces = surfaceAreas[g.name];
|
|
118
152
|
const isValid = surfaces && surfaces.length > 0;
|
|
119
153
|
if (!isValid) {
|
|
120
|
-
console.warn(
|
|
154
|
+
console.warn(
|
|
155
|
+
`Intersection surface group '${g.name}' has no valid entries and will be discarded.`,
|
|
156
|
+
);
|
|
121
157
|
}
|
|
122
158
|
return isValid;
|
|
123
159
|
})
|
|
@@ -139,10 +175,14 @@ function combineSurfacesAndStratColumn(
|
|
|
139
175
|
stratColumn: StratUnit[],
|
|
140
176
|
stratGroups: Map<string, StratGroup>,
|
|
141
177
|
): Stratigraphy[] {
|
|
142
|
-
const firstUnit =
|
|
178
|
+
const firstUnit =
|
|
179
|
+
stratColumn && stratColumn.find((d: StratUnit) => d.stratUnitLevel === 1);
|
|
143
180
|
const defaultGroupName: string = firstUnit ? firstUnit.identifier : 'SEABED';
|
|
144
181
|
const stratigrafies = mappedSurfaces
|
|
145
|
-
.filter(
|
|
182
|
+
.filter(
|
|
183
|
+
(d: MappedSurfaces) =>
|
|
184
|
+
d.visualization === 'interval' || d.visualization === 'none',
|
|
185
|
+
)
|
|
146
186
|
.map((s: MappedSurfaces) => {
|
|
147
187
|
const path: StratUnit[] = [];
|
|
148
188
|
const stratUnit = findStratcolumnUnit(stratColumn, s.name, path);
|
|
@@ -201,14 +241,22 @@ function sortStratigraphies(stratigrafies: Stratigraphy[]): void {
|
|
|
201
241
|
* @param {string} unitname
|
|
202
242
|
* @param {[]} path
|
|
203
243
|
*/
|
|
204
|
-
function findStratcolumnUnit(
|
|
205
|
-
|
|
244
|
+
function findStratcolumnUnit(
|
|
245
|
+
units: StratUnit[],
|
|
246
|
+
unitname: string,
|
|
247
|
+
path: StratUnit[] = [],
|
|
248
|
+
): StratUnit | null {
|
|
249
|
+
const unit = units.find(
|
|
250
|
+
(u: StratUnit) => u.identifier.toLowerCase() === unitname.toLowerCase(),
|
|
251
|
+
);
|
|
206
252
|
if (unit) {
|
|
207
253
|
// Build path
|
|
208
254
|
let temp: StratUnit | undefined = unit;
|
|
209
255
|
do {
|
|
210
256
|
path.unshift(temp);
|
|
211
|
-
temp = units.find(
|
|
257
|
+
temp = units.find(
|
|
258
|
+
(u: StratUnit) => u.identifier === temp!.stratUnitParent,
|
|
259
|
+
);
|
|
212
260
|
} while (temp);
|
|
213
261
|
|
|
214
262
|
return unit;
|
|
@@ -247,7 +295,12 @@ const unassignedColorScale = scaleOrdinal<number, string>()
|
|
|
247
295
|
/**
|
|
248
296
|
* Find the best matching base index based on name or by values
|
|
249
297
|
*/
|
|
250
|
-
function findBestMatchingBaseIndex(
|
|
298
|
+
function findBestMatchingBaseIndex(
|
|
299
|
+
top: Stratigraphy,
|
|
300
|
+
index: number,
|
|
301
|
+
surfaces: Stratigraphy[],
|
|
302
|
+
stratColumn: StratUnit[],
|
|
303
|
+
): number | undefined {
|
|
251
304
|
const nextIndex: number = index + 1;
|
|
252
305
|
|
|
253
306
|
if (!surfaces || nextIndex >= surfaces.length) {
|
|
@@ -255,7 +308,10 @@ function findBestMatchingBaseIndex(top: Stratigraphy, index: number, surfaces: S
|
|
|
255
308
|
}
|
|
256
309
|
|
|
257
310
|
// If there is a matching base by name, use that. More robust, does not rely on sorting
|
|
258
|
-
const baseSurfaceIndex = surfaces.findIndex(
|
|
311
|
+
const baseSurfaceIndex = surfaces.findIndex(
|
|
312
|
+
(candidate: Stratigraphy) =>
|
|
313
|
+
candidate.isBase && candidate.name === top.name,
|
|
314
|
+
);
|
|
259
315
|
if (baseSurfaceIndex !== -1) {
|
|
260
316
|
return baseSurfaceIndex;
|
|
261
317
|
}
|
|
@@ -272,38 +328,61 @@ function findBestMatchingBaseIndex(top: Stratigraphy, index: number, surfaces: S
|
|
|
272
328
|
return undefined;
|
|
273
329
|
}
|
|
274
330
|
|
|
275
|
-
function isAnchestor(
|
|
331
|
+
function isAnchestor(
|
|
332
|
+
descendant: Stratigraphy,
|
|
333
|
+
candidate: Stratigraphy,
|
|
334
|
+
stratColumn: StratUnit[],
|
|
335
|
+
): boolean {
|
|
276
336
|
const path: StratUnit[] = [];
|
|
277
337
|
findStratcolumnUnit(stratColumn, descendant.name, path);
|
|
278
338
|
return path.some((p: StratUnit) => candidate.name === p.identifier);
|
|
279
339
|
}
|
|
280
340
|
|
|
281
|
-
function generateSurfaceAreas(
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
341
|
+
function generateSurfaceAreas(
|
|
342
|
+
projection: number[][],
|
|
343
|
+
surfaces: Stratigraphy[],
|
|
344
|
+
stratColumn: StratUnit[],
|
|
345
|
+
): SurfaceAreaGrouping {
|
|
346
|
+
const areas: SurfaceAreaGrouping = surfaces.reduce(
|
|
347
|
+
(acc: SurfaceAreaGrouping, surface: Stratigraphy, i: number) => {
|
|
348
|
+
if (!surface.isBase) {
|
|
349
|
+
if (!acc[surface.group]) {
|
|
350
|
+
acc[surface.group] = [];
|
|
351
|
+
}
|
|
352
|
+
const baseIndex = findBestMatchingBaseIndex(
|
|
353
|
+
surface,
|
|
354
|
+
i,
|
|
355
|
+
surfaces,
|
|
356
|
+
stratColumn,
|
|
357
|
+
);
|
|
358
|
+
acc[surface.group]?.push({
|
|
359
|
+
id: surface.name,
|
|
360
|
+
label: surface.name,
|
|
361
|
+
color: (surface.unit && getColorFromUnit(surface.unit)) || WHITE,
|
|
362
|
+
exclude: surface.visualization === 'none' || !surface.unit,
|
|
363
|
+
data: projection.map((p, j) => {
|
|
364
|
+
const baseValue =
|
|
365
|
+
surface.values[j] != null
|
|
366
|
+
? getBaseValue(baseIndex, surfaces, j)
|
|
367
|
+
: undefined;
|
|
368
|
+
return [p[0]!, surface.values[j]!, baseValue!];
|
|
369
|
+
}),
|
|
370
|
+
});
|
|
286
371
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
color: (surface.unit && getColorFromUnit(surface.unit)) || WHITE,
|
|
292
|
-
exclude: surface.visualization === 'none' || !surface.unit,
|
|
293
|
-
data: projection.map((p, j) => {
|
|
294
|
-
const baseValue = surface.values[j] != null ? getBaseValue(baseIndex, surfaces, j) : undefined;
|
|
295
|
-
return [p[0]!, surface.values[j]!, baseValue!];
|
|
296
|
-
}),
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
return acc;
|
|
300
|
-
}, {});
|
|
372
|
+
return acc;
|
|
373
|
+
},
|
|
374
|
+
{},
|
|
375
|
+
);
|
|
301
376
|
return areas;
|
|
302
377
|
}
|
|
303
378
|
|
|
304
379
|
// get the value from the surface with the supplied index,
|
|
305
380
|
// iterate to next surface if value is null
|
|
306
|
-
function getBaseValue(
|
|
381
|
+
function getBaseValue(
|
|
382
|
+
index: number | undefined,
|
|
383
|
+
surfaces: Stratigraphy[],
|
|
384
|
+
datapoint: number,
|
|
385
|
+
): number | undefined {
|
|
307
386
|
if (!surfaces || !index || index >= surfaces.length) {
|
|
308
387
|
return undefined;
|
|
309
388
|
}
|
|
@@ -15,12 +15,16 @@ const pathSteps = 10;
|
|
|
15
15
|
* Code originally developed for REP
|
|
16
16
|
* @param {[]} poslog Position log from SMDA
|
|
17
17
|
*/
|
|
18
|
-
export function generateProjectedWellborePath(
|
|
18
|
+
export function generateProjectedWellborePath(
|
|
19
|
+
poslog: SurveySample[],
|
|
20
|
+
): [number, number][] {
|
|
19
21
|
if (!poslog || poslog.length === 0) {
|
|
20
22
|
return [];
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
const points: [number, number, number, number][] = poslog
|
|
25
|
+
const points: [number, number, number, number][] = poslog
|
|
26
|
+
? poslog.map((p: SurveySample) => [p.easting, p.northing, p.tvd, p.md])
|
|
27
|
+
: [];
|
|
24
28
|
|
|
25
29
|
const projection = simplify(projectCurtain(points));
|
|
26
30
|
const offset = projection[projection.length - 1]?.[0];
|
|
@@ -40,14 +44,22 @@ export function generateProjectedWellborePath(poslog: SurveySample[]): [number,
|
|
|
40
44
|
* @param {[]} poslog Position log from SMDA
|
|
41
45
|
* @param {number} defaultIntersectionAngle Default intersection angle for the field
|
|
42
46
|
*/
|
|
43
|
-
export function generateProjectedTrajectory(
|
|
47
|
+
export function generateProjectedTrajectory(
|
|
48
|
+
poslog: SurveySample[],
|
|
49
|
+
defaultIntersectionAngle: number,
|
|
50
|
+
): number[][] {
|
|
44
51
|
if (!poslog || poslog.length === 0) {
|
|
45
52
|
return [];
|
|
46
53
|
}
|
|
47
54
|
|
|
48
|
-
const points: [number, number, number, number][] = poslog
|
|
55
|
+
const points: [number, number, number, number][] = poslog
|
|
56
|
+
? poslog.map(p => [p.easting, p.northing, p.tvd, p.md])
|
|
57
|
+
: [];
|
|
49
58
|
|
|
50
|
-
const interpolator: CurveInterpolator = new CurveInterpolator(points, {
|
|
59
|
+
const interpolator: CurveInterpolator = new CurveInterpolator(points, {
|
|
60
|
+
tension: 0.75,
|
|
61
|
+
arcDivisions: 5000,
|
|
62
|
+
});
|
|
51
63
|
const displacement: number = interpolator.length;
|
|
52
64
|
|
|
53
65
|
const nPoints: number = Math.round(displacement * pathSteps);
|
|
@@ -67,12 +79,19 @@ export function generateProjectedTrajectory(poslog: SurveySample[], defaultInter
|
|
|
67
79
|
|
|
68
80
|
if (relativeDist < thresholdRelativeDist) {
|
|
69
81
|
const oneEighty = 180;
|
|
70
|
-
const radCurtainDirection =
|
|
71
|
-
|
|
82
|
+
const radCurtainDirection =
|
|
83
|
+
(defaultIntersectionAngle / oneEighty) * Math.PI;
|
|
84
|
+
v = new Vector2(
|
|
85
|
+
Math.cos(radCurtainDirection),
|
|
86
|
+
Math.sin(radCurtainDirection),
|
|
87
|
+
).mutable;
|
|
72
88
|
} else {
|
|
73
89
|
v = getDirectionVector(path, thresholdDirectionDist);
|
|
74
90
|
}
|
|
75
|
-
const extensionLengthStart: number = Math.max(
|
|
91
|
+
const extensionLengthStart: number = Math.max(
|
|
92
|
+
0,
|
|
93
|
+
extensionLength - displacement,
|
|
94
|
+
);
|
|
76
95
|
const offset: number = extensionLengthStart + displacement;
|
|
77
96
|
const trajectory: [number, number][] = [];
|
|
78
97
|
|
|
@@ -83,7 +102,7 @@ export function generateProjectedTrajectory(poslog: SurveySample[], defaultInter
|
|
|
83
102
|
|
|
84
103
|
if (extensionLengthStart > 0) {
|
|
85
104
|
// extend from start
|
|
86
|
-
firstPoints = seqI(Math.ceil(extensionLengthStart * stepSize)).map(
|
|
105
|
+
firstPoints = seqI(Math.ceil(extensionLengthStart * stepSize)).map(t =>
|
|
87
106
|
v
|
|
88
107
|
.set(initial)
|
|
89
108
|
.scale(extensionLengthStart * (1 - t))
|
|
@@ -96,7 +115,7 @@ export function generateProjectedTrajectory(poslog: SurveySample[], defaultInter
|
|
|
96
115
|
trajectory.push(...path);
|
|
97
116
|
|
|
98
117
|
const endPoints = seqI(Math.ceil(extensionLength * stepSize))
|
|
99
|
-
.map(
|
|
118
|
+
.map(t =>
|
|
100
119
|
v
|
|
101
120
|
.set(initial)
|
|
102
121
|
.scale(extensionLength * t)
|
|
@@ -107,7 +126,11 @@ export function generateProjectedTrajectory(poslog: SurveySample[], defaultInter
|
|
|
107
126
|
|
|
108
127
|
trajectory.push(...endPoints);
|
|
109
128
|
|
|
110
|
-
const projectedTrajectory: number[][] = projectCurtain(
|
|
129
|
+
const projectedTrajectory: number[][] = projectCurtain(
|
|
130
|
+
trajectory,
|
|
131
|
+
undefined,
|
|
132
|
+
offset,
|
|
133
|
+
);
|
|
111
134
|
|
|
112
135
|
return projectedTrajectory;
|
|
113
136
|
}
|
|
@@ -154,12 +177,16 @@ function getDirectionVector(path: number[][], threshold: number): Vector2 {
|
|
|
154
177
|
*
|
|
155
178
|
* @return {Number[]} Simplified array
|
|
156
179
|
*/
|
|
157
|
-
function simplify(
|
|
180
|
+
function simplify(
|
|
181
|
+
inputArr: [number, number][],
|
|
182
|
+
maxOffset = 0.001,
|
|
183
|
+
maxDistance = 10,
|
|
184
|
+
): [number, number][] {
|
|
158
185
|
if (inputArr.length <= 4) {
|
|
159
186
|
return inputArr;
|
|
160
187
|
}
|
|
161
188
|
const [o0, o1] = inputArr[0]!;
|
|
162
|
-
const arr = inputArr.map<[number, number]>(
|
|
189
|
+
const arr = inputArr.map<[number, number]>(d => [d[0]! - o0, d[1]! - o1]);
|
|
163
190
|
let [a0, a1] = arr[0]!;
|
|
164
191
|
const sim = [inputArr[0]!];
|
|
165
192
|
|
|
@@ -168,9 +195,17 @@ function simplify(inputArr: [number, number][], maxOffset = 0.001, maxDistance =
|
|
|
168
195
|
const [b0, b1] = arr[i + 1] ?? [];
|
|
169
196
|
|
|
170
197
|
// If t->b vector is NOT [0, 0]
|
|
171
|
-
if (
|
|
198
|
+
if (
|
|
199
|
+
t0 != null &&
|
|
200
|
+
t1 != null &&
|
|
201
|
+
b0 != null &&
|
|
202
|
+
b1 != null &&
|
|
203
|
+
(b0 - t0 !== 0 || b1 - t1 !== 0)
|
|
204
|
+
) {
|
|
172
205
|
// Proximity check
|
|
173
|
-
const proximity: number =
|
|
206
|
+
const proximity: number =
|
|
207
|
+
Math.abs(a0 * b1 - a1 * b0 + b0 * t1 - b1 * t0 + a1 * t0 - a0 * t1) /
|
|
208
|
+
Math.sqrt((b0 - a0) ** 2 + (b1 - a1) ** 2);
|
|
174
209
|
|
|
175
210
|
const dir: [number, number] = [a0 - t0, a1 - t1];
|
|
176
211
|
const len: number = Math.sqrt(dir[0] ** 2 + dir[1] ** 2);
|
|
@@ -194,10 +229,14 @@ function simplify(inputArr: [number, number][], maxOffset = 0.001, maxDistance =
|
|
|
194
229
|
* @param offset
|
|
195
230
|
* @returns {array}
|
|
196
231
|
*/
|
|
197
|
-
function projectCurtain(
|
|
232
|
+
function projectCurtain(
|
|
233
|
+
points: [number, number, ...number[]][],
|
|
234
|
+
origin?: [number, number, number, number],
|
|
235
|
+
offset = 0,
|
|
236
|
+
): [number, number][] {
|
|
198
237
|
let p0 = origin || points[0]!;
|
|
199
238
|
let l = 0;
|
|
200
|
-
const projected = points.map<[number, number]>(
|
|
239
|
+
const projected = points.map<[number, number]>(p1 => {
|
|
201
240
|
const dx = p1[0] - p0[0];
|
|
202
241
|
const dy = p1[1] - p0[1];
|
|
203
242
|
l += Math.sqrt(dx ** 2 + dy ** 2);
|