Select newly created feature

1450
13
Jump to solution
03-14-2014 07:04 AM
TonyAlmeida
MVP Regular Contributor
I have a script that creates a point with a mouse click (onMouseDownMap). The feature class is in a SDE geodatabase which has about 80,000 features in it. An edit session and an edit operation is needed, creating the point work just fine but i need some code after stopping the edit session to select the point that was just created to be able to pass to another function. The problem with starting the an edit session and an edit operation is that it clears the selection.

Any help would be awesome!
Thanks.
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JamesCrandall
MVP Alum
jamesfreddyc that sounds intresting, but how would pass the click (input) to do the selection by location on the parcels?
thanks for the replay.


See this thread for some examples: http://gis.stackexchange.com/questions/49713/select-and-copy-features-in-arcmap-using-python-add-in-...

Important part is:

  def onMouseDownMap(self, x, y, button, shift):     mxd = arcpy.mapping.MapDocument("CURRENT")     pointGeom = arcpy.PointGeometry(arcpy.Point(x, y), mxd.activeDataFrame.spatialReference)     searchdistance = getSearchDistanceInches(mxd.activeDataFrame.scale)     lyr = arcpy.mapping.ListLayers(mxd)[0] # assumes you want to select features from 1st layer in TOC     arcpy.SelectLayerByLocation_management(lyr, "INTERSECT", pointGeom, "%d INCHES" % searchdistance)     arcpy.RefreshActiveView() 


Make sure "lyr" is referencing your Parcel layer, then after the refresh you should be able get access to the attributes with a SearchCursor.  Use the values in the cursor to populate your point feature with.

(note: I have not implemented the code above, so you would have validate it works.)

View solution in original post

0 Kudos
13 Replies
Zeke
by
Honored Contributor
The new feature should have the highest ObjectID, but I wouldn't necessarily rely on that. After creating it, before any edit session, while the new feature is still selected, put the ObjectID in a variable. Then when you go to edit, select that ObjectID.
0 Kudos
RobertBorchert
Honored Contributor
any reason why you don't just create the point from a template.  then it would be automatically selected when you place it?

I have a script that creates a point with a mouse click (onMouseDownMap). The feature class is in a SDE geodatabase which has about 80,000 features in it. An edit session and an edit operation is needed, creating the point work just fine but i need some code after stopping the edit session to select the point that was just created to be able to pass to another function. The problem with starting the an edit session and an edit operation is that it clears the selection.

Any help would be awesome!
Thanks.
0 Kudos
TonyAlmeida
MVP Regular Contributor
I have tried to put the new feature Object id in a variable (I think i am doing it right) but I am uncertain because the script takes a long time like it's selecting every point feature.

my script creates the point, populates certain fields, then it's suppose to take that new point and runt a spatial join against the parcels feature class and output the result to the in-memory workspace, then Insert the result from above into your original points feature class.

Here is what i have.

import arcpy
import pythonaddins
arcpy.env.overwriteOutput = True

fcTarget = "TT"
workspace = r"Connection to sqlexpress.sde"

#arcpy.ChangeVersion_management('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()

input = arcpy.GetParameterAsText(0)
CC_list = []
with arcpy.da.SearchCursor(fcTarget, ["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)

rows = arcpy.SearchCursor(input)
for row in rows:
    geom = row.shape
    x = geom.lastPoint.X
    y = geom.lastPoint.Y 
del row, rows
    
row_values = [(x, y, (x, y), AddressID)]
cursor = arcpy.da.InsertCursor(fcTarget, ["X_Coord", "Y_Coord", "SHAPE@XY", "ADDRESSID"])

for row in row_values:
    cursor.insertRow(row)
#del cursor

Parcellyr = "testParcelsAdmit"

#maxValue = arcpy.SearchCursor(fcTarget, "", "", "", 'AddressID D').next().getValue("AddressID") #Get 1st row in descending cursor sort
#arcpy.SelectLayerByAttribute_management(fcTarget, "NEW_SELECTION", "\"AddressID\"= " + maxValue)

Par_lyr = 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(Par_lyr, "INTERSECT", fcTarget, "", "NEW_SELECTION")
    #if arcpy.Exists(pt_lyr): arcpy.Delete_management(pt_lyr)

#### populates fields

add_fields = ["ACCOUNT","SiteNum","OwnerName","SiteAddres","SiteNumSfx","SiteStreet","predir","StreetType","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(Par_lyr, 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, query)
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')
arcpy.RefreshActiveView()


# Stop the edit operation.
edit.stopOperation()

# Stop the edit session and save the changes
edit.stopEditing(True)
                            
0 Kudos
TonyAlmeida
MVP Regular Contributor
Anyone have an example of code that they can share on how to select the newest feature created to pass onto another function?
0 Kudos
JoshuaChisholm
Frequent Contributor
Hello Tony,

I'm not sure if this is what you're looking for, but this should get you the most recent*** AddressID. If you need more fields, make sure you add them after "OID@" so that it will still be reverse sorted on ObjectID.

for row in sorted(arcpy.da.SearchCursor(fcTarget, ["OID@", "AddressID"]),reverse=True):
    mostRecentOID=row[0]
    mostRecentAddressID=row[1]
    break

#Do stuff with mostRecentOID and mostRecentAddressID


From this point you can use proceed with your script. You can (if you need to) perform a select by attribute using mostRecentOID.

***: As Greg said, we are (dangerously) assuming the record with the highest Object ID (OID) is the most recent.
0 Kudos
TonyAlmeida
MVP Regular Contributor
hua17 thank you for the help and reply.

I have add the the code you posted to my code.

It seems to kind of work, the issue is that now the OBJECTID field is not being populated and second the first point gets created but the OBJECTID and "add_fields" don't get populated, until I use the tool again to create a second point, then all the fields that i need populated get populated except for OBJECTID field.


Here is my current code.

import arcpy
import pythonaddins
arcpy.env.overwriteOutput = True

fcTarget = "Points_1"
workspace = r"C:\Temp\default.gdb"

DS3 = "oool"

if arcpy.Exists(DS3):
    arcpy.Delete_management(DS3)

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

input = arcpy.GetParameterAsText(0)
CC_list = []
with arcpy.da.SearchCursor(fcTarget, ["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)

rows = arcpy.SearchCursor(input)
for row in rows:
    geom = row.shape
    x = geom.lastPoint.X
    y = geom.lastPoint.Y 
del row, rows
    
row_values = [(x, y, (x, y), AddressID)]
cursor = arcpy.da.InsertCursor(fcTarget, ["X_Coord", "Y_Coord", "SHAPE@XY", "ADDRESSID"])

for row in row_values:
    cursor.insertRow(row)
#del cursor

Parcellyr = "testParcelsAdmit"

for row in sorted(arcpy.da.SearchCursor(fcTarget, ["OID@", "AddressID"]),reverse=True):
    mostRecentOID=row[0]
    mostRecentAddressID=row[1]
    break
#Do stuff with mostRecentOID and mostRecentAddressID

arcpy.MakeFeatureLayer_management(Parcellyr, "Parcel layer")
if int(arcpy.GetCount_management(fcTarget).getOutput(0)) > 0:
    arcpy.SelectLayerByLocation_management(fcTarget, "INTERSECT", "Parcel layer", "", "NEW_SELECTION")

#### populates fields

add_fields = ["ACCOUNT","SiteNum","OwnerName","SiteAddres","SiteNumSfx","SiteStreet","predir","StreetType","SubName"]

# fix args
if not isinstance(add_fields, list):
    # from script tool
    add_fields = add_fields.split(';')

# do not need this scratch file
fcOutput = 'oool'
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')
arcpy.RefreshActiveView()


# Stop the edit operation.
edit.stopOperation()

# Stop the edit session and save the changes
edit.stopEditing(True)
0 Kudos
JoshuaChisholm
Frequent Contributor
Hello Tony,

Could explain exactly what you are trying to achieve in this script? I'm finding it a little hard to follow.

Thank you!
0 Kudos
TonyAlmeida
MVP Regular Contributor
The script(add-in tool) is suppose to create a point (for addresses)with the mouse click but i need some fields populated (X_Coord, Y_Coord, ADDRESSID) automatically after the click. The field "AddressID" is suppose to be populated by taking the highest number in that filed and adding 1 to it like auto sequential number, but only one's with CC in front of it. I also need it to populate fields from the parcel the new created point sits on. Hopefully it makes sense.
0 Kudos
JoshuaChisholm
Frequent Contributor
Hello Tony,

There are a lot of complexities to your script and I'm not exactly sure what the problem is. It is very difficult to replicate the issues you are having because there are so many processes/dependencies.

Did your script stop working and we are trying to find out why?
Is this a new tool that you are trying to get working?
Is the tool already working and are you trying to select the point that you just created in your script?
0 Kudos