'use client'; 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 type SimpleFillSymbol from '@arcgis/core/symbols/SimpleFillSymbol'; import './esri-ui-grundlagenkarte.css'; import { Vienna, Austria } from '@/public/borders-vienna-austria'; import { BASEMAP_AT_URL, AMPEL_EWS_URL, RESOURCES_EWS_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 { updateAmpelkarteEWS } from '@/redux/ampelkarteEWSSlice'; import { updateResourcesEWS } from '@/redux/resourcesEWSSlice'; import { updateScreenshot } from '@/redux/screenshotSlice'; import { useAppDispatch } from '@/redux/hooks'; import PanelGrundlagenkarte from './panel-grundlagenkarte'; // set path for local assets esriConfig.assetsPath = '/assets'; export default function MapComponent() { const dispatch = useAppDispatch(); const mapDiv = useRef(null); const [address, setAddress] = useState([]); const isMobile = useMediaQuery({ maxWidth: 480 }); useEffect(() => { let handle: IHandle; let view: MapView; if (mapDiv.current) { dispatch(updateAmpelkarteEWS([])); dispatch(updateResourcesEWS([])); dispatch(updateScreenshot('')); 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_ews = new FeatureLayer({ url: AMPEL_EWS_URL + '/0', title: 'Mögliche Einschränkungen', visible: false, listMode: 'show', opacity: 0.5, }); const resources_ews = new MapImageLayer({ title: 'Ressourcen', url: RESOURCES_EWS_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_ews, ampelkarte_ews, viennaGraphicsLayer], }); const layerList = new LayerList({ view, listItemCreatedFunction: addPanelInfo, }); 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 && dispatch) { takeScreenshot(view, event.mapPoint, dispatch, true); getAddress(event.mapPoint, setAddress); identifyAllLayers(view, event.mapPoint, dispatch, 'EWS'); } }); // 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, mapDiv]); return (
); } const addPanelInfo = (event: any) => { let item = event.item; switch (item.layer.id) { case 0: item.panel = { content: 'mittlere jährliche Bodentemperatur laut Satellitendaten (MODIS)', className: 'esri-icon-description', }; break; case 1: item.panel = { content: 'mittlere Temperatur des Untergrunds für eine Tiefe von 0 bis 100 m', className: 'esri-icon-description', }; break; case 2: item.panel = { content: 'mittlere konduktive Wärmeleitfähigkeit des Untergrunds für eine Tiefe von 0 bis 100 m', className: 'esri-icon-description', }; break; case 3: item.panel = { content: 'Entzugsleistung einer 100 m tiefen Einzelsonde im standortbezogenen Normbetrieb (Heizen und Kühlen mit Normbetriebsstunden eines typischen Wohngebäudes am Standort)', className: 'esri-icon-description', }; break; case 4: item.panel = { content: 'Entzugsleistung einer 100 m tiefen Einzelsonde im saisonalem Speicherbetrieb (die im Winter zur Heizung entzogene Wärme wird im Sommer vollständig wieder zurückgegeben)', className: 'esri-icon-description', }; break; case 5: item.panel = { content: 'flächenspezifische Jahresenergie eines 1156 m² großen und 100 m tiefen Sondenfeldes im standortbezogenen Normbetrieb (4 x 4 Sonden mit je 10 m Abstand - Heizen und Kühlen mit Normbetriebsstunden eines typischen Wohngebäudes am Standort)', className: 'esri-icon-description', }; break; case 6: item.panel = { content: 'flächenspezifische Jahresenergie eines 1156 m² großen und 100 m tiefen Sondenfeldes im saisonalem Speicherbetrieb (7 x 7 Sonden mit je 5 m Abstand - die im Winter zur Heizung entzogene Wärme wird im Sommer vollständig wieder zurückgegeben)', className: 'esri-icon-description', }; break; case 7: item.panel = { content: 'mittlere Jahresbetriebsstunden für Heizen', className: 'esri-icon-description', }; break; case 8: item.panel = { content: 'mittlere Jahresbetriebsstunden für Kühlen', className: 'esri-icon-description', }; break; default: break; } };