Select to view content in your preferred language

Field not get calculated in geoprocessing service

2219
15
Jump to solution
10-01-2013 08:57 AM
ionarawilson1
Deactivated User
This script works great in ArcMap, updating the field EditField. However when I create a geoprocessing service from the result and run it, the field does not get update, although I get no error messages when running it. Does anybody would have any idea why the field would not get updated with the geoprocessing service? Thank you

# -*- coding: utf-8 -*- # --------------------------------------------------------------------------- # calcfeatures_script.py # Created on: 2013-09-30 15:22:46.00000 #   (generated by ArcGIS/ModelBuilder) # Usage: calcfeatures_script <Selecting_Features> <value>  # Description:  # test # ---------------------------------------------------------------------------  # Import arcpy module import os, sys, arcpy, traceback, arcgisscripting  # Script arguments Selecting_Features = arcpy.GetParameterAsText(0) value = arcpy.GetParameterAsText(1) Stewardship = arcpy.GetParameterAsText(2) arcpy.AddMessage("TEST") arcpy.AddMessage(value)   # Local variables: Input_Points = Stewardship #Final_Output = value  Input_Points_Layer = "SamplePoints_Layer"  # Process: Make Feature Layer arcpy.MakeFeatureLayer_management(Input_Points, Input_Points_Layer) # Process: Select Layer By Location arcpy.SelectLayerByLocation_management(Input_Points_Layer, "INTERSECT", Selecting_Features, "", "NEW_SELECTION")  # Process: Calculate Field    with arcpy.da.UpdateCursor(Input_Points_Layer, ("City")) as rows:         # row comes back as a tuple in the order specified here, so Office is row[0], Forester is row[1]         for row in rows:             row[0] = value                         rows.updateRow(row)
Tags (2)
0 Kudos
15 Replies
ionarawilson1
Deactivated User
Ah, I see it! It totally makes sense now that you explained. Also about arcgis server being able to see it, If I am editing a feature service, I need to create a local copy. I don't have a choice of where I can save it. It gets saved to a folder in the user directory. Is there a way for arcgis server to see that? It is because my final objective is to have a web app to edit features in a feature service. But the web app will run a geoprocessing service. However to test the gp, I cannot run the data with the feature service without first having a local copy. However the data that was copied to the local folder cannot be copied to the server (this is the message I get when I try to publish it) so I am not sure how to publish a geoprocessing service that will be editing a feature service.  Is there any way this can be done?  How do people run geoprocessing services in web apps when trying to edit a feature in a sde geodatabase? I can't find any information about it.

Let me start a new thread with this question so you can get more points for it. Thanks

Thank you so much for your help. Your knowledge has helped me tremendously. I have been trying to figure out this for days and there is not really a training course I could take to learn all this.
0 Kudos
T__WayneWhitley
Honored Contributor
Let me be honest, I am learning this with you... so it is as hit or miss, read, change something, and test again for me as it is for you.  I try to follow along here on the forums to make sure I am more and more engaged.  Certainly I contribute here or there where my reach has exceeded my knowledge, or else I have become rusty and forgetful -- either way, let's just say I'm stretching to make more room for increased knowledge, and to help each other attain it.

You've got me stumped at the moment, just read so far that you can set up your gp service to read layers I am assuming are from a published map, to then pass to the server script task, but as I understand it not quite the same as a feature editing service, but I'll have to read up more.  I'll be watching out and following some of your new threads....maybe you can entice Kevin to contribute with a rich answer!  I will tune in for that.

Enjoy,
Wayne
0 Kudos
ionarawilson1
Deactivated User
Thank you Wayne. I have started writing the web app in javascript and I am using a edit widget that can be used to enter new features in the feature service. Everything works great, I can already create features and they get automatically created in the sql database. Since the data in the feature service comes from the same sde I have been using, I am guessing I can run a geoprocessing service on the same dataset (instead of trying to run in a feature service), just like I did on my previous posts, and then call this geoprocessing service from the web app after I create the feature. I think it might work. I am going to try that and will keep you posted. Thank you so much for your help again!
0 Kudos
KevinHibma
Esri Regular Contributor

OR MAYBE THIS, IF YOU LIKE IT BETTER:
(either way, pathnames are assembled out of text passed in)

>>> import os
>>> os.path.join(workspace, GetPolyFC)

'\\\\myServer\\myGDB.sde\\my user-defined value'
>>> 


100% use os.path.join.
Please dont "add (+)" paths together. Scripts and publishing of those scripts aren't guaranteed to work as we might not be able to find data. Using the OS methods as you describe is the way to go.

And you're doing great with the explanation.
I tried to help over here: http://gis.stackexchange.com/questions/72719/field-does-not-get-updated-with-geoprocessing-service/7... but I'm still not 100% sure the goal of this project. Wayne has done a good job explaining the different input methods with GP Server, but I'm still confused if ionara_wilson is wanting to provide features to the GP Service, or if the data is already on the Server.
The Service Editor may modify the input parameter's input mode when publishing based on what we think you want when you have an unsupported input type. Simply pressing the "publish" button without checking and ensuring the input type is correct might be whats going wrong here.

To sum up how it works one more time, because I'm not sure what the desired goal is besides "calculating a value".

--feature class as input is not supported with GP Server. If your model/script is taking a featureclass as input, we change that to FeatureSet in the Service Editor. Your only other option would be to hardcode it by setting it to "constant".
--FeatureSet is a supported input type. If you've set to featureset, we leave it as featureset. FeatureSet allows you to digitize features and send them. If you're using REST, you can send a GPFeatureRecordSet, which is basically just the JSON representation of the features you want the service to use.
--Using a layer as an input the the tool, it gets mapped to Choice List in the Service Editor. A choice list means that and any other layers which are checked off will be available for use in the service. Your "select" them by name when consumed via REST. Looking at that parameter in the REST end point, you'll see that choice list of layers and the name you'd choose.

Based on the last script you've posted, it seems you want to update a featureclass.

At the risk of confusing everything, I've modified the script to make use of LAYERS which get name matched from the tool. (thats how they're found). I suggest this as its a performance gain and the better way to work against data (vs. continually going back and re-opening it at the source: sde). If this doesn't make sense then go the way you are, just change this:
"Database Connections\\Connection to tfsgis-iisd01IWILSON.sde\\%s" %Input_Points
to this:
os.path.join("Database Connections\\Connection to tfsgis-iisd01IWILSON.sde", Input_Points)



import os, sys, arcpy, traceback, arcgisscripting
# DELETED WORKSPACE AND REFERENCE TO SDE FILES

# Script arguments
Selecting_Features = arcpy.GetParameterAsText(0)
value = arcpy.GetParameterAsText(1)
stewardship =  arcpy.GetParameterAsText(2)

# DELETED MAKE FEATURE LAYER....

#Drag the layer from SDE you want into ArcMap. Its this layer:
#Connection to tfsgis-iisd01IWILSON.sde\sars.dbo.CITYTEST
#Name that layer in the TOC "CITYTEST"
#You'll have a variable in the script which references that layer, here:

myLayerToModify = "CITYTEST"
#When you run this script, in ArcMap, it will look for a layer called CITYTEST when you use the myLayerToModify variable. A name matching occurs.

#This variable "myLayerToModify" will be used in the script. You don't need MakeFeatureLayer.

# Process: Select Layer By Location
arcpy.SelectLayerByLocation_management(myLayerToModify, "INTERSECT", Selecting_Features, "", "NEW_SELECTION")


# Process: Calculate Field
#arcpy.CalculateField_management(myLayerToModify, "City, '"' + value + '"', "PYTHON_9.3")

with arcpy.da.UpdateCursor(myLayerToModify, ("City")) as rows:
        # row comes back as a tuple in the order specified here, so Office is row[0], Forester is row[1]
        for row in rows:
            row[0] = value
           
            rows.updateRow(row)


Either approach you take, I don't see any reason why you can't reference the same sde layers here in the GP Service which would also be the same layers the feature service runs off of.
Fast forward to about 28minutes into this video: http://video.esri.com/watch/1658/creating-geoprocessing-services
Scott explain's parameter transformation and datastore, then I do a demo which uses SDE data that is consumed both from a FeatureService and a GP Service.  (edits made the to FS impact the result of the GP Service)
0 Kudos
ionarawilson1
Deactivated User
Thank you for the thorough explanation Kevin. The issue I have is that I need to create a web app where users will create a feature and then some values will be calculated, for example an id number that will be called PlanID that will be created from the combination of fiscal year, county where feature is located and a unique number - if there are no other features in that county, the unique number will be 1, so the id number would be for example 2013-230-001. If there is another feature in that county in that year, the id would be 2013-230-002. So I was thinking I could use a feature service for the user to digitize the features in the web app (I already have a web app in javascript with a editor and I can already create features and populate the date field for example). Then I thought I could use a geoprocessing service to calculate the PlanID, based on the year entered and the county where the feature is located, plus that unique value. I already have a python script for the calculation of the PlanID in ArcMap, but I need to change the script to create the geoprocessing service that will be running in the web app after the feature is digitized. Would this be the best approach - creating a feature service to create features in a web app and then run a geoprocessing service to calculate values based on the features created?

So if this works, perhaps I don't even need to select the features in the python script, as they already will be selected when the user is digitizing (editing) the feature in the web app using the editor widget. Would this work?
So far, I have the code that it is updating the year field from the date the user will enter (please see below). I need to have the code where it intersects with the county to get the county number and also define the unique number that goes after the county number.


import os, sys, arcpy, traceback, arcgisscripting
arcpy.env.workspace = "Database Connections\\sars.sde\\"

Input_Points = "Stewardship"


Input_Polygons = "Polygon_Layer"

# Process: Make Feature Layer
arcpy.MakeFeatureLayer_management(Input_Polygons, Input_Polygon_Layer)



with arcpy.da.UpdateCursor(Input_Polygon_Layer, ("DateStart", "FFY")) as rows:


       
    for row in rows:


       Datestarstr1 = row[0]

       Datestarstr2 = str(Datestarstr1)
       
      
       yearonly = Datestarstr2[0:4]

                 
       row[1] = yearonly


       rows.updateRow(row)   



So, as you are saying, I should be able to just use a layer (Stewardship). In my case, would the web app be able to identify that layer as the feature class? Please see code below. Thank you!!!


import os, sys, arcpy, traceback, arcgisscripting


Input_Polygons = "Stewardship"


with arcpy.da.UpdateCursor(Input_Polygons, ("DateStart", "FFY")) as rows:


       
    for row in rows:


       Datestarstr1 = row[0]

       Datestarstr2 = str(Datestarstr1)
       
      
       yearonly = Datestarstr2[0:4]

                 
       row[1] = yearonly


       rows.updateRow(row)   

0 Kudos
ionarawilson1
Deactivated User
Ok, I found what the problem was. A parameter cannot have a feature class as an input (go figure!), so if you use arcpy.GetParameterAsText() and then have that parameter as a featureset (which I needed for my gp) it won't work. What I did was to create a variable for that parameter and when I run it inside ArcMap I grab the layer for that feature class (in my case the layer is referencing a feature class in a sde geodatabase). Then I publish the gp, then when I run the geoprocessing service I can grab the file directly from the connection instead of the layer. I hope it will help somebody because it took me a while to figure this out.

 Input_Polygons = "Stewardship"    with arcpy.da.UpdateCursor(Input_Polygons, ("DateStart", "PlanID", "FFY")) as rows:      for row in rows:          if not (row[1] or "").strip(): #covers blank, one blank space, or Null             Datestarstr1 = row[0]             Datestarstr2 = str(Datestarstr1)                      yearonly = Datestarstr2[0:4]                               row[2] = yearonly              rows.updateRow(row)    
0 Kudos