geosphere-maps/app/[locale]/layer-list.tsx
2023-10-25 14:51:44 +02:00

146 lines
4.3 KiB
TypeScript

import { useRef, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import MapView from '@arcgis/core/views/MapView';
import LayerList from '@arcgis/core/widgets/LayerList';
import FeatureTable from '@arcgis/core/widgets/FeatureTable';
import ImageryTileLayer from '@arcgis/core/layers/ImageryTileLayer';
import MapImageLayer from '@arcgis/core/layers/MapImageLayer';
import Sublayer from '@arcgis/core/layers/support/Sublayer';
import ButtonMenuItem from '@arcgis/core/widgets/FeatureTable/Grid/support/ButtonMenuItem';
export default function Layers({ view, tableDiv }: { view: MapView; tableDiv: HTMLDivElement }) {
const layerListDiv = useRef<HTMLDivElement | null>(null);
const featureTable = useRef<FeatureTable | null>(null);
const rendered = useRef<boolean>(false);
const { t } = useTranslation();
useEffect(() => {
if (rendered.current) return;
rendered.current = true;
const createTable = async (layer: Sublayer, view: MapView) => {
const tableContainer = document.createElement('div');
tableContainer.className = 'h-full w-full';
if (tableDiv) {
tableDiv.classList.remove('hidden');
tableDiv.append(tableContainer);
}
const featureLayer = await layer.createFeatureLayer();
featureTable.current = new FeatureTable({
view: view,
layer: featureLayer,
container: tableContainer,
menuConfig: {
items: [
{
label: t('layers.table.close'),
iconClass: 'esri-icon-close',
clickFunction: function () {
featureTable.current?.destroy();
if (tableDiv) {
tableDiv.classList.add('hidden');
}
},
} as unknown as ButtonMenuItem,
],
},
});
};
if (layerListDiv.current) {
const arcGISAPIWidgetContainer = document.createElement('div');
layerListDiv.current.append(arcGISAPIWidgetContainer);
const layerList = new LayerList({
view,
container: layerListDiv.current,
selectionEnabled: true,
listItemCreatedFunction: async function (event) {
const item = event.item;
const type = item.layer.type;
if (type === 'imagery-tile' || type === 'map-image') {
item.actionsSections = [
[
{
title: 'Info',
className: 'esri-icon-description',
id: 'info',
},
],
[
{
title: t('layers.increaseOpacity'),
className: 'esri-icon-up',
id: 'increase-opacity',
},
{
title: t('layers.decreaseOpacity'),
className: 'esri-icon-down',
id: 'decrease-opacity',
},
],
];
}
if (item.layer.declaredClass === 'esri.layers.support.Sublayer') {
item.actionsSections = [
[
{
title: 'Table',
className: 'esri-icon-table',
id: 'table',
},
],
];
}
},
});
layerList.on('trigger-action', async (event) => {
const id = event.action.id;
const item = event.item;
const layer = item.layer;
const type = layer.type;
if (id === 'info') {
if (type === 'imagery-tile') {
window.open((layer as ImageryTileLayer).portalItem?.itemPageUrl);
}
if (type === 'map-image') {
window.open((layer as MapImageLayer).portalItem?.itemPageUrl);
}
}
if (id === 'increase-opacity') {
if (layer.opacity < 1) {
layer.opacity += 0.25;
}
}
if (id === 'decrease-opacity') {
if (layer.opacity > 0) {
layer.opacity -= 0.25;
}
}
if (id === 'table') {
featureTable.current?.destroy();
try {
createTable(layer as unknown as Sublayer, view);
} catch (error) {}
}
});
}
}, [t, tableDiv, view]);
return <div ref={layerListDiv}></div>;
}