【问题标题】:add items to map, collectively, one at a time, per attribute id每个属性 id 一次一个地添加项目到地图
【发布时间】:2020-10-11 15:08:37
【问题描述】:

我已经成功地能够通过属性 id 过滤,例如抖动图 - 我已经成功地实现了多种方式 - 但都以同样的问题结束。

1.) 使用 where 过滤器 2.) 定义表达式 3.) 遍历所有属性 id 并将它们带回来。

问题: 一次只允许/显示每个attribute id 一个.. 我的目标是将attribute ids 输入复选框列表(我已经这样做了),但是允许通过属性 id 将项目添加到地图中,因为它们一次被检查,共同地,一次出现一个 - 目前我似乎无法让它与一次出现多个或多个然后一个的方面一起工作地图。

1.) 下面的过滤器(尝试逻辑 1)&CodePen:

.....
         function filterByID(event) {
           const selectedID = event.target.getAttribute("data-id");
             eqLayerView.filter = {
             where: "id = '" + selectedID + "'"
           };
         }

         view.whenLayerView(fl)
           .then(function(layerView) {

           eqLayerView = layerView;

           eqLayerView.filter = {
             where: "id = ''"
           };
.............

2.) 另一个尝试的逻辑(在此处一次添加多个,逐行或通过数组):

layer.definitionExpression = "id = 'us70008jr5'",
layer.definitionExpression = "id = 'cgi988jr52'",

3.) 第 3 次尝试,这里有关于 GIS 交换的建议:https://gis.stackexchange.com/questions/364578/loop-through-attribute-ids-of-featurelayer

layer
  .load()
  .then(() => {
    // create a query from the layer
    const query = layer.createQuery();
    query.returnDistinctValues = true;
    query.where = "grid_value > 2"; // or 1=1 if you need them all
    // the field you want distinct values for
    query.outFields = ["id"];
    return layer.queryFeatures(query);
  })
  .then(({ features }) => {
    // extract the ids to a list
    const ids = features.map(({ attributes }) => attributes.id);
    return ids;
  })
  .then((ids) => {
    // You can store them how you want, in this case,
    // I put them in a dropdown select menu
    const fragment = document.createDocumentFragment();
    ids.forEach((id) => {
      const option = document.createElement('option');
      option.value = id;
      option.innerText = id;
      fragment.appendChild(option);
    });
    list.appendChild(fragment);
    map.add(layer);
});

以上所有尝试的逻辑都会导致 attribute id 一次只显示一个抖动图 - 通过切换一个新的打开,前一个关闭,我需要能够有多个能够存在地图。

ArcGIS - javascript - 4.15

【问题讨论】:

    标签: javascript esri arcgis-js-api


    【解决方案1】:

    我很确定我在几周前回答了这个问题,但我找不到我的答案,所以也许我只是以为我回答了,在那种情况下我很抱歉。

    无论如何,通过一些修复,您的代码应该可以工作。我认为这里的主要问题是,如果您要使用复选框,您的查询不正确。您需要使用像IN 这样的集合查询。如果您使用单选按钮,我会很好。

    这里有我提到的修复示例,

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset='utf-8' />
      <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
      <title>Filter features by attribute - 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: 500px;
          width: 100%;
        }
      </style>
      <script>
        require([
          'esri/views/MapView',
          'esri/Map',
          'esri/layers/FeatureLayer',
          'esri/widgets/Expand'
        ], function (MapView, Map, FeatureLayer, Expand) {
          const layer = new FeatureLayer({
            url: 'https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/USGS_Seismic_Data_v1/FeatureServer/1/',
            outFields: ['*']
            , definitionExpression: 'eventTime >= CURRENT_TIMESTAMP - 30 AND grid_value > 2'
          });
          const map = new Map({
            basemap: 'gray-vector'
            , layers: [layer]
          });
    
          const view = new MapView({
            map: map,
            container: 'viewDiv',
            center: [-98, 40],
            zoom: 4
          });
    
          let eqLayerView;
          let selectedIDs = {};
    
          function updatedFilter() {
            const ids = [];
            for(const [key, value] of Object.entries(selectedIDs)) {
              if (value) {
                ids.push(`'${key}'`);
              }
            }
            eqLayerView.filter = {
              where: `id IN (${ids.join(',')})`
            };
            console.log(`[updateFilter] ${eqLayerView.filter.where}`);
          }
    
          const idElement = document.getElementById('id-filter');
          idElement.addEventListener('click', filterByID);
          function filterByID(event) {
            const chk = event.target;
            console.log(`[filterByID] ${chk.getAttribute('data-id')} ${chk.checked}`);
            selectedIDs[chk.getAttribute('data-id')] = chk.checked;
            updatedFilter();
          }
    
          view.whenLayerView(layer).then(function (layerView) {
    
            eqLayerView = layerView;
            updatedFilter();
    
            var query = layer.createQuery();
            query.outFields = ['id'];
            query.returnDistinctValues = true;
            query.returnGeometry = false;
            layer.queryFeatures(query).then(function (results) {
              results.features.map(function (feat) {
                let id = feat.attributes['id'];
                let opt = document.createElement('input');
                opt.type = 'checkbox';
                let label = document.createElement('label')
                label.innerHTML = id;
                opt.className = 'id-item visible-id';
                opt.setAttribute('data-id', id);
    
                idElement.appendChild(opt);
                idElement.appendChild(label);
    
                selectedIDs[id] = false;
              });
            });
    
          });
    
        });
      </script>
    </head>
    
    <body>
      <div id='id-filter' class='esri-widget'>
      </div>
      <div id='viewDiv'></div>
    </body>
    
    </html>

    顺便说一句,我添加了一些日志供您查看我认为的事件导入信息。

    最后,我使用辅助字典来跟踪要过滤的可见特征。另一种方法是简单地查询所有复选框并将id添加到过滤器中,如果它是checked

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 2019-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多