This sample demonstrates how to create ViewshedAnalysis and how to place Viewsheds in a 3D scene.
// Initialize viewshed analysis and add it to the view.
const viewshedAnalysis = new ViewshedAnalysis();
viewElement.analyses.add(viewshedAnalysis);
// Create the viewshed shape programmatically and add it to the analysis.
const programmaticViewshed = new Viewshed({
observer: {
spatialReference: SpatialReference.WebMercator,
x: -9754426,
y: 5143111,
z: 330,
},
farDistance: 900, // In meters
tilt: 84, // Tilt of 0 looks down, tilt of 90 looks parallel to the ground, tilt of 180 looks up to the sky
heading: 63, // Counted clockwise from North
horizontalFieldOfView: 85,
verticalFieldOfView: 60,
});
viewshedAnalysis.viewsheds.add(programmaticViewshed);
Place additional viewsheds using a custom UI element by calling the place() method on the analysis view.
// Access the viewshed's analysis view.
const analysisView = await viewElement.whenAnalysisView(viewshedAnalysis);
// Controller for aborting the viewshed place operation.
let abortController = null;
placeButton.addEventListener("click", () => startPlacing());
async function startPlacing() {
// Create a new abort controller for the new operation.
abortController = new AbortController();
const { signal } = abortController;
// Pass the controller as an argument to the interactive place method.
try {
await analysisView.place({ signal: abortController.signal });
} catch (error) {
// This is used to handle the case when the viewshed placement is aborted.
if (!promiseUtils.isAbortError(error)) {
throw error;
}
} finally {
if (abortController && abortController.signal === signal) {
abortController = null;
}
updateUI();
}
}
Cancel the ongoing placement operation with the abort
.
cancelButton.addEventListener("click", () => stopPlacing());
function stopPlacing() {
abortController?.abort();
abortController = null;
updateUI();
}
One can also limit the viewshed's field of view. In the sample, this is done using a switch element in the UI.
if (viewshed.horizontalFieldOfView > horizontalLimit) {
viewshed.horizontalFieldOfView = horizontalLimit;
}
if (viewshed.verticalFieldOfView > verticalLimit) {
viewshed.verticalFieldOfView = verticalLimit;
}
Additionally, the sample demonstrates how to set up a second camera that shows the view from a selected viewshed's observer point.
function getCameraFromViewshed(viewshed) {
return new Camera({
position: viewshed.observer,
heading: viewshed.heading,
tilt: viewshed.tilt,
// Calculate camera's diagonal field of view angle.
fov: getDiagonal(viewshed.verticalFieldOfView, viewshed.horizontalFieldOfView),
});
}
function getDiagonal(a, b) {
return Math.sqrt(a ** 2 + b ** 2);
}