1

enter image description hereI have been tasked with creating a model on ArcGIS Pro that allows you to create a point feature and input XY coordinates (British National Grid) from ModelBuilder.

Please note I don't want to use a .csv file or an external table, but just type in the coordinates in the tool.

What I have done on ModelBuilder:

  • Copy features (from a template point feature in projected BNG and geographic OSGB 1936). I am using a template with a single row of data.
  • Add fields (Northing and Easting, file type: double)
  • Calculate fields (here I add the coordinates for Northing and Easting, for example for Easting: 300000, and for Northing: 600000)
  • Add XY coordinates
  • Calculate fields (I add the value in Easting to Point X and Northing to Point Y).

The model completes the task "succesfully" but unfortunately the final output is not what it should be.

The attribute table of the output shows the fields exactly as I intended them to be (northing, easting, point_x, point_y) as well with the values I inputted, but the feature cannot be located (zoom to layer results in zooming out at very small scale and no point is visible).

If I try to add a new field and calculate point x (from the attribute table) I get - "skipping feature 0 because of NULL or EMPTY geometry".

The output is in the correct spatial reference as are the other working layers and the current map (projected BNG and geographic OSGB 1936).

I don't want to extract the coordinates from an existing table or add the xy coordinates from the attribute table, or create the point with coordinates from the tab "Edit" - I would like to do this in a ModelBuilder tool.


Following advice from stackexchange users I have added the tool "Calculate Value" to the model to update the point geometry, the code is as below:

Expression: getValue(site_location)

Code block:

import arcpy 
input = "site_location" 
fields = ["Easting", "Northing", "SHAPE@X", "SHAPE@Y"] 
cursor=arcpy.UpdateCursor(input, fields) 
for row in cursor: 
row.setValue(SHAPE@X, row.getValue(Easting)) 
row.setValue(SHAPE@Y, row.getValue(Northing)) 
cursor.updateRow(row)

Data type: XY Domain

Unfortunately this doesn't seem to work, resulting in an error: “NameError: name 'getValue' is not defined”

4
  • 2
    Edit your question and include an image of your model. Describing the workflow is not that helpful although hearing the (failed) outcome is.
    – Hornbydd
    Oct 25, 2021 at 15:48
  • @J.R is correct with his answer at no point do you actually update the shape field which holds the point geometry. Despite giving them names like Point_X or Northings they are nothing more than numeric fields to the Featureclass, its the shape field you need to insert a point object into. You can keep your workflow in modelbuilder by calling the update cursor using python in the model only tool calculate value.
    – Hornbydd
    Oct 26, 2021 at 9:16
  • Thanks Hornbydd I have looked at calculate value tool but I am not a pro with python. I have tried this code: Expression: getValue(site_location) Code block: import arcpy input = "site_location" fields = ["Easting", "Northing", "SHAPE@X", "SHAPE@Y"] cursor=arcpy.UpdateCursor(input, fields) for row in cursor: row.setValue(SHAPE@X, row.getValue(Easting)) row.setValue(SHAPE@Y, row.getValue(Northing)) cursor.updateRow(row) Data type: XY Domain I get “NameError: name 'getValue' is not defined” and I am not sure what the expression or the code block should be. Could you help?
    – chlha
    Nov 8, 2021 at 16:45
  • Add your code correctly formatted to your question, its impossible to read in a comment line...
    – Hornbydd
    Nov 8, 2021 at 20:51

3 Answers 3

2

Your steps are a bit unclear to me (why copying feature if you want to create a new one, the adding/calculating field are confusing, please edit your question to clarify) but it seem you never update or create the geometry field.

As the geometry field is the one that hold the point geometry you need a step where you update the geometry field with your coordinate, as it is the geometry field is left empty or not created explaining the error message :

"skipping feature 0 because of NULL or EMPTY geometry"

1
  • Hi J.R., I hope that the image of the model helps. I decided to copy from an existing feature (with only one row) because I couldn't add the coordinates (or I couldn't find a way) to a new empty point feature class. After the step "Add XY coordinates", the model copies the coordinates (from the newly created fields Easting and Northing) to the X and Y fields.
    – chlha
    Oct 26, 2021 at 8:58
1

Instead of using the Add XY Coordinates tool, instead try replacing it with the XY Table to Point tool in your model. Looking at the documentation for the Add XY tool, it only updates the table with a Point X and Point Y field, for points that already exist. It doesn't output any geometry. It seems like the template doesn't have points either.

Since you want to create the point as the model runs, you could have the X and Y field of the XY Table to Point parameters be your Easting and Northing fields, respectfully. It'll output the points for you. As a result, you can get rid of the final calculate field as well.

1
  • Hi Vince, thanks for your reply. how do I actually output the geometry (based on the X and Y fields)? I was hoping to do that with a tool
    – chlha
    Nov 8, 2021 at 15:49
0

Your inclusion of python code in the Calculate Value tool is the right way to go to keep it all in model builder. But your code is badly flawed, as you are mixing old style with new style cursors, which won't make sense and not constructing the correct syntax for a function. It is strongly recommended you use the new style cursors as they are faster and more flexible. I have rewritten your code with the new style, study it and understand where values are coming from.

Expression: SetShape("site_location")

Code block:

import arcpy
def SetShape(myLayer): # myLayer is set to "site_location" which must be a point layer in your map 
    fields = ["Easting", "Northing", "SHAPE@X", "SHAPE@Y"] 
    with arcpy.da.UpdateCursor(myLayer, fields) as cursor: 
        for row in cursor: 
            row[2] = row[0] #Set @x to easting
            row[3] = row[1] #Set @y to northing
            cursor.updateRow(row)
    return True

Data type: Boolean

The calculate value tool needs to run at the end of your model as the cursor in it is stepping over all rows to update the geometry.

7
  • thanks Hornbydd, it's making sense as I look at the code. unfortunately it still doesn't work as I get: "RuntimeError: A column was specified that does not exist." I would think that it refers to "shape@x" and "shape@y" but even changing the field names to POINT_X and POINT_Y in the code block didn't make a difference (and yes, I am running the tool at the end of the model).
    – chlha
    Nov 9, 2021 at 11:40
  • I spotted I had missed off an end colon from SetShape(myLayer) and was not returning a Boolean. I have amended my answer. Just tested the function above in a Calculate Value tool in model builder and it works for me... I would suggest you double check your spelling of fields?
    – Hornbydd
    Nov 9, 2021 at 13:15
  • I have tried copying and pasting your new code with no edits and (sorry for being a pain) now I am getting "File "<expression>", line 1, in <module> "NameError: name 'setshape' is not defined". The expression is currently setshape("site_location") as indicated by you. I have tried changing the names of the other variables in the model (so that site_location is the name of the output of Calculate fields (multiple) (2)) only, in case there was any conflict with similar names, but that didn't help.
    – chlha
    Nov 9, 2021 at 15:00
  • You say you have tried to copy and paste my code directly....? Well setshape is not the same as SetShape. Python is case sensitive.
    – Hornbydd
    Nov 9, 2021 at 15:06
  • @chlha also looking at your model image make sure the output of the final calculate fields tool is a precondition to the calculate value tool, this will ensure the correct order of operations.
    – Hornbydd
    Nov 9, 2021 at 15:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.