Add Scalar exposed as Argument in raster function rest api

3740
6
Jump to solution
11-12-2014 06:18 AM
Labels (2)
nita14
by
Occasional Contributor III

Hi,

 

Is there any way to expose a scalar (added to Local function in Raster Functions Chain - attached screenshot) as an argument of raster function added to an image service?

 

I would like to being able to filter my slope function results in specific range of values for example from 5 to 25 degrees using REST. This is the same idea as parameter in GP service.

 

Update 1: I found out that I can use remap function to achieve pixel filtering and get my inputs exposed as arguments. The problem, still not resolved, is how I can access these arguments as they are in nested functions inside Raster Function Template file added to my Image Service.

 

Update 2: Is it possible to use arguments in nested functions inside Raster Function Template file using ArcGIS Runtime for Java and ArcGIS for Server ? Is it possible to create the app like this Flex sample. using ArcGIS Runtme 10.2.4.?

 

Any ideas or experiences to share?

 

Edited by: nicinski adam

1 Solution

Accepted Solutions
DavidJohnson5
Esri Contributor

Hi adam,

I apologize in advance for a very long answer to your question.  If I had more time, I would make it shorter. But in brief, yes, you can expose a scalar value in a local function and override it's default values via REST. 

Now for the long answer.  I'll explain how this works by way of example:

1 - RFT.png

This function chain uses a Local function to divide the pixel values from the service data by a scalar value. 

2 - Local tab.png

After the division, a stretch function is used to transform the result of the division to an unsigned 8-bit output (0-255).  This is followed by a Colormap function to display the result and a ColorMapToRGB function to convert the output to RGB so it can be viewed in web maps and apps.  But let's focus on the Local function, and how you pass in scalar values for the divisor via REST - the rest is window dressing. 

Local functions configured with the Divide operater require two inputs: the data to be divided, which in this case are the pixels from the image service, and the scalar value to divide by.  In this example, the default value for the divisor scalar is "1".  Now let's take a look at the Variable Manager tab of the Local Function Properties window.  

3 - variable manager tab.png

I assigned to the "Rasters" argument the variable name "Rasters" (although I could have assigned it any name I wanted).  In order to override the default scalar value for the divisor, you need to know the name assigned to this argument.  We'll get back to this in a moment.

I uploaded this template to an image service which contains a single raster dataset of the "normal" global rainfall for a particular month and year.  Here is what the default service output looks like:

ExportImage1.png

To invoke the raster function template with the default argument values, simply call the function by name (in this example "LocalFunctionScalarTest")  by passing in the following JSON string as the Rendering Rule parameter of the Export Image operation.

{

    "rasterFunction": "LocalFunctionScalarTest",

}

ExportImage2.png

Now we can get back to your original question about how to override the default scalar values for arguments in the Local function.  In this example, I divide the precipitation values by 0.1:

{

    "rasterFunction": "LocalFunctionScalerTest",

    "rasterFunctionArguments": { "Rasters": ["$$", 0.1 ] }

}

Note the variable name "Rasters" and the array of values following it.  The first value in the array, "$$", is a "keyword" which represents the default pixel values from the service data.  This is identical to the first item in the "Input Rasters" list in the Local tab of the function properties window.  The second value, of course, is the new scalar value for the divisor.  Here is the result:

ExportImage3.png

I hope this helps.  Here are some links to documentation for the REST API that might answer any further questions you have:

Export Image: ArcGIS REST API

Using Rasters in Rendering Rules: ArcGIS REST API

By the way, I'm the author of the article you mentioned in Update #2. I have only a small amount of experience developing with the ArcGIS Runtime, and it's been a while since I have worked in that space.  But I'm not aware of any reason why you could not develop an app similar to that one using the ArcGIS Runtime.  To build an application that interacts with image services and custom server functions, start with the back-end server part:

  1. publish your image service.
  2. build the function template using the Raster Function Template Editor in ArcMap.  Assign unique variable names to each of the function arguments you want to override in your app (using the Variable Manager tabs of the functions in the template), and upload the template to the service.
  3. Test the function by passing in JSON strings into the rendering rule of the service REST endpoint to make sure you are getting the expected results. 

After the back-end server part is working according to design, build a custom widget with the ArcGIS Runtime to override the default function arguments.

Good luck!

-dave

View solution in original post

6 Replies
DavidJohnson5
Esri Contributor

Hi adam,

I apologize in advance for a very long answer to your question.  If I had more time, I would make it shorter. But in brief, yes, you can expose a scalar value in a local function and override it's default values via REST. 

Now for the long answer.  I'll explain how this works by way of example:

1 - RFT.png

This function chain uses a Local function to divide the pixel values from the service data by a scalar value. 

2 - Local tab.png

After the division, a stretch function is used to transform the result of the division to an unsigned 8-bit output (0-255).  This is followed by a Colormap function to display the result and a ColorMapToRGB function to convert the output to RGB so it can be viewed in web maps and apps.  But let's focus on the Local function, and how you pass in scalar values for the divisor via REST - the rest is window dressing. 

Local functions configured with the Divide operater require two inputs: the data to be divided, which in this case are the pixels from the image service, and the scalar value to divide by.  In this example, the default value for the divisor scalar is "1".  Now let's take a look at the Variable Manager tab of the Local Function Properties window.  

3 - variable manager tab.png

I assigned to the "Rasters" argument the variable name "Rasters" (although I could have assigned it any name I wanted).  In order to override the default scalar value for the divisor, you need to know the name assigned to this argument.  We'll get back to this in a moment.

I uploaded this template to an image service which contains a single raster dataset of the "normal" global rainfall for a particular month and year.  Here is what the default service output looks like:

ExportImage1.png

To invoke the raster function template with the default argument values, simply call the function by name (in this example "LocalFunctionScalarTest")  by passing in the following JSON string as the Rendering Rule parameter of the Export Image operation.

{

    "rasterFunction": "LocalFunctionScalarTest",

}

ExportImage2.png

Now we can get back to your original question about how to override the default scalar values for arguments in the Local function.  In this example, I divide the precipitation values by 0.1:

{

    "rasterFunction": "LocalFunctionScalerTest",

    "rasterFunctionArguments": { "Rasters": ["$$", 0.1 ] }

}

Note the variable name "Rasters" and the array of values following it.  The first value in the array, "$$", is a "keyword" which represents the default pixel values from the service data.  This is identical to the first item in the "Input Rasters" list in the Local tab of the function properties window.  The second value, of course, is the new scalar value for the divisor.  Here is the result:

ExportImage3.png

I hope this helps.  Here are some links to documentation for the REST API that might answer any further questions you have:

Export Image: ArcGIS REST API

Using Rasters in Rendering Rules: ArcGIS REST API

By the way, I'm the author of the article you mentioned in Update #2. I have only a small amount of experience developing with the ArcGIS Runtime, and it's been a while since I have worked in that space.  But I'm not aware of any reason why you could not develop an app similar to that one using the ArcGIS Runtime.  To build an application that interacts with image services and custom server functions, start with the back-end server part:

  1. publish your image service.
  2. build the function template using the Raster Function Template Editor in ArcMap.  Assign unique variable names to each of the function arguments you want to override in your app (using the Variable Manager tabs of the functions in the template), and upload the template to the service.
  3. Test the function by passing in JSON strings into the rendering rule of the service REST endpoint to make sure you are getting the expected results. 

After the back-end server part is working according to design, build a custom widget with the ArcGIS Runtime to override the default function arguments.

Good luck!

-dave

nita14
by
Occasional Contributor III

Dear Dave,

thank you very much for your feedback. It works like a charm in the ArcGIS Runtime App!

However, I still have a problem when I want to combine more arguments in my rtf file. I would like to ask you one more question:

How I can pass result from one function as the input of another function in the same rtf file?

Suppose that I want to filter my DEM by elevation and slope, just like you did in your sample app. I use local and slope function to achieve this. How I can pass result of my slope function to another local function?  Attached is the screenshot of my rtf file.

RTF.png

I found in the documentation that it is possible. But there is no example how to achieve this.

"A raster value can be the image service ("$$") -- default, an image in the image service ("$oid"), or a result from another function (a rendering rule object)."

Thank you in advance,

Best regards,

Adam

0 Kudos
DavidJohnson5
Esri Contributor

Hi Adam,

Actually, the flow of processing is controlled by the template and not the rendering rule.  The role of the rendering rule is to define the values used as the arguments of the functions in the template.

I was working on an example to show you for filtering a DEM by slope and elevation.  But for some reason my example is not working! I was trying to implement the filters using Local functions, similar to your screenshot.  I don't know if the problem is due to a bug or user-error.  Hopefully I can get that sorted out next week.  In the app described in the article, I primarily used Remap and Arithmetic functions to handle the filtering logic (there was no Local function at the time).  I may have to go back to that approach to get this to work.  I'll take another look at this next week after the Thanksgiving holiday and get back to you. 

0 Kudos
DavidJohnson5
Esri Contributor

Hi Adam,

I've done some further research into your question about passing in multiple scalar values to a raster function template with our software developers. It turns out this is currently not possible.  The reason is because raster functions, and raster function templates, have only one input raster array.  This array is the “variableName” parameter in the rendering rule, or the "Raster" or "Rasters" argument seen in the Variable Manager tab of a Function Properties window in ArcMap.  As I showed you in the "LocalFunctionScalarTest" example, it's possible to resolve a single Local function argument which expects a raster array to the variableName parameter.  But since templates currently have only one input raster array, it’s not possible to resolve more than one raster array that exists as a function argument in the template via REST with this approach.

This is unfortunate, because your approach to filter by elevation and slope using multiple Local functions is more elegant and straightforward than the approach I took for the app described in the Esri APL blog article.  So we have to go back to my old, tried and true approach, which uses Remap functions to perform the filtering.

I've uploaded the raster function templates used in the DEM filtering app to arcgis.com.  Now you and everybody can download them here.  I've included a readme file that describes how to work with them and includes several examples of rendering rules in JSON that you can use for testing on your own image service.  I hope this is helps.  Let me know if you run into any issues or have further questions about this.

Best Regards,

Dave

0 Kudos
nita14
by
Occasional Contributor III

Hi Dave,

First of all, I would like to thank you for the support offered to me and for uploading rtfs to ArcGIS Online. I hope some day, multiple raster arrays will be supported as input to image service functions. I successfully configured yours raster functions to run against my own image service and consumed them in ArcGIS Runtime for Java 10.2.4 application. Thank you once again.

Best Regards,

Adam

0 Kudos
DavidJohnson5
Esri Contributor

You are welcome!

0 Kudos