geosphere-maps/app/[locale]/map.tsx
2023-09-22 11:33:13 +02:00

122 lines
3.2 KiB
TypeScript

import { useRef, useEffect, lazy } from 'react';
import { createRoot } from 'react-dom/client';
import '@esri/calcite-components/dist/calcite/calcite.css';
import MapView from '@arcgis/core/views/MapView.js';
import WebMap from '@arcgis/core/WebMap.js';
import esriConfig from '@arcgis/core/config.js';
import LayerList from '@arcgis/core/widgets/LayerList';
import Expand from '@arcgis/core/widgets/Expand';
import ScaleBar from '@arcgis/core/widgets/ScaleBar.js';
import WMTSLayer from '@arcgis/core/layers/WMTSLayer';
import Map from '@arcgis/core/Map.js';
import Basemap from '@arcgis/core/Basemap';
import * as reactiveUtils from '@arcgis/core/core/reactiveUtils.js';
import * as intl from '@arcgis/core/intl.js';
// set asset path for ArcGIS Maps SDK widgets
esriConfig.assetsPath = './assets';
let mapView: MapView;
const webMapID = '7d0768f73d3e4be2b32c22274c600cb3';
// lazy load Print component
const Print = lazy(() => import('./print'));
export default function MapComponent({ locale }: { locale: string }) {
const printRoot = useRef<any>(null);
const mapRef = useRef(null);
const maskRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (mapRef.current) {
// set locale for ArcGIS Maps SDK widgets
intl.setLocale(locale);
const webMap = new WebMap({
portalItem: {
id: webMapID,
portal: {
url: 'https://gis.geosphere.at/portal',
},
},
});
const wmtsLayer = new WMTSLayer({
url: 'https://mapsneu.wien.gv.at/basemapneu',
});
const basemap = new Basemap({
baseLayers: [wmtsLayer],
});
const map = new Map({
basemap: basemap,
});
const mapView = new MapView({
container: mapRef.current,
map: map,
});
webMap.load().then(() => {
map.layers = webMap.layers;
});
const layerList = new LayerList({
view: mapView,
});
const layerListExpand = new Expand({
content: layerList,
});
const container = document.createElement('div');
const printExpand = new Expand({
content: container,
expandIcon: 'print',
label: 'Print',
});
reactiveUtils.watch(
() => printExpand.expanded,
(expanded) => {
if (expanded) {
printRoot.current = createRoot(container);
printRoot.current.render(<Print view={mapView} mask={maskRef}></Print>);
} else {
maskRef.current?.classList.add('hidden');
printRoot.current.unmount();
}
}
);
const scaleBar = new ScaleBar({
view: mapView,
unit: 'metric',
});
mapView.ui.add([layerListExpand, printExpand], 'top-right');
mapView.ui.add([scaleBar], 'bottom-left');
}
return () => {
mapView.destroy();
if (printRoot.current) {
printRoot.current.unmount();
}
};
}, [mapRef, maskRef]);
return (
<div className="h-screen overflow-hidden">
<div ref={mapRef} className="h-screen"></div>
<div
ref={maskRef}
className="hidden absolute bg-red-300 border-2 border-red-600 pointer-events-none opacity-50"
></div>
</div>
);
}