Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Well clutter #2424

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Layer } from "@deck.gl/core";
import { CollisionFilterExtension } from "@deck.gl/extensions";

const injectionVs = {
"vs:DECKGL_FILTER_COLOR": `
color.a = 1.0 / collision_fade; // Note: this will counteract the fading of the labels caused by deck.gl's CollisionFilterExtension
`,
};

export class CollisionModifierExtension extends CollisionFilterExtension {
getShaders(this: Layer) {
const superShaders = super.getShaders();
return {
...superShaders,
inject: injectionVs,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import type {
Position,
UpdateParameters,
} from "@deck.gl/core";

import { CollisionModifierExtension } from "../../extensions/collision-modifier-extension";
import { CompositeLayer, OrbitViewport } from "@deck.gl/core";

import type {
ExtendedLayerProps,
LayerPickInfo,
Expand Down Expand Up @@ -115,6 +114,10 @@ export interface WellsLayerProps extends ExtendedLayerProps {
wellNameAtTop: boolean;
wellNameSize: number;
wellNameColor: Color;
/** If true will prevent well name cluttering by not displaying overlapping names.
* default false.
*/
wellNameReduceClutter: boolean;
isLog: boolean;
depthTest: boolean;
/** If true means that input z values are interpreted as depths.
Expand Down Expand Up @@ -151,6 +154,7 @@ const defaultProps = {
wellNameAtTop: false,
wellNameSize: 14,
wellNameColor: [0, 0, 0, 255],
wellNameReduceClutter: false,
selectedWell: "@@#editedData.selectedWells", // used to get data from deckgl layer
depthTest: true,
ZIncreasingDownwards: true,
Expand Down Expand Up @@ -618,7 +622,38 @@ export default class WellsLayer extends CompositeLayer<WellsLayerProps> {
})
);

// well name
// Reduced cluttering properties
const clutterProps = {
background: true,
collisionEnabled: true,
getCollisionPriority: (d: Feature<Geometry, GeoJsonProperties>) => {
const labelSize = d.properties?.["name"].length ?? 1;
//return labelSize;
if (is3d) {
// In 3D prioritize according to label size.
return labelSize;
} else {
// In 2D prioritize according z height.
const labelPosition = getAnnotationPosition(
d,
this.props.wellNameAtTop,
true,
this.props.lineStyle?.color
);

const priority = labelPosition
? (labelPosition?.[2] ?? 1) / 10 + Math.random() // priority must be in [-1000, 1000]
: labelSize;
return priority;
}
},
collisionTestProps: {
sizeScale: 2,
},
collisionGroup: "nobodys",
extensions: [new CollisionModifierExtension()],
};

const namesLayer = new TextLayer<Feature>(
this.getSubLayerProps({
id: "names",
Expand All @@ -644,6 +679,8 @@ export default class WellsLayer extends CompositeLayer<WellsLayerProps> {
},
parameters,
visible: this.props.wellNameVisible && !fastDrawing,

...(this.props.wellNameReduceClutter ? clutterProps : {}),
})
);

Expand Down Expand Up @@ -799,8 +836,8 @@ function getAnnotationPosition(
color_accessor: ColorAccessor
): Position | null {
if (name_at_top) {
// Read top position from Point geometry, if not present, read it from LineString geometry
let top;

// Read top position from Point geometry, if not present, read it from LineString geometry
const well_head = getWellHeadPosition(well_data);
if (well_data) top = well_head;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import { NativeSelect } from "@equinor/eds-core-react";

import type { SubsurfaceViewerProps } from "../../SubsurfaceViewer";
import SubsurfaceViewer from "../../SubsurfaceViewer";
import type { MapMouseEvent } from "../../components/Map";
import type {
MapMouseEvent,
Point3D,
BoundingBox2D,
} from "../../components/Map";
import AxesLayer from "../../layers/axes/axesLayer";
import WellsLayer from "../../layers/wells/wellsLayer";

Expand Down Expand Up @@ -614,6 +618,8 @@ const SimplifiedRenderingComponent: React.FC<SubsurfaceViewerProps> = (
layers: [
new WellsLayer({
data: "./gullfaks.json",
wellNameVisible: true,
wellNameAtTop: true,
wellHeadStyle: { size: 4 },
refine: true,
outline: true,
Expand Down Expand Up @@ -652,6 +658,112 @@ export const SimplifiedRendering: StoryObj<typeof SubsurfaceViewer> = {
render: (args) => <SimplifiedRenderingComponent {...args} />,
};

type ClutterProps = {
wellNameReduceClutter: boolean;
wellNameAtTop: boolean;
};

const ReducedWellNameClutterComponent: React.FC<ClutterProps> = (
props: ClutterProps
) => {
const propsWithLayers = {
id: "clutter",
layers: [
new WellsLayer({
data: "./gullfaks.json",
wellNameVisible: true,
wellNameAtTop: props.wellNameAtTop,
wellHeadStyle: { size: 4 },
wellNameReduceClutter: props.wellNameReduceClutter,
refine: true,
outline: true,
ZIncreasingDownwards: false,
}),
new AxesLayer({
id: "axes-layer",
bounds: [450000, 6781000, 0, 464000, 6791000, 3500],
}),
],
cameraPosition: {
rotationOrbit: 45,
rotationX: 45,
zoom: -4,
target: [
(450000 + 464000) / 2,
(6781000 + 6791000) / 2,
-3500 / 2,
] as Point3D,
},
views: {
layout: [1, 1] as [number, number],
viewports: [
{
id: "view_1",
show3D: true,
},
],
},
};

return <SubsurfaceViewer {...propsWithLayers} />;
};

export const ReducedWellNameClutter3D: StoryObj<
typeof ReducedWellNameClutterComponent
> = {
args: {
wellNameReduceClutter: false,
wellNameAtTop: true,
},
render: (args) => <ReducedWellNameClutterComponent {...args} />,
};

const ReducedWellNameClutterComponent2D: React.FC<ClutterProps> = (
props: ClutterProps
) => {
const propsWithLayers = {
id: "clutter",
layers: [
new WellsLayer({
data: "./gullfaks.json",
wellNameVisible: true,
wellNameAtTop: props.wellNameAtTop,
wellHeadStyle: { size: 4 },
wellNameReduceClutter: props.wellNameReduceClutter,
refine: true,
outline: true,
ZIncreasingDownwards: false,
}),
new AxesLayer({
id: "axes-layer",
bounds: [450000, 6781000, 0, 464000, 6791000, 3500],
}),
],
bounds: [450000, 6781000, 464000, 6791000] as BoundingBox2D,
views: {
layout: [1, 1] as [number, number],
viewports: [
{
id: "view_1",
show3D: false,
},
],
},
};

return <SubsurfaceViewer {...propsWithLayers} />;
};

export const ReducedWellNameClutter2D: StoryObj<
typeof ReducedWellNameClutterComponent
> = {
args: {
wellNameReduceClutter: false,
wellNameAtTop: true,
},
render: (args) => <ReducedWellNameClutterComponent2D {...args} />,
};

export const Wells3dDashed: StoryObj<typeof SubsurfaceViewer> = {
args: {
...defaultProps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export const volveWellsFromResourcesLayer = {
id: "volve-wells",
data: "@@#resources.wellsData",
ZIncreasingDownwards: false,
wellNameVisible: true,
};

export const volveWellsLayer = {
Expand Down
Loading