Geoprocessing service cannot input/output rasters

4932
5
Jump to solution
06-08-2015 07:32 AM
JonMorris2
Occasional Contributor II

I'm trying to write a javascript web app that does a multi-stage raster calculation. At each stage, I'd like to display the output raster, then use it as input to the next stage. What is the best way to pass rasters from one GP tool to another?

I've tried setting the output parameter to raster dataset, which does generate a TIFF in the scratch workspace (for example http://xxxxxx:6080/arcgis/rest/directories/arcgisjobs/createrandomraster_gpserver/j20ddb907be1d44049...), but I can't work out how to use this url to create a layer that can be added to the map. A number of the layer constructors take a url, but none of them display the layer on my map.

ArcGISDynamicMapServiceLayer constructor

ArcGISImageServiceLayer constructor

RasterLayer constructor

I've also tried setting the tool output to raster layer, which displays on the web map ok, but doesn't work as an input to the second tool.

I've looked through the help docs and javascript api, but there isn't much detail on raster handling. I know I'm getting the input format wrong, but can't find any clues as to what I should be doing. The only response I get from the server is a Failed message, which isn't much use.

Any ideas? This discussion seems to cover the same area, but no-one has come up with the answer yet.

0 Kudos
1 Solution

Accepted Solutions
JonMorris2
Occasional Contributor II

So, I'll answer my own question (again!):

Parameter data types need to be Raster Layer, and when you publish, make sure you check View Result with a Map Service on the Parameters tab.

Then when you get the result data, it's the value property that needs to be passed into the next tool. This is a JSON element containing type and url properties.

Here's a simplified example of the finished code:

gpSetup = {
    /**
     * @ Description: LFP setup basic GP tool.
     */


    outZ: null,


    init: function () {
        require(["esri/layers/ImageParameters", "esri/tasks/Geoprocessor"],
            function (ImageParameters, Geoprocessor) {
                "use strict";
                //Define the hosted geoprocessor task
                var gp = new Geoprocessor(urlSetup),
                //Pass in values that are found in the forms to the geoprocessor object
                    params = {
                        "Stage Age": "Aqui",
                        "WATER Depth": "203.70"
                    };


                function setupCallback(jobInfo) {
                    var imageParams;
                    if (jobInfo.jobStatus !== "esriJobFailed") {
                        setupJobId = jobInfo.jobId;


                        //Put the resulting images in the following maps.
                        imageParams = new ImageParameters();
                        imageParams.imageSpatialReference = map0.spatialReference;


  // keep output to pass on to next tool
                        gp.getResultData(setupJobId, "InputZ", function (gpData) {
                            gpSetup.outZ = gpData.value;
  gpNpp.init();
                        });


  // display output as map layer
                        gp.getResultImageLayer(setupJobId, "InputZ", imageParams, function (gpLayer) {
                            map0.addLayer(gpLayer);
                            leftMapTitle.innerHTML = "InputZ";
                        });
                    }
                }


                gp.submitJob(params, setupCallback, statusCallback, errorCallback);
            }
        );
    }
};


gpNpp = {
    /**
     * @ Description: Create NPP GP tool.
     */


    init: function () {
        require(["esri/layers/ImageParameters", "esri/tasks/Geoprocessor"],
            function (ImageParameters, Geoprocessor) {
                "use strict";
                var gp, params;
                //Define the hosted geoprocessor task
                gp = new Geoprocessor(urlNPP);


                //Pass in values that are found in the forms to the geoprocessor object
                params = {
                    "Input_Z": gpSetup.outZ
                };


                function nppCallback(jobInfo) {
                    var imageParams;
                    if (jobInfo.jobStatus !== "esriJobFailed") {
                        nppJobId = jobInfo.jobId;


                        //Put the resulting images in the following maps.
                        imageParams = new ImageParameters();
                        imageParams.imageSpatialReference = map1.spatialReference;


                        gp.getResultImageLayer(nppJobId, "NPP", imageParams, function (gpLayer) {
                            map1.addLayer(gpLayer);
                            rightMapTitle.innerHTML = "NPP";
                        });
                    }
                }


                gp.submitJob(params, nppCallback, statusCallback, errorCallback);
            }
        );
    }
};

View solution in original post

0 Kudos
5 Replies
JonMorris2
Occasional Contributor II

So, I'll answer my own question (again!):

Parameter data types need to be Raster Layer, and when you publish, make sure you check View Result with a Map Service on the Parameters tab.

Then when you get the result data, it's the value property that needs to be passed into the next tool. This is a JSON element containing type and url properties.

Here's a simplified example of the finished code:

gpSetup = {
    /**
     * @ Description: LFP setup basic GP tool.
     */


    outZ: null,


    init: function () {
        require(["esri/layers/ImageParameters", "esri/tasks/Geoprocessor"],
            function (ImageParameters, Geoprocessor) {
                "use strict";
                //Define the hosted geoprocessor task
                var gp = new Geoprocessor(urlSetup),
                //Pass in values that are found in the forms to the geoprocessor object
                    params = {
                        "Stage Age": "Aqui",
                        "WATER Depth": "203.70"
                    };


                function setupCallback(jobInfo) {
                    var imageParams;
                    if (jobInfo.jobStatus !== "esriJobFailed") {
                        setupJobId = jobInfo.jobId;


                        //Put the resulting images in the following maps.
                        imageParams = new ImageParameters();
                        imageParams.imageSpatialReference = map0.spatialReference;


  // keep output to pass on to next tool
                        gp.getResultData(setupJobId, "InputZ", function (gpData) {
                            gpSetup.outZ = gpData.value;
  gpNpp.init();
                        });


  // display output as map layer
                        gp.getResultImageLayer(setupJobId, "InputZ", imageParams, function (gpLayer) {
                            map0.addLayer(gpLayer);
                            leftMapTitle.innerHTML = "InputZ";
                        });
                    }
                }


                gp.submitJob(params, setupCallback, statusCallback, errorCallback);
            }
        );
    }
};


gpNpp = {
    /**
     * @ Description: Create NPP GP tool.
     */


    init: function () {
        require(["esri/layers/ImageParameters", "esri/tasks/Geoprocessor"],
            function (ImageParameters, Geoprocessor) {
                "use strict";
                var gp, params;
                //Define the hosted geoprocessor task
                gp = new Geoprocessor(urlNPP);


                //Pass in values that are found in the forms to the geoprocessor object
                params = {
                    "Input_Z": gpSetup.outZ
                };


                function nppCallback(jobInfo) {
                    var imageParams;
                    if (jobInfo.jobStatus !== "esriJobFailed") {
                        nppJobId = jobInfo.jobId;


                        //Put the resulting images in the following maps.
                        imageParams = new ImageParameters();
                        imageParams.imageSpatialReference = map1.spatialReference;


                        gp.getResultImageLayer(nppJobId, "NPP", imageParams, function (gpLayer) {
                            map1.addLayer(gpLayer);
                            rightMapTitle.innerHTML = "NPP";
                        });
                    }
                }


                gp.submitJob(params, nppCallback, statusCallback, errorCallback);
            }
        );
    }
};
0 Kudos
JonMorris2
Occasional Contributor II

Wow, this code editor really is horrible. Apologies for bad layout above, but I don't have time to keep re-editing it to try and fix it.

0 Kudos
michellechristmas1
New Contributor II

Hi

I have a custom gp tool that does raster difference, the geoprocessing is working the esriJobSucceeded, however when I add the gpLayer to the map it trows an error saying ReferenceError: gp is not defined at completeCallback

I'm not sure what this mean, have you ever seen this error. Here is the code so you get some Idea

  executeGP = function () {

                 

                    if ($("#compareMethodDD").val() !== null) {

                        if ($("#compareMethodDD").val().length > 0) {

                            compareMethodVal = $("#compareMethodDD").val();

                        } else {

                            console.log("Compare method not selected.");

                        }

                    }

                    if ($("#compareLayer1DD").val() !== null) {

                        if ($("#compareLayer1DD").val().length > 0) {

                            compareLayer1Val = $("#compareLayer1DD").val();

                        } else {

                            console.log("Compare Layer 1 not selected.")

                           

                        }

                    }

                    if ($("#compareLayer2DD").val() !== null) {

                        if ($("#compareLayer2DD").val().length > 0) {

                            compareLayer2Val = $("#compareLayer2DD").val();

                        } else {

                            console.log("Compare Layer 2 not selected.")

                        }

                    }

                   

                 

                    var gp = new Geoprocessor("gpURL);

                    gp.setOutputSpatialReference({

                        wkid: 4326

                    });

                    var params = {

                        Raster1: compareLayer1Val,

                        Raster2: compareLayer2Val

                    };

                    gp.submitJob(params, completeCallback, statusCallback);

                }

                function statusCallback(jobInfo) {

                    console.log(jobInfo.jobStatus);

                }

                function completeCallback(jobInfo) {

                    var imageParams = new ImageParameters();

                   

                    imageParams.imageSpatialReference = map.spatialReference;

                    gp.getResultImageLayer(jobInfo.jobId, imageParams, "Output_Raster", function (gpLayer) {

                        gpLayer.setOpacity(0.5);

                        map.addLayer(gpLayer);

                    });

                }

0 Kudos
JonMorris2
Occasional Contributor II

Hi Michelle,

Your statusCallback and completeCallback are outside the anonymous function. All you need to do is move the brace below gp.submitjob to the end of the snippet, then gp will be in scope for these functions too.

executeGP = function () {


    if ($("#compareMethodDD").val() !== null) {
        if ($("#compareMethodDD").val().length > 0) {
            compareMethodVal = $("#compareMethodDD").val();
        } else {


            console.log("Compare method not selected.");


        }
    }


    if ($("#compareLayer1DD").val() !== null) {
        if ($("#compareLayer1DD").val().length > 0) {
            compareLayer1Val = $("#compareLayer1DD").val();
        } else {


            console.log("Compare Layer 1 not selected.")
           
        }
    }


    if ($("#compareLayer2DD").val() !== null) {
        if ($("#compareLayer2DD").val().length > 0) {
            compareLayer2Val = $("#compareLayer2DD").val();
        } else {
            console.log("Compare Layer 2 not selected.")
        }
    }
     
    var gp = new Geoprocessor("gpURL);
    gp.setOutputSpatialReference({
        wkid: 4326
    });


    var params = {
        Raster1: compareLayer1Val,
        Raster2: compareLayer2Val
    };


    function statusCallback(jobInfo) {
        console.log(jobInfo.jobStatus);
    }


    function completeCallback(jobInfo) {
        var imageParams = new ImageParameters();
       
        imageParams.imageSpatialReference = map.spatialReference;
        gp.getResultImageLayer(jobInfo.jobId, imageParams, "Output_Raster", function (gpLayer) {
            gpLayer.setOpacity(0.5);
            map.addLayer(gpLayer);
        });
    }


    gp.submitJob(params, completeCallback, statusCallback);


}
0 Kudos
michellechristmas1
New Contributor II

Hi Jon

Thank you so much, I had been staring at this code for a long time, and it was something as simple as that, thanks again!!!!

0 Kudos