XY not in correct location via GP tool

2289
33
Jump to solution
10-03-2019 08:04 AM
jaykapalczynski
Frequent Contributor

I have an application that I am testing out.  But first a little back information

My Steps:

I created a simple Python script that creates a new point in a FeatureClass. (see below)

I then add this script to a toolbox

I then set the parameters for the Classification, X and Y in the properties (Classifcation=string, XY are set to double)

I can run this with hard coded values via IDLE and it works fine as seen below

Next:

Seeing that the script works in IDLE I publish a GP Service from the process I just ran to my ArcGIS Server.

I can run the GP Service from our ArcGIS Server and it runs fine.

Finally:

I then reference this from AppStudio and attempt to run it with hard coded values as seen below

1. I can get it to run and create a new point THIS WORKS

2. BUT the XY coordinates I feed it don't appear where they should.  If I use the EXACT same ones that I use in the script below they don't show up in the same place as the points added .

The data in SDE is WGS 84 decimal degrees.

MY ISSUE:

If I hard code the XY in the script and run from IDLE it works fine

If I add the exact same Coordinates from the GP Service that I published in ArcGIS Service it works fine

If I hard code the exact same Coordinates as seen below in AppStudio it puts the points at roughly (-78, 39)

      I dont see where and how to coordinates I am submitting in the job are being converted from (-77.43153, 37.527056) to (-78, 39)

     Funny thing is if I export the data and calculate XY for the points the ones done through AppStudio are truncated and have no Sig Figs, while the points added in the Service and Script via IDLE have sig figs.

Very confused.  Seems the sig figs are being dropped but then again the XY corrds are goin from 77 to 78 and 37 to 39?

      

I know this is a lot to digest but figure someone might have seen this before?

import arcpy
from arcpy import env
import os

#varXCoord = arcpy.GetParameterAsText(4)
#varYCoord = arcpy.GetParameterAsText(5)
#varClassification = arcpy.GetParameterAsText(6)

varClassification = "New Classification"
varYCoord = "37.527056"
varXCoord = "-77.43153"

fc = 'xE.DBO.xxx'
workspace = arcpy.env.workspace = r'C:\Users\x\AppData\Roaming\ESRI\Desktop10.5\ArcCatalog\x@xxxxxxx.sde'

## Start an edit session. Must provide the workspace.
edit = arcpy.da.Editor(workspace)

edit.startEditing(False, False)

## Start an edit operation
edit.startOperation()

row_values = [( varXCoord ,varYCoord, varClassification)]
print(row_values)

cursor = arcpy.da.InsertCursor(fc,['SHAPE@X', 'SHAPE@Y', 'Classification'])
for row in row_values:   
    cursor.insertRow(row) 
del cursor
                         
## Stop the edit operation.
edit.stopOperation()

## Stop the edit session and save the changes
edit.stopEditing(True)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

GeoprocessingTask {
   id: insertCursorTask
   url: "https://xxx.xx.xxxx.xx/arcgis/rest/services/xxx/InsertCursor/GPServer/InsertCursor/submitJob"

   function insertFunction() {

       var varClassification = "New Classification";
       var xlocation = -77.43153;
       var ylocation = 37.527056;

       var gpParametersInsert = ArcGISRuntimeEnvironment.createObject("GeoprocessingParameters",
     {executionType: Enums.GeoprocessingExecutionTypeSynchronousExecute});

       var inputsI = {};

       inputsI["classification"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingString", {value: varClassification});
       inputsI["SHAPE@X"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingString", {value: xlocation });
       inputsI["SHAPE@Y"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingString", {value: ylocation });

       //var inputresults = inputs;
       gpParametersInsert.inputs = inputsI;

       // Create the job that handles the communication between the application and the geoprocessing task
       insertCursorJob = insertCursorTask.createJob(gpParametersInsert);

       console.log("gp job: " + JSON.stringify(insertCursorJob));
 
       insertCursorJob.start();

}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
33 Replies
ErwinSoekianto
Esri Regular Contributor

Yes, something like that. Try it out first by opening the URL to the GP REST endpoint, then enter the parameters in the text box, and then after you submit it, you can see the URL is created with the parameters added to it.

0 Kudos
jaykapalczynski
Frequent Contributor

These are the results that I set to console.log....

Not sure how to return the entire url with the attributes attached....well I think thats what its supposed to be doing..

hmmmmm

qml: response text: {"jobId":"jd64deeb127104dcb948ace3aae71f56c","jobStatus":"esriJobSubmitted"}

qml: log: https://xxx.gov/arcgis/rest/services/Tools/InsertCursor/GPServer/Cursor/submitJob

            NetworkRequest {
                id: uploadRequest
                url: "https://xxx.gov/arcgis/rest/services/Tools/Cursor/GPServer/Cursor/submitJob"
                method: "POST"
                headers.referrer: "https://www.arcgis.com/home/index.html"
                headers.userAgent: "Mozilla/5.0"

                onReadyStateChanged: {
                    if ( readyState === NetworkRequest.DONE ) {
                        //result.text = responseText
                        console.log("response text: " + responseText);
                        console.log("log: " + url)
                    }
                }
                onError: console.log(errorText + ", " + errorCode);  //result.text = errorText + ", " + errorCode
            }

                    Button {
                        id: networkRequest
                        visible: true
                        text: "Network Request"

                        onClicked: {
                            uploadRequest.send({adds:"[{\"attributes\":{\"description\":\"Networkrequest Sample\",\"Comments\":\"some comment\",\"timestamp\":null},\"geometry\":{\"paths\":[[-11542803.322978519,3129176.1574580222]],\"spatialReference\":{\"latestWkid\":3857,\"wkid\":102100}}}]", f:"json"});

                        }
                    } // END OF INSERT BUTTON
0 Kudos
ErwinSoekianto
Esri Regular Contributor

Looks good. 

I see that you got a jobId back, and it is submitted, then you can check the job status using another NetworkRequest, Check job status—ArcGIS REST API: Services Directory | ArcGIS for Developers 

0 Kudos
jaykapalczynski
Frequent Contributor

I am confused:

1. How can I see the url that is being submitted in its entirety? for verification purposes?

2. I assume this request is passing the values I put in the attributes section

uploadRequest.send({adds:"[{\"attributes\":{\"description\":\"Networkrequest Sample\",\"Comments\":\"some comment\",\"timestamp\":null},\"geometry\":{\"paths\":[[-11542803.322978519,3129176.1574580222]],\"spatialReference\":{\"latestWkid\":3857,\"wkid\":102100}}}]", f:"json"});

3. I am unclear how this is received and processed in the rest end point....where the other way I was doing this i could control them by name and parameters set in the GP tool.  confused how the attributes are handled and the coordinates are handled on the GP side....do I need to create a new GP service?

my inputs the other way have names that are captured by the GP service parameters....well I think thats how its happening...

inputsI["aItem"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingString", {value: varItem});
inputsI["bPublicPrivate"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingString", {value: varPublicPrivate});
inputsI["cCaseNum"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingString", {value: varCaseNum});
inputsI["dComments"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingString", {value: xlocation + "  " + ylocation});
inputsI["eSHAPE@X"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingDouble", {value: xlocation});
inputsI["fSHAPE@Y"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingDouble", {value: ylocation});
inputsI["gSHAPE@XY"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingString", {value: centercoord});
inputsI["hCLassification"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingString", {value: varClassification});

0 Kudos
ErwinSoekianto
Esri Regular Contributor

1. There are many ways to snoop the URL, using Fiddler is one option.

2. Yes, it will be in the body of the request, see the parameter of the send method in NetworkRequest NetworkRequest QML Type | ArcGIS 

3. This approach is going to the REST endpoint directly, where the previous approach is using the GeoprocessingTask Object from ArcGIS Runtime, which is doing the REST endpoint request behind the scene. I don't think you need to create a new GP service. 

I suggested using the REST endpoint approach because it is a simpler approach for this scenario (in my opinion). Plus it seemed hard to troubleshoot the issue with the GeoprocessingParameters in this forum, Esri Technical Support could probably help you troubleshoot the issue in more detail 

jaykapalczynski
Frequent Contributor

my head is spinning...haahahaahaah

0 Kudos
jaykapalczynski
Frequent Contributor

Well with the help of ESRI supports eyes we have located the problem.  A little embarrassed at this point....

The problem was in the hand shake from AppStudio to the Published GP Tool in ArcGIS Server

1. I wrote the python script with an insertCursor and this ran fine

2. I created and added this script to a GP tool in desktop

3. I set the parameters and then ran with no data, successful (GPS params were eSHAPE@x and fSHAPE@Y)

4. I took the result and published to ArcGIS Server

5. I then ran the insert from this GP tool RestEndpoint and it ran fine

Now here is where I went wrong. 

In AppStudio I was using the parameter name from the parameters set in step 3 above

            inputsI["eSHAPE@X"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingDouble", {value: xlocation});
            inputsI["fSHAPE@Y"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingDouble", {value: ylocation});

Upon closer look at the GP Tool published to ArcGIS Server the names if the parameters were:

eSHAPE_X and fSHAPE_Y

I modified the code in AppStudio to this and it worked.

            inputsI["eSHAPE_X"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingDouble", {value: xlocation});
            inputsI["fSHAPE_Y"] = ArcGISRuntimeEnvironment.createObject("GeoprocessingDouble", {value: ylocation});

NOW comes my final question.

How do I return the JobID number and Status code of this call to the GP Tool????

I want to test if successful or unsuccessful

I am using the below code to .createjob and pass my parameters...

                   // Create the job that handles the communication between the application and the geoprocessing task

            updateCursorJob = updateCursorTask.createJob(gpParameters);
            console.log("gp job: " + JSON.stringify(updateCursorJob));
            updateCursorJob.start();

I can do something like this in a NetworkRequest

BUT how do I do this from the CREATEJOB that I am doing below...

            NetworkRequest {
                id: uploadRequest
                url: "https://xxxx/arcgis/rest/services/xx/InsertCursor/GPServer/InsertCursor/submitJob"
                method: "POST"
                headers.referrer: "https://www.arcgis.com/home/index.html"
                headers.userAgent: "Mozilla/5.0"

                onReadyStateChanged: {
                    if ( readyState === NetworkRequest.DONE ) {
                        //result.text = responseText
                        console.log("response text: " + responseText);

                        var obj = JSON.parse(responseText);
                        objJobID = obj.jobId;
                        objJobStatus = obj.jobStatus;
                        console.log("jobId: " + objJobID);
                        console.log("jobStatus: " + objJobStatus);

                        console.log("log: " + url)
                        //verifyRequest.send({adds: "/"+ objJobID, f:"json"});


                    }
                }
                onError: console.log(errorText + ", " + errorCode);  //result.text = errorText + ", " + errorCode
            }
0 Kudos
ErwinSoekianto
Esri Regular Contributor

Jay, 

Esri Technical Support‌ is awesome. Glad to hear that it works out. 

To check the status of the Job, you can call another Network request to check the job status using the job id, see this doc, Check job status—ArcGIS REST API: Services Directory | ArcGIS for Developers 

Erwin

0 Kudos
jaykapalczynski
Frequent Contributor

I know how to get the status once I have the job id but cant figure out how to get the JobID from my request 

I am not using a Network Request to call the GP tool to insert the parameters and create a new feature...I am simply doing the below where I am passing my values into the gpParameters object.

I then start the job with updateCursorJob.start()

How do I get the JobID of this createJob request?

                   // Create the job that handles the communication between the application and the geoprocessing task

            updateCursorJob = updateCursorTask.createJob(gpParameters);
            console.log("gp job: " + JSON.stringify(updateCursorJob));
            updateCursorJob.start();

0 Kudos
ErwinSoekianto
Esri Regular Contributor

The submitJob operation will result in geoprocessing job resources in response that includes jobid in the response. 

Submit GP Job—ArcGIS REST API: Services Directory | ArcGIS for Developers 

0 Kudos