Skip to content

Commit

Permalink
Allow creating view annotations using ViewAnnotation component. (#1384)
Browse files Browse the repository at this point in the history
* Allow creating view annotations using ViewAnnotation component.

Allows creating view annotations using Dash.

* Fixed ViewAnnotation handling with Dash

* Removed SubsurfaceViewerDashWrapper story, as it
only works to demonstrate Dash.

* Applied black formatting.

Co-authored-by: Havard Bjerke <[email protected]>
  • Loading branch information
hkfb and Havard Bjerke authored Jan 17, 2023
1 parent e04bfe3 commit 5359393
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 81 deletions.
121 changes: 121 additions & 0 deletions examples/deckgl_annotation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import numpy as np
import xtgeo
import dash
import webviz_subsurface_components as wsc

from utils.xtgeo_surface_to_float32 import get_surface_float32
from utils.xtgeo_polygons_to_json import xtgeo_polygons_to_polylines_geojson

# Import a depth surface and a property surface using xtgeo
depth_surface = xtgeo.surface_from_file("examples/example-data/topvolantis_depth.gri")
property_surface = xtgeo.surface_from_file(
"examples/example-data/topvolantis_seismic_attribute.gri"
)
polygons = xtgeo.polygons_from_file(
"examples/example-data/topvolantis_faultpolygons.pol"
)

app = dash.Dash(__name__)

app.layout = wsc.SubsurfaceViewerDashWrapper(
id="deckgl-map",
layers=[
{
"@@type": "AxesLayer",
"id": "axes-layer",
"bounds": [
depth_surface.xmin,
depth_surface.ymin,
-np.nanmax(depth_surface.values),
depth_surface.xmax,
depth_surface.ymax,
np.nanmin(depth_surface.values),
],
},
{
"@@type": "MapLayer",
"id": "mesh-layer",
"meshUrl": "/map/mesh",
"frame": {
"origin": [depth_surface.xori, depth_surface.yori],
"count": [depth_surface.ncol, depth_surface.nrow],
"increment": [depth_surface.xinc, depth_surface.yinc],
"rotDeg": depth_surface.rotation,
},
"contours": [0, 20],
"isContoursDepth": True,
"gridLines": False,
"material": True,
"colorMapName": "Physics",
"name": "mesh",
},
{
"@@type": "MapLayer",
"id": "mesh-and-property-layer",
"meshUrl": "/map/mesh",
"propertiesUrl": "/map/property",
"frame": {
"origin": [depth_surface.xori, depth_surface.yori],
"count": [depth_surface.ncol, depth_surface.nrow],
"increment": [depth_surface.xinc, depth_surface.yinc],
"rotDeg": depth_surface.rotation,
},
"isContoursDepth": True,
"gridLines": False,
"material": True,
"colorMapName": "Seismic",
"name": "mesh",
},
{
"@@type": "FaultPolygonsLayer",
"id": "fault-layer",
"data": "/faults/faults.json",
"refine": False,
},
],
views={
"layout": [1, 2],
"showLabel": True,
"viewports": [
{
"id": "view_1",
"show3D": False,
"name": "Depth surface",
"layerIds": ["axes-layer", "mesh-layer"],
"isSync": True,
},
{
"id": "view_2",
"show3D": False,
"name": "Property mapped on depth surface",
"layerIds": [
"fault-layer",
"axes-layer",
"mesh-and-property-layer",
],
"isSync": True,
},
],
},
children=[
wsc.ViewAnnotation(id="view_1", children=[wsc.ViewFooter(children="Hugin")]),
wsc.ViewAnnotation(id="view_2", children=[wsc.ViewFooter(children="sdfsfd")]),
],
)


@app.server.route("/map/<map_name>")
def send_map(map_name: str):
if map_name == "mesh":
return get_surface_float32(depth_surface)
if map_name == "property":
return get_surface_float32(property_surface)


@app.server.route("/faults/faults.json")
def send_faults():
return xtgeo_polygons_to_polylines_geojson(polygons, xy_only=True)


if __name__ == "__main__":
app.run_server(debug=True)

This file was deleted.

33 changes: 12 additions & 21 deletions react/src/lib/components/DeckGLMap/SubsurfaceViewerDashWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,18 @@ export interface SubsurfaceViewerDashWrapperProps {
cameraPosition?: ViewStateType | undefined;

children?: React.ReactNode;

/**
* A mapping associating annotation components to view ids.
* Example: {"view_1": <ColorLegend/>}
*/
annotation?: Record<string, unknown>;
}

function mapAnnotation(annotation: Record<string, unknown>) {
return Object.entries(annotation).map(([viewId, annotation]) => (
// @ts-expect-error This is demonstrated to work with js, but with ts it gives error
<View key={viewId} id={viewId}>
{annotation}
</View>
));
function mapAnnotation(annotationContainers: React.ReactNode) {
return React.Children.map(annotationContainers, (annotationContainer) => {
const viewId = (annotationContainer as React.ReactElement).key;
return (
// @ts-expect-error This is demonstrated to work with js, but with ts it gives error
<View key={viewId} id={viewId}>
{annotationContainer}
</View>
);
});
}

const SubsurfaceViewerDashWrapper: React.FC<
Expand All @@ -105,7 +102,6 @@ const SubsurfaceViewerDashWrapper: React.FC<
triggerHome,
triggerResetMultipleWells,
children,
annotation = {},
}: SubsurfaceViewerDashWrapperProps) => {
const mapArgs: DeckGLMapProps = {
id: id,
Expand All @@ -127,10 +123,9 @@ const SubsurfaceViewerDashWrapper: React.FC<
getCameraPosition: getCameraPosition,
triggerHome: triggerHome,
triggerResetMultipleWells: triggerResetMultipleWells,
children: children,
};

return <DeckGLMap {...mapArgs}>{mapAnnotation(annotation)}</DeckGLMap>;
return <DeckGLMap {...mapArgs}>{mapAnnotation(children)}</DeckGLMap>;
};

SubsurfaceViewerDashWrapper.defaultProps = {
Expand Down Expand Up @@ -265,11 +260,7 @@ SubsurfaceViewerDashWrapper.propTypes = {
*/
onMouseEvent: PropTypes.func,

/**
* A mapping associating annotation components to view ids.
* Example: {"view_1": <ColorLegend/>}
*/
annotation: PropTypes.any,
children: PropTypes.any,
};

export default SubsurfaceViewerDashWrapper;
16 changes: 16 additions & 0 deletions react/src/lib/components/DeckGLMap/components/ViewAnnotation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";
import PropTypes from "prop-types";

interface ViewAnnotationProps {
id: string;
children?: React.ReactNode;
}

export const ViewAnnotation: React.FC<ViewAnnotationProps> = ({ children }) => {
return <> {children} </>;
};

ViewAnnotation.propTypes = {
id: PropTypes.string.isRequired,
children: PropTypes.any,
};
2 changes: 2 additions & 0 deletions react/src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { WellsPickInfo } from "./components/DeckGLMap/layers/wells/wellsLayer";
import TerrainMapPickInfo from "./components/DeckGLMap/layers/terrain/terrainMapLayer";
import { FeatureCollection } from "@nebula.gl/edit-modes";
import { ViewFooter } from "./components/DeckGLMap/components/ViewFooter";
import { ViewAnnotation } from "./components/DeckGLMap/components/ViewAnnotation";

export {
HistoryMatch,
Expand Down Expand Up @@ -58,4 +59,5 @@ export {
ViewFooter,
View,
SubsurfaceViewerDashWrapper,
ViewAnnotation,
};
5 changes: 4 additions & 1 deletion react/tsconfig.dash.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
"rootDir": "src/lib"
},
"include": [],
"files": ["src/lib/components/DeckGLMap/components/ViewFooter.tsx"]
"files": [
"src/lib/components/DeckGLMap/components/ViewFooter.tsx",
"src/lib/components/DeckGLMap/components/ViewAnnotation.tsx"
]
}

0 comments on commit 5359393

Please sign in to comment.