Skip to content

Commit

Permalink
Use wsc.SubsurfaceViewer in map module (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKallekleiv authored Apr 26, 2023
1 parent 1f486cc commit e3fab0c
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 62 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/webviz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
- name: 🏗️ Build JavaScript bundle
working-directory: ./frontend
run: |
# Building wsc requires increasing memory allocated to Node
export NODE_OPTIONS="--max_old_space_size=4096"
npm run build
- name: 🕵️ Check code style & linting
Expand Down
66 changes: 66 additions & 0 deletions backend/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pydantic = "^1.10.4"
numpy = "^1.24.1"
sumo-wrapper-python = {git = "https://github.com/equinor/sumo-wrapper-python.git", rev = "master"}
fmu-sumo = {git = "https://github.com/equinor/fmu-sumo.git", rev = "afb37e944fdf510c68033e11b588ff6f44d7a2b6"}
orjson = "^3.8.10"


[tool.poetry.group.dev.dependencies]
Expand Down
27 changes: 11 additions & 16 deletions backend/src/fastapi_app/routers/surface/converters.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
import base64

import orjson
import xtgeo

from src.services.utils.surface_to_png import surface_to_png_bytes_optimized
from src.services.utils.surface_orientation import (
calc_surface_orientation_for_colormap_layer,
)
from src.services.utils.surface_to_float32 import surface_to_float32_array
from . import schemas


def to_api_surface_data(xtgeo_surf: xtgeo.RegularSurface) -> schemas.SurfaceData:
"""
Create API SurfaceData from xtgeo regular surface
"""
png_bytes: bytes = surface_to_png_bytes_optimized(xtgeo_surf)
base64_data = base64.b64encode(png_bytes).decode("ascii")

surf_orient = calc_surface_orientation_for_colormap_layer(xtgeo_surf)
float32values = surface_to_float32_array(xtgeo_surf)

return schemas.SurfaceData(
x_min=surf_orient.x_min,
x_max=surf_orient.x_max,
y_min=surf_orient.y_min,
y_max=surf_orient.y_max,
x_ori=xtgeo_surf.xori,
y_ori=xtgeo_surf.yori,
x_count=xtgeo_surf.ncol,
y_count=xtgeo_surf.nrow,
x_inc=xtgeo_surf.xinc,
y_inc=xtgeo_surf.yinc,
val_min=xtgeo_surf.values.min(),
val_max=xtgeo_surf.values.max(),
rot_deg=surf_orient.rot_around_xmin_ymax_deg,
base64_encoded_image=f"{base64_data}",
rot_deg=xtgeo_surf.rotation,
mesh_data=orjson.dumps(float32values),
)
14 changes: 8 additions & 6 deletions backend/src/fastapi_app/routers/surface/schemas.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from enum import Enum
from typing import List, Tuple, Dict
from typing import List

from pydantic import BaseModel

Expand Down Expand Up @@ -27,11 +27,13 @@ class StaticSurfaceDirectory(BaseModel):


class SurfaceData(BaseModel):
x_min: float
x_max: float
y_min: float
y_max: float
x_ori: float
y_ori: float
x_count: int
y_count: int
x_inc: float
y_inc: float
val_min: float
val_max: float
rot_deg: float
base64_encoded_image: str
mesh_data: str
17 changes: 17 additions & 0 deletions backend/src/services/utils/surface_to_float32.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import List

import numpy as np
import xtgeo


def surface_to_float32_array(surface: xtgeo.RegularSurface) -> List[float]:
values = surface.values.astype(np.float32)
values.fill_value = np.nan
values = np.ma.filled(values)

# Rotate 90 deg left.
# This will cause the width of to run along the X axis
# and height of along Y axis (starting from bottom.)
values = np.rot90(values)

return values.flatten().tolist()
3 changes: 3 additions & 0 deletions frontend-prod.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ COPY --chown=node:node . /usr/src/app
WORKDIR /usr/src/app/frontend
ENV NODE_ENV production

# Building wsc requires increasing memory allocated to Node
ENV NODE_OPTIONS="--max-old-space-size=4096"

RUN npm ci --ignore-scripts --include=dev && npm run build && node compress_static.cjs

###########################################
Expand Down
12 changes: 7 additions & 5 deletions frontend/src/api/models/SurfaceData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
/* eslint-disable */

export type SurfaceData = {
x_min: number;
x_max: number;
y_min: number;
y_max: number;
x_ori: number;
y_ori: number;
x_count: number;
y_count: number;
x_inc: number;
y_inc: number;
val_min: number;
val_max: number;
rot_deg: number;
base64_encoded_image: string;
mesh_data: string;
};

77 changes: 42 additions & 35 deletions frontend/src/modules/Map/MapView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useElementSize } from "@lib/hooks/useElementSize";
import { useSurfaceDataQueryByAddress } from "./MapQueryHooks";
import { MapState } from "./MapState";
import { makeSurfAddrString } from "./SurfAddr";

import {SubsurfaceViewer} from "@webviz/subsurface-components"
//-----------------------------------------------------------------------------------------------------------
export function MapView({ moduleContext }: ModuleFCProps<MapState>) {
const wrapperDivRef = React.useRef<HTMLDivElement>(null);
Expand All @@ -22,41 +22,48 @@ export function MapView({ moduleContext }: ModuleFCProps<MapState>) {

const surfDataQuery = useSurfaceDataQueryByAddress(surfAddr);
const surfAddrAsAny = surfAddr as any;
if (surfDataQuery.data) {
return (
<div className="relative w-full h-full flex flex-col">
<SubsurfaceViewer
id="deckgl"
layers={[ {
"@@type": "MapLayer",
"id": "mesh-layer",
"meshData": JSON.parse(surfDataQuery.data?.mesh_data),
"frame": {
"origin": [
surfDataQuery.data?.x_ori,
surfDataQuery.data?.y_ori
],
"count": [
surfDataQuery.data?.x_count,
surfDataQuery.data?.y_count
],
"increment": [
surfDataQuery.data?.x_inc,
surfDataQuery.data?.y_inc
],
"rotDeg": surfDataQuery.data?.rot_deg,

},

"contours": [
0,
100
],
"isContoursDepth": true,
"gridLines": false,
"material": true,
"smoothShading": true,
"colorMapName": "Physics"
},
]}
/>


return (
<div className="w-full h-full flex flex-col">
<div>
addressType: {surfAddr?.addressType ?? "---"}
<br />
caseUuid: {surfAddr?.caseUuid ?? "---"}
<br />
ensembleName: {surfAddr?.ensemble ?? "---"}
<br />
surfaceName: {surfAddr?.name ?? "---"}
<br />
surfaceAttribute: {surfAddr?.attribute ?? "---"}
<br />
timeOrInterval: {surfAddrAsAny?.timeOrInterval ?? "---"}
<br />
realizationNum: {surfAddrAsAny?.realizationNum ?? "---"}
<br />
statisticFunction: {surfAddrAsAny?.statisticFunction ?? "Single realization"}
</div>
<br />
min x,y: {surfDataQuery.data?.x_min.toFixed(2)}, {surfDataQuery.data?.y_min.toFixed(2)}
<br />
min/max val: {surfDataQuery.data?.val_min.toFixed(2)}, {surfDataQuery.data?.val_max.toFixed(2)}
<br />
rot: {surfDataQuery.data?.rot_deg.toFixed(2)}
<br />
renderCount: {renderCount.current}
<div className="flex-grow h-0" ref={wrapperDivRef}>
<img
alt={surfDataQuery.status}
src={surfDataQuery.data ? `data:image/png;base64,${surfDataQuery.data.base64_encoded_image}` : ""}
style={{ objectFit: "contain", width: wrapperDivSize.width, height: wrapperDivSize.height }}
></img>
</div>
</div>
);
}
return (<div/>)
}

0 comments on commit e3fab0c

Please sign in to comment.