From 83dc67870bc7538a3607752ac6bfdef263de2e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Bjerke?= Date: Wed, 23 Jun 2021 07:19:35 +0200 Subject: [PATCH] Measured depth linear interpolation (#401) * Added measured depth values to well trajectory example data. * Added mathjs dependency. Co-authored-by: Havard Bjerke --- package.json | 1 + .../DeckGLMap/layers/wells/wellsLayer.ts | 56 ++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 88a580be9..2f33d4a9d 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "leaflet": "^1.6.0", "leaflet-draw": "^1.0.4", "lodash": "^4.17.21", + "mathjs": "^9.4.2", "nebula.gl": "^0.22.3", "react": "^17.0.2", "react-dom": "^17.0.2", diff --git a/src/lib/components/DeckGLMap/layers/wells/wellsLayer.ts b/src/lib/components/DeckGLMap/layers/wells/wellsLayer.ts index ec7bfd354..cbbb16442 100644 --- a/src/lib/components/DeckGLMap/layers/wells/wellsLayer.ts +++ b/src/lib/components/DeckGLMap/layers/wells/wellsLayer.ts @@ -2,7 +2,8 @@ import { CompositeLayer } from "@deck.gl/core"; import { CompositeLayerProps } from "@deck.gl/core/lib/composite-layer"; import { GeoJsonLayer, PathLayer } from "@deck.gl/layers"; import { RGBAColor } from "@deck.gl/core/utils/color"; -import { PickInfo } from "@deck.gl/core/lib/deck"; +import { PickInfo } from "deck.gl"; +import { subtract, distance, dot } from "mathjs"; import { interpolateRgbBasis } from "d3-interpolate"; import { color } from "d3-color"; @@ -103,6 +104,48 @@ function squared_distance(a, b): number { return dx * dx + dy * dy; } +function getMd(pickInfo): number | null { + if (!pickInfo.object.properties || !pickInfo.object.geometry) return null; + + const measured_depths = pickInfo.object.properties.md[0]; + const trajectory = pickInfo.object.geometry.geometries[1].coordinates; + + // Get squared distance from survey point to picked point. + const d2 = trajectory.map((element) => + squared_distance(element, pickInfo.coordinate) + ); + + // Enumerate squared distances. + let index: number[] = Array.from(d2.entries()); + + // Sort by squared distance. + index = index.sort((a: number, b: number) => a[1] - b[1]); + + // Get the nearest indexes. + const index0 = index[0][0]; + const index1 = index[1][0]; + + // Get the nearest MD values. + const md0 = measured_depths[index0]; + const md1 = measured_depths[index1]; + + // Get the nearest survey points. + const survey0 = trajectory[index0]; + const survey1 = trajectory[index1]; + + const dv = distance(survey0, survey1) as number; + + // Calculate the scalar projection onto segment. + const v0 = subtract(pickInfo.coordinate, survey0); + const v1 = subtract(survey1, survey0); + const scalar_projection: number = dot(v0 as number[], v1 as number[]) / dv; + + // Interpolate MD value. + const c0 = scalar_projection / dv; + const c1 = dv - c0; + return (md0 * c1 + md1 * c0) / dv; +} + export interface WellsPickInfo extends PickInfo { logName?: string; propertyValue?: number; @@ -207,6 +250,17 @@ export default class WellsLayer extends CompositeLayer< }: { info: PickInfo; }): WellsPickInfo | PickInfo { + if (!info.object) return info; + + // Return MD if a trajectory has been picked. + const measured_depth = getMd(info); + if (measured_depth != null) { + return { + ...info, + propertyValue: measured_depth, + }; + } + if (!info.object || !(info.object as LogCurveDataType)?.data) return info;