Select to view content in your preferred language

Is a legend possible on an ImageryLayer with pixelFilter rendering?

889
2
06-04-2020 07:50 AM
JayHill
Frequent Contributor

I've been using the ESRI pixelFilter sample code to test with.

<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <!--
     ArcGIS API for JavaScript, https://js.arcgis.com
     For more information about the layers-imagery-pixelvalues sample,
     read the original sample description at developers.arcgis.com.
     https://developers.arcgis.com/javascript/latest/sample-code/layers-imagery-pixelvalues/index.html
     -->
    <title>ImageryLayer - client side pixel filter - 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%;
      }
    </style>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/ImageryLayer",
        "esri/widgets/Legend",
        "esri/layers/support/DimensionalDefinition",
        "esri/layers/support/MosaicRule",
        "esri/core/watchUtils"
      ], function(
        Map,
        MapView,
        ImageryLayer,
        Legend,
        DimensionalDefinition,
        MosaicRule,
        watchUtils
      ) {
        // The URL to an image layer representing sea temperature
        var url =
          "https://webmaps.geology.utah.gov/arcgis/rest/services/Energy_Mineral/Bouger_Gravity_Anomaly/ImageServer";

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

        var view = new MapView({
          container: "viewDiv",
          map: map,
          zoom: 10,
          center: [-113, 38.5],
          popup: {
            actions: []
          }
        });

        /**********************************************************
         * The PixelFilter function. This function is used to color the
         * pixels. By default, each pixel has one band containing
         * a temperature value. We will replace the single band with
         * three bands - red, green, and blue to give color to the layer.
         *********************************************************/

        function colorize(pixelData) {
          var pixelBlock, factor, minValue, maxValue;

          if (
            pixelData === null ||
            pixelData.pixelBlock === null ||
            pixelData.pixelBlock.pixels === null
          ) {
            return;
          }

          // The pixelBlock stores the values of all pixels visible in the view
          pixelBlock = pixelData.pixelBlock;

          // Get the min and max values of the data in the current view
          minValue = pixelBlock.statistics[0].minValue;
          maxValue = pixelBlock.statistics[0].maxValue;

          // The pixels visible in the view
          var pixels = pixelBlock.pixels;

          // The number of pixels in the pixelBlock
          var numPixels = pixelBlock.width * pixelBlock.height;

          // Get the pixels containing temperature values in the only band of the data
          var tempBand = pixels[0];

          // Create empty arrays for each of the RGB bands to set on the pixelBlock
          var rBand = [];
          var gBand = [];
          var bBand = [];

          // Loop through all the pixels in the view
          for (i = 0; i < numPixels; i++) {
            // Get the pixel value (the temperature) recorded at the pixel location
            var tempValue = tempBand[i];
            // Calculate the red value based on the factor
            var red = tempValue;

            // Sets a color between blue (coldest) and red (warmest) in each band
            rBand[i] = 0;
            gBand[i] = red;
            bBand[i] = 255 - red;
          }

          // Set the new pixel values on the pixelBlock
          pixelData.pixelBlock.pixels = [rBand, gBand, bBand];
          pixelData.pixelBlock.pixelType = "U8"; // U8 is used for color
        }

        var layer = new ImageryLayer({
          url: url,
          pixelFilter: colorize,
          popupTemplate: {
            // autocasts as new PopupTemplate()
            title: "Sea Surface Temperature",
            content: "{Raster.ServicePixelValue}° Celsius"
          }
        });

        // Add sea temperature layer to the map
        map.add(layer);

        var legend = new Legend({
          view: view,
          layerInfos: [
            {
              layer: layer,
              title: "Legend"
            }
          ]
        });

        view.ui.add(legend, "bottom-right");


      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>
Tags (2)
0 Kudos
2 Replies
UndralBatsukh
Esri Regular Contributor

Hi there, 

Unfortunately, it is not possible. Developers can change the pixels any which way they want with the use pixel filter. So it is too hard to count for all the different changes made via pixel filter.

-Undral
0 Kudos
JayHill
Frequent Contributor

Ok Thanks Undral!

0 Kudos