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
JavaScript
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 };