Select to view content in your preferred language

XY not in correct location via GP tool

3523
33
Jump to solution
10-03-2019 08:04 AM
jaykapalczynski
Honored 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
1 Solution

Accepted Solutions
jaykapalczynski
Honored 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
            }

View solution in original post

0 Kudos
33 Replies
jaykapalczynski
Honored Contributor

I think I got it...I had to Float the String value in Python ...this seemed to work...I now need to do some testing.

varXCoord = float(arcpy.GetParameterAsText(4))
varYCoord = float(arcpy.GetParameterAsText(5))

MicahBabinski
Frequent Contributor

Ah nice. Let us know if that works. I think if you use arcpy.GetParameter you won't need to convert those values to float.

0 Kudos
jaykapalczynski
Honored Contributor

For some reason it looks like I have to....If I run it from the Script via IDLE or from the service itself it works fine.  It fails when sent from AppStudio for some reason....I change to Float in python and it now works from App Studio...sometimes you just dont ask...it works and I am moving on.....hahahaha

0 Kudos
jaykapalczynski
Honored Contributor

Take that back....still not working...

0 Kudos
MicahBabinski
Frequent Contributor

Here are three things I would try:

  1. Use the @SHAPEXY token in your insert cursor, rather than the individual X and Y coordinates
  2. Explicitly set the output spatial reference environment as shown in the first response on this thread: Points added with da.InsertCursor have different coordinates than those used to create the point 
  3. Create a PointGeometry object from your X and Y coordinates with the spatial reference defined, and insert that object as the @SHAPE in your insert cursor

Good luck! Seems what you have written should just work.

Micah

jaykapalczynski
Honored Contributor

RESPONSE TO 2 of your replys...

Hope you can help me out a bit here....trying to implement the 3 ideas you mentioned...

not sure how to handle the:

pointList

pt in pointList

assigning the point to the SHAPE@XY

Is this close to what you were thinking

import arcpy
from arcpy import env
import os

# Geting user input for project name, status, type, submital date and planner name  
varXCoord = arcpy.GetParameter(0)
varYCoord = arcpy.GetParameter(1)
varClassification = arcpy.GetParameterAsText(2)

fc = 'xxDBO.xxx'
workspace = arcpy.env.workspace = r'C:\Users\xx\AppData\Roaming\ESRI\Desktop10.5\ArcCatalog\xxx@xxx.sde'

# http://desktop.arcgis.com/en/arcmap/10.3/analyze/arcpy-classes/pointgeometry.htm

# A list of coordinate pairs
pointList = [[varXCoord,varYCoord ]]

# Create an empty Point object
point = arcpy.Point()

# A list to hold the PointGeometry objects
pointGeometryList = []

for pt in pointList:
    point.X = pt[0]
    point.Y = pt[1]

    pointGeometry = arcpy.PointGeometry(point)
    pointGeometryList.append(pointGeometry)


#?????????
varXYCoord = point  

sr = arcpy.Describe(fc).spatialReference
arcpy.env.outputCoordinateSystem = sr


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

## Edit session is started without an undo/redo stack for versioned data
##  (for second argument, use False for unversioned data)
edit.startEditing(False, False)

## Start an edit operation
edit.startOperation()

row_values = [( varXYCoord , varClassification)]
print(row_values)

cursor = arcpy.da.InsertCursor(fc,['SHAPE@XY', 'Classification'])
for row in row_values:   
    cursor.insertRow(row) 

del cursor‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
jaykapalczynski
Honored Contributor

OK so it seems the only way I can run publish the python script to a service is if I give it an XY value.  BUT then because I give it the value it makes this the default value....

1. If I run from the Submit from the service it runs fine

2. If I run and call the GP Service from AppStudio it puts the new point at the same XY as the default no matter what.

I seemingly cant overwrite the XY value that is defaulted in the service.

0 Kudos
MicahBabinski
Frequent Contributor

What do you have set as the Input modes and parameter data types for your task parameters?

0 Kudos
ErwinSoekianto
Esri Alum

On the QML side of things (client application), I think the might be in the conversion from the loosely-typed javascript variable to ArcGIS Runtime SDK for Qt GeoProcessingString object.

Please refer to this guide on the GeoProcessing task parameter doc, Run a geoprocessing task—ArcGIS Runtime SDK for Qt | ArcGIS for Developers and the GeoProcessingParamater API reference, GeoprocessingParameter QML Type | ArcGIS for Developers, to decide which one to use for your GP service input.