Select to view content in your preferred language

Hawaii, Alaska and other US territories to be displayed near contiguous US map

960
2
07-31-2023 02:10 PM
learnArcGISMaps
New Contributor

Hello,

I am researching solutions for having Hawaii, Alaska and other US territories near the contiguous US map. The map is displayed within a web application.

I did find some solutions that allows them to be inserted in different data frames and then controlling the extent. https://developers.arcgis.com/javascript/latest/sample-code/views-composite-views/. However, when I zoom into a county in contiguous US map Hawaii, Alaska which are in separate frames are also there. Is it possible that when a user zooms into a county or any other region within a state the view removes Alaska, Hawaii and only shows zoomed area. This should also happen when we zoom into Hawaii and Alaska too. 

0 Kudos
2 Replies
KenBuja
MVP Esteemed Contributor

Instead of using a single FeatureLayer containing the map that is added to all of the data frames, why not use different FeatureLayer for each data frame, each with its own definitionExpression? This way you can filter out the states you want to either exclude or include for that specific data frame.

0 Kudos
KenBuja
MVP Esteemed Contributor

Actually, a better way would be to use the FeatureFilter on each layer view. Using the example above, I filtered the main view to not show Alaska and Hawaii (lines 158-162) and make it zoomable to show the filtered states (line 146). This maintains the interactivity when mousing over the counties using only the one FeatureLayer.

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>
      Create an app with composite views | Sample | ArcGIS Maps SDK for
      JavaScript 4.27
    </title>

    <style>
      html,
      body,
      #mainViewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      #akViewDiv {
        padding: 0;
        margin: 0;
        height: 225px;
        width: 300px;
        background-color: rgba(255, 255, 255, 0.9);
      }

      #hiViewDiv {
        padding: 0;
        margin: 0;
        height: 135px;
        width: 200px;
        background-color: rgba(255, 255, 255, 0.9);
      }
    </style>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.27/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.27/"></script>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/widgets/Legend", "esri/layers/support/FeatureFilter"
      ], (Map, MapView, FeatureLayer, Legend, FeatureFilter) => {
        const layer = new FeatureLayer({
          portalItem: {
            id: "b234a118ab6b4c91908a1cf677941702"
          },
          outFields: ["NAME", "STATE_NAME", "VACANT", "HSE_UNITS"],
          title: "U.S. counties"
        });

        const map = new Map({
          layers: [layer]
        });

        const mainView = new MapView({
          container: "mainViewDiv",
          map: map,
          popup: {
            highlightEnabled: false,
            dockEnabled: true,
            dockOptions: {
              breakpoint: false,
              position: "top-right"
            }
          },
          extent: {
            xmin: -3094834,
            ymin: -44986,
            xmax: 2752687,
            ymax: 3271654,
            spatialReference: {
              wkid: 5070
            }
          },
          spatialReference: {
            // NAD_1983_Contiguous_USA_Albers
            wkid: 5070
          },
          ui: {
            components: ["attribution"]
          }
        });
        mainView.ui.add(
          new Legend({
            view: mainView
          }),
          "bottom-right"
        );

        const akView = new MapView({
          container: "akViewDiv",
          map: map,
          extent: {
            xmin: 396381,
            ymin: -2099670,
            xmax: 3393803,
            ymax: 148395,
            spatialReference: {
              wkid: 5936
            }
          },
          spatialReference: {
            // WGS_1984_EPSG_Alaska_Polar_Stereographic
            wkid: 5936
          },
          ui: {
            components: []
          }
        });
        mainView.ui.add("akViewDiv", "bottom-left");

        const hiView = new MapView({
          container: "hiViewDiv",
          map: map,
          extent: {
            xmin: -342537,
            ymin: 655453,
            xmax: 231447,
            ymax: 1023383,
            spatialReference: {
              wkid: 102007
            }
          },
          spatialReference: {
            // Hawaii_Albers_Equal_Area_Conic
            wkid: 102007
          },
          ui: {
            components: []
          }
        });
        mainView.ui.add("hiViewDiv", "bottom-left");

        mainView
          .when(maintainFixedExtent)
          //.then(disableNavigation)
          .then(disablePopupOnClick)
          .then(enableHighlightOnPointerMove);
        akView
          .when(disableNavigation)
          .then(disablePopupOnClick)
          .then(enableHighlightOnPointerMove);
        hiView
          .when(disableNavigation)
          .then(disablePopupOnClick)
          .then(enableHighlightOnPointerMove);
          
        mainView.whenLayerView(layer).then((layerView) => {
          layerView.filter = new FeatureFilter({
            where: "STATE_NAME <> 'Alaska' AND STATE_NAME <> 'Hawaii'"
          });        
        });

        function maintainFixedExtent(view) {
          const fixedExtent = view.extent.clone();
          // keep a fixed extent in the view
          // when the view size changes
          view.on("resize", () => {
            view.extent = fixedExtent;
          });
          return view;
        }

        let highlight = null;
        let lastHighlight = null;

        function enableHighlightOnPointerMove(view) {
          view.whenLayerView(layer).then((layerView) => {
            view.on("pointer-move", (event) => {
              view.hitTest(event).then((response) => {
                lastHighlight = highlight;

                // if a feature is returned, highlight it
                // and display its attributes in the popup
                // if no features are returned, then close the popup
                let id = null;

                if (response.results.length) {
                  const feature = response.results.filter((result) => {
                    return result.graphic.layer === layer;
                  })[0].graphic;

                  feature.popupTemplate = layer.popupTemplate;
                  id = feature.attributes.OBJECTID;
                  highlight = layerView.highlight([id]);
                  const selectionId = mainView.popup.selectedFeature
                    ? mainView.popup.selectedFeature.attributes.OBJECTID
                    : null;

                  if (highlight && id !== selectionId) {
                    mainView.openPopup({
                      features: [feature]
                    });
                  }
                } else {
                  if (mainView.popup.visible) {
                    mainView.closePopup();
                    mainView.popup.clear();
                  }
                }

                // remove the previous highlight
                if (lastHighlight) {
                  lastHighlight.remove();
                  lastHighlight = null;
                }
              });
            });
          });
        }

        // disables all navigation in the view
        function disableNavigation(view) {
          view.popup.dockEnabled = true;

          // Removes the zoom action on the popup
          view.popup.actions = [];

          // stops propagation of default behavior when an event fires
          function stopEvtPropagation(event) {
            event.stopPropagation();
          }

          // disable mouse wheel scroll zooming on the view
          view.navigation.mouseWheelZoomEnabled = false;

          // disable zooming via double-click on the view
          view.on("double-click", stopEvtPropagation);

          // disable zooming out via double-click + Control on the view
          view.on("double-click", ["Control"], stopEvtPropagation);

          // disables pinch-zoom and panning on the view
          view.navigation.browserTouchPanEnabled = false;
          view.on("drag", stopEvtPropagation);

          // disable the view's zoom box to prevent the Shift + drag
          // and Shift + Control + drag zoom gestures.
          view.on("drag", ["Shift"], stopEvtPropagation);
          view.on("drag", ["Shift", "Control"], stopEvtPropagation);

          // prevents zooming and rotation with the indicated keys
          view.on("key-down", (event) => {
            const prohibitedKeys = ["+", "-", "_", "=", "a", "d"];
            const keyPressed = event.key.toLowerCase();
            if (prohibitedKeys.indexOf(keyPressed) !== -1) {
              event.stopPropagation();
            }
          });

          return view;
        }

        // prevents the user from opening the popup with click

        function disablePopupOnClick(view) {
          view.on("click", (event) => {
            event.stopPropagation();
          });
          return view;
        }
      });
    </script>
  </head>

  <body>
    <div id="mainViewDiv"></div>
    <div id="akViewDiv" class="esri-widget"></div>
    <div id="hiViewDiv" class="esri-widget"></div>
  </body>
</html>

 

0 Kudos