1

I have integrated a popup on the map for a specific layer. Some time the poup shows pagination (featureNavigation) multiple data. Sometimes it fails to show the data, or mismatch in the data that actually the service returns.

    var popupTrailheads = {
            title: "ID: {ID}",
            content: this.getcustomcontent.bind(this),
          };
          // Add layer special layer
          this.layer_fifteen = new FeatureLayer({
            url: `${this.esriURL}/15`,
            visible: true,
            outFields: ['*'],
            popupTemplate: popupTrailheads,
          });
    
     getcustomcontent(feature) {
    // The popup content will become here from angular service
return `<div>content</div>`;
    }

I have a few options to fix the issue. 1)Popup for this layer enables only at a specific Zoom level. Else the popup won't appear. 2)The click on the map should trigger only for a point. (I believe when click on the layer it triggers multiple points that is the reason it shows multiple feature details.)

Can you please suggest an idea, how to enable a popup in specific zoom level, or select only one feature in one click on the map.

Thanks in advance.

Adam-KER
  • 67
  • 9
  • Hi @adam-ker, what do you mean with "fails to show the data"?, and same on "mismatch in the data that actually the service returns" .. The selection with a click will retrieve all the features that the "ray" intersects in his path (with a certain screen buffer), you only want one result?, in that case witch result you want? – cabesuon Oct 14 '20 at 04:00
  • I have an Angular 'sevice' which I am using to collect data according to the ID get from the feature. And this collected data will be added to the popup content section. Some times the popup shows multiple features and pagination arrows appear in the popup. I believe this multiple feature will case the mismatch of the data from 'service'. Can we get only one feature from the map? Is it possible to enable the popup in a specific zoom level? – Adam-KER Oct 14 '20 at 06:07
  • How can we know if all the layers are loaded on the map? Is there any flag or status something available? Sorry if I am asking too many questions :) – Adam-KER Oct 14 '20 at 12:12
  • Hi @adam-ker, no problem buddy .. So I will answer this question with a code example tonight (sorry I can't do it right now) .. In order to keep the questions on one subject,so it make easy to search, answer, and helps others, can you post a new question with the last comment?. If no one else answer it I will do it tonight also .. BTW, yes it is possible, there are a couple of ways, for example each layer has a `loaded` property, you can check, or you can use `when` method, some layers also have others method – cabesuon Oct 14 '20 at 12:42
  • Thanks Cabesuon. I will post another question. and thanks for the hint, 'loaded'. – Adam-KER Oct 14 '20 at 12:46
  • Hi Cabesuon, Can you please check this thread, https://stackoverflow.com/questions/64358580/click-event-on-map-not-reloading-the-geometry-polygon-angular-10-arcgis-4-16 – Adam-KER Oct 14 '20 at 17:30

1 Answers1

2

So, there are a number of possible ways to enable the popup under certain conditions, like the zoom level of the view.

In the example that I made for you popup only opens if zoom is greatest than 10.

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
  <title>PopupTemplate - Auto Open False</title>

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

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

  <script>
    var populationChange;
    require(["esri/Map", "esri/views/MapView", "esri/layers/Layer"], function (
      Map,
      MapView,
      Layer
    ) {
      var map = new Map({
        basemap: "dark-gray"
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 7,
        center: [-87, 34]
      });

      var highlightSelect = null;

      Layer.fromPortalItem({
        portalItem: {
          id: "e8f85b4982a24210b9c8aa20ba4e1bf7"
        }
      }).then(function (layer) {
        map.add(layer);

        var popupTemplate = {
          title: "Population in {NAME}",
          outFields: ["*"],
          content: [{
            type: 'fields',
            fieldInfos: [
              {
                fieldName: "POP2010",
                format: {
                  digitSeparator: true,
                  places: 0
                },
                visible: false
              },
              {
                fieldName: "POP10_SQMI",
                format: {
                  digitSeparator: true,
                  places: 2
                }
              },
              {
                fieldName: "POP2013",
                format: {
                  digitSeparator: true,
                  places: 0
                }
              },
              {
                fieldName: "POP13_SQMI",
                format: {
                  digitSeparator: true,
                  places: 2
                }
              }
            ]
          }],
        };
        layer.popupTemplate = popupTemplate;
        function populationChange(feature) {
          var div = document.createElement("div");
          var upArrow =
            '<svg width="16" height="16" ><polygon points="14.14 7.07 7.07 0 0 7.07 4.07 7.07 4.07 16 10.07 16 10.07 7.07 14.14 7.07" style="fill:green"/></svg>';
          var downArrow =
            '<svg width="16" height="16"><polygon points="0 8.93 7.07 16 14.14 8.93 10.07 8.93 10.07 0 4.07 0 4.07 8.93 0 8.93" style="fill:red"/></svg>';

          var diff =
            feature.graphic.attributes.POP2013 -
            feature.graphic.attributes.POP2010;
          var pctChange = (diff * 100) / feature.graphic.attributes.POP2010;
          var arrow = diff > 0 ? upArrow : downArrow;

          div.innerHTML =
            "As of 2010, the total population in this area was <b>" +
            feature.graphic.attributes.POP2010 +
            "</b> and the density was <b>" +
            feature.graphic.attributes.POP10_SQMI +
            "</b> sq mi. As of 2013, the total population was <b>" +
            feature.graphic.attributes.POP2013 +
            "</b> and the density was <b>" +
            feature.graphic.attributes.POP13_SQMI +
            "</b> sq mi. <br/> <br/>" +
            "Percent change is " +
            arrow +
            "<span style='color: " +
            (pctChange < 0 ? "red" : "green") +
            ";'>" +
            pctChange.toFixed(3) +
            "%</span>";
          return div;
        }

        view.popup.autoOpenEnabled = false; // <- disable view popup auto open
        view.on("click", function (event) { // <- listen to view click event
          if (event.button === 0) { // <- check that was left button or touch

            console.log(view.zoom);
            if (view.zoom > 10) { // <- zoom related condition to open popup

              view.popup.open({ // <- open popup
                location: event.mapPoint, // <- use map point of the click event
                fetchFeatures: true // <- fetch the selected features (if any)
              });

            } else {
              
              window.alert(`Popup display zoom lower than 10 .. Zoom in buddy! .. (Current zoom ${view.zoom})`);

            }

          }
        });
      });
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
</body>

</html>

Related to only display one result in the popup, you could hide the navigation like this,

view.popup.visibleElements.featureNavigation = false;

Now if what you actually want is to get only one result, then I suggest to use view method hitTest, that only gets the topmost result of the layers. You could do this after inside the click handler and only open if any result of desire layer. For this you need to set featFeatures: false, and set the features with the hit one.

Just as a comment it could result weird or confusing to the user retrieve just one of all possible features. I think probable you may have a problem with the content.

cabesuon
  • 4,860
  • 2
  • 15
  • 24