Move point locations

1650
8
Jump to solution
11-10-2016 11:20 AM
jaykapalczynski
Frequent Contributor

I have a FC with locations of facilities.

I have another FC with improper locations BUT can link the two FC by SiteName field.

Can I move the improper located facilities to the proper locations via a similar field.  Join and then move to proper position?

0 Kudos
1 Solution

Accepted Solutions
DarrenWiens2
MVP Honored Contributor

You can read more fields in the update cursor by adding them to the field list. The first field is read as row[0], next as row[1], and so on.

with arcpy.da.UpdateCursor(fc2, ["SHAPE@XY","JoinedFC.XField","JoinedFC.YField"]) as cursor:
    for row in cursor:
        row[0] = ([row[1],row[2]])
        cursor.updateRow(row)‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

8 Replies
DanPatterson_Retired
MVP Esteemed Contributor

An attribute join should work...did you not try it?

DarrenWiens2
MVP Honored Contributor

You can't actually move geometry with a join, but you can transfer attributes between the two, calculate XY coordinates, and then create a new FC based on those coordinates.

Make XY Event Layer—Help | ArcGIS for Desktop 

Or, join, then run an arcpy.da.UpdateCursor to update the geometry.

jaykapalczynski
Frequent Contributor

My problem is that this FC is being exported from ArcGIS Online.  It has an attachment Table and Relationship Class.  If I start creating Event Layers etc I will be blowing up the connection to my attachments and Relationship class.

I should be able to Create and XY field and populate with the correct XY.  Is there a "Move To" or something?  Where I can move the geometry without creating a new Event layer?

0 Kudos
jaykapalczynski
Frequent Contributor

Maybe something like this?  But not an offset but the actual XY that are calculated via the join?  how would I substitute the X and Y instead of the Offsets.

import arcpy
# Set some variables
fc = r"C:\temp\test.gdb\testFC"
fc2 = r"C:\temp\test.gdb\testFCcopy"
xOffset = 0.001
yOffset = 0.001
# Code to make a copy which will have its coordinates moved (and can be compared with original)
if arcpy.Exists(fc2):
    arcpy.Delete_management(fc2)
arcpy.Copy_management(fc,fc2)
# Perform the move
with arcpy.da.UpdateCursor(fc2, ["SHAPE@XY"]) as cursor:
    for row in cursor:
        cursor.updateRow([[row[0][0] + xOffset,row[0][1] + yOffset]])
0 Kudos
DarrenWiens2
MVP Honored Contributor

You can read more fields in the update cursor by adding them to the field list. The first field is read as row[0], next as row[1], and so on.

with arcpy.da.UpdateCursor(fc2, ["SHAPE@XY","JoinedFC.XField","JoinedFC.YField"]) as cursor:
    for row in cursor:
        row[0] = ([row[1],row[2]])
        cursor.updateRow(row)‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

jaykapalczynski
Frequent Contributor

OK I am looking at this but has a couple more questions.

I created a Lat Long field with JoinField_management so it copied them down permanently.  So they now exist in the FC

  • I specified a workspace
  • I have the name of the FC (BR_NoAttachments
  • I specified Long and Lat via the UpdateCursor
  • Now just unsure about the row[0] = ([row[1],row[2]])
    • Is this refering the the index number being specified in the UpdateCursor?
    • with arcpy.da.UpdateCursor(fc2, ["SHAPE@XY","Long","Lat"]) as cursor:
      • Where SHAPE@XY is [0] index and "Long" is [1] index etc.

arcpy.env.workspace = "C:\\Users\\x\\AppData\\Roaming\ESRI\\Desktop10.4\\ArcCatalog\\x@x.sde"

## Set some variables
fc2 = "BR_NoAttachments"

with arcpy.da.UpdateCursor(fc2, ["SHAPE@XY","Long","Lat"]) as cursor:
    for row in cursor:
        row[0] = ([row[1],row[2]])
        cursor.updateRow(row)‍‍‍‍‍‍‍‍‍
0 Kudos
DarrenWiens2
MVP Honored Contributor

Yes, that's all correct. Are you running into issues? I could imagine a problem by naming a field "Long" just because that may be a reserved word in some cases (I usually use "Lng" to avoid problems), but not necessarily an error in this situation.

jaykapalczynski
Frequent Contributor

works great....I have to code in an edit session for things to work....

This script deletes two fields, recreates with Join (permanent and only brings in X and Y) then moves the points to the new XY coordinates.

  1. I set my workspace
  2. Set join variables
  3. Delete two fields
  4. Permanent join and add X and Y fields
  5. Start Edit session
  6. Use Update Cursor to move the points to the new X and Y coordinates
  7. Stop and save edit session.

import arcpy
import os

# Set environment settings
arcpy.env.workspace = "C:\\Users\\xx\\AppData\\Roaming\ESRI\\Desktop10.4\\ArcCatalog\\xx@xx.sde"

# ==================================================================================================================================
# JOIN
# ==================================================================================================================================
# WEBSITE JOIN: http://pro.arcgis.com/en/pro-app/tool-reference/data-management/add-join.htm
print "Started Join"
arcpy.AddMessage("Started Join")

# JOIN
# Set the local parameters
inFeatures = "BR_Boat_Ramp_Inspection_2"
joinField = "ramp_1"
joinTable = "BoatRampsWGS_1"
joinField2 = "SITENAME"
fieldList = ["Lat", "Long"]

arcpy.DeleteField_management(inFeatures, ["Lat", "Long"])

# Join two feature classes by the zonecode field and only carry
# Perminant Join bring only the Lat Long over
arcpy.JoinField_management (inFeatures, joinField, joinTable, joinField2, fieldList)

fc = "C:\\Users\\xx\\AppData\\Roaming\ESRI\\Desktop10.4\\ArcCatalog\\xx@xx.sde\\BR_Boat_Ramp_Inspection_2"
workspace = os.path.dirname(fc)

# 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()

## Set Update Cursor to move points.
with arcpy.da.UpdateCursor(inFeatures, ["SHAPE@XY","Long","Lat"]) as cursor:
    for row in cursor:
        row[0] = ([row[1],row[2]])
        cursor.updateRow(row)

# Stop the edit operation.
edit.stopOperation()

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