Функции фильтра ArcGIS Api For Javascript в сочетании с функциями запросов - PullRequest
0 голосов
/ 01 мая 2020

У меня возникли проблемы при попытке объединить функциональность между фильтром по атрибуту и ​​функциями запроса из FeatureLayerView. Оба образца приведены ниже:

https://developers.arcgis.com/javascript/latest/sample-code/featurefilter-attributes/index.html

https://developers.arcgis.com/javascript/latest/sample-code/featurelayerview-query/index.html

Целью является применение выбранного фильтра ( Фильтровать объект по атрибуту), и этот фильтр будет применен к Query FeatureLayerView, отображаемому на боковой панели.

В настоящее время обе функции работают правильно в одном примере, однако они по-прежнему работают изолированно друг от друга. Я добавил код, который у нас есть ниже.

Любая помощь будет принята с благодарностью.

    <script src="https://js.arcgis.com/4.15/"></script>

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

        #seasons-filter {
            height: 160px;
            width: 160px;
            width: 100%;
            visibility: hidden;
        }

        .season-item {
            width: 100%;
            padding: 12px;
            text-align: center;
            vertical-align: baseline;
            cursor: pointer;
            height: 40px;
            height: 50px;
        }

        .season-item:focus {
            background-color: dimgrey;
        }

        .season-item:hover {
            background-color: dimgrey;
        }

        .panel-container {
            position: relative;
            width: 100%;
            height: 100%;
        }

        .panel-side {
            padding: 2px;
            box-sizing: border-box;
            width: 300px;
            height: 100%;
            position: absolute;
            top: 0;
            right: 0;
            color: #fff;
            background-color: rgba(0, 0, 0, 0.6);
            overflow: auto;
            z-index: 60;
        }

        .panel-side h3 {
            padding: 0 20px;
            margin: 20px 0;
        }

        .panel-side ul {
            list-style: none;
            margin: 0;
            padding: 0;
        }

        .panel-side li {
            list-style: none;
            padding: 10px 20px;
        }

        .panel-result {
            cursor: pointer;
            margin: 2px 0;
            background-color: rgba(0, 0, 0, 0.3);
        }

        .panel-result:hover,
        .panel-result:focus {
            color: orange;
            background-color: rgba(0, 0, 0, 0.75);
        }
    </style>
    <script>
        require([
            "esri/views/MapView",
            "esri/Map",
            "esri/layers/FeatureLayer",
            "esri/widgets/Expand"
        ], function(MapView, Map, FeatureLayer, Expand) {

            let floodLayerView;
            let graphics;
            const listNode = document.getElementById("nyc_graphics");

            const popupTemplate = {
                // autocasts as new PopupTemplate()
                title: "{NAME} in {COUNTY}",
                content: [
                    {
                        type: "fields",
                        fieldInfos: [
                            {
                                fieldName: "B12001_calc_pctMarriedE",
                                label: "% Married",
                                format: {
                                    places: 0,
                                    digitSeparator: true
                                }
                            }
                        ]
                    }
                ]
            };

            // flash flood warnings layer

            const layer = new FeatureLayer({
                url:
                    "https://services.arcgis.com/P3ePLMYs2RVChkJx/ArcGIS/rest/services/ACS_Marital_Status_Boundaries/FeatureServer/2",
                outFields: ["NAME", "GEOID"], // used by queryFeatures
                popupTemplate: popupTemplate
            });

            const map = new Map({
                basemap: "gray-vector",
                layers: [layer]
            });

            const view = new MapView({
                map: map,
                container: "viewDiv",
                center: [-73.95, 40.702],
                zoom: 11
            });

            const seasonsNodes = document.querySelectorAll(`.season-item`);
            const seasonsElement = document.getElementById("seasons-filter");

            // click event handler for seasons choices
            seasonsElement.addEventListener("click", filterBySeason);

            // User clicked on Winter, Spring, Summer or Fall
            // set an attribute filter on flood warnings layer view
            // to display the warnings issued in that season
            function filterBySeason(event) {
                const selectedSeason = event.target.getAttribute("data-season");
                floodLayerView.filter = {
                    where: "State = '" + selectedSeason + "'"
                };
            }

            view.whenLayerView(layer).then(function(layerView) {
                // flash flood warnings layer loaded
                // get a reference to the flood warnings layerview
                floodLayerView = layerView;

                // set up UI items
                seasonsElement.style.visibility = "visible";
                const seasonsExpand = new Expand({
                    view: view,
                    content: seasonsElement,
                    expandIconClass: "esri-icon-filter",
                    group: "top-left"
                });
                //clear the filters when user closes the expand widget
                seasonsExpand.watch("expanded", function() {
                    if (!seasonsExpand.expanded) {
                        floodLayerView.filter = null;
                    }
                });
                view.ui.add(seasonsExpand, "top-left");
            });

            // Start Of Side Bar Element

           view.whenLayerView(layer).then(function(layerView) {
                layerView.watch("updating", function(value) {
                    if (!value) {
                        // wait for the layer view to finish updating
                        // query all the features available for drawing.
                        layerView
                            .queryFeatures({
                                geometry: view.extent,
                                returnGeometry: true,
                                orderByFields: ["NAME"]
                            })
                            .then(function(results) {
                                graphics = results.features;

                                const fragment = document.createDocumentFragment();

                                graphics.forEach(function(result, index) {
                                    const attributes = result.attributes;
                                    const name = attributes.NAME;

                                    // Create a list zip codes in NY
                                    const li = document.createElement("li");
                                    li.classList.add("panel-result");
                                    li.tabIndex = 0;
                                    li.setAttribute("data-result-id", index);
                                    li.textContent = name;

                                    fragment.appendChild(li);
                                });
                                // Empty the current list
                                listNode.innerHTML = "";
                                listNode.appendChild(fragment);
                            })
                            .catch(function(error) {
                                console.error("query failed: ", error);
                            });
                    }
                });
            });

            // listen to click event on the zip code list
            listNode.addEventListener("click", onListClickHandler);

            function onListClickHandler(event) {
                const target = event.target;
                const resultId = target.getAttribute("data-result-id");

                // get the graphic corresponding to the clicked zip code
                const result =
                    resultId && graphics && graphics[parseInt(resultId, 10)];

                if (result) {
                    // open the popup at the centroid of zip code polygon
                    // and set the popup's features which will populate popup content and title.

                    view
                        .goTo(result.geometry.extent.expand(2))
                        .then(function() {
                            view.popup.open({
                                features: [result],
                                location: result.geometry.centroid
                            });
                        })
                        .catch(function(error) {
                            if (error.name != "AbortError") {
                                console.error(error);
                            }
                        });
                }
            }

        });
    </script>

Ответы [ 2 ]

0 голосов
/ 04 мая 2020

Я также пытаюсь добавить опцию в раскрывающемся списке для очистки или фильтрации и сброса боковой панели. Я добавил событие нажатия, которое очищает фильтры, но не сбрасывает боковую панель.

Любая помощь будет принята с благодарностью.

        require([
            "esri/views/MapView",
            "esri/Map",
            "esri/layers/FeatureLayer",
            "esri/widgets/Expand"
        ], function(MapView, Map, FeatureLayer, Expand) {
            const listNode = document.getElementById("list_graphics");
            const seasonsNodes = document.querySelectorAll(`.season-item`);
            const seasonsElement = document.getElementById("seasons-filter");
            let layer, map, view;
            let selectedSeason = null;
            let floodLayerView;
            let graphics = null;
            // functions
            const filterBySeason = function (event) {
                selectedSeason = event.target.getAttribute("data-season");
                floodLayerView.filter = {
                    where: "Season = '" + selectedSeason + "'"
                };
                document
                    .getElementById("filterReset")
                    .addEventListener("click", function() {
                        floodLayerView.filter = selectedSeason;
                    });

                updateList();
            };
            const updateList = function () {
                if (!graphics) {
                    return;
                }
                const fragment = document.createDocumentFragment();
                graphics.forEach(function(result, index) {
                    const attributes = result.attributes;
                    if (!selectedSeason || attributes.SEASON ===  selectedSeason) {
                        const name = attributes.IssueDate;
                        // Create the list
                        const li = document.createElement("li");
                        li.classList.add("panel-result");
                        li.tabIndex = 0;
                        li.setAttribute("data-result-id", index);
                        li.textContent = name;
                        fragment.appendChild(li);
                    }
                });
                // Empty the current list
                listNode.innerHTML = "";
                listNode.appendChild(fragment);
            };
            // flash flood warnings layer
            layer = new FeatureLayer({
                portalItem: {
                    id: "f9e348953b3848ec8b69964d5bceae02"
                },
                outFields: ["SEASON", "IssueDate"]
            });
            map = new Map({
                basemap: "gray-vector",
                layers: [layer]
            });
            view = new MapView({
                map: map,
                container: "viewDiv",
                center: [-98, 40],
                zoom: 10
            });
            // click event handler for seasons choices
            seasonsElement.addEventListener("click", filterBySeason);
            view.whenLayerView(layer).then(function(layerView) {
                /*

                filter

                */
                floodLayerView = layerView;
                // set up UI items
                seasonsElement.style.visibility = "visible";
                const seasonsExpand = new Expand({
                    view: view,
                    content: seasonsElement,
                    expandIconClass: "esri-icon-filter",
                    group: "top-left"
                });
                //clear the filters when user closes the expand widget

                view.ui.add(seasonsExpand, "top-left");
                view.ui.add("titleDiv", "bottom-left");

                /*

                query

                */
                layerView.watch("updating", function(value) {
                    if (!value) {
                        // wait for the layer view to finish updating
                        // query all the features available for drawing.
                        layerView
                            .queryFeatures({
                                geometry: view.extent,
                                returnGeometry: true,
                                orderByFields: ["IssueDate"]
                            })
                            .then(function (results) {
                                graphics = results.features;
                                updateList();
                            })
                            .catch(function(error) {
                                console.error("query failed: ", error);
                            });
                    }
                });
            });
            /*

            query

            */
            // listen to click event on list items
            listNode.addEventListener("click", onListClickHandler);
            function onListClickHandler(event) {
                const target = event.target;
                const resultId = target.getAttribute("data-result-id");
                // get the graphic corresponding to the clicked item
                const result =
                    resultId && graphics && graphics[parseInt(resultId, 10)];
                if (result) {
                    // open the popup at the centroid of polygon
                    // and set the popup's features which will populate popup content and title.
                    view
                        .goTo(result.geometry.extent.expand(2))
                        .then(function() {
                            view.popup.open({
                                features: [result],
                                location: result.geometry.centroid
                            });
                        })
                        .catch(function(error) {
                            if (error.name != "AbortError") {
                                console.error(error);
                            }
                        });
                }
            };
        });
    </script>```
0 голосов
/ 02 мая 2020

Что вы можете сделать, это отфильтровать полученную графику с помощью простого условия. Используя оба примера ArcGIS, я собрал то, что, как мне кажется, вы пытаетесь получить.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>Filter and Query - 4.15</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%;
      }

      #seasons-filter {
        height: 160px;
        width: 100%;
        visibility: hidden;
      }

      .season-item {
        width: 100%;
        padding: 12px;
        text-align: center;
        vertical-align: baseline;
        cursor: pointer;
        height: 40px;
      }

      .season-item:focus {
        background-color: dimgrey;
      }

      .season-item:hover {
        background-color: dimgrey;
      }

      #titleDiv {
        padding: 10px;
      }

      #titleText {
        font-size: 20pt;
        font-weight: 60;
        padding-bottom: 10px;
      }

      .panel-container {
        position: relative;
        width: 100%;
        height: 100%;
      }

      .panel-side {
        padding: 2px;
        box-sizing: border-box;
        width: 300px;
        height: 100%;
        position: absolute;
        top: 0;
        right: 0;
        color: #fff;
        background-color: rgba(0, 0, 0, 0.6);
        overflow: auto;
        z-index: 60;
      }

      .panel-side h3 {
        padding: 0 20px;
        margin: 20px 0;
      }

      .panel-side ul {
        list-style: none;
        margin: 0;
        padding: 0;
      }

      .panel-side li {
        list-style: none;
        padding: 10px 20px;
      }

      .panel-result {
        cursor: pointer;
        margin: 2px 0;
        background-color: rgba(0, 0, 0, 0.3);
      }

      .panel-result:hover,
      .panel-result:focus {
        color: orange;
        background-color: rgba(0, 0, 0, 0.75);
      }
    </style>
    <script>
      require([
        "esri/views/MapView",
        "esri/Map",
        "esri/layers/FeatureLayer",
        "esri/widgets/Expand"
      ], function(MapView, Map, FeatureLayer, Expand) {
        const listNode = document.getElementById("list_graphics");
        const seasonsNodes = document.querySelectorAll(`.season-item`);
        const seasonsElement = document.getElementById("seasons-filter");
        let layer, map, view;
        let selectedSeason = null;
        let floodLayerView;
        let graphics = null;
        // functions
        const filterBySeason = function (event) {
          selectedSeason = event.target.getAttribute("data-season");
          floodLayerView.filter = {
            where: "Season = '" + selectedSeason + "'"
          };
          updateList();
        };
        const updateList = function () {
          if (!graphics) {
            return;
          }
          const fragment = document.createDocumentFragment();
          graphics.forEach(function(result, index) {
            const attributes = result.attributes;
            if (!selectedSeason || attributes.SEASON ===  selectedSeason) {
              const name = attributes.IssueDate;
              // Create the list
              const li = document.createElement("li");
              li.classList.add("panel-result");
              li.tabIndex = 0;
              li.setAttribute("data-result-id", index);
              li.textContent = name;
              fragment.appendChild(li);
            }
          });
          // Empty the current list
          listNode.innerHTML = "";
          listNode.appendChild(fragment);
        };
        // flash flood warnings layer
        layer = new FeatureLayer({
          portalItem: {
            id: "f9e348953b3848ec8b69964d5bceae02"
          },
          outFields: ["SEASON", "IssueDate"]
        });
        map = new Map({
          basemap: "gray-vector",
          layers: [layer]
        });
        view = new MapView({
          map: map,
          container: "viewDiv",
          center: [-98, 40],
          zoom: 10
        });
        // click event handler for seasons choices
        seasonsElement.addEventListener("click", filterBySeason);
        view.whenLayerView(layer).then(function(layerView) {
          /*
          
          filter
          
          */
          floodLayerView = layerView;
          // set up UI items
          seasonsElement.style.visibility = "visible";
          const seasonsExpand = new Expand({
            view: view,
            content: seasonsElement,
            expandIconClass: "esri-icon-filter",
            group: "top-left"
          });
          //clear the filters when user closes the expand widget
          seasonsExpand.watch("expanded", function() {
            if (!seasonsExpand.expanded) {
              floodLayerView.filter = null;
            }
          });
          view.ui.add(seasonsExpand, "top-left");
          view.ui.add("titleDiv", "bottom-left");

          /*

          query
          
          */
          layerView.watch("updating", function(value) {
            if (!value) {
              // wait for the layer view to finish updating
              // query all the features available for drawing.
              layerView
                .queryFeatures({
                  geometry: view.extent,
                  returnGeometry: true,
                  orderByFields: ["IssueDate"]
                })
                .then(function (results) {
                  graphics = results.features;
                  updateList();
                })
                .catch(function(error) {
                  console.error("query failed: ", error);
                });
            }
          });
        });
        /*

        query
        
        */
        // listen to click event on list items
        listNode.addEventListener("click", onListClickHandler);
        function onListClickHandler(event) {
          const target = event.target;
          const resultId = target.getAttribute("data-result-id");
          // get the graphic corresponding to the clicked item
          const result =
            resultId && graphics && graphics[parseInt(resultId, 10)];
          if (result) {
            // open the popup at the centroid of polygon
            // and set the popup's features which will populate popup content and title.
            view
              .goTo(result.geometry.extent.expand(2))
              .then(function() {
                view.popup.open({
                  features: [result],
                  location: result.geometry.centroid
                });
              })
              .catch(function(error) {
                if (error.name != "AbortError") {
                  console.error(error);
                }
              });
          }
        };
      });
    </script>
  </head>

  <body>
    <div class="panel-container">
      <div id="seasons-filter" class="esri-widget">
        <div class="season-item visible-season" data-season="Winter">Winter</div>
        <div class="season-item visible-season" data-season="Spring">Spring</div>
        <div class="season-item visible-season" data-season="Summer">Summer</div>
        <div class="season-item visible-season" data-season="Fall">Fall</div>
      </div>
      <div class="panel-side esri-widget">
        <ul id="list_graphics">
          <li>Loading&hellip;</li>
        </ul>
      </div>
      <div id="viewDiv"></div>
      <div id="titleDiv" class="esri-widget">
        <div id="titleText">Flash Floods by Season</div>
        <div>Flash Flood Warnings (2002 - 2012)</div>
      </div>
    </div>
  </body>
</html>

Я просто немного перемещаю вещи, чтобы каждый раз, когда пользовательский фильтр по сезонам обновлялся список боковой панели. Теперь вы увидите, что я не запрашиваю новый сезон, я просто фильтрую графику, которая у нас уже есть. Каждый раз, когда делается новый запрос, список будет фильтроваться таким же образом.

...