#ShieldToolAddin.py #By Kerry Alley 2013-03-12 #Vermont Agency of Transportation # #Python Add-In for ArcMap 10.1, 10.2 # #SELECT_ROAD (button) #When activated, will select features within 20 map-meters of the mouse click on the map. #The features are selected only from the top-most layer with the GDB_HMS.HMSADMIN.rdsmall_arc # data source, regardless of layer name. # #CREATE_SHIELD (button) #Requires that a single rdsmall_arc feature already be selected #User makes a single click on the map to indicate the location of the highway shield, and # makes a double-click where the leader line extending from the highway shield will end. #Both a point feature and a line feature are created, with relevant attributes transferred # from the selected rdsmall_arc feature. #There is an un-commentable option in this script that sets the length of the leader line to # a fixed length, for uniformity. # #NOTE: This addin works "normally" if there is not an active editing session in ArcMap, but if # there is an active editing session, the addin "crashes" at the call to stopEditing(). The # features will still be created, but the screen will not refresh if there is a pre-existing # editing session active. import arcpy, time, os, math import pythonaddins class SelectRoadClass(object): """Implementation for ShieldToolAddinA_addin.tool (Tool)""" def __init__(self): self.enabled = True self.shape = "NONE" def onMouseDownMap(self, x, y, button, shift): #start_time = time.time() #only used to compare run-times of different versions of the script arcpy.env.overwriteOutput = True rdsmall_dataSource = r"GDB_HMS.HMSADMIN.rdsmall_arc" mxd = arcpy.mapping.MapDocument('current') flag_rdsmall = 0 #flag_rdsmall is used to flag the first occurence of a layer having the desired dataSource in TOC for lyr in arcpy.mapping.ListLayers(mxd): if lyr.supports("dataSource"): if str(lyr.dataSource).endswith(rdsmall_dataSource) and not flag_rdsmall: rdsmall_lyr = lyr flag_rdsmall = 1 point = arcpy.Point() point.X = x point.Y = y pointGeometry = arcpy.PointGeometry(point) arcpy.SelectLayerByLocation_management(rdsmall_lyr, "WITHIN_A_DISTANCE", pointGeometry, "20 Meters", "NEW_SELECTION") #print time.time() - start_time, "seconds" class CreateShieldClass(object): """Implementation for ShieldToolAddinB_addin.tool (Tool)""" def __init__(self): self.enabled = True self.cursor = 3 self.shape = "LINE" def onLine(self, line_geometry): #start_time = time.time() #only used to compare rough run-times of different versions of the script arcpy.env.overwriteOutput = True #Hard-wiring the exact feature classes that will be edited with shield tool. shield_points_dataSource = r"GDB_HMS.HMSADMIN.hms_shields_points" shield_arcs_dataSource = r"GDB_HMS.HMSADMIN.hms_shields_arcs" rdsmall_dataSource = r"GDB_HMS.HMSADMIN.rdsmall_arc" mxd = arcpy.mapping.MapDocument('current') #for new shields to appear in current mxd, this script must refer to layers in the current mxd lyrs = arcpy.mapping.ListLayers(mxd) flag_points = 0 flag_arcs = 0 flag_rdsmall = 0 for lyr in arcpy.mapping.ListLayers(mxd): if lyr.supports("dataSource"): if str(lyr.dataSource).endswith(shield_points_dataSource) and flag_points == 0: shield_points_lyr = lyr flag_points = 1 if str(lyr.dataSource).endswith(shield_arcs_dataSource) and flag_arcs == 0: shield_arcs_lyr = lyr flag_arcs = 1 if str(lyr.dataSource).endswith(rdsmall_dataSource) and flag_rdsmall == 0: rdsmall_lyr = lyr flag_rdsmall = 1 if not (shield_points_lyr and shield_arcs_lyr and rdsmall_lyr): print "Must have 3 layers in this mxd: shield points, shield arcs, and rdsmall" #only allow shield creation if a single road arc is selected num_road_arcs = int(arcpy.GetCount_management(rdsmall_lyr).getOutput(0)) print "%s rdsmall arc(s) selected" %num_road_arcs if num_road_arcs == 1: workspace = rdsmall_lyr.workspacePath #(refers to .sde file in DatabaseConnections) arcpy.env.workspace = workspace edit = arcpy.da.Editor(workspace) edit.startEditing(True, True) #with undo, multiuser mode #identify maximum SHI_GRP_ID value currently used in shields feature class max_id = sorted(arcpy.da.SearchCursor(shield_points_lyr.dataSource, "SHI_GRP_ID"), reverse = 1)[0][0] #print max_id + 1 #collect selected road arc attributes rdsmall_values = sorted(arcpy.da.SearchCursor(rdsmall_lyr, ["UA", "FAID_S", "CTCODE", "RTNUMBER", "AOTCLASS"])) #uncomment the last line of this block of code to turn off the truncation of the leader line #determine line coordinates, slope, and truncated line geometry based on first and last point. a_pt = line_geometry.firstPoint b_pt = line_geometry.lastPoint slope = (b_pt.Y - a_pt.Y)/(b_pt.X - a_pt.X) theta = math.atan(slope) #fixed_length = 150. fixed_length = 185. if b_pt.X - a_pt.X < 0: x = fixed_length * math.cos(theta) * -1 y = fixed_length * math.sin(theta) * -1 else: x = fixed_length * math.cos(theta) y = fixed_length * math.sin(theta) point = arcpy.Point() point.X = a_pt.X + x point.Y = a_pt.Y + y array = arcpy.Array() array.add(line_geometry.firstPoint) array.add(point) fixed_line = arcpy.Polyline(array) #To remove the constraint of fixed shield arc lengths, uncomment the following line: fixed_line = line_geometry #this line reverts the fixed_line to the original input geometry #create shield point feature and populate attributes new_points_Cur = arcpy.da.InsertCursor(shield_points_lyr, ["SHAPE@XY", "UA", "FAID_S", "CTCODE", "RTNUMBER", "AOTCLASS", "SHI_GRP_ID", "INSET", "ISVISIBLE", "SUBINSET"]) test = (fixed_line.firstPoint,) + tuple(rdsmall_values) + (max_id + 1,) test_tuple = ((test[0].X, test[0].Y), test[1][0], test[1][1], str(test[1][2]), str(test[1][3]), test[1][4], test[2], "N", 1, "N") #test_tuple = ((test[0].X, test[0].Y), rdsmall_values[0], str(rdsmall_values[2]), str(rdsmall_values[3]), rdsmall_values[4], max_id + 1, "N", 1, "N") edit.startOperation() new_points_Cur.insertRow(test_tuple) edit.stopOperation() del new_points_Cur #create shield arc feature and populate SHI_GRP_ID, CTCODE, UA, INSET, ISVISIBLE, and SUBINSET fields new_arc_Cur = arcpy.da.InsertCursor(shield_arcs_lyr.dataSource, ["SHAPE@", "SHI_GRP_ID", "CTCODE", "UA", "INSET", "ISVISIBLE", "SUBINSET"]) edit.startOperation() new_arc_Cur.insertRow([fixed_line, max_id + 1, str(rdsmall_values[0][2]), rdsmall_values[0][0], "N", 1, "N"]) edit.stopOperation() del new_arc_Cur edit.stopEditing(True) #save changes (doesn't work if an editing session is open in ArcMap, but ) arcpy.SelectLayerByAttribute_management(rdsmall_lyr, "CLEAR_SELECTION") arcpy.RefreshActiveView() else: print "Shield Not Created" print "Must select a single arc from rdsmall" #print time.time() - start_time, "seconds"
I have a Python Addin that selects a feature by mouse click location and updates the attributes
Aangemelde leden kunnen berichten plaatsen, updates volgen en meer. Nieuw hier? Registreer een gratis account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.