UNPKG

react-arcgis-wmws

Version:

React component to display a public arcgis online webmap, webscene or feature table. Uses the ESM version of the ArcGIS Javascript API. Does not use esri-loader.

225 lines (219 loc) 7.46 kB
import React, { useRef, useEffect, useState } from 'react'; import config from '@arcgis/core/config'; import WebMap from '@arcgis/core/WebMap'; import MapView from '@arcgis/core/views/MapView'; import Legend from '@arcgis/core/widgets/Legend'; import WebScene from '@arcgis/core/WebScene'; import SceneView from '@arcgis/core/views/SceneView'; import '@arcgis/core/assets/esri/themes/light/main.css'; import Layer from '@arcgis/core/layers/Layer'; import FeatureTable from '@arcgis/core/widgets/FeatureTable'; const WebMapView = ({ itemId, dockPopup, showLegend, portalUrl = 'https://www.arcgis.com', ...props }) => { const viewDivRef = useRef(null); const ViewContainer = React.createElement("div", { ref: viewDivRef, ...props }); const legendRef = useRef(null); const viewRef = useRef(null); useEffect(() => { const map = new WebMap({ portalItem: { id: itemId, portal: { url: portalUrl } } }); const view = new MapView({ map, container: viewDivRef.current }); viewRef.current = view; return () => { legendRef.current && legendRef.current.destroy(); map.destroy(); view.destroy(); legendRef.current = null; viewRef.current = null; }; }, [itemId, portalUrl]); useEffect(() => { if (viewRef.current) { const view = viewRef.current; if (dockPopup) { view.popup.dockOptions.breakpoint = { width: 2400, height: 2400 }; view.popup.dockEnabled = true; } else { view.popup.dockOptions.breakpoint = false; view.popup.dockEnabled = false; } } }, [dockPopup]); useEffect(() => { if (viewRef.current) { const view = viewRef.current; if (legendRef.current) { view.ui.remove(legendRef.current); legendRef.current.destroy(); legendRef.current = null; } if (showLegend) { const legend = new Legend({ view, style: 'card' }); legendRef.current = legend; view.ui.add(legend, 'bottom-left'); } } }, [showLegend, viewRef.current]); return ViewContainer; }; const WebSceneView = ({ itemId, portalUrl = 'https://www.arcgis.com', dockPopup, showLegend, ...props }) => { const viewDivRef = useRef(null); const ViewContainer = React.createElement("div", { ref: viewDivRef, ...props }); const viewRef = useRef(null); const legendRef = useRef(null); useEffect(() => { const scene = new WebScene({ portalItem: { id: itemId, portal: { url: portalUrl } } }); const view = new SceneView({ map: scene, container: viewDivRef.current }); viewRef.current = view; return () => { legendRef.current && legendRef.current.destroy(); scene.destroy(); view.destroy(); legendRef.current = null; viewRef.current = null; }; }, [itemId, portalUrl]); useEffect(() => { if (viewRef.current) { const view = viewRef.current; if (dockPopup) { view.popup.dockOptions.breakpoint = { width: 2400, height: 2400 }; view.popup.dockEnabled = true; } else { view.popup.dockOptions.breakpoint = false; view.popup.dockEnabled = false; } } }, [dockPopup]); useEffect(() => { if (viewRef.current) { const view = viewRef.current; if (legendRef.current) { view.ui.remove(legendRef.current); legendRef.current.destroy(); legendRef.current = null; } if (showLegend) { const legend = new Legend({ view, style: 'card' }); legendRef.current = legend; view.ui.add(legend, 'bottom-left'); } } }, [showLegend, viewRef.current]); return ViewContainer; }; config.request.useIdentity = false; const Viewer = ({ dimension, itemId, dockPopup = true, showLegend = false, env = 'prod', ...props }) => { let portalSub = 'www'; if (env == 'dev') { portalSub = 'devext'; } else if (env == 'qa' || env == 'uat') { portalSub = 'qaext'; } const portal = `https://${portalSub}.arcgis.com`; return dimension == '3d' ? React.createElement(WebSceneView, { itemId: itemId, portalUrl: portal, dockPopup: dockPopup, showLegend: showLegend, ...props }) : React.createElement(WebMapView, { itemId: itemId, portalUrl: portal, dockPopup: dockPopup, showLegend: showLegend, ...props }); }; function resolveLayer(lyr) { return new Promise((resolve, reject) => { if (lyr.type == 'feature') { resolve(lyr); } else if (lyr.type == 'scene') { resolve(lyr); } else { reject(`Layer ${lyr.title} of ${lyr.type} is not allowed to be shown in a feature table`); } }); } function layerFromId(id, portalUrl = 'https://www.arcgis.com') { return Layer.fromPortalItem({ portalItem: ({ id, portal: ({ url: portalUrl }) }) }).then(resolveLayer); } function layerFromUrl(url) { return Layer.fromArcGISServerUrl({ url }).then(resolveLayer); } config.request.useIdentity = false; const TableView = ({ itemId, url, layer, env = 'prod', ...props }) => { const tableDivRef = useRef(null); const TableContainer = React.createElement("div", { ref: tableDivRef, ...props }); const [tableLayer, setTableLayer] = useState(); const tableRef = useRef(); function tableCleanUp() { if (tableRef.current && tableDivRef.current) { tableDivRef.current.innerHTML = ''; tableRef.current = undefined; } } useEffect(() => { if (layer) { setTableLayer(layer); } else if (itemId) { let portalSub = 'www'; if (env == 'dev') { portalSub = 'devext'; } else if (env == 'qa' || env == 'uat') { portalSub = 'qaext'; } const portal = `https://${portalSub}.arcgis.com`; layerFromId(itemId, portal).then((lyr) => { setTableLayer(lyr); }); } else if (url) { layerFromUrl(url).then((lyr) => { setTableLayer(lyr); }); } }, [itemId, url, layer, env]); useEffect(() => { tableCleanUp(); if (tableLayer) { tableRef.current = new FeatureTable({ layer: tableLayer, container: tableDivRef.current, visibleElements: { selectionColumn: false } }); } return () => { tableCleanUp(); }; }, [tableLayer]); return TableContainer; }; export { TableView, Viewer };