156 lines
4.5 KiB
TypeScript
156 lines
4.5 KiB
TypeScript
|
import { useRef, useEffect, RefObject } from 'react';
|
||
|
|
||
|
import { useTranslation } from 'react-i18next';
|
||
|
import initI18n from './i18n';
|
||
|
|
||
|
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';
|
||
|
|
||
|
// load localized strings
|
||
|
const match = location.pathname.match(/\/(\w+)/);
|
||
|
if (match && match.length > 1) {
|
||
|
const locale = match[1];
|
||
|
initI18n(locale);
|
||
|
}
|
||
|
|
||
|
export default function Layers({ view, tableRoot }: { view: MapView; tableRoot: RefObject<HTMLDivElement> }) {
|
||
|
const htmlDiv = useRef<HTMLDivElement>(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 (tableRoot && tableRoot.current) {
|
||
|
tableRoot.current.classList.remove('hidden');
|
||
|
tableRoot.current.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 (tableRoot && tableRoot.current) {
|
||
|
tableRoot.current.classList.add('hidden');
|
||
|
}
|
||
|
},
|
||
|
} as unknown as ButtonMenuItem,
|
||
|
],
|
||
|
},
|
||
|
});
|
||
|
};
|
||
|
|
||
|
if (htmlDiv.current) {
|
||
|
const arcGISAPIWidgetContainer = document.createElement('div');
|
||
|
htmlDiv.current.append(arcGISAPIWidgetContainer);
|
||
|
|
||
|
const layerList = new LayerList({
|
||
|
view,
|
||
|
container: htmlDiv.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) {}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return () => {};
|
||
|
});
|
||
|
|
||
|
return <div ref={htmlDiv}></div>;
|
||
|
}
|