diff --git a/frontend/src/modules/2DViewer/view/components/ReadoutBoxWrapper.tsx b/frontend/src/modules/2DViewer/view/components/ReadoutBoxWrapper.tsx index bdc92c052..70a488c0b 100644 --- a/frontend/src/modules/2DViewer/view/components/ReadoutBoxWrapper.tsx +++ b/frontend/src/modules/2DViewer/view/components/ReadoutBoxWrapper.tsx @@ -62,22 +62,30 @@ export function ReadoutBoxWrapper(props: ReadoutBoxWrapperProps): React.ReactNod // 1. defined as propertyValue, used for general layer info (now using for positional data) // 2. Another defined as array of property object described by type PropertyDataType + const layerReadout = newReadoutItems.find((item) => item.label === layerName); + // collecting card data for 1st type const zValue = (layerPickInfo as LayerPickInfo).propertyValue; if (zValue !== undefined) { - const property = positionReadout.info?.find((item) => item.name === layerName); - if (property) { - property.value = zValue; - } else { - positionReadout.info.push({ - name: layerName, + if (layerReadout) { + layerReadout.info.push({ + name: "Property value", value: zValue, }); + } else { + newReadoutItems.push({ + label: layerName ?? "Unknown layer", + info: [ + { + name: "Property value", + value: zValue, + }, + ], + }); } } // collecting card data for 2nd type - const layerReadout = newReadoutItems.find((item) => item.label === layerName); if (!layerProps || layerProps.length === 0) { continue; } diff --git a/frontend/src/modules/2DViewer/view/utils/AdvancedWellsLayer.ts b/frontend/src/modules/2DViewer/view/utils/AdvancedWellsLayer.ts new file mode 100644 index 000000000..3b62d3fcd --- /dev/null +++ b/frontend/src/modules/2DViewer/view/utils/AdvancedWellsLayer.ts @@ -0,0 +1,46 @@ +import { FilterContext, Layer, LayersList } from "@deck.gl/core/typed"; +import { GeoJsonLayer } from "@deck.gl/layers/typed"; +import { WellsLayer } from "@webviz/subsurface-viewer/dist/layers"; + +export class AdvancedWellsLayer extends WellsLayer { + constructor(props: any) { + super(props); + } + + filterSubLayer(context: FilterContext): boolean { + if (context.layer.id.includes("names")) { + return context.viewport.zoom > -2; + } + + return true; + } + + renderLayers(): LayersList { + const layers = super.renderLayers(); + + if (!Array.isArray(layers)) { + return layers; + } + + const colorsLayer = layers.find((layer) => { + if (!(layer instanceof Layer)) { + return false; + } + + return layer.id.includes("colors"); + }); + + if (!(colorsLayer instanceof GeoJsonLayer)) { + return layers; + } + + const newColorsLayer = new GeoJsonLayer({ + ...colorsLayer.props, + id: "colors2", + lineWidthMinPixels: 2, + lineWidthUnits: "pixels", + }); + + return [newColorsLayer, ...layers.filter((layer) => layer !== colorsLayer)]; + } +} diff --git a/frontend/src/modules/2DViewer/view/utils/wellPickLayer.ts b/frontend/src/modules/2DViewer/view/utils/WellborePicksLayer.ts similarity index 76% rename from frontend/src/modules/2DViewer/view/utils/wellPickLayer.ts rename to frontend/src/modules/2DViewer/view/utils/WellborePicksLayer.ts index 62c364d0b..733b61389 100644 --- a/frontend/src/modules/2DViewer/view/utils/wellPickLayer.ts +++ b/frontend/src/modules/2DViewer/view/utils/WellborePicksLayer.ts @@ -1,5 +1,5 @@ -import { CompositeLayer } from "@deck.gl/core/typed"; -// import { CollisionFilterExtension } from "@deck.gl/extensions/typed"; +import { CompositeLayer, FilterContext } from "@deck.gl/core/typed"; +import { CollisionFilterExtension } from "@deck.gl/extensions/typed"; import { GeoJsonLayer, TextLayer } from "@deck.gl/layers/typed"; import type { Feature, FeatureCollection } from "geojson"; @@ -20,7 +20,15 @@ export type WellBorePicksLayerProps = { data: WellBorePickLayerData[]; }; -export class WellPicksLayer extends CompositeLayer { +export class WellborePicksLayer extends CompositeLayer { + filterSubLayer(context: FilterContext): boolean { + if (context.layer.id.includes("text")) { + return context.viewport.zoom > -4; + } + + return true; + } + renderLayers() { const features: Feature[] = this.props.data.map((wellPick) => { return { @@ -53,16 +61,17 @@ export class WellPicksLayer extends CompositeLayer { data: pointsData, // pointType: 'circle+text', filled: true, - lineWidthMinPixels: 20, - + lineWidthMinPixels: 10, + lineWidthUnits: "meters", parameters: { depthTest: false, }, + getLineWidth: 10, depthTest: false, pickable: true, getText: (d: Feature) => d.properties?.wellBoreUwi, - // getFillColor: [100, 100, 100, 100], getLineColor: [50, 50, 50], + extensions: [new CollisionFilterExtension()], }) ), @@ -73,22 +82,15 @@ export class WellPicksLayer extends CompositeLayer { depthTest: false, pickable: true, getColor: [0, 0, 0], - getSize: 100, + getSize: 10, sizeUnits: "meters", - sizeMaxPixels: 20, + sizeMinPixels: 12, getAlignmentBaseline: "top", getTextAnchor: "middle", getPixelOffset: [0, 10], getPosition: (d: TextLayerData) => d.coordinates, getText: (d: TextLayerData) => d.name, - // collisionEnabled: true, - // // getCollisionPriority: d => Math.log10(d.population), - // collisionTestProps: { - // sizeScale: 32 * 2, - // sizeMaxPixels: 30 * 2, - // sizeMinPixels: 30 * 2, - // }, - // extensions: [new CollisionFilterExtension()], + extensions: [new CollisionFilterExtension()], }) ), ]; diff --git a/frontend/src/modules/2DViewer/view/utils/layerFactory.ts b/frontend/src/modules/2DViewer/view/utils/layerFactory.ts index 209205481..e2669bed7 100644 --- a/frontend/src/modules/2DViewer/view/utils/layerFactory.ts +++ b/frontend/src/modules/2DViewer/view/utils/layerFactory.ts @@ -13,7 +13,8 @@ import { Rgb, parse } from "culori"; import { Feature } from "geojson"; import { SurfaceDataPng } from "src/api/models/SurfaceDataPng"; -import { WellBorePickLayerData, WellPicksLayer } from "./wellPickLayer"; +import { AdvancedWellsLayer } from "./AdvancedWellsLayer"; +import { WellBorePickLayerData, WellborePicksLayer } from "./WellborePicksLayer"; import { DrilledWellTrajectoriesLayer } from "../../layers/implementations/layers/DrilledWellTrajectoriesLayer/DrilledWellTrajectoriesLayer"; import { DrilledWellborePicksLayer } from "../../layers/implementations/layers/DrilledWellborePicksLayer/DrilledWellborePicksLayer"; @@ -41,13 +42,28 @@ export function makeLayer(layer: LayerInterface, colorScale?: ColorSca return null; } if (layer instanceof ObservedSurfaceLayer) { - return createMapImageLayer(data, layer.getItemDelegate().getId(), colorScale); + return createMapImageLayer( + data, + layer.getItemDelegate().getId(), + layer.getItemDelegate().getName(), + colorScale + ); } if (layer instanceof RealizationSurfaceLayer) { - return createMapImageLayer(data, layer.getItemDelegate().getId(), colorScale); + return createMapImageLayer( + data, + layer.getItemDelegate().getId(), + layer.getItemDelegate().getName(), + colorScale + ); } if (layer instanceof StatisticalSurfaceLayer) { - return createMapImageLayer(data, layer.getItemDelegate().getId(), colorScale); + return createMapImageLayer( + data, + layer.getItemDelegate().getId(), + layer.getItemDelegate().getName(), + colorScale + ); } if (layer instanceof RealizationPolygonsLayer) { return createPolygonsLayer(data, layer.getItemDelegate().getId()); @@ -69,7 +85,7 @@ export function makeLayer(layer: LayerInterface, colorScale?: ColorSca } return null; } -function createWellPicksLayer(wellPicksDataApi: WellborePick_api[], id: string): WellPicksLayer { +function createWellPicksLayer(wellPicksDataApi: WellborePick_api[], id: string): WellborePicksLayer { const wellPicksData: WellBorePickLayerData[] = wellPicksDataApi.map((wellPick) => { return { easting: wellPick.easting, @@ -77,9 +93,10 @@ function createWellPicksLayer(wellPicksDataApi: WellborePick_api[], id: string): wellBoreUwi: wellPick.uniqueWellboreIdentifier, tvdMsl: wellPick.tvdMsl, md: wellPick.md, + pickable: true, }; }); - return new WellPicksLayer({ + return new WellborePicksLayer({ id: id, data: wellPicksData, pickable: true, @@ -109,9 +126,16 @@ function createMapFloatLayer(layerData: SurfaceDataFloat_trans, id: string): Map }); } -function createMapImageLayer(layerData: SurfaceDataPng, id: string, colorScale?: ColorScaleWithName): ColormapLayer { +function createMapImageLayer( + layerData: SurfaceDataPng, + id: string, + name: string, + colorScale?: ColorScaleWithName +): ColormapLayer { return new ColormapLayer({ id: id, + // @ts-expect-error - wrong typescript definition of AspenTech - ColormapLayer should extend ExtendedLayer in addition to BitmapLayer + name: name, image: `data:image/png;base64,${layerData.png_image_base64}`, bounds: _calcBoundsForRotationAroundUpperLeftCorner(layerData.surface_def), rotDeg: layerData.surface_def.rot_deg, @@ -211,7 +235,7 @@ export function makeWellsLayer( return [50, 50, 50, 100]; } - const wellsLayer = new WellsLayer({ + const wellsLayer = new AdvancedWellsLayer({ id: id, data: { type: "FeatureCollection", @@ -221,6 +245,7 @@ export function makeWellsLayer( refine: false, lineStyle: { width: getLineStyleWidth, color: getColor }, wellHeadStyle: { size: getWellHeadStyleWidth, color: getColor }, + wellNameVisible: true, pickable: true, ZIncreasingDownwards: false, outline: false, diff --git a/frontend/src/modules/2DViewer/view/utils/makeViewsAndLayers.ts b/frontend/src/modules/2DViewer/view/utils/makeViewsAndLayers.ts index 141dfd5d3..0d0438094 100644 --- a/frontend/src/modules/2DViewer/view/utils/makeViewsAndLayers.ts +++ b/frontend/src/modules/2DViewer/view/utils/makeViewsAndLayers.ts @@ -121,6 +121,10 @@ export function recursivelyMakeViewsAndLayers(group: Group, numCollectedLayers: } function findColorScale(layer: Layer): { id: string; colorScale: ColorScaleWithName } | null { + if (layer.getLayerDelegate().getColoringType() !== "COLORSCALE") { + return null; + } + let colorScaleWithName = new ColorScaleWithName({ colorPalette: defaultContinuousSequentialColorPalettes[0], gradientType: ColorScaleGradientType.Sequential, @@ -139,11 +143,7 @@ function findColorScale(layer: Layer): { id: string; colorScale: Color .getParentGroup() ?.getAncestorAndSiblingItems((item) => item instanceof ColorScale); - if ( - colorScaleItemArr && - colorScaleItemArr.length > 0 && - layer.getLayerDelegate().getColoringType() === "COLORSCALE" - ) { + if (colorScaleItemArr && colorScaleItemArr.length > 0) { const colorScaleItem = colorScaleItemArr[0]; if (colorScaleItem instanceof ColorScale) { colorScaleWithName = ColorScaleWithName.fromColorScale(