import { useRef, useEffect, RefObject } from 'react'; import { useTranslation } from 'react-i18next'; import initI18n from './i18n'; import MapView from '@arcgis/core/views/MapView'; import Basemap from '@arcgis/core/Basemap'; import esriRequest from '@arcgis/core/request'; import BaseTileLayer from '@arcgis/core/layers/BaseTileLayer'; import BasemapGallery from '@arcgis/core/widgets/BasemapGallery'; import VectorTileLayer from '@arcgis/core/layers/VectorTileLayer'; import TileLayer from '@arcgis/core/layers/TileLayer'; const BEVURL = 'https://maps.bev.gv.at/tiles/{z}/{x}/{y}.png'; // load localized strings const match = location.pathname.match(/\/(\w+)/); if (match && match.length > 1) { const locale = match[1]; initI18n(locale); } export default function Basemaps({ view }: { view: MapView }) { const basemapGalleryContainer = useRef(null); const rendered = useRef(false); const { t } = useTranslation(); const BEVTileLayer = (BaseTileLayer as any).createSubclass({ // define instance properties properties: { urlTemplate: null, }, // generate the tile url for a given level, row and column getTileUrl: function (level: number, row: number, col: number) { const z = level.toString().padStart(2, '0'); let x = row.toString().padStart(9, '0'); let y = col.toString().padStart(9, '0'); // this is the BEV tiling scheme x = x.substring(0, 3) + '/' + x.substring(3, 3) + '/' + x.substring(6, 3); y = y.substring(0, 3) + '/' + y.substring(3, 3) + '/' + y.substring(6, 3); return this.urlTemplate.replace(/\{z\}/g, z).replace(/\{x\}/g, y).replace(/\{y\}/g, x); }, // This method fetches tiles for the specified level and size. fetchTile: function (level: number, row: number, col: number, options: any) { // get the url for this tile const url = this.getTileUrl(level, row, col); // request for tiles based on the generated url // the signal option ensures that obsolete requests are aborted return esriRequest(url, { responseType: 'image', }).then( function (this: any, response: any) { // when esri request resolves successfully // get the image from the response const image = response.data; const width = this.tileInfo.size[0]; const height = this.tileInfo.size[0]; // create a canvas with 2D rendering context const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); canvas.width = width; canvas.height = height; // Draw the blended image onto the canvas. context?.drawImage(image, 0, 0, width, height); const imageData = context?.getImageData(0, 0, canvas.width, canvas.height); if (imageData) context?.putImageData(imageData, 0, 0); return canvas; }.bind(this) ); }, copyright: t('basemaps.copyright-bev'), }); useEffect(() => { if (rendered.current) return; rendered.current = true; if (view) { const topoLayer = new BEVTileLayer({ urlTemplate: BEVURL, title: 'BEV-Topografie', }); const basemapBEV = new Basemap({ baseLayers: [topoLayer], title: t('basemaps.basemap-bev-title'), id: 'basemap', thumbnailUrl: 'https://gis.geosphere.at/portal/sharing/rest/content/items/1a94736328a1458abe435d23508f1822/data', }); const basemapAT = new Basemap({ portalItem: { id: 'df7d6cc9be754db8970614d2ee661f57', portal: { url: 'https://gis.geosphere.at/portal', }, }, }); const basemapOSM = new Basemap({ portalItem: { id: '5f6efd84434842fb9dcdcf6b9116dcd9', portal: { url: 'https://gis.geosphere.at/portal' }, }, }); const lightgrayBase = new VectorTileLayer({ url: 'https://gis.geosphere.at/portal/sharing/rest/content/items/291da5eab3a0412593b66d384379f89f/resources/styles/root.json', opacity: 0.5, }); const lightGrayReference = new VectorTileLayer({ url: 'https://gis.geosphere.at/portal/sharing/rest/content/items/1768e8369a214dfab4e2167d5c5f2454/resources/styles/root.json', opacity: 1, }); const worldHillshade = new TileLayer({ url: 'https://services.arcgisonline.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer', }); const basemapEsri = new Basemap({ baseLayers: [worldHillshade, lightgrayBase, lightGrayReference], title: t('basemaps.basemap-esri-title'), thumbnailUrl: 'https://gis.geosphere.at/portal/sharing/rest/content/items/3eb1510943be4f29ae01c01ce229d8ba/data', }); const basemapGalleryDiv = document.createElement('div'); basemapGalleryContainer.current?.append(basemapGalleryDiv); new BasemapGallery({ container: basemapGalleryDiv, view: view, source: [basemapAT, basemapBEV, basemapOSM, basemapEsri], }); } return () => {}; }); return
; }