I have the following code that is in a tool.
The tool creates a point on click, then auto sequential populates the "AddressID" field and also populates X_Coord, , Y_Coord. This part of the tool works smoothly.
After these fileds are populated i need the new created feature to populate other fields based on Parcel the newly created point sits on. I do a spatial join in order to get the fields populated.
The two functions work perfectly if they are separate but once i combine the two and run the tool ArcMap just sits thinking and thinking nothing happens. I eventually have to end ArcMap process with task manager. I don't get no error at all. After i reopen the mxd i see the newly created point but nothing is populated from the Parcels.
Here are the two codes.
import arcpy
import pythonaddins
import os
from arcpy import env
class Add_points(object):
"""Implementation for AddPoints_addin.Add_points (Tool)"""
def __init__(self):
self.enabled = True
self.cursor = 3 # Can set to "Line", "Circle" or "Rectangle" for interactive shape drawing and to activate the onLine/Polygon/Circle event sinks.
def onMouseDownMap(self, x, y, button, shift):
fc = "TonyTwoWay.DBO.TT"
workspace = r"C:\Users\talmeida\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog\Connection to dsd15_sqlexpress.sde"
arcpy.env.overwriteOutput = True
#arcpy.ChangeVersion_management('TonyTwoWay.DBO.TT','TRANSACTIONAL','dbo.DEFAULT', "")
# Start an edit session. Must provide the worksapce.
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(True)
# Start an edit operation
edit.startOperation()
CC_list = []
with arcpy.da.SearchCursor(fc, ["AddressID"]) as cursor:
for row in cursor:
try:
if "CC" in row[0]:
CC_list.append(int(row[0].strip("CC")))
except TypeError:
pass
del cursor
CC_list.sort()
AddressID = CC_list[-1] + 1
AddressID = 'CC' + str(AddressID)
row_values = [(x, y, (x, y), AddressID)]
cursor = arcpy.da.InsertCursor(fc, ["X_Coord", "Y_Coord", "SHAPE@XY", "ADDRESSID"])
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)
arcpy.RefreshActiveView()
arcpy.AddMessage('Updated all records sucussefully')
pass
Here the spatial join part.
import arcpy
import pythonaddins
import os
import time
from arcpy import env
fcTarget = "TonyTwoWay.DBO.TT"
workspace = r"C:\Users\talmeida\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog\Connection to dsd15_sqlexpress.sde"
arcpy.env.overwriteOutput = True
####Select by location on parcels with created point
Parcellyr = "testParcelsAdmit"
fcTarget = "TonyTwoWay.DBO.TT"
arcpy.MakeFeatureLayer_management(Parcellyr, "Parcel layer")
entries = int(arcpy.GetCount_management(fcTarget).getOutput(0))
for i in xrange(entries):
arcpy.MakeFeatureLayer_management(fcTarget, "point layer", "\"OBJECTID \"={}".format(str(i)))
arcpy.SelectLayerByLocation_management("Parcel layer", "INTERSECT", fcTarget, "", "NEW_SELECTION")
#if arcpy.Exists(pt_lyr): arcpy.Delete_management(pt_lyr)
#### populates fields
#fcTarget = "TonyTwoWay.DBO.TT"
#fcJoin = "testParcelsAdmit"
add_fields = ["ACCOUNT","SiteNum","OwnerName","SiteAddres","SiteNumSfx","SiteStreet","predir","StreetTyp e","SubName"]
# fix args
if not isinstance(add_fields, list):
# from script tool
add_fields = add_fields.split(';')
# do not need this scratch file
fcOutput = r'in_memory\temp_join'
arcpy.SpatialJoin_analysis("Parcel layer", fcTarget, fcOutput, 'JOIN_ONE_TO_MANY', 'KEEP_COMMON')
# grab oid field from points
oid_t = arcpy.Describe(fcTarget).OIDFieldName
# init rowW and rowR
curR = arcpy.SearchCursor(fcOutput)
join_dict = dict([(r.JOIN_FID,[r.getValue(f) for f in add_fields]) for r in curR])
del curR
# Now update the new target
curW = arcpy.UpdateCursor(fcTarget)
for row in curW:
t_oid = row.getValue(oid_t)
if t_oid in join_dict:
for f in add_fields:
row.setValue(f, join_dict[t_oid][add_fields.index(f)])
curW.updateRow(row)
del row, curW
arcpy.Delete_management(r"in_memory\temp_join")
arcpy.AddMessage('Updated all records sucussefully')
I use this part of the code to select the new created feature. am i going the wrong way about it?
Parcellyr = "testParcelsAdmit"
arcpy.MakeFeatureLayer_management(Parcellyr, "Parcel layer")
entries = int(arcpy.GetCount_management(fcTarget).getOutput(0))
for i in xrange(entries):
arcpy.MakeFeatureLayer_management(fcTarget, "point layer", "\"OBJECTID\"={}".format(str(i)))
arcpy.SelectLayerByLocation_management("Parcel layer", "INTERSECT", fcTarget, "", "NEW_SELECTION")
-
1When you "combined" the two functions, did you change the logic so that only the one point you just created is selected for the spatial join? Otherwise it makes no sense to do a full spatial join on both full layers every time you want to interactively add a new point. Include the actual combined code as this is what you are asking about, yes?blah238– blah2382014年03月05日 22:27:38 +00:00Commented Mar 5, 2014 at 22:27
-
Also I hope you never delete address points because if you do, you'll eventually reuse an ID, which is not a good thing. You should be using a sequence stored in the DB to pull an unused ID from.blah238– blah2382014年03月05日 22:40:01 +00:00Commented Mar 5, 2014 at 22:40
-
I use this part of the code to select the new created feature. am i going the wrong way about it? Parcellyr = "testParcelsAdmit" arcpy.MakeFeatureLayer_management(Parcellyr, "Parcel layer") entries = int(arcpy.GetCount_management(fcTarget).getOutput(0)) for i in xrange(entries): arcpy.MakeFeatureLayer_management(fcTarget, "point layer", "\"OBJECTID\"={}".format(str(i))) arcpy.SelectLayerByLocation_management("Parcel layer", "INTERSECT", fcTarget, "", "NEW_SELECTION")user27706– user277062014年03月06日 14:53:18 +00:00Commented Mar 6, 2014 at 14:53
1 Answer 1
If I understand the problem correctly, you are:
- Getting an X and Y coordinate where the user has clicked in the map locating where a new point should be added.
- Getting an ID by sorting all existing IDs and adding 1 to the highest ID
- Looking to add some additional attributes to this point by spatially joining it to another layer (parcels)
- Inserting the point into the points layer
Steps 1 and 2 are working fine for you (although I have some reservations about your method of getting the next ID based on the highest existing ID -- this likely to cause reused or duplicated IDs in some editing scenarios).
You appear to be having some trouble getting the spatial join logic right.
Once you have your X, Y and ID, here's what I suggest you do:
Create an in-memory point feature class and insert the point at X and Y and include the ID attribute.
Run Spatial Join with the in-memory points feature class against the parcels feature class and output the result to the in-memory workspace (creating another in-memory points feature class).
Insert the result from above into your original points feature class (either using Append or an insert cursor).
-
Thank you for the reply, i am a newbe to python so i am uncertain on how to accomplish your suggestions.user27706– user277062014年03月06日 19:42:19 +00:00Commented Mar 6, 2014 at 19:42
-
If anyone can help me put this together i would very regretfully appreciative.user27706– user277062014年03月06日 22:53:51 +00:00Commented Mar 6, 2014 at 22:53