geothermie-atlas/app/gwwp/grundlagenkarte-gwwp.tsx

181 lines
5.4 KiB
TypeScript

import { useEffect, useRef, useState } from 'react';
import { useMediaQuery } from 'react-responsive';
import ArcGISMap from '@arcgis/core/Map';
import Extent from '@arcgis/core/geometry/Extent';
import MapView from '@arcgis/core/views/MapView';
import Basemap from '@arcgis/core/Basemap';
import MapImageLayer from '@arcgis/core/layers/MapImageLayer';
import WMTSLayer from '@arcgis/core/layers/WMTSLayer';
import SpatialReference from '@arcgis/core/geometry/SpatialReference';
import Search from '@arcgis/core/widgets/Search';
import ScaleBar from '@arcgis/core/widgets/ScaleBar';
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer';
import Graphic from '@arcgis/core/Graphic';
import LayerList from '@arcgis/core/widgets/LayerList';
import Zoom from '@arcgis/core/widgets/Zoom';
import Legend from '@arcgis/core/widgets/Legend';
import FeatureLayer from '@arcgis/core/layers/FeatureLayer';
import Polygon from '@arcgis/core/geometry/Polygon';
import esriConfig from '@arcgis/core/config';
import { watch } from '@arcgis/core/core/reactiveUtils';
import SimpleFillSymbol from '@arcgis/core/symbols/SimpleFillSymbol';
import './esri-ui-grundlagenkarte.css';
import { Vienna, Austria } from '@/public/borders-vienna-austria';
import { BASEMAP_AT_URL, AMPEL_GWWP_URL, RESOURCES_GWWP_URL, SRS } from '@/app/config/config';
import getAddress from '@/app/utils/getAddress';
import identifyAllLayers from '@/app/utils/identify';
import takeScreenshot from '@/app/utils/screenshot';
import { useAppDispatch } from '@/redux/hooks';
import PanelGrundlagenkarte from './panel-grundlagenkarte-gwwp';
// set path for local assets
esriConfig.assetsPath = '/assets';
export default function MapComponent() {
const dispatch = useAppDispatch();
const isMobile = useMediaQuery({ maxWidth: 480 });
const mapDiv = useRef<HTMLDivElement | null>(null);
const [address, setAddress] = useState<string[]>([]);
useEffect(() => {
let view: MapView;
let handle: IHandle;
if (mapDiv.current) {
view = new MapView({
container: mapDiv.current,
extent: new Extent({
xmin: -19000,
ymin: 325000,
xmax: 29000,
ymax: 360000,
spatialReference: new SpatialReference({ wkid: SRS }),
}),
popupEnabled: false,
});
let viennaGraphic = new Graphic({
geometry: new Polygon({ rings: [Austria, Vienna], spatialReference: { wkid: SRS } }),
symbol: {
type: 'simple-fill',
color: [209, 213, 219, 0.65],
style: 'solid',
outline: {
color: 'white',
width: 0,
},
} as unknown as SimpleFillSymbol,
});
// graphic layers
let viennaGraphicsLayer = new GraphicsLayer({ title: 'Wien', listMode: 'hide' });
viennaGraphicsLayer.add(viennaGraphic);
const ampelkarte_gwwp = new FeatureLayer({
url: AMPEL_GWWP_URL + '/0',
title: 'Mögliche Einschränkungen',
visible: false,
listMode: 'show',
opacity: 0.5,
});
const resources_gwwp = new MapImageLayer({
title: 'Ressourcen',
url: RESOURCES_GWWP_URL,
visible: false,
listMode: 'show',
opacity: 0.5,
});
// basemap in Viennese coordinate system due to tranformation inaccuracies from MGI to WGS84
// default transformation in ArcGIS API from MGI to WGS84 is 1306
// transformation 1618 is recommended
const basemap_at = new WMTSLayer({
url: BASEMAP_AT_URL,
listMode: 'hide',
});
let basemap = new Basemap({
baseLayers: [basemap_at],
title: 'basemap.at',
id: 'basemap.at',
spatialReference: { wkid: SRS },
});
let arcgisMap = new ArcGISMap({
basemap: basemap,
layers: [resources_gwwp, ampelkarte_gwwp, viennaGraphicsLayer],
});
const layerList = new LayerList({
view,
});
const search = new Search({
view,
popupEnabled: true,
});
const scaleBar = new ScaleBar({
view: view,
unit: 'metric',
});
const zoom = new Zoom({
view,
layout: 'horizontal',
});
const legend = new Legend({
view,
});
// register event handler for mouse clicks
view.on('immediate-click', (event) => {
if (setAddress) {
takeScreenshot(view, event.mapPoint, dispatch, true);
getAddress(event.mapPoint, setAddress);
identifyAllLayers(view, event.mapPoint, dispatch, 'GWWP');
}
});
// add map to view
view.map = arcgisMap;
// add UI components
view.ui.components = [];
if (!isMobile) {
view.ui.add([zoom, search, layerList], 'top-left');
view.ui.add(scaleBar, 'bottom-left');
}
view.when(() => {
handle = watch(
() => view.map?.layers?.map((layer) => layer.visible),
() => {
if (view.map?.layers?.some((layer) => layer.title !== 'Wien' && layer.visible === true)) {
view.ui?.add(legend, 'top-left');
} else {
view.ui?.remove(legend);
}
}
);
});
}
return () => {
handle?.remove();
view?.destroy();
};
}, [dispatch, isMobile]);
return (
<div ref={mapDiv} className="absolute top-16 bottom-0 w-full">
<PanelGrundlagenkarte address={address}></PanelGrundlagenkarte>
</div>
);
}