@equinor/esv-intersection 3.0.3 → 3.0.4

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 (109) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.mjs +1 -2
  4. package/dist/index.mjs.map +1 -1
  5. package/dist/index.umd.js +1 -1
  6. package/dist/index.umd.js.map +1 -1
  7. package/package.json +11 -11
  8. package/dist/components/axis.d.ts +0 -47
  9. package/dist/components/index.d.ts +0 -1
  10. package/dist/control/ExtendedCurveInterpolator.d.ts +0 -58
  11. package/dist/control/IntersectionReferenceSystem.d.ts +0 -96
  12. package/dist/control/LayerManager.d.ts +0 -76
  13. package/dist/control/MainController.d.ts +0 -154
  14. package/dist/control/ZoomPanHandler.d.ts +0 -158
  15. package/dist/control/index.d.ts +0 -5
  16. package/dist/control/interfaces.d.ts +0 -37
  17. package/dist/control/overlay.d.ts +0 -20
  18. package/dist/datautils/colortable.d.ts +0 -1
  19. package/dist/datautils/findsample.d.ts +0 -2
  20. package/dist/datautils/index.d.ts +0 -6
  21. package/dist/datautils/interfaces.d.ts +0 -63
  22. package/dist/datautils/picks.d.ts +0 -74
  23. package/dist/datautils/schematicShapeGenerator.d.ts +0 -59
  24. package/dist/datautils/seismicimage.d.ts +0 -45
  25. package/dist/datautils/surfacedata.d.ts +0 -10
  26. package/dist/datautils/trajectory.d.ts +0 -14
  27. package/dist/layers/CalloutCanvasLayer.d.ts +0 -60
  28. package/dist/layers/CustomDisplayObjects/ComplexRope.d.ts +0 -22
  29. package/dist/layers/CustomDisplayObjects/ComplexRopeGeometry.d.ts +0 -27
  30. package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRope.d.ts +0 -20
  31. package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.d.ts +0 -26
  32. package/dist/layers/CustomDisplayObjects/UniformTextureStretchRope.d.ts +0 -17
  33. package/dist/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.d.ts +0 -24
  34. package/dist/layers/GeomodelCanvasLayer.d.ts +0 -28
  35. package/dist/layers/GeomodelLabelsLayer.d.ts +0 -49
  36. package/dist/layers/GeomodelLayerV2.d.ts +0 -12
  37. package/dist/layers/GridLayer.d.ts +0 -29
  38. package/dist/layers/ImageCanvasLayer.d.ts +0 -20
  39. package/dist/layers/ReferenceLineLayer.d.ts +0 -29
  40. package/dist/layers/SchematicLayer.d.ts +0 -113
  41. package/dist/layers/SeismicCanvasLayer.d.ts +0 -18
  42. package/dist/layers/WellborePathLayer.d.ts +0 -17
  43. package/dist/layers/base/CanvasLayer.d.ts +0 -19
  44. package/dist/layers/base/HTMLLayer.d.ts +0 -13
  45. package/dist/layers/base/Layer.d.ts +0 -69
  46. package/dist/layers/base/PixiLayer.d.ts +0 -32
  47. package/dist/layers/base/SVGLayer.d.ts +0 -13
  48. package/dist/layers/base/index.d.ts +0 -5
  49. package/dist/layers/index.d.ts +0 -16
  50. package/dist/layers/schematicInterfaces.d.ts +0 -209
  51. package/dist/utils/arc-length.d.ts +0 -23
  52. package/dist/utils/binary-search.d.ts +0 -8
  53. package/dist/utils/color.d.ts +0 -5
  54. package/dist/utils/index.d.ts +0 -1
  55. package/dist/utils/root-finder.d.ts +0 -34
  56. package/dist/utils/text.d.ts +0 -14
  57. package/dist/utils/vectorUtils.d.ts +0 -15
  58. package/dist/vendor/pixi-dashed-line/index.d.ts +0 -57
  59. package/src/components/axis.ts +0 -247
  60. package/src/components/index.ts +0 -1
  61. package/src/control/ExtendedCurveInterpolator.ts +0 -155
  62. package/src/control/IntersectionReferenceSystem.ts +0 -391
  63. package/src/control/LayerManager.ts +0 -294
  64. package/src/control/MainController.ts +0 -296
  65. package/src/control/ZoomPanHandler.ts +0 -436
  66. package/src/control/index.ts +0 -5
  67. package/src/control/interfaces.ts +0 -42
  68. package/src/control/overlay.ts +0 -118
  69. package/src/datautils/colortable.ts +0 -14
  70. package/src/datautils/findsample.ts +0 -64
  71. package/src/datautils/index.ts +0 -6
  72. package/src/datautils/interfaces.ts +0 -68
  73. package/src/datautils/picks.ts +0 -328
  74. package/src/datautils/schematicShapeGenerator.ts +0 -1008
  75. package/src/datautils/seismicimage.ts +0 -180
  76. package/src/datautils/surfacedata.ts +0 -318
  77. package/src/datautils/trajectory.ts +0 -206
  78. package/src/layers/CalloutCanvasLayer.ts +0 -338
  79. package/src/layers/CustomDisplayObjects/ComplexRope.ts +0 -45
  80. package/src/layers/CustomDisplayObjects/ComplexRopeGeometry.ts +0 -190
  81. package/src/layers/CustomDisplayObjects/FixedWidthSimpleRope.ts +0 -41
  82. package/src/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.ts +0 -149
  83. package/src/layers/CustomDisplayObjects/UniformTextureStretchRope.ts +0 -39
  84. package/src/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.ts +0 -174
  85. package/src/layers/GeomodelCanvasLayer.ts +0 -176
  86. package/src/layers/GeomodelLabelsLayer.ts +0 -619
  87. package/src/layers/GeomodelLayerV2.ts +0 -110
  88. package/src/layers/GridLayer.ts +0 -145
  89. package/src/layers/ImageCanvasLayer.ts +0 -55
  90. package/src/layers/ReferenceLineLayer.ts +0 -185
  91. package/src/layers/SchematicLayer.ts +0 -872
  92. package/src/layers/SeismicCanvasLayer.ts +0 -46
  93. package/src/layers/WellborePathLayer.ts +0 -129
  94. package/src/layers/base/CanvasLayer.ts +0 -102
  95. package/src/layers/base/HTMLLayer.ts +0 -70
  96. package/src/layers/base/Layer.ts +0 -217
  97. package/src/layers/base/PixiLayer.ts +0 -190
  98. package/src/layers/base/SVGLayer.ts +0 -63
  99. package/src/layers/base/index.ts +0 -5
  100. package/src/layers/index.ts +0 -16
  101. package/src/layers/schematicInterfaces.ts +0 -472
  102. package/src/utils/arc-length.ts +0 -66
  103. package/src/utils/binary-search.ts +0 -26
  104. package/src/utils/color.ts +0 -22
  105. package/src/utils/index.ts +0 -1
  106. package/src/utils/root-finder.ts +0 -78
  107. package/src/utils/text.ts +0 -88
  108. package/src/utils/vectorUtils.ts +0 -67
  109. package/src/vendor/pixi-dashed-line/index.ts +0 -394
@@ -1,180 +0,0 @@
1
- import { clamp } from '@equinor/videx-math';
2
- import { SeismicCanvasDataOptions } from '../layers/SeismicCanvasLayer';
3
-
4
- import { createColorTable } from './colortable';
5
- import { findIndexOfSample } from './findsample';
6
-
7
- export type SeismicInfo = {
8
- minX: number;
9
- maxX: number;
10
- minTvdMsl: number;
11
- maxTvdMsl: number;
12
- domain: {
13
- min: number;
14
- max: number;
15
- difference: number;
16
- };
17
- };
18
-
19
- export const getSeismicOptions = (info: SeismicInfo | null): SeismicCanvasDataOptions => {
20
- if (!info) {
21
- return {
22
- x: 0,
23
- y: 0,
24
- width: 0,
25
- height: 0,
26
- };
27
- }
28
- return {
29
- x: info.minX,
30
- y: info.minTvdMsl,
31
- width: info.maxX - info.minX,
32
- height: info.maxTvdMsl - info.minTvdMsl,
33
- };
34
- };
35
-
36
- /**
37
- * Get key information about the seismic data
38
- * Code originally developed for the REP project
39
- * @param data Seismic data
40
- * @param trajectory Wellbore or freehand trajectory
41
- * @return Key domain and depth information for seismic data
42
- */
43
- export function getSeismicInfo(data: { datapoints: number[][]; yAxisValues: number[] }, trajectory: number[][]): SeismicInfo | null {
44
- if (!(data && data.datapoints)) {
45
- return null;
46
- }
47
- const minX = trajectory.reduce((acc: number, val: number[]) => Math.min(acc, val[0]), 0);
48
- const maxX = trajectory.reduce((acc: number, val: number[]) => Math.max(acc, val[0]), 0);
49
-
50
- const minTvdMsl = data.yAxisValues && data.yAxisValues[0];
51
- const maxTvdMsl = data.yAxisValues && data.yAxisValues[data.yAxisValues.length - 1];
52
-
53
- // Find value domain
54
- const dp = data.datapoints || [];
55
- const min = -dp.reduce((val: number, array: number[]) => Math.min(...array, val), 0);
56
- const max = dp.reduce((val: number, array: number[]) => Math.max(...array, val), 0);
57
-
58
- const absMax = Math.max(Math.abs(min), Math.abs(max));
59
-
60
- const dmin = -absMax;
61
- const dmax = absMax;
62
-
63
- const info = {
64
- minX,
65
- maxX,
66
- minTvdMsl,
67
- maxTvdMsl,
68
- domain: {
69
- min: dmin,
70
- max: dmax,
71
- difference: dmax - dmin,
72
- },
73
- };
74
-
75
- return info;
76
- }
77
-
78
- /**
79
- * Generate seismic
80
- * Code originally developed for the REP project
81
- * @param data Seismic data
82
- * @param trajectory Wellbore or freehand trajectory
83
- * @param colormap Color map for rendering
84
- * @param options.isLeftToRight (optional) draw left to right
85
- * @param options.seismicRange (optional) Range for mapping seimic values to color map
86
- * @param options.seismicMin (optional) Min seismic value for mapping seimic values to color map
87
- * @param options.seismicMax (optional) Max seismic value for mapping seimic values to color map
88
- * @return Key domain and depth information for seismic data
89
- */
90
- export async function generateSeismicSliceImage(
91
- data: { datapoints: number[][]; yAxisValues: number[] },
92
- trajectory: number[][],
93
- colormap: string[],
94
- options?: {
95
- isLeftToRight: true;
96
- seismicRange?: number;
97
- seismicMin?: number;
98
- seismicMax?: number;
99
- },
100
- ): Promise<ImageBitmap> {
101
- if (!(data && data.datapoints && data.datapoints.length > 0)) {
102
- return;
103
- }
104
- const { datapoints: dp } = data;
105
-
106
- const min = options?.seismicMin || options?.seismicRange || dp.reduce((val: number, array: number[]) => Math.min(...array, val), 0);
107
- const max = options?.seismicMax || options?.seismicRange || dp.reduce((val: number, array: number[]) => Math.max(...array, val), 0);
108
-
109
- const absMax = Math.max(Math.abs(min), Math.abs(max));
110
-
111
- const dmin = -absMax;
112
- const dmax = absMax;
113
-
114
- const domain = {
115
- min: dmin,
116
- max: dmax,
117
- difference: dmax - dmin,
118
- };
119
-
120
- const length = trajectory[0][0] - trajectory[trajectory.length - 1][0];
121
- // eslint-disable-next-line no-magic-numbers
122
- const width = Math.abs(Math.floor(length / 5));
123
- const height = data.yAxisValues.length;
124
-
125
- // Generate color table
126
- const colorTableSize = 1000;
127
- const colorTable = createColorTable(colormap, colorTableSize);
128
-
129
- // Generate image
130
- const d = new Uint8ClampedArray(width * height * 4);
131
-
132
- let offset = 0;
133
- const colorFactor = (colorTableSize - 1) / domain.difference;
134
-
135
- let pos = options?.isLeftToRight ? trajectory[0][0] : trajectory[trajectory.length - 1][0];
136
-
137
- const step = (length / width) * (options?.isLeftToRight ? -1 : 1);
138
-
139
- let val1;
140
- let val2;
141
- let val;
142
- let i;
143
- let col: number[];
144
- const black = [0, 0, 0];
145
- let opacity;
146
-
147
- for (let x = 0; x < width; x++) {
148
- offset = x * 4;
149
- const index = findIndexOfSample(trajectory, pos);
150
- const x1 = trajectory[index][0];
151
- const x2 = trajectory[index + 1][0];
152
- const span = x2 - x1;
153
- const dx = pos - x1;
154
- const ratio = dx / span;
155
-
156
- for (let y = 0; y < height; y++) {
157
- val1 = dp[y][index];
158
- val2 = dp[y][index + 1];
159
- if (val1 == null || val2 == null) {
160
- col = black;
161
- opacity = 0;
162
- } else {
163
- val = val1 * (1 - ratio) + val2 * ratio;
164
- i = (val - domain.min) * colorFactor;
165
- i = clamp(~~i, 0, colorTableSize - 1);
166
- col = colorTable[i];
167
- opacity = 255;
168
- }
169
-
170
- d.set([col[0], col[1], col[2], opacity], offset);
171
-
172
- offset += width * 4;
173
- }
174
- pos += step;
175
- }
176
- const imageData = new ImageData(d, width, height);
177
- const image = await createImageBitmap(imageData, 0, 0, width, height);
178
-
179
- return image;
180
- }
@@ -1,318 +0,0 @@
1
- import { interpolateRgb, quantize } from 'd3-interpolate';
2
- import { scaleOrdinal } from 'd3-scale';
3
- import { convertColor } from '../utils/color';
4
- import { StratUnit, SurfaceMetaAndValues, SurfaceLine, SurfaceArea, SurfaceData } from './interfaces';
5
-
6
- const TRANSLUCENT_RED = 0x80000000;
7
- const WHITE = 0xffffffff;
8
-
9
- type MappedSurfaces = {
10
- name: string;
11
- isBase: boolean;
12
- values: number[];
13
- color: string;
14
- visualization: string;
15
- };
16
-
17
- type StratGroup = {
18
- age: number;
19
- name: string;
20
- };
21
-
22
- type Stratigraphy = {
23
- unit: StratUnit;
24
- group: string;
25
- name: string;
26
- isBase: boolean;
27
- values: number[];
28
- color: string;
29
- visualization: string;
30
- };
31
-
32
- type MappedGroup = {
33
- id: string;
34
- label: string;
35
- color: string;
36
- top: number[];
37
- };
38
-
39
- interface SurfaceAreaGrouping {
40
- [propType: string]: SurfaceArea[];
41
- }
42
-
43
- /**
44
- * Generate surface data from trajectory, stratcolum and surface data
45
- * Code originally developed for the REP project
46
- * @param trajectory Projected trajectory generated from the poslog used when retrieving surface data from surface API
47
- * @param stratColumn Strat columnd from SMDA
48
- * @param surfaceData - Surfaces meta data with surface values in data section
49
- * @return Surface areas ready for rendering in geolayer
50
- */
51
- export function generateSurfaceData(trajectory: number[][], stratColumn: StratUnit[], surfaceData: SurfaceMetaAndValues[]): SurfaceData {
52
- const filteredSurfaces: SurfaceMetaAndValues[] = surfaceData.filter((s) => s.data.values);
53
- const mappedSurfaces = mapSurfaceData(filteredSurfaces);
54
-
55
- const stratGroups = new Map<string, StratGroup>();
56
- const stratigraphies = combineSurfacesAndStratColumn(mappedSurfaces, stratColumn, stratGroups);
57
- sortStratigraphies(stratigraphies);
58
-
59
- const lines: SurfaceLine[] = getSurfaceLines(mappedSurfaces, trajectory);
60
- const surfaceAreas: SurfaceAreaGrouping = generateSurfaceAreas(trajectory, stratigraphies, stratColumn);
61
-
62
- const groups: MappedGroup[] = mapGroups(stratGroups, surfaceAreas);
63
- const groupAreas: SurfaceArea[] = generateGroupAreas(groups, trajectory);
64
-
65
- //Combine group areas with surface areas
66
- const areas: SurfaceArea[] = [
67
- ...groupAreas,
68
- ...Object.values(surfaceAreas)
69
- .flat()
70
- .filter((d) => !d.exclude),
71
- ];
72
-
73
- const data = {
74
- lines,
75
- areas,
76
- };
77
-
78
- return data;
79
- }
80
-
81
- /**
82
- * Get surfaces which should be rendered as lines
83
- * @param mappedSurfaces
84
- * @param trajectory
85
- */
86
- function getSurfaceLines(mappedSurfaces: MappedSurfaces[], trajectory: number[][]): SurfaceLine[] {
87
- const lines: SurfaceLine[] = mappedSurfaces
88
- .filter((d: MappedSurfaces) => d.visualization === 'line')
89
- .map((l: MappedSurfaces) => ({
90
- id: l.name,
91
- label: l.name,
92
- width: 2,
93
- color: convertColor(l.color || 'black'),
94
- data: trajectory.map((p, j) => [p[0], l.values[j]]),
95
- }));
96
-
97
- return lines;
98
- }
99
-
100
- function generateGroupAreas(groups: MappedGroup[], trajectory: number[][]): SurfaceArea[] {
101
- const groupAreas = groups.map((g: MappedGroup, i: number) => {
102
- const next: MappedGroup | null = i + 1 < groups.length ? groups[i + 1] : null;
103
- return {
104
- id: g.id,
105
- label: g.label,
106
- color: convertColor(g.color),
107
- data: trajectory.map((p: number[], j: number) => [p[0], g.top[j], next ? next.top[j] : null]),
108
- };
109
- });
110
- return groupAreas;
111
- }
112
-
113
- function mapGroups(stratGroups: Map<string, StratGroup>, surfaceAreas: SurfaceAreaGrouping): MappedGroup[] {
114
- const groups = Array.from(stratGroups.values())
115
- .sort((a: StratGroup, b: StratGroup) => a.age - b.age)
116
- .filter((g: StratGroup) => {
117
- const surfaces: SurfaceArea[] = surfaceAreas[g.name];
118
- const isValid = surfaces && surfaces.length > 0;
119
- if (!isValid) {
120
- console.warn(`Intersection surface group '${g.name}' has no valid entries and will be discarded.`);
121
- }
122
- return isValid;
123
- })
124
- .map((g: StratGroup, i: number) => {
125
- const surface: SurfaceArea[] = surfaceAreas[g.name];
126
- const top = surface[0];
127
- return {
128
- id: g.name,
129
- label: g.name,
130
- color: unassignedColorScale(i),
131
- top: top.data.map((d: number[]) => d[1]),
132
- };
133
- });
134
- return groups;
135
- }
136
-
137
- function combineSurfacesAndStratColumn(
138
- mappedSurfaces: MappedSurfaces[],
139
- stratColumn: StratUnit[],
140
- stratGroups: Map<string, StratGroup>,
141
- ): Stratigraphy[] {
142
- const firstUnit = stratColumn && stratColumn.find((d: StratUnit) => d.stratUnitLevel === 1);
143
- const defaultGroupName: string = firstUnit ? firstUnit.identifier : 'SEABED';
144
- const stratigrafies = mappedSurfaces
145
- .filter((d: MappedSurfaces) => d.visualization === 'interval' || d.visualization === 'none')
146
- .map((s: MappedSurfaces) => {
147
- const path: StratUnit[] = [];
148
- const stratUnit: StratUnit = findStratcolumnUnit(stratColumn, s.name, path);
149
- if (!stratUnit) {
150
- console.warn(`No match for ${s.name} in strat column`);
151
- }
152
- const group: StratUnit = path[0] || stratUnit;
153
- const groupName: string = (group && group.identifier) || defaultGroupName;
154
- if (group && !stratGroups.has(groupName)) {
155
- stratGroups.set(groupName, {
156
- age: group.topAge,
157
- name: group.identifier,
158
- });
159
- }
160
- return {
161
- ...s,
162
- unit: stratUnit,
163
- group: groupName,
164
- };
165
- });
166
- return stratigrafies;
167
- }
168
-
169
- /**
170
- * Sort stratigrafies on unit and age, base after top and higher level after lower
171
- * @param stratigrafies
172
- */
173
- function sortStratigraphies(stratigrafies: Stratigraphy[]): void {
174
- stratigrafies.sort((a: Stratigraphy, b: Stratigraphy) => {
175
- if (!a.unit && !b.unit) {
176
- return 0;
177
- }
178
- if (!a.unit) {
179
- return -1;
180
- }
181
- if (!b.unit) {
182
- return 1;
183
- }
184
- const aAge = a.isBase ? a.unit.baseAge : a.unit.topAge;
185
- const bAge = b.isBase ? b.unit.baseAge : b.unit.topAge;
186
- if (aAge !== bAge) {
187
- return aAge - bAge;
188
- }
189
- if (a.isBase && !b.isBase) {
190
- return 1;
191
- }
192
- if (!a.isBase && b.isBase) {
193
- return -1;
194
- }
195
- return a.unit.stratUnitLevel - b.unit.stratUnitLevel;
196
- });
197
- }
198
-
199
- /**
200
- * @param {[]} units
201
- * @param {string} unitname
202
- * @param {[]} path
203
- */
204
- function findStratcolumnUnit(units: StratUnit[], unitname: string, path: StratUnit[] = []): StratUnit | null {
205
- const unit: StratUnit = units.find((u: StratUnit) => u.identifier.toLowerCase() === unitname.toLowerCase());
206
- if (unit) {
207
- // Build path
208
- let temp: StratUnit = unit;
209
- do {
210
- path.unshift(temp);
211
- temp = units.find((u: StratUnit) => u.identifier === temp.stratUnitParent);
212
- } while (temp);
213
-
214
- return unit;
215
- }
216
- return null;
217
- }
218
-
219
- function mapSurfaceData(surfaces: SurfaceMetaAndValues[]): MappedSurfaces[] {
220
- return surfaces.map((s: SurfaceMetaAndValues) => {
221
- const displayName: string = s.visualSettings.displayName;
222
- const name: string = displayName.replace(/\s(Base|Top)/gi, '');
223
- const isBase: boolean = displayName.toLowerCase().endsWith('base');
224
-
225
- return {
226
- name,
227
- isBase,
228
- values: s.data.values,
229
- color: s.visualSettings.colors.crossSection,
230
- visualization: s.visualSettings.crossSection.toLowerCase(),
231
- };
232
- });
233
- }
234
-
235
- function getColorFromUnit(unit: StratUnit): number {
236
- if (unit.colorR === null || unit.colorG === null || unit.colorB === null) {
237
- return TRANSLUCENT_RED;
238
- }
239
- const res: number = (unit.colorR << 16) | (unit.colorG << 8) | unit.colorB;
240
- return res;
241
- }
242
-
243
- const unassignedColorScale = scaleOrdinal<number, string>()
244
- .domain([0, 100])
245
- // eslint-disable-next-line no-magic-numbers
246
- .range(quantize(interpolateRgb('#e6f1cf', '#85906d'), 10));
247
-
248
- /**
249
- * Find the best matching base index based on name or by values
250
- */
251
- function findBestMatchingBaseIndex(top: Stratigraphy, index: number, surfaces: Stratigraphy[], stratColumn: StratUnit[]): number {
252
- const nextIndex: number = index + 1;
253
-
254
- if (!surfaces || nextIndex >= surfaces.length) {
255
- return null;
256
- }
257
-
258
- // If there is a matching base by name, use that. More robust, does not rely on sorting
259
- const baseSurfaceIndex = surfaces.findIndex((candidate: Stratigraphy) => candidate.isBase && candidate.name === top.name);
260
- if (baseSurfaceIndex !== -1) {
261
- return baseSurfaceIndex;
262
- }
263
-
264
- for (let i = nextIndex; i < surfaces.length; i++) {
265
- const candidate = surfaces[i];
266
- if (!candidate.isBase) {
267
- return i;
268
- }
269
- if (isAnchestor(top, candidate, stratColumn)) {
270
- return i;
271
- }
272
- }
273
- return null;
274
- }
275
-
276
- function isAnchestor(descendant: Stratigraphy, candidate: Stratigraphy, stratColumn: StratUnit[]): boolean {
277
- const path: StratUnit[] = [];
278
- findStratcolumnUnit(stratColumn, descendant.name, path);
279
- return path.some((p: StratUnit) => candidate.name === p.identifier);
280
- }
281
-
282
- function generateSurfaceAreas(projection: number[][], surfaces: Stratigraphy[], stratColumn: StratUnit[]): SurfaceAreaGrouping {
283
- const areas: SurfaceAreaGrouping = surfaces.reduce((acc: SurfaceAreaGrouping, surface: Stratigraphy, i: number) => {
284
- if (!surface.isBase) {
285
- if (!acc[surface.group]) {
286
- acc[surface.group] = [];
287
- }
288
- const baseIndex: number = findBestMatchingBaseIndex(surface, i, surfaces, stratColumn);
289
- acc[surface.group].push({
290
- id: surface.name,
291
- label: surface.name,
292
- color: (surface.unit && getColorFromUnit(surface.unit)) || WHITE,
293
- exclude: surface.visualization === 'none' || !surface.unit,
294
- data: projection.map((p, j) => {
295
- const baseValue: number = surface.values[j] !== null ? getBaseValue(baseIndex, surfaces, j) : null;
296
- return [p[0], surface.values[j], baseValue];
297
- }),
298
- });
299
- }
300
- return acc;
301
- }, {});
302
- return areas;
303
- }
304
-
305
- // get the value from the surface with the supplied index,
306
- // iterate to next surface if value is null
307
- function getBaseValue(index: number, surfaces: Stratigraphy[], datapoint: number): number {
308
- if (!surfaces || !index || index >= surfaces.length) {
309
- return null;
310
- }
311
-
312
- for (let i: number = index; i < surfaces.length; i++) {
313
- if (surfaces[i].values[datapoint] !== null) {
314
- return surfaces[i].values[datapoint];
315
- }
316
- }
317
- return null;
318
- }
@@ -1,206 +0,0 @@
1
- import Vector2 from '@equinor/videx-vector2';
2
- import { seqI } from '@equinor/videx-math';
3
- import { CurveInterpolator } from 'curve-interpolator';
4
- import { SurveySample } from './interfaces';
5
-
6
- const stepSize = 0.1;
7
- const extensionLength = 1000;
8
- const thresholdRelativeDist = 150;
9
- const thresholdDirectionDist = 30;
10
-
11
- const pathSteps = 10;
12
-
13
- /**
14
- * Generate projected wellbore path for drawing using wellbore path layer
15
- * Code originally developed for REP
16
- * @param {[]} poslog Position log from SMDA
17
- */
18
- export function generateProjectedWellborePath(poslog: SurveySample[]): number[][] {
19
- if (!poslog || poslog.length === 0) {
20
- return [];
21
- }
22
-
23
- const points: number[][] = poslog ? poslog.map((p: SurveySample) => [p.easting, p.northing, p.tvd, p.md]) : [];
24
-
25
- const projection: number[][] = simplify(projectCurtain(points));
26
- const offset: number = projection[projection.length - 1][0];
27
-
28
- projection.forEach((p, i) => {
29
- projection[i][0] = offset - p[0];
30
- });
31
-
32
- return projection;
33
- }
34
-
35
- /**
36
- * Generate Trajectory
37
- * Code originally developed for REP
38
- * @param {[]} poslog Position log from SMDA
39
- * @param {number} defaultIntersectionAngle Default intersection angle for the field
40
- */
41
- export function generateProjectedTrajectory(poslog: SurveySample[], defaultIntersectionAngle: number): number[][] {
42
- if (!poslog || poslog.length === 0) {
43
- return [];
44
- }
45
-
46
- const points: number[][] = poslog ? poslog.map((p) => [p.easting, p.northing, p.tvd, p.md]) : [];
47
-
48
- const interpolator: CurveInterpolator = new CurveInterpolator(points, { tension: 0.75, arcDivisions: 5000 });
49
- const displacement: number = interpolator.length;
50
-
51
- const nPoints: number = Math.round(displacement * pathSteps);
52
- let path: number[][] = null;
53
- if (nPoints > 0) {
54
- const maxOffset = 0.0005;
55
- const maxDistance = 10;
56
- path = simplify(interpolator.getPoints(nPoints), maxOffset, maxDistance);
57
- } else {
58
- path = [[points[0][0], points[0][1]]];
59
- }
60
-
61
- const first: number[] = path[0];
62
- const last: number[] = path[path.length - 1];
63
- const relativeDist: number = Vector2.distance(first, last);
64
- let v: Vector2 = null;
65
-
66
- if (relativeDist < thresholdRelativeDist) {
67
- const oneEighty = 180;
68
- const radCurtainDirection = (defaultIntersectionAngle / oneEighty) * Math.PI;
69
- v = new Vector2(Math.cos(radCurtainDirection), Math.sin(radCurtainDirection)).mutable;
70
- } else {
71
- v = getDirectionVector(path, thresholdDirectionDist);
72
- }
73
- const extensionLengthStart: number = Math.max(0, extensionLength - displacement);
74
- const offset: number = extensionLengthStart + displacement;
75
- const trajectory: number[][] = [];
76
-
77
- let firstPoints: number[][] = [];
78
-
79
- // Reference to initial vector
80
- const initial: number[] = v.toArray();
81
-
82
- if (extensionLengthStart > 0) {
83
- // extend from start
84
- firstPoints = seqI(Math.ceil(extensionLengthStart * stepSize)).map((t) =>
85
- v
86
- .set(initial)
87
- .scale(extensionLengthStart * (1 - t))
88
- .subFrom(first)
89
- .toArray(),
90
- );
91
- firstPoints.pop();
92
- trajectory.push(...firstPoints);
93
- }
94
- trajectory.push(...path);
95
-
96
- const endPoints: number[][] = seqI(Math.ceil(extensionLength * stepSize))
97
- .map((t) =>
98
- v
99
- .set(initial)
100
- .scale(extensionLength * t)
101
- .add(last)
102
- .toArray(),
103
- )
104
- .splice(1);
105
-
106
- trajectory.push(...endPoints);
107
-
108
- const projectedTrajectory: number[][] = projectCurtain(trajectory, null, offset);
109
-
110
- return projectedTrajectory;
111
- }
112
-
113
- /**
114
- * Get direction vector
115
- * Code originally developed for REP
116
- * @param {[]} path
117
- * @param {number} threshold
118
- * @returns {Vector2}
119
- */
120
- function getDirectionVector(path: number[][], threshold: number): Vector2 {
121
- const res: Vector2 = Vector2.zero.mutable;
122
- let len = 0;
123
- const temp: Vector2 = Vector2.zero.mutable;
124
-
125
- for (let i = 0; i < path.length - 1; i++) {
126
- const index = path.length - 1 - i;
127
- temp.set(path[index]).sub(path[index - 1]);
128
- res.add(temp);
129
-
130
- len = res.magnitude;
131
- if (len > threshold) {
132
- break;
133
- }
134
- }
135
-
136
- if (len === 0) {
137
- return new Vector2([0, 0]);
138
- }
139
- return res.scale(1 / len);
140
- }
141
-
142
- /**
143
- * Simplify array
144
- *
145
- * Simplifies an array using given parameters.
146
- * Code originally developed for REP
147
- * @access public
148
- *
149
- * @param {Number[]} inputArr Array to simplify
150
- * @param {Number} [maxOffset=0.001] Max offset (Default = 0.001)
151
- * @param {Number} [maxDistance=10] Max distance (Default = 10)
152
- *
153
- * @return {Number[]} Simplified array
154
- */
155
- function simplify(inputArr: number[][], maxOffset = 0.001, maxDistance = 10): number[][] {
156
- if (inputArr.length <= 4) {
157
- return inputArr;
158
- }
159
- const [o0, o1] = inputArr[0];
160
- const arr = inputArr.map((d) => [d[0] - o0, d[1] - o1]);
161
- let [a0, a1] = arr[0];
162
- const sim: number[][] = [inputArr[0]];
163
-
164
- for (let i = 1; i + 1 < arr.length; i++) {
165
- const [t0, t1] = arr[i];
166
- const [b0, b1] = arr[i + 1];
167
-
168
- // If t->b vector is NOT [0, 0]
169
- if (b0 - t0 !== 0 || b1 - t1 !== 0) {
170
- // Proximity check
171
- const proximity: number = Math.abs(a0 * b1 - a1 * b0 + b0 * t1 - b1 * t0 + a1 * t0 - a0 * t1) / Math.sqrt((b0 - a0) ** 2 + (b1 - a1) ** 2);
172
-
173
- const dir: number[] = [a0 - t0, a1 - t1];
174
- const len: number = Math.sqrt(dir[0] ** 2 + dir[1] ** 2);
175
-
176
- if (proximity > maxOffset || len >= maxDistance) {
177
- sim.push([t0 + o0, t1 + o1]);
178
- [a0, a1] = [t0, t1];
179
- }
180
- }
181
- }
182
- const last: number[] = arr[arr.length - 1];
183
- sim.push([last[0] + o0, last[1] + o1]);
184
-
185
- return sim;
186
- }
187
-
188
- /**
189
- * Perform a curtain projection on a set of points in 3D
190
- * @param points
191
- * @param origin
192
- * @param offset
193
- * @returns {array}
194
- */
195
- function projectCurtain(points: number[][], origin: number[] = null, offset = 0): number[][] {
196
- let p0: number[] = origin || points[0];
197
- let l = 0;
198
- const projected = points.map((p1: number[]) => {
199
- const dx = p1[0] - p0[0];
200
- const dy = p1[1] - p0[1];
201
- l += Math.sqrt(dx ** 2 + dy ** 2);
202
- p0 = p1;
203
- return [offset > 0 ? offset - l : l, p1[2] || 0];
204
- });
205
- return projected;
206
- }