Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change order of polygons within a feature layer? (arcgis js 4.xx)

I have tried using the below in my initial query, and query right before drawing my polygons with class breaks.

    query.orderByFields = ["Shape__Area DESC"];

However this did not seem to do anything. I have also tried using grid_value field as well.

Here is my relevant code in which I am querying and then doing the drawing... main problem is occasionally large polygons block out smaller ones.. I can mostly see them, but visibility is not the issue.. I need to be able to click them as well.. if the smaller polygons would draw on top most layer, or even higher grid values on top should solve it. I found orderByFields in the docs but doesn't seem to do anything at all...

query.outFields = ["*"];
  //query.orderByFields = ["Shape__Area DESC"];
  query.returnDistinctValues = false;
  query.returnGeometry = true;
  QT.execute(query).then(function (evt) {
    evt.features.forEach(function (feature) {
      var att = feature.attributes
      var test = geometryEngine.convexHull(feature.geometry)
      var genpoly = null
      if (att.grid_value <= 4.0) {
        var rad = att.Shape__Length / 75
        genpoly = new Circle({
          center: test.centroid,
          radius: rad,
          radiusUnit: "meters"
        })
      } else {
        genpoly = test
      }
      var polygonGraphic = new Graphic({
        geometry: genpoly,
        attributes: att,
        type: "polygon"
      });
      gras.push(polygonGraphic);
    });
    var renderer = {
      type: "class-breaks",
      field: "grid_value",
      classificationMethod: "esriClassifyManual",
      classBreakInfos: [{
          minValue: 0,
          maxValue: 1.9999,
          symbol: {
            color: [0, 0, 0, 0],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "I (Not Felt)"
        },
        {
          minValue: 2.0,
          maxValue: 3.0,
          symbol: {
            color: [191, 204, 255, .3],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "II (Weak)"
        },
        {
          minValue: 3.1,
          maxValue: 3.9,
          symbol: {
            color: [153, 153, 255, .4],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "III (Weak)"
        },
        {
          minValue: 4.0,
          maxValue: 4.5,
          symbol: {
            color: [136, 255, 255, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "IV (Light)"
        },
        {
          minValue: 4.5,
          maxValue: 4.9999,
          symbol: {
            color: [125, 248, 148, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "V (Light)"
        },
        {
          minValue: 6.0,
          maxValue: 6.9999,
          symbol: {
            color: [255, 255, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "VI (Strong)"
        },
        {
          minValue: 7.0,
          maxValue: 7.9999,
          symbol: {
            color: [255, 221, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "VII (Very Strong)"
        },
        {
          minValue: 8.0,
          maxValue: 8.9999,
          symbol: {
            color: [255, 145, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "VIII (Severe) "
        },
        {
          minValue: 9.0,
          maxValue: 9.9999,
          symbol: {
            color: [255, 0, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "IX (Violent)"
        },
        {
          minValue: 10.0,
          maxValue: 10.9999,
          symbol: {
            color: [221, 0, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "X"
        },
        {
          minValue: 11.0,
          maxValue: 11.9999,
          symbol: {
            color: [136, 0, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "XI"
        },
        {
          minValue: 12.0,
          maxValue: 12.0,
          symbol: {
            color: [68, 0, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "XII"
        }
      ]
    }
         var popupTrails = {
             outFields: ["*"],
             "title": "Shake ID: {id}",
            "content": function (feature){
              let name_plc;
              let dlv = document.createElement("div");
              dlv.className = "popd";
              dlv.innerHTML = `<b><span class='name_plc'></span></b><br>ID: <span class="ida">${feature.graphic.attributes.id}</span><br> URL: <a href="${feature.graphic.attributes.url}" target="_blank">View</a> <br> Updated: ${feature.graphic.attributes.updated} <br>Grid_value: ${feature.graphic.attributes.grid_value}<br> Event Time: ${feature.graphic.attributes.eventTime} <style>.esri-popup__navigation { display: none;}</style>`;
              
              getName();
              
              function getName() {
               let cId = $('span.ida').text();
               if (cId) { 
                  //console.log(cId);
                  let q3 = new Query();
                  q3.where = "id = '"+ cId +"'";
                  q3.outFields = ["*"];
                   QTt.execute(q3).then(function (results) {
                      results.features.map(function (feat) {
                        let pID = feat.attributes["id"];
                        if (cId === pID) {
                           name_plc = feat.attributes["place"];
                             console.log(name_plc);
                             let tx = $('.name_plc').text();
                             if (tx == 0){
                               $(".name_plc").append(name_plc);
                             }
                        }
                      });
                  });
              } else {
                setTimeout(getName, 230);
              }
             }
              return dlv; 
      },
    };
    fl = new FeatureLayer({
      source: gras,
      objectIdField: "ObjectID",
      geometryType: "polygon",
      fields: [{
        name: "ObjectID",
        alias: "ObjectID",
        type: "oid"
      }, {
        name: "id",
        alias: "id",
        type: "string"
      }, {
        name: "updated",
        alias: "Last Update",
        type: "string"
      }, {
        name: "eventTime",
        alias: "eventTime",
        type: "string"
      }, {
        name: "url",
        alias: "url",
        type: "string"
      }, {
        name: "grid_value",
        alias: "grid_value",
        type: "double"
      }],
      renderer: renderer,
      popupEnabled: true,
      //outFields: ['*'],
      popupTemplate: popupTrails,
      visibleElements: [{
          featureNavigation: false, 
      }],
    });
    map.add(fl);

Here is my full CodePen as well.. Any way to do this client side javascript? simply change index to smallest polygons on top?! 1/3 times some of my polygons render in the correct order.. but I need to ensure they all always do, so they are visible and I can click them.


Update:

Here is a better screenshot: For instance, I try to click the green shape in the middle, the largest blue circle highlights and the popup only displays the meta for that one. Cannot click the smaller inner ones.

i.e. before click.

enter image description here

i.e. after trying to click the green inner small polygon -- only outer is accessible.

enter image description here

perhaps the issue is my order by clause needs to be handled within my filter?

 eqLayerView.filter = {
          outFields: "*",
          orderByFields: "Shape__Area DESC",
          where: "id IN (" + sqlExp + ")"
        };
like image 578
fred randall Avatar asked Dec 18 '25 11:12

fred randall


1 Answers

Take a look at this example, is base on your code, I just remove lot of things and keep the important ones to see that sort by area works. Like I told you, the layer plus the renderer did not help you to realize this. Just click and you will see each feature been selected.

<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>OrderByFields - Render order</title>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>
  <link rel="stylesheet" href="https://js.arcgis.com/4.15/esri/themes/light/main.css">
  <script src="https://js.arcgis.com/4.15/"></script>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "esri/geometry/geometryEngine",
      "esri/geometry/Circle",
      "esri/Graphic",
      "esri/symbols/SimpleFillSymbol",
      "esri/tasks/QueryTask",
      "esri/tasks/support/Query"
    ], function (
      Map,
      MapView,
      FeatureLayer,
      geometryEngine,
      Circle,
      Graphic,
      SimpleFillSymbol,
      QueryTask,
      Query) {

      var map = new Map({
        basemap: "gray"
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        center: [-122, 37],
        zoom: 2
      });

      let fl;
      let gras = [];
      let dVals = [];

      const QT = new QueryTask({
        url: "https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/USGS_Seismic_Data_v1/FeatureServer/1"
      });

      const query = new Query();
      query.where = "eventTime >= CURRENT_TIMESTAMP - 30 AND updated >= CURRENT_TIMESTAMP - 30 AND grid_value > 2 AND id = 'us6000ah9t'";
      query.outFields = ["*"];
      query.orderByFields = ["Shape__Area DESC"];
      query.returnDistinctValues = false;
      query.returnGeometry = true;
      QT.execute(query).then(function (evt) {
        evt.features.forEach(function (feature) {
          const att = feature.attributes
          console.log(att.Shape__Area);
          const test = geometryEngine.convexHull(feature.geometry)
          let genpoly = null
          if (att.grid_value <= 4.0) {
            const rad = att.Shape__Length / 75
            genpoly = new Circle({
              center: test.centroid,
              radius: rad,
              radiusUnit: "meters"
            })
          } else {
            genpoly = test
          }
          att.newArea = geometryEngine.geodesicArea(genpoly);
          const polygonGraphic = new Graphic({
            geometry: genpoly,
            attributes: att,
            type: "polygon"
          });
          gras.push(polygonGraphic);
        });

        fl = new FeatureLayer({
          source: gras.sort((a, b) => {
            if (a.attributes.newArea < b.attributes.newArea) {
              return 1;
            }
            if (a.attributes.newArea > b.attributes.newArea) {
              return -1;
            }
            return 0;
          }),
          objectIdField: "ObjectID",
          geometryType: "polygon",
          fields: [
            {
              name: "ObjectID",
              alias: "ObjectID",
              type: "oid"
            }, {
              name: "id",
              alias: "id",
              type: "string"
            }, {
              name: "grid_value",
              alias: "grid_value",
              type: "double"
            }, {
              name: "Shape__Area",
              alias: "Original Area",
              type: "double"
            }, {
              name: "newArea",
              alias: "Process Area",
              type: "double"
            }
          ],
          popupTemplate: {
            title: "{id}",
            content: [
              {
                type: "fields",
                fieldInfos: [
                  {
                    fieldName: "grid_value",
                    label: "Grid Value"
                  },
                  {
                    fieldName: "Shape__Area",
                    label: "Old Area"
                  },
                  {
                    fieldName: "newArea",
                    label: "Process Area"
                  }
                ]
              }
            ]
          },
          renderer: {
            type: "simple",
            symbol: {
              type: "simple-fill",
              color: [255, 0, 0, 1],
              outline: {
                width: 1,
                color: "black"
              }
            }
          }
        });
        map.add(fl);
      });
    });
  </script>
</head>

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

</html>

UPDATE:

After reviewing your update, I think I understand better the issue and I notice something that I miss before, featureNavigation: false. I am pretty sure that on click all features are selected, the problem is that the one you want is not the fist one to appear. In other words, you have a problem with the order in witch popup is showing clicked features.

So, I will propose you a simple solution, manually open the popup with the desire feature (in you case the one with less area). For this, you need to:

  1. disable popup auto open
  2. handle view click event
  3. use view hittest method to get features
  4. open popup with the desire feature

Take a look at this example I made for you, I add an extra condition to retrieve some features to make it faster

<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>esriFieldTimeDate</title>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>
  <link rel="stylesheet" href="https://js.arcgis.com/4.15/esri/themes/light/main.css">
  <script src="https://js.arcgis.com/4.15/"></script>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "esri/geometry/geometryEngine",
      "esri/geometry/Circle",
      "esri/Graphic",
      "esri/symbols/SimpleFillSymbol",
      "esri/tasks/QueryTask",
      "esri/tasks/support/Query"
    ], function (
      Map,
      MapView,
      FeatureLayer,
      geometryEngine,
      Circle,
      Graphic,
      SimpleFillSymbol,
      QueryTask,
      Query) {

      var map = new Map({
        basemap: "gray"
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        center: [-122, 37],
        zoom: 2
      });

      let fl;
      let gras = [];

      const QT = new QueryTask({
        url: "https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/USGS_Seismic_Data_v1/FeatureServer/1"
      });

      function newAreaCompareFunction(a, b) {
        if (a.attributes.newArea < b.attributes.newArea) {
          return 1;
        }
        if (a.attributes.newArea > b.attributes.newArea) {
          return -1;
        }
        return 0;
      }

      const simpleRenderer = {
        type: "simple",
        symbol: {
          type: "simple-fill",
          color: [255, 0, 0, 1],
          outline: {
            width: 1,
            color: "black"
          }
        }
      };
      const docRenderer = {
        type: "class-breaks",
        field: "grid_value",
        classificationMethod: "esriClassifyManual",
        classBreakInfos: [{
          minValue: 0,
          maxValue: 1.9999,
          symbol: {
            color: [0, 0, 0, 0],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "I (Not Felt)"
        },
        {
          minValue: 2.0,
          maxValue: 3.0,
          symbol: {
            color: [191, 204, 255, .3],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "II (Weak)"
        },
        {
          minValue: 3.1,
          maxValue: 3.9,
          symbol: {
            color: [153, 153, 255, .4],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "III (Weak)"
        },
        {
          minValue: 4.0,
          maxValue: 4.5,
          symbol: {
            color: [136, 255, 255, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "IV (Light)"
        },
        {
          minValue: 4.5,
          maxValue: 4.9999,
          symbol: {
            color: [125, 248, 148, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "V (Light)"
        },
        {
          minValue: 6.0,
          maxValue: 6.9999,
          symbol: {
            color: [255, 255, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "VI (Strong)"
        },
        {
          minValue: 7.0,
          maxValue: 7.9999,
          symbol: {
            color: [255, 221, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "VII (Very Strong)"
        },
        {
          minValue: 8.0,
          maxValue: 8.9999,
          symbol: {
            color: [255, 145, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "VIII (Severe) "
        },
        {
          minValue: 9.0,
          maxValue: 9.9999,
          symbol: {
            color: [255, 0, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "IX (Violent)"
        },
        {
          minValue: 10.0,
          maxValue: 10.9999,
          symbol: {
            color: [221, 0, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "X"
        },
        {
          minValue: 11.0,
          maxValue: 11.9999,
          symbol: {
            color: [136, 0, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "XI"
        },
        {
          minValue: 12.0,
          maxValue: 12.0,
          symbol: {
            color: [68, 0, 0, 1],
            outline: {
              color: [0, 0, 0, 0],
              width: 0.4,
              type: "simple-line",
              style: "solid"
            },
            type: "simple-fill",
            style: "solid"
          },
          label: "XII"
        }
        ]
      };

      const query = new Query();
      query.where = "eventTime >= CURRENT_TIMESTAMP - 30 AND updated >= CURRENT_TIMESTAMP - 30 AND grid_value > 2 AND id = 'us6000ah9t'";
      query.outFields = ["*"];
      query.orderByFields = ["Shape__Area DESC"];
      query.returnDistinctValues = false;
      query.returnGeometry = true;
      QT.execute(query).then(function (evt) {
        evt.features.forEach(function (feature) {
          const att = feature.attributes
          console.log(att.Shape__Area);
          const test = geometryEngine.convexHull(feature.geometry)
          let genpoly = null
          if (att.grid_value <= 4.0) {
            const rad = att.Shape__Length / 75
            genpoly = new Circle({
              center: test.centroid,
              radius: rad,
              radiusUnit: "meters"
            })
          } else {
            genpoly = test
          }
          att.newArea = geometryEngine.geodesicArea(genpoly);
          const polygonGraphic = new Graphic({
            geometry: genpoly,
            attributes: att,
            type: "polygon"
          });
          gras.push(polygonGraphic);
        });

        fl = new FeatureLayer({
          source: gras.sort(newAreaCompareFunction),
          objectIdField: "ObjectID",
          geometryType: "polygon",
          fields: [
            {
              name: "ObjectID",
              alias: "ObjectID",
              type: "oid"
            }, {
              name: "id",
              alias: "id",
              type: "string"
            }, {
              name: "grid_value",
              alias: "grid_value",
              type: "double"
            }, {
              name: "Shape__Area",
              alias: "Original Area",
              type: "double"
            }, {
              name: "newArea",
              alias: "Process Area",
              type: "double"
            }
          ],
          popupTemplate: {
            title: "{id}",
            content: [
              {
                type: "fields",
                fieldInfos: [
                  {
                    fieldName: "ObjectID",
                    label: "Object ID"
                  },
                  {
                    fieldName: "grid_value",
                    label: "Grid Value"
                  },
                  {
                    fieldName: "Shape__Area",
                    label: "Old Area"
                  },
                  {
                    fieldName: "newArea",
                    label: "Process Area"
                  }
                ]
              }
            ]
          },
          renderer: docRenderer
        });
        map.add(fl);

        view.goTo(
          gras
            .map(f => f.geometry.extent)
            .reduce(
              (p, c) => p ? p.union(c) : c
            )
        );

        view.popup.autoOpenEnabled = false; // <- disable view popup auto open
        view.on("click", function (event) { // <- listen to view click event
          view.hitTest(event, { include: fl }) // <- retrieve features
            .then(function (response) {
              if (response.results.length) {
                var feature = response.results // <- get desire feature 
                  .map(result => result.graphic)
                  .reduce(
                    (p, c) => 
                    p ? (c.attributes.newArea < p.attributes.newArea ? c : p) : c
                  )
                  ;
                view.popup.open({ // <- open popup
                  location: event.mapPoint, // <- use map point of the click event
                  features: [feature] // <- add the desire feature
                });
              }
            });
        });
      });
    });
  </script>
</head>

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

</html>
like image 58
cabesuon Avatar answered Dec 20 '25 08:12

cabesuon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!