JavaScript API: Can I use setRenderingRule on an Image Service Layer to show above/below a given value?

5978
12
Jump to solution
03-27-2015 11:26 AM
JustinShepard
Occasional Contributor II

I have an image service that I want to let the user quickly show what from that layer is above and below a given value using a basic symbology of red being values less than the user specified value and green being values larger. Would this be an appropriate use for the ArcGISImageServiceLayer setRenderingRule method?

I looked through the API and all I can find from RasterFunction | API Reference | ArcGIS API for JavaScript is that raster functions are objects. I was thinking of creating a remap raster function, like you would in ArcMap/Catalog for a mosaic dataset, but I'm not sure how to set this up dynamically as part of a JavaScript application. So my question is really two parts 1) how do I write a raster function in JavaScript to handle the remap 2) how do I then set the symbology (assume remaped values indicate 1 = less than value of interest and 2 = greater than value of interest) so that it displays properly in the web application?

I haven't done this before so any help is appreciated, this might not even be the best approach so I'm open to other ideas.

Thanks!

1 Solution

Accepted Solutions
KristianEkenes
Esri Regular Contributor

Chaining raster functions is doable using the JavaScript API. You can read about it in the REST help documentation: ArcGIS REST API. See the Overview section starting with the paragraph that begins, "At 10.2 and later, a client can define a raster function template by chaining multiple well-known raster functions and can also specify output pixel types..." There's an example of this at the bottom of that page. Basically you would define both raster functions and set one of them in the Raster functionArgument. See snippets below and full sample here: JS Bin - Collaborative JavaScript Debugging

        var rf = new RasterFunction();
        rf.functionName = "Remap";
        rf.functionArguments = {
          "InputRanges" : [-3,10,11,37],
          "OutputValues" : [1,2],
          "Raster" : "$$"  //Use the image service
        };
        rf.variableName = "water_temp";
        rf.outputPixelType = "U8";
         
        var colorRF = new RasterFunction();
        colorRF.functionName = "Colormap";
        colorRF.variableName = "water_temp";
        colorRF.functionArguments = {
          "Colormap" : [
            [1, 255, 0, 0],
            [2, 0, 255, 0] 
            ],
          "Raster" : rf  //use the output of the remap rasterFunction for the Colormap rasterFunction
        };

        imageServiceLayer.setRenderingRule(colorRF);

This information is there, but it is buried. We'll update the JS reference to be more clear about how to chain raster functions. Thanks, again for the input!

View solution in original post

0 Kudos
12 Replies
KristianEkenes
Esri Regular Contributor

To answer to your first question, I found this resources page from the REST API helpful. Click on "Remap" and look at the examples. I was able to successfully remap an image service of sea temperatures this way:

      var rf = new RasterFunction();        
      rf.functionName = "Remap";        
      rf.functionArguments = {          
        InputRanges: [-3,10,11,37],  //temperature ranges (-3 to 10) and (11 to 37)          
        OutputValues: [1,35]  //symbolize the above ranges using the colors                                                               //values 1 and 35 respectfully        
      };        
      rf.variableName = "water_temp";    
      var params = new ImageServiceParameters();    
      params.renderingRule = rf;
      var imageServiceLayer = new ArcGISImageServiceLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/ScientificData/SeaTemperature/ImageServer", {
          imageServiceParameters: params,
          opacity: 0.75
      });
      map.addLayer(imageServiceLayer);
    
      imageServiceLayer.refresh();

Now, while that allows you to reclassify pixel values, it obviously doesn't allow you to specify the colors, say red and green. I'm not sure how to answer your second question about accomplishing this, but perhaps the "Colormap" raster function would be useful for this. Try adapting the code snippet above in your code and see how that goes. I'll continue to read more about more easily rendering the values in a more customizable way.

0 Kudos
JustinShepard
Occasional Contributor II

Thanks for the snippet and Colormap suggestion. I'll give it a try on Monday and let you know how it goes.

0 Kudos
JustinShepard
Occasional Contributor II

Using your snippet I got the remap working today.

In Catalog I have it doing what I want by chaining the remap and colormap functions together. However, in the JavaScript API I can't find anything about how to chain raster functions, it would be a real shame if we can't chain them in the JavaScript API.

I also found this useful for figuring out function syntax.

ArcGIS REST API

0 Kudos
KristianEkenes
Esri Regular Contributor

You make a good point about chaining raster functions. We'll make that a discussion topic when documenting future versions of the API. Thanks for the suggestion!

0 Kudos
KristianEkenes
Esri Regular Contributor

Chaining raster functions is doable using the JavaScript API. You can read about it in the REST help documentation: ArcGIS REST API. See the Overview section starting with the paragraph that begins, "At 10.2 and later, a client can define a raster function template by chaining multiple well-known raster functions and can also specify output pixel types..." There's an example of this at the bottom of that page. Basically you would define both raster functions and set one of them in the Raster functionArgument. See snippets below and full sample here: JS Bin - Collaborative JavaScript Debugging

        var rf = new RasterFunction();
        rf.functionName = "Remap";
        rf.functionArguments = {
          "InputRanges" : [-3,10,11,37],
          "OutputValues" : [1,2],
          "Raster" : "$$"  //Use the image service
        };
        rf.variableName = "water_temp";
        rf.outputPixelType = "U8";
         
        var colorRF = new RasterFunction();
        colorRF.functionName = "Colormap";
        colorRF.variableName = "water_temp";
        colorRF.functionArguments = {
          "Colormap" : [
            [1, 255, 0, 0],
            [2, 0, 255, 0] 
            ],
          "Raster" : rf  //use the output of the remap rasterFunction for the Colormap rasterFunction
        };

        imageServiceLayer.setRenderingRule(colorRF);

This information is there, but it is buried. We'll update the JS reference to be more clear about how to chain raster functions. Thanks, again for the input!

0 Kudos
JustinShepard
Occasional Contributor II

thanks!

Worked great.

0 Kudos
KevinPiraino1
New Contributor

Hello Kristian Ekenes,

I have a similar question to that of Justin's question. I am in the process of creating a simple map algebra web map application that takes two image service layers and uses two RasterFunctions, "Remap" and "Arithmetic". Now I am able to use the "Remap" function just fine and the output from this function is what I expected. When I try to use the RenderingRule from the "Remap" functions in the "Arithmetic" function, I either receive no output or an output that I would not expect. I have posted this question else where on the GeoNet community site in hopes that it will get answered. If you could possibly just take a look the attached script in my original post and let me know what the issue may be. Issue with ESRI API - RasterFunction "Arithmetic"

0 Kudos
KristianEkenes
Esri Regular Contributor

Hi Kevin,

I'm not able to access your image services, so I'm not sure how much help I'll be, but there were a couple of things in your code that stuck out to me.

1. The Raster and Raster2 params in your functionArguments for suit are strings. They should be variables if you want to do map algebra between two rasters. Also, they're referring to the wrong variables. You're point to ImageServiceParamaters when they should be pointing to RasterFunctions. So instead of:

functionArguments_alge.Raster @= "params"; //these are ImageServiceParameters

functionArguments_alge.Raster2 = "params_land";  //and are strings, not variables

It should be:

functionArguments_alge.Raster = reclass_dem; //these should point to your

functionArguments_alge.Raster2 = reclass_landcover; //RasterFunction variables

The case where you'll see a string will probably be when using the original raster which is referenced like this: "$$". Or a constant:

functionArguments_alge.Raster = "$$"; //this would use the values in the original raster

functionArguments_alge.Raster2 = "100"; //and multiply/add/whatever the cells by 100

2. I'm not an expert on the Arithmetic function, but I don't think you would apply it to both layers as you do here:

var dem = new ArcGISImageServiceLayer("http://indian.geo.msu.edu:6080/arcgis/rest/services/Piraino/dem_un8/ImageServer",{imageServiceParameters:params_suit});

var landcov = new ArcGISImageServiceLayer("http://indian.geo.msu.edu:6080/arcgis/rest/services/Piraino/Landcover/ImageServer", {imageServiceParameters:params_suit});

Try only applying it to just one of them.

3. Also, try experimenting with the ExtentType and CellsizeType functionArguments for Arithmetic. If you have different cell sizes, that perhaps could be giving you issues? I would also play around with the outputPixelType as well...

Sorry I can't see your services, but that's the process I would go through. Maybe someone who's used this function can jump in and give a more authoritative answer.

KevinPiraino1
New Contributor

The two image Services that I have are a DEM and a Landcover raster. Attached is a more comprehensive script that I have been building as well as the outputs that I am receiving versus the outputs I should be getting based on the input parameters. WebAppError.jpg

0 Kudos