Skip to content

Commit 07da07a

Browse files
committed
fix: Reduce wellname clutter.
1 parent a6c36b2 commit 07da07a

File tree

5 files changed

+172
-6
lines changed

5 files changed

+172
-6
lines changed

typescript/packages/subsurface-viewer/src/components/Map.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ const Map: React.FC<MapProps> = ({
554554
): PickingInfo[] => {
555555
if (coords?.multiPicking && pickInfo.layer?.context.deck) {
556556
const pickInfos =
557-
pickInfo.layer.context.deck.pickMultipleObjects({ // XXX
557+
pickInfo.layer.context.deck.pickMultipleObjects({
558558
x: event.offsetCenter.x,
559559
y: event.offsetCenter.y,
560560
depth: coords.pickDepth ?? undefined,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { LayerExtension } from "@deck.gl/core";
2+
import type { Layer } from "@deck.gl/core";
3+
4+
const injectionVs = {
5+
"vs:DECKGL_FILTER_COLOR": `
6+
color.a = 1.0 / collision_fade; // Note: this will counteract the fading of the labels caused by deck.gl's CollisionFilterExtension
7+
`,
8+
};
9+
10+
export class CollisionModifierExtension extends LayerExtension {
11+
static defaultProps = {};
12+
static extensionName = "CollisionModifierExtension";
13+
14+
getShaders(this: Layer) {
15+
return {
16+
modules: [],
17+
inject: injectionVs,
18+
};
19+
}
20+
}

typescript/packages/subsurface-viewer/src/layers/wells/wellsLayer.ts

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import type {
77
Position,
88
UpdateParameters,
99
} from "@deck.gl/core";
10-
10+
import { CollisionFilterExtension } from "@deck.gl/extensions";
11+
import { CollisionModifierExtension } from "../../extensions/collision-modifier-extension";
1112
import { CompositeLayer, OrbitViewport } from "@deck.gl/core";
12-
1313
import type {
1414
ExtendedLayerProps,
1515
LayerPickInfo,
@@ -115,6 +115,10 @@ export interface WellsLayerProps extends ExtendedLayerProps {
115115
wellNameAtTop: boolean;
116116
wellNameSize: number;
117117
wellNameColor: Color;
118+
/** If true will prevent well name cluttering by not displaying overlapping names.
119+
* default false.
120+
*/
121+
wellNameReduceClutter: boolean;
118122
isLog: boolean;
119123
depthTest: boolean;
120124
/** If true means that input z values are interpreted as depths.
@@ -150,7 +154,8 @@ const defaultProps = {
150154
wellNameVisible: false,
151155
wellNameAtTop: false,
152156
wellNameSize: 14,
153-
wellNameColor: [0, 0, 0, 255],
157+
wellNameColor: [0, 0, 0],
158+
wellNameReduceClutter: false,
154159
selectedWell: "@@#editedData.selectedWells", // used to get data from deckgl layer
155160
depthTest: true,
156161
ZIncreasingDownwards: true,
@@ -618,7 +623,41 @@ export default class WellsLayer extends CompositeLayer<WellsLayerProps> {
618623
})
619624
);
620625

621-
// well name
626+
// Reduced cluttering properties
627+
const clutterProps = {
628+
background: true,
629+
collisionEnabled: true,
630+
getCollisionPriority: (d) => {
631+
const labelSize = d.properties.name.length;
632+
//return labelSize;
633+
if (is3d) {
634+
// In 3D prioritize according to label size.
635+
return labelSize;
636+
} else {
637+
// In 2D prioritize according z height.
638+
const labelPosition = getAnnotationPosition(
639+
d,
640+
this.props.wellNameAtTop,
641+
true,
642+
this.props.lineStyle?.color
643+
);
644+
645+
const priority = labelPosition
646+
? (labelPosition?.[2] ?? 1) / 10 + Math.random() // priority must be in [-1000, 1000]
647+
: labelSize;
648+
return priority;
649+
}
650+
},
651+
collisionTestProps: {
652+
sizeScale: 2,
653+
},
654+
collisionGroup: "nobodys",
655+
extensions: [
656+
new CollisionFilterExtension(),
657+
new CollisionModifierExtension(),
658+
],
659+
};
660+
622661
const namesLayer = new TextLayer<Feature>(
623662
this.getSubLayerProps({
624663
id: "names",
@@ -644,6 +683,8 @@ export default class WellsLayer extends CompositeLayer<WellsLayerProps> {
644683
},
645684
parameters,
646685
visible: this.props.wellNameVisible && !fastDrawing,
686+
687+
...(this.props.wellNameReduceClutter ? clutterProps : {}),
647688
})
648689
);
649690

@@ -799,8 +840,8 @@ function getAnnotationPosition(
799840
color_accessor: ColorAccessor
800841
): Position | null {
801842
if (name_at_top) {
843+
// Read top position from Point geometry, if not present, read it from LineString geometry
802844
let top;
803-
804845
// Read top position from Point geometry, if not present, read it from LineString geometry
805846
const well_head = getWellHeadPosition(well_data);
806847
if (well_data) top = well_head;

typescript/packages/subsurface-viewer/src/storybook/layers/WellsLayer.stories.tsx

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,8 @@ const SimplifiedRenderingComponent: React.FC<SubsurfaceViewerProps> = (
614614
layers: [
615615
new WellsLayer({
616616
data: "./gullfaks.json",
617+
wellNameVisible: true,
618+
wellNameAtTop: true,
617619
wellHeadStyle: { size: 4 },
618620
refine: true,
619621
outline: true,
@@ -652,6 +654,108 @@ export const SimplifiedRendering: StoryObj<typeof SubsurfaceViewer> = {
652654
render: (args) => <SimplifiedRenderingComponent {...args} />,
653655
};
654656

657+
type ClutterProps = {
658+
wellNameReduceClutter: boolean;
659+
wellNameAtTop: boolean;
660+
};
661+
662+
const ReducedWellNameClutterComponent: React.FC<ClutterProps> = (
663+
props: ClutterProps
664+
) => {
665+
const propsWithLayers = {
666+
id: "clutter",
667+
layers: [
668+
new WellsLayer({
669+
data: "./gullfaks.json",
670+
wellNameVisible: true,
671+
wellNameAtTop: props.wellNameAtTop,
672+
wellHeadStyle: { size: 4 },
673+
wellNameReduceClutter: props.wellNameReduceClutter,
674+
refine: true,
675+
outline: true,
676+
ZIncreasingDownwards: false,
677+
}),
678+
new AxesLayer({
679+
id: "axes-layer",
680+
bounds: [450000, 6781000, 0, 464000, 6791000, 3500],
681+
}),
682+
],
683+
cameraPosition: {
684+
rotationOrbit: 45,
685+
rotationX: 45,
686+
zoom: -4,
687+
target: [(450000 + 464000) / 2, (6781000 + 6791000) / 2, -3500 / 2],
688+
},
689+
views: {
690+
layout: [1, 1] as [number, number],
691+
viewports: [
692+
{
693+
id: "view_1",
694+
show3D: true,
695+
},
696+
],
697+
},
698+
};
699+
700+
return <SubsurfaceViewer {...propsWithLayers} />;
701+
};
702+
703+
export const ReducedWellNameClutter3D: StoryObj<
704+
typeof ReducedWellNameClutterComponent
705+
> = {
706+
args: {
707+
wellNameReduceClutter: false,
708+
wellNameAtTop: true,
709+
},
710+
render: (args) => <ReducedWellNameClutterComponent {...args} />,
711+
};
712+
713+
const ReducedWellNameClutterComponent2D: React.FC<ClutterProps> = (
714+
props: ClutterProps
715+
) => {
716+
const propsWithLayers = {
717+
id: "clutter",
718+
layers: [
719+
new WellsLayer({
720+
data: "./gullfaks.json",
721+
wellNameVisible: true,
722+
wellNameAtTop: props.wellNameAtTop,
723+
wellHeadStyle: { size: 4 },
724+
wellNameReduceClutter: props.wellNameReduceClutter,
725+
refine: true,
726+
outline: true,
727+
ZIncreasingDownwards: false,
728+
}),
729+
new AxesLayer({
730+
id: "axes-layer",
731+
bounds: [450000, 6781000, 0, 464000, 6791000, 3500],
732+
}),
733+
],
734+
bounds: [450000, 6781000, 464000, 6791000],
735+
views: {
736+
layout: [1, 1] as [number, number],
737+
viewports: [
738+
{
739+
id: "view_1",
740+
show3D: false,
741+
},
742+
],
743+
},
744+
};
745+
746+
return <SubsurfaceViewer {...propsWithLayers} />;
747+
};
748+
749+
export const ReducedWellNameClutter2D: StoryObj<
750+
typeof ReducedWellNameClutterComponent
751+
> = {
752+
args: {
753+
wellNameReduceClutter: false,
754+
wellNameAtTop: true,
755+
},
756+
render: (args) => <ReducedWellNameClutterComponent2D {...args} />,
757+
};
758+
655759
export const Wells3dDashed: StoryObj<typeof SubsurfaceViewer> = {
656760
args: {
657761
...defaultProps,

typescript/packages/subsurface-viewer/src/storybook/sharedSettings.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export const volveWellsFromResourcesLayer = {
9494
id: "volve-wells",
9595
data: "@@#resources.wellsData",
9696
ZIncreasingDownwards: false,
97+
wellNameVisible: true,
9798
};
9899

99100
export const volveWellsLayer = {

0 commit comments

Comments
 (0)