Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenthoms committed Sep 16, 2024
1 parent ec5a90a commit 8b153d7
Show file tree
Hide file tree
Showing 15 changed files with 283 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { MenuDivider } from "@lib/components/MenuDivider";
import { MenuHeading } from "@lib/components/MenuHeading";
import { MenuItem } from "@lib/components/MenuItem";
import { Dropdown, MenuButton } from "@mui/base";
import { Add, ArrowDropDown, GridView } from "@mui/icons-material";
import { Add, ArrowDropDown } from "@mui/icons-material";

export type LayersAction = {
identifier: string;
Expand Down Expand Up @@ -40,7 +40,7 @@ export function LayersActions<TLayerType extends string, TSettingType extends st
content.push(<MenuDivider key={index} />);
}
content.push(
<MenuHeading key={`${item.label}-${index}`} style={{ paddingLeft: `${indentLevel * 1}rem` }}>
<MenuHeading key={`${item.label}-${index}`} style={{ paddingLeft: `${indentLevel + 1}rem` }}>
{item.label}
</MenuHeading>
);
Expand Down
19 changes: 19 additions & 0 deletions frontend/src/modules/2DViewer/layers/components/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { SurfaceDef_api } from "@api";
import { SortableListItemProps } from "@lib/components/SortableList";
import { Vec2, rotatePoint2Around } from "@lib/utils/vec2";

import { GroupComponent } from "./GroupComponent";
import { LayerComponent } from "./LayerComponent";
Expand Down Expand Up @@ -31,3 +33,20 @@ export function makeComponent(
}
throw new Error("Not implemented");
}

export function calcBoundsForRotationAroundUpperLeftCorner(surfDef: SurfaceDef_api): [number, number, number, number] {
const width = (surfDef.npoints_x - 1) * surfDef.inc_x;
const height = (surfDef.npoints_y - 1) * surfDef.inc_y;
const orgRotPoint: Vec2 = { x: surfDef.origin_utm_x, y: surfDef.origin_utm_y };
const orgTopLeft: Vec2 = { x: surfDef.origin_utm_x, y: surfDef.origin_utm_y + height };

const transTopLeft: Vec2 = rotatePoint2Around(orgTopLeft, orgRotPoint, (surfDef.rot_deg * Math.PI) / 180);
const tLeft = transTopLeft.x;
const tBottom = transTopLeft.y - height;
const tRight = transTopLeft.x + width;
const tTop = transTopLeft.y;

const bounds: [number, number, number, number] = [tLeft, tBottom, tRight, tTop];

return bounds;
}
15 changes: 14 additions & 1 deletion frontend/src/modules/2DViewer/layers/delegates/LayerDelegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { SettingsContextDelegateTopic } from "./SettingsContextDelegate";
import { LayerManager, LayerManagerTopic } from "../LayerManager";
import { PublishSubscribe, PublishSubscribeHandler } from "../PublishSubscribeHandler";
import { SharedSetting } from "../SharedSetting";
import { Layer, LayerStatus, Settings, SettingsContext } from "../interfaces";
import { BoundingBox, Layer, LayerStatus, Settings, SettingsContext } from "../interfaces";

export enum LayerDelegateTopic {
STATUS = "STATUS",
Expand All @@ -32,6 +32,7 @@ export class LayerDelegate<TSettings extends Settings, TData>
private _status: LayerStatus = LayerStatus.IDLE;
private _data: TData | null = null;
private _error: StatusMessage | string | null = null;
private _boundingBox: BoundingBox | null = null;

constructor(owner: Layer<TSettings, TData>, settingsContext: SettingsContext<TSettings>) {
this._owner = owner;
Expand Down Expand Up @@ -71,6 +72,14 @@ export class LayerDelegate<TSettings extends Settings, TData>
return this._settingsContext;
}

getBoundingBox(): BoundingBox | null {
return this._boundingBox;
}

private invalidateBoundingBox(): void {
this._boundingBox = null;
}

setLayerManager(layerManager: LayerManager | null): void {
this._layerManager = layerManager;
this._settingsContext.getDelegate().setLayerManager(layerManager);
Expand Down Expand Up @@ -210,9 +219,13 @@ export class LayerDelegate<TSettings extends Settings, TData>
}

this.setStatus(LayerStatus.LOADING);
this.invalidateBoundingBox();

try {
this._data = await this._owner.fechData(queryClient);
if (this._owner.makeBoundingBox) {
this._boundingBox = this._owner.makeBoundingBox();
}
if (this._queryKeys.length === null && isDevMode()) {
console.warn(
"Did you forget to use 'setQueryKeys' in your layer implementation of 'fetchData'? This will cause the queries to not be cancelled when settings change and might lead to undesired behaviour."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { DrilledWellTrajectoriesContext } from "./DrilledWellTrajectoriesContext
import { DrilledWellTrajectoriesSettings } from "./types";

import { LayerDelegate } from "../../../delegates/LayerDelegate";
import { Layer } from "../../../interfaces";
import { BoundingBox, Layer } from "../../../interfaces";

export class DrilledWellTrajectoriesLayer implements Layer<DrilledWellTrajectoriesSettings, WellboreTrajectory_api[]> {
private _layerDelegate: LayerDelegate<DrilledWellTrajectoriesSettings, WellboreTrajectory_api[]>;
Expand Down Expand Up @@ -41,6 +41,36 @@ export class DrilledWellTrajectoriesLayer implements Layer<DrilledWellTrajectori
return !isEqual(prevSettings, newSettings);
}

makeBoundingBox(): BoundingBox | null {
const data = this._layerDelegate.getData();
if (!data) {
return null;
}

const bbox: BoundingBox = {
x: [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY],
y: [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY],
z: [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY],
};

for (const trajectory of data) {
for (const point of trajectory.northingArr) {
bbox.x[0] = Math.min(bbox.x[0], point);
bbox.x[1] = Math.max(bbox.x[1], point);
}
for (const point of trajectory.eastingArr) {
bbox.y[0] = Math.min(bbox.y[0], point);
bbox.y[1] = Math.max(bbox.y[1], point);
}
for (const point of trajectory.tvdMslArr) {
bbox.z[0] = Math.min(bbox.z[0], point);
bbox.z[1] = Math.max(bbox.z[1], point);
}
}

return bbox;
}

fechData(queryClient: QueryClient): Promise<WellboreTrajectory_api[]> {
const workbenchSession = this.getSettingsContext().getDelegate().getLayerManager().getWorkbenchSession();
const ensembleSet = workbenchSession.getEnsembleSet();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { ObservedSurfaceContext } from "./ObservedSurfaceContext";
import { ObservedSurfaceSettings } from "./types";

import { LayerDelegate } from "../../../delegates/LayerDelegate";
import { Layer } from "../../../interfaces";
import { BoundingBox, Layer } from "../../../interfaces";

export class ObservedSurfaceLayer
implements Layer<ObservedSurfaceSettings, SurfaceDataFloat_trans | SurfaceDataPng_api>
Expand Down Expand Up @@ -46,6 +46,19 @@ export class ObservedSurfaceLayer
return !isEqual(prevSettings, newSettings);
}

makeBoundingBox(): BoundingBox | null {
const data = this._layerDelegate.getData();
if (!data) {
return null;
}

return {
x: [data.transformed_bbox_utm.min_x, data.transformed_bbox_utm.max_x],
y: [data.transformed_bbox_utm.min_y, data.transformed_bbox_utm.max_y],
z: [0, 0],
};
}

fechData(queryClient: QueryClient): Promise<SurfaceDataFloat_trans | SurfaceDataPng_api> {
let surfaceAddress: FullSurfaceAddress | null = null;
const addrBuilder = new SurfaceAddressBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { RealizationGridContext } from "./RealizationGridContext";
import { RealizationGridSettings } from "./types";

import { LayerDelegate } from "../../../delegates/LayerDelegate";
import { Layer } from "../../../interfaces";
import { BoundingBox, Layer } from "../../../interfaces";

export class RealizationGridLayer
implements
Expand Down Expand Up @@ -67,6 +67,19 @@ export class RealizationGridLayer
return !isEqual(prevSettings, newSettings);
}

makeBoundingBox(): BoundingBox | null {
const data = this._layerDelegate.getData();
if (!data) {
return null;
}

return {
x: [data.gridSurfaceData.xmin, data.gridSurfaceData.xmax],
y: [data.gridSurfaceData.ymin, data.gridSurfaceData.ymax],
z: [data.gridSurfaceData.zmin, data.gridSurfaceData.zmax],
};
}

fechData(queryClient: QueryClient): Promise<{
gridSurfaceData: GridSurface_trans;
gridParameterData: GridMappedProperty_trans;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { isEqual } from "lodash";
import { RealizationPolygonsContext } from "./RealizationPolygonsContext";
import { RealizationPolygonsSettings } from "./types";

import { Layer } from "../../../interfaces";
import { BoundingBox, Layer } from "../../../interfaces";

export class RealizationPolygonsLayer implements Layer<RealizationPolygonsSettings, PolygonData_api[]> {
private _layerDelegate: LayerDelegate<RealizationPolygonsSettings, PolygonData_api[]>;
Expand Down Expand Up @@ -41,6 +41,36 @@ export class RealizationPolygonsLayer implements Layer<RealizationPolygonsSettin
return !isEqual(prevSettings, newSettings);
}

makeBoundingBox(): BoundingBox | null {
const data = this._layerDelegate.getData();
if (!data) {
return null;
}

const bbox: BoundingBox = {
x: [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY],
y: [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY],
z: [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY],
};

for (const polygon of data) {
for (const point of polygon.x_arr) {
bbox.x[0] = Math.min(bbox.x[0], point);
bbox.x[1] = Math.max(bbox.x[1], point);
}
for (const point of polygon.y_arr) {
bbox.y[0] = Math.min(bbox.y[0], point);
bbox.y[1] = Math.max(bbox.y[1], point);
}
for (const point of polygon.z_arr) {
bbox.z[0] = Math.min(bbox.z[0], point);
bbox.z[1] = Math.max(bbox.z[1], point);
}
}

return bbox;
}

fechData(queryClient: QueryClient): Promise<PolygonData_api[]> {
const settings = this.getSettingsContext().getDelegate().getSettings();
const ensembleIdent = settings[SettingType.ENSEMBLE].getDelegate().getValue();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SurfaceDataPng_api, SurfaceTimeType_api } from "@api";
import { apiService } from "@framework/ApiService";
import { calcBoundsForRotationAroundUpperLeftCorner } from "@modules/2DViewer/layers/components/utils";

Check failure on line 3 in frontend/src/modules/2DViewer/layers/implementations/layers/RealizationSurfaceLayer/RealizationSurfaceLayer.ts

View workflow job for this annotation

GitHub Actions / frontend

'calcBoundsForRotationAroundUpperLeftCorner' is defined but never used
import { ItemDelegate } from "@modules/2DViewer/layers/delegates/ItemDelegate";
import { LayerDelegate } from "@modules/2DViewer/layers/delegates/LayerDelegate";
import { CACHE_TIME, STALE_TIME } from "@modules/2DViewer/layers/queryConstants";
Expand All @@ -14,7 +15,7 @@ import { isEqual } from "lodash";
import { RealizationSurfaceContext } from "./RealizationSurfaceContext";
import { RealizationSurfaceSettings } from "./types";

import { Layer } from "../../../interfaces";
import { BoundingBox, Layer } from "../../../interfaces";

export class RealizationSurfaceLayer
implements Layer<RealizationSurfaceSettings, SurfaceDataFloat_trans | SurfaceDataPng_api>
Expand Down Expand Up @@ -46,6 +47,19 @@ export class RealizationSurfaceLayer
return !isEqual(prevSettings, newSettings);
}

makeBoundingBox(): BoundingBox | null {
const data = this._layerDelegate.getData();
if (!data) {
return null;
}

return {
x: [data.transformed_bbox_utm.min_x, data.transformed_bbox_utm.max_x],
y: [data.transformed_bbox_utm.min_y, data.transformed_bbox_utm.max_y],
z: [0, 0],
};
}

fechData(queryClient: QueryClient): Promise<SurfaceDataFloat_trans | SurfaceDataPng_api> {
let surfaceAddress: FullSurfaceAddress | null = null;
const addrBuilder = new SurfaceAddressBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { isEqual } from "lodash";
import { StatisticalSurfaceContext } from "./StatisticalSurfaceContext";
import { StatisticalSurfaceSettings } from "./types";

import { Layer } from "../../../interfaces";
import { BoundingBox, Layer } from "../../../interfaces";

export class StatisticalSurfaceLayer
implements Layer<StatisticalSurfaceSettings, SurfaceDataFloat_trans | SurfaceDataPng_api>
Expand Down Expand Up @@ -46,6 +46,19 @@ export class StatisticalSurfaceLayer
return !isEqual(prevSettings, newSettings);
}

makeBoundingBox(): BoundingBox | null {
const data = this._layerDelegate.getData();
if (!data) {
return null;
}

return {
x: [data.transformed_bbox_utm.min_x, data.transformed_bbox_utm.max_x],
y: [data.transformed_bbox_utm.min_y, data.transformed_bbox_utm.max_y],
z: [0, 0],
};
}

fechData(queryClient: QueryClient): Promise<SurfaceDataFloat_trans | SurfaceDataPng_api> {
let surfaceAddress: FullSurfaceAddress | null = null;
const addrBuilder = new SurfaceAddressBuilder();
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/modules/2DViewer/layers/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ export enum LayerStatus {
INVALID_SETTINGS = "INVALID_SETTINGS",
}

export type BoundingBox = {
x: [number, number];
y: [number, number];
z: [number, number];
};

export interface FetchDataFunction<TSettings extends Settings, TKey extends keyof TSettings> {
(oldValues: { [K in TKey]: TSettings[K] }, newValues: { [K in TKey]: TSettings[K] }): void;
}
Expand All @@ -41,6 +47,7 @@ export interface Layer<TSettings extends Settings, TData> extends Item {
getLayerDelegate(): LayerDelegate<TSettings, TData>;
doSettingsChangesRequireDataRefetch(prevSettings: TSettings, newSettings: TSettings): boolean;
fechData(queryClient: QueryClient): Promise<TData>;
makeBoundingBox?(): BoundingBox | null;
}

export function instanceofLayer(item: Item): item is Layer<Settings, any> {
Expand Down
23 changes: 15 additions & 8 deletions frontend/src/modules/2DViewer/settings/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,31 @@ export function Settings(props: ModuleSettingsProps<any>): React.ReactNode {
groupDelegate = group.getGroupDelegate();
}

const numSharedSettings = groupDelegate.findChildren((item) => {
return item instanceof SharedSetting;
}).length;

switch (identifier) {
case "view":
groupDelegate.appendChild(new View("New View", colorSet.getNextColor()));
groupDelegate.insertChild(new View("New View", colorSet.getNextColor()), numSharedSettings);
return;
case "observed_surface":
groupDelegate.appendChild(new ObservedSurfaceLayer());
groupDelegate.insertChild(new ObservedSurfaceLayer(), numSharedSettings);
return;
case "statistical_surface":
groupDelegate.appendChild(new StatisticalSurfaceLayer());
groupDelegate.insertChild(new StatisticalSurfaceLayer(), numSharedSettings);
return;
case "realization_surface":
groupDelegate.appendChild(new RealizationSurfaceLayer());
groupDelegate.insertChild(new RealizationSurfaceLayer(), numSharedSettings);
return;
case "realization_polygons":
groupDelegate.appendChild(new RealizationPolygonsLayer());
groupDelegate.insertChild(new RealizationPolygonsLayer(), numSharedSettings);
return;
case "drilled_wellbores":
groupDelegate.appendChild(new DrilledWellTrajectoriesLayer());
groupDelegate.insertChild(new DrilledWellTrajectoriesLayer(), numSharedSettings);
return;
case "realization_grid":
groupDelegate.appendChild(new RealizationGridLayer());
groupDelegate.insertChild(new RealizationGridLayer(), numSharedSettings);
return;
case "ensemble":
groupDelegate.prependChild(new SharedSetting(new Ensemble()));
Expand Down Expand Up @@ -161,13 +165,16 @@ export function Settings(props: ModuleSettingsProps<any>): React.ReactNode {
destination.insertChild(movedItem, position);
}

const hasView = groupDelegate.findChildren((item) => item instanceof View).length > 0;
const adjustedLayerActions = hasView ? LAYER_ACTIONS : LAYER_ACTIONS.filter((group) => group.label === "View");

return (
<div className="h-full flex flex-col gap-1">
<div className="flex-grow flex flex-col min-h-0">
<div className="w-full flex-grow flex flex-col min-h-0">
<div className="flex bg-slate-100 p-2 items-center border-b border-gray-300 gap-2">
<div className="flex-grow font-bold text-sm">Layers</div>
<LayersActions layersActionGroups={LAYER_ACTIONS} onActionClick={handleLayerAction} />
<LayersActions layersActionGroups={adjustedLayerActions} onActionClick={handleLayerAction} />
</div>
<div className="w-full flex-grow flex flex-col relative h-full">
<SortableList
Expand Down
Loading

0 comments on commit 8b153d7

Please sign in to comment.