Skip to content

Commit d63aab2

Browse files
committed
feat: add hook to write the application context
1 parent 941c2ff commit d63aab2

File tree

1 file changed

+221
-0
lines changed

1 file changed

+221
-0
lines changed

src/hooks/useWriteAppContext.ts

+221
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
import OlFeature from 'ol/Feature';
2+
import OlFormatGeoJSON from 'ol/format/GeoJSON';
3+
import OlLayerBase from 'ol/layer/Base';
4+
import OlLayerGroup from 'ol/layer/Group';
5+
import OlLayer from 'ol/layer/Layer';
6+
import OlLayerVector from 'ol/layer/Vector';
7+
import {
8+
toLonLat
9+
} from 'ol/proj';
10+
import OlSourceImageWMS from 'ol/source/ImageWMS';
11+
import {
12+
getUid
13+
} from 'ol/util';
14+
15+
import useMap from '@terrestris/react-geo/dist/Hook/useMap';
16+
import {
17+
DigitizeUtil
18+
} from '@terrestris/react-geo/dist/Util/DigitizeUtil';
19+
20+
import Application, {
21+
DefaultApplicationLayerConfig,
22+
DefaultApplicationTheme,
23+
DefaultApplicationToolConfig,
24+
DefaultLayerTree
25+
} from '@terrestris/shogun-util/dist/model/Application';
26+
27+
import {
28+
ClientTools
29+
} from '../store/toolConfig';
30+
31+
import useAppSelector from './useAppSelector';
32+
import useSHOGunAPIClient from './useSHOGunAPIClient';
33+
34+
const useWriteAppContext = () => {
35+
const map = useMap();
36+
37+
const appId = useAppSelector(state => state.id);
38+
const appTitle = useAppSelector(state => state.title);
39+
const appDescription = useAppSelector(state => state.description);
40+
const appLogoPath = useAppSelector(state => state.logoPath);
41+
const appToolConfig = useAppSelector(state => state.toolConfig);
42+
43+
const client = useSHOGunAPIClient();
44+
45+
if (!map || !client) {
46+
return;
47+
}
48+
49+
const getLayerConfig = (layers: OlLayer[]) => {
50+
const layerConfig = layers
51+
.filter(layer => layer.get('appSettings'))
52+
.map(layer => layer.get('appSettings') as DefaultApplicationLayerConfig);
53+
54+
const externalLayerConfig = getExternalLayerConfig(layers);
55+
56+
return [
57+
...layerConfig,
58+
...externalLayerConfig
59+
];
60+
};
61+
62+
const getExternalLayerConfig = (layers: OlLayer[]) => {
63+
return layers
64+
.filter(layer => layer.get('isExternalLayer'))
65+
.map(layer => ({
66+
layerId: `EXTERNAL-${getUid(layer)}`,
67+
sourceConfig: {
68+
legendUrl: layer.get('legendUrl'),
69+
useBearerToken: false,
70+
// TODO
71+
// attribution: (layer.getSource() as OlSourceImageWMS).getAttributions()(),
72+
layerNames: (layer.getSource() as OlSourceImageWMS).getParams().LAYERS,
73+
url: (layer.getSource() as OlSourceImageWMS).getUrl() || ''
74+
},
75+
clientConfig: {
76+
opacity: layer.getOpacity()
77+
}
78+
} as DefaultApplicationLayerConfig));
79+
};
80+
81+
const getTheme = (): DefaultApplicationTheme => {
82+
const appElement = document.querySelector('.App');
83+
84+
if (!appElement) {
85+
return {};
86+
}
87+
88+
const style = getComputedStyle(appElement);
89+
90+
return {
91+
primaryColor: style.getPropertyValue('--primaryColor'),
92+
secondaryColor: style.getPropertyValue('--secondaryColor'),
93+
complementaryColor: style.getPropertyValue('--complementaryColor')
94+
};
95+
};
96+
97+
const getDigitizedFeatures = () => {
98+
const clonedFeatures: OlFeature[] = [];
99+
const mapProjection = map.getView().getProjection().getCode();
100+
const digitizeLayer = DigitizeUtil.getDigitizeLayer(map);
101+
const digitizedFeatures = digitizeLayer.getSource()?.getFeatures();
102+
103+
if (!digitizedFeatures || digitizedFeatures.length === 0) {
104+
return [];
105+
}
106+
107+
digitizedFeatures.forEach(feat => {
108+
const clonedFeature = feat.clone();
109+
clonedFeature.getGeometry()?.transform(mapProjection, 'EPSG:4326');
110+
clonedFeatures.push(clonedFeature);
111+
});
112+
113+
return new OlFormatGeoJSON().writeFeaturesObject(clonedFeatures);
114+
};
115+
116+
const getDigitizeStyle = () => {
117+
const digitizeLayer = DigitizeUtil.getDigitizeLayer(map);
118+
119+
return digitizeLayer.get('gsStyle');
120+
};
121+
122+
const getToolConfig = (): DefaultApplicationToolConfig[] => {
123+
const filteredToolConfig = appToolConfig.filter(toolConfig => toolConfig.name !== ClientTools.DRAW_TOOLS);
124+
const drawToolConfig = appToolConfig.find(toolConfig => toolConfig.name === ClientTools.DRAW_TOOLS);
125+
126+
return [
127+
...filteredToolConfig,
128+
{
129+
name: ClientTools.DRAW_TOOLS,
130+
config: {
131+
visible: drawToolConfig?.config.visible,
132+
features: getDigitizedFeatures(),
133+
style: getDigitizeStyle()
134+
}
135+
}
136+
];
137+
};
138+
139+
const getLayerTreeChildren = (layers: OlLayerBase[]): DefaultLayerTree[] => {
140+
const children: DefaultLayerTree[] = [];
141+
142+
for (const layer of layers) {
143+
if (layer.get('hideInLayerTree')) {
144+
continue;
145+
}
146+
147+
if (layer instanceof OlLayerVector) {
148+
continue;
149+
}
150+
151+
if (layer instanceof OlLayerGroup) {
152+
children.push({
153+
title: layer.get('name'),
154+
checked: layer.getVisible(),
155+
children: getLayerTreeChildren([...layer.getLayers().getArray()].reverse())
156+
});
157+
}
158+
159+
if (layer instanceof OlLayer) {
160+
if (layer.get('isExternalLayer')) {
161+
children.push({
162+
title: layer.get('name'),
163+
checked: layer.getVisible(),
164+
layerId: `EXTERNAL-${getUid(layer)}`
165+
});
166+
} else {
167+
children.push({
168+
title: layer.get('name'),
169+
checked: layer.getVisible(),
170+
layerId: layer.get('shogunId')
171+
});
172+
}
173+
}
174+
}
175+
176+
return children;
177+
};
178+
179+
const writeAppContext = () => {
180+
const view = map.getView();
181+
const center = view.getCenter();
182+
const layers = map.getLayers().getArray();
183+
const theme = getTheme();
184+
185+
const app: Application = {
186+
id: appId,
187+
name: appTitle,
188+
created: new Date(),
189+
modified: new Date(),
190+
stateOnly: true,
191+
clientConfig: {
192+
description: appDescription,
193+
mapView: {
194+
center: center ? toLonLat(center, view.getProjection()) as [number, number] : [0, 0],
195+
zoom: view.getZoom(),
196+
resolutions: view.getResolutions(),
197+
projection: view.getProjection().getCode(),
198+
extent: view.get('extent')
199+
},
200+
theme: {
201+
...theme,
202+
...{
203+
logoPath: appLogoPath
204+
}
205+
}
206+
},
207+
layerTree: {
208+
checked: true,
209+
children: getLayerTreeChildren([...layers].reverse())
210+
},
211+
layerConfig: getLayerConfig(map.getLayerGroup().getLayersArray()),
212+
toolConfig: getToolConfig()
213+
};
214+
215+
return app;
216+
};
217+
218+
return writeAppContext;
219+
};
220+
221+
export default useWriteAppContext;

0 commit comments

Comments
 (0)