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


