def edit_version(self, connection_file: str): records = self._edit() if records: log.debug("Writing edited rows to a csv...") csv_file = f'.\\facilityid\\log\\{self.feature_name}_Edits.csv' write_to_csv(csv_file, records) self.add_edit_metadata() guid_facid = {x['GLOBALID']: x["NEWFACILITYID"] for x in records} if connection_file: edit_conn = os.path.join(connection_file, *self.tuple_path[1:]) try: # Start an arc edit session log.debug("Entering an arc edit session...") editor = Editor(connection_file) editor.startEditing(False, True) editor.startOperation() log.debug("Filtering the table to editted records only...") # Query only the entries that need editing guids = ", ".join(f"'{x}'" for x in guid_facid.keys()) query = f"GLOBALID IN ({guids})" # Open an update cursor and perform edits log.debug("Opening an update cursor to perform edits...") fields = ["GLOBALID", "FACILITYID"] with UpdateCursor(edit_conn, fields, query) as cursor: for row in cursor: row[1] = guid_facid[row[0]] cursor.updateRow(row) # Stop the edit operation log.debug("Closing the edit session...") editor.stopOperation() editor.stopEditing(True) del editor ClearWorkspaceCache_management() log.info(("Successfully performed versioned edits on " f"{self.feature_name}...")) # Reset the aprx connection to the versioned connection self.aprx_connection = edit_conn self.version_name = os.path.basename( connection_file).strip(".sde") self.add_to_aprx() except RuntimeError: log.exception(("Could not perform versioned edits " f"on {self.feature_name}...")) log.debug("Logging edits to csv file containing all edits ever...") all_edits = r'.\\facilityid\\log\\AllEditsEver.csv' write_to_csv(all_edits, records) else: log.info("No edits were necessary...")
def prepLayer(fc, copy_table, unique, rc_obj, gdb): #copy features and add field for the parsed label CopyFeatures_management(fc, copy_table) AddField_management(copy_table, "ROAD_" + rc_obj.LABEL, "TEXT", "", "", 100) #calculate the road label road_label_fields = rc_obj.LABEL_FIELDS if "LABEL" in road_label_fields: road_label_fields.remove("LABEL") road_label_fields.insert(0, "ROAD_" + rc_obj.LABEL) edit = Editor(gdb) edit.startEditing(False, False) #run update cursor with UpdateCursor(copy_table, road_label_fields) as rows: for row in rows: field_count = len(road_label_fields) start_int = 1 label = "" #loop through the fields to see what's null & skip it while start_int < field_count: if row[start_int] is not None: if row[start_int] not in ("", " "): label = label + "|" + str(row[start_int]) start_int = start_int + 1 row[0] = label.strip("|") rows.updateRow(row) edit.stopEditing(True) lyr1 = "lyr1" MakeFeatureLayer_management(copy_table, lyr1) Dissolve_management(lyr1, unique, ["ROAD_" + rc_obj.LABEL]) Delete_management(lyr1)
def main(): print( "Using the new field logic to calculate the values of the source lrs ID and measure fields." ) if useSQLLocationToRecalculateFields == True: addMissingFields(sqlFCWithFieldsToRecalculate) MakeFeatureLayer_management(sqlFCWithFieldsToRecalculate, fcAsFeatureLayer) workspace = os.path.dirname(sqlFCWithFieldsToRecalculate) editSession = Editor(workspace) editSession.startEditing(False, True) editSession.startOperation() recalculateKeyValues() editSession.stopOperation() # Stop the edit session and save the changes editSession.stopEditing(True) else: MakeFeatureLayer_management(fcWithFieldsToRecalculate, fcAsFeatureLayer) recalculateKeyValues()
def UpdateKdotNameInCenterline(centerlineToIntersect, centerlineAliasTable): ############################################################################### # Create a list here for output and then use logic on the dictionary to decide # what value you want the KDOT_ROUTENAME in the centerline feature class to have. # Then, use an update cursor to match the SEGID with the value to update. ############################################################################### # Need to check to see if the centerlineToIntersect has a field that already # exists for the KDOT_ROUTENAME, and if not, create one. # Create a list of fields using the ListFields function fieldsList = ListFields(centerlineToIntersect) fieldNamesList = list() # Iterate through the list of fields for field in fieldsList: fieldNamesList.append(field.name) # If the KDOT_ROUTENAME field is not found, # add it with adequate parameters. if "KDOT_ROUTENAME" not in fieldNamesList: #AddMessage("Adding KDOT_ROUTENAME to " + centerlineToIntersect + ".") #previousWorkspace = env.workspace # @UndefinedVariable addFieldWorkspace = getGDBLocationFromFC(centerlineToIntersect) env.workspace = addFieldWorkspace fieldNameToAdd = "KDOT_ROUTENAME" fieldLength = 10 AddField_management(centerlineToIntersect, fieldNameToAdd, "TEXT", "", "", fieldLength) # Set the workspace back to what it was previously to prevent # problems from occurring in the rest of the script. #env.workspace = previousWorkspace AddMessage("The " + str(fieldNameToAdd) + " field was added to " + str(centerlineToIntersect) + ".") else: AddMessage("The KDOT_ROUTENAME field already exists within " + centerlineToIntersect + ".") AddMessage("It will not be added again, but its values will be updated (where necessary).") aliasFields = ['SEGID', 'KDOT_ROUTENAME'] #for fieldNameItem in fieldNamesList: #print fieldNameItem aliasCursor = SearchCursor(centerlineAliasTable, aliasFields) aliasList = list() for aliasRow in aliasCursor: if aliasRow[1] is not None: aliasList.append(aliasRow) else: pass try: del aliasCursor except: pass aliasDictionary = dict() for aliasListItem in aliasList: if aliasListItem[0] in aliasDictionary.keys(): listContainer = aliasDictionary[aliasListItem[0]] listContainer.append(aliasListItem) aliasDictionary[aliasListItem[0]] = listContainer else: listContainer = list() listContainer.append(aliasListItem) aliasDictionary[aliasListItem[0]] = listContainer aliasListForUpdate = list() for aliasDictKey in aliasDictionary.keys(): listContainer = aliasDictionary[aliasDictKey] bestRouteName = '' for listContainerItem in listContainer: currentRouteName = listContainerItem[1] # Logic to decide route to use based on route dominance is in # the compareRouteNames function. bestRouteName = compareRouteNames(bestRouteName, currentRouteName) aliasListForUpdate.append((aliasDictKey, bestRouteName)) # Have to start an edit session because the feature class participates in a topology. try: editWorkspace = getGDBLocationFromFC(centerlineToIntersect) editSession = Editor(editWorkspace) editSession.startEditing(False, False) editSession.startOperation() routeToUpdateCursor = UpdateCursor(centerlineToIntersect, aliasFields) for routeToUpdate in routeToUpdateCursor: routeToUpdate = list(routeToUpdate) for aliasForUpdate in aliasListForUpdate: if routeToUpdate[0] == aliasForUpdate[0]: routeToUpdate[1] = aliasForUpdate[1] else: pass routeToUpdateCursor.updateRow(routeToUpdate) del routeToUpdateCursor editSession.stopOperation() editSession.stopEditing(True) except ExecuteError: AddMessage((GetMessages(2)))
def prep_roads_for_comparison(rd_fc, name_field, code_fields, city_fields, field_list): # calculate values for NAME_OVLERAP field fields1 = tuple(field_list) # add the NAME_OVERLAP field if not fieldExists(rd_fc, name_field): AddField_management(rd_fc, name_field, "TEXT", "", "", 100) i = 0 if "rcTable" in rd_fc: field_list.append("NGSEGID") i = field_list.index("NGSEGID") elif "apTable" in rd_fc: if "NGSEGID" in field_list: field_list.remove("NGSEGID") field_list.append("NGADDID") i = field_list.index("NGADDID") ## AddMessage("Query field list:" + ", ".join(field_list)) if "in_memory" not in rd_fc: # start edit session working_gdb = dirname(rd_fc) if working_gdb[-3:] not in ("gdb"): working_gdb = dirname(dirname(rd_fc)) if r"Database Servers\GISS01_SQLEXPRESSGIS.gds" in working_gdb: working_gdb = r"Database Servers\GISS01_SQLEXPRESSGIS.gds\KSNG911S(VERSION:dbo.DEFAULT)" # made some changes to account for Butler Co's SDE gdb ## AddMessage(working_gdb) edit = Editor(working_gdb) if "dbo.DEFAULT" not in working_gdb: edit.startEditing(False, False) else: edit.startEditing(False, True) # run update cursor with UpdateCursor(rd_fc, fields1) as rows: for row in rows: field_count = len(fields1) start_int = 1 label = "" # loop through the fields to see what's null & skip it while start_int < field_count: if row[start_int] is not None: if row[start_int] not in ("", " "): label = label + "|" + str(row[start_int]).strip().upper() start_int = start_int + 1 row[0] = label.replace("||","|") try: rows.updateRow(row) except: AddMessage("Error with " + rd_fc + field_list[i] + row[i]) if "in_memory" not in rd_fc: edit.stopEditing(True) # clean up all labels trim_expression = '" ".join(!' + name_field + '!.split())' CalculateField_management(rd_fc, name_field, trim_expression, "PYTHON_9.3") # covert labels to road code with MSAG city code code_block= """def calc_code(rd, city): b = {"A":1,"B":2,"C":3,"D":4,"E":5,"F":6,"G":7,"H":8,"I":9,"J":10,"K":11, "L":12,"M":13,"N":14,"O":15,"P":16,"Q":17,"R":18,"S":19,"T":20,"U":21, "V":22,"W":23,"X":24,"Y":25,"Z":26," ":27,"0":28,"1":29,"2":30,"3":31,"4":32,"5":33,"6":34,"7":35, "8":36,"9":37,"|":38,"-":39,"'":40,";":43} tot = 0 if city is None or city in ('', ' ', ' '): city = " " for name in rd, city: name = name.strip().upper() while len(name) < 3: name = name + " " list_len = len(name) k = 0 while k < list_len: try: chars1 = b[name[k].upper()] except: chars1 = 42 if 0 < k + 1 < list_len: try: chars1 = chars1 * k * b[name[k+1].upper()] except: chars1 = chars1 * k * 42 else: try: chars1 = chars1 * b[name[list_len - 1]] except: chars1 = chars1 * 42 tot += chars1 k += 1 # make sure all the values actually work if name[0].upper() not in b: a0 = 42 else: a0 = b[name[0].upper()] if name[1].upper() not in b: a1 = 43 else: a1 = b[name[1].upper()] if name[2].upper() not in b: a2 = 44 else: a2 = b[name[2].upper()] if name[-1].upper() not in b: a3 = 45 else: a3 = b[name[-1].upper()] c = len(rd) + len(city) tot = tot * c - a1 + a2 - a3 return tot""" for code_field in code_fields: i = code_fields.index(code_field) city_field = city_fields[i] # add the NAME_OVERLAP field if not fieldExists(rd_fc, code_field): AddField_management(rd_fc, code_field, "LONG") ## try: CalculateField_management(rd_fc, code_field, "calc_code( !" + name_field + "!.upper(), !" + city_field + "! )", "PYTHON_9.3", code_block)
def main(): import CoordConvertor from arcpy import GetParameterAsText, AddMessage from arcpy.da import Editor, UpdateCursor from os.path import dirname ct = CoordConvertor.CoordTranslator() #declare parameter variables for feature class and #X and Y fields and the National Grid field fc = GetParameterAsText(0) xField = GetParameterAsText(1) yField = GetParameterAsText(2) NG = GetParameterAsText(3) #establish workspace path = dirname(fc) if '.gdb' in path: place = path.find('.gdb') + 4 else: if '.mdb' in path: place = path.find('.mdb') + 4 else: if '.sde' in path: place = path.find('.sde') + 4 else: place = len(path) - 1 workspace = path[:place] AddMessage(workspace) #Start an edit session edit = 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, True) # Start an edit operation edit.startOperation() #define the field list fields = (xField, yField, NG) #calculate the NG coordinate for each row try: with UpdateCursor(fc, fields) as cursor: for row in cursor: x = row[0] y = row[1] if x is not None: if y is not None: row[2] = ct.AsMGRS([y,x], 5, False) cursor.updateRow(row) #release the locks on the data del row del cursor except: AddMessage("USNG coordinates could not be updated.") finally: # Stop the edit operation. edit.stopOperation() # Stop the edit session and save the changes edit.stopEditing(True)
def main(): layer = GetParameterAsText(0) updateBlanksOnly = GetParameterAsText(1) expression = "" a = "" field_list = [] #define object & field list if basename(layer) in ("RoadCenterline", "AddressPoints"): a = getFCObject(layer) field_list = a.LABEL_FIELDS else: userMessage(layer + " does not work with this tool. Please select the NG911 road centerline or address point file.") #make sure the object is something if a != "": #start at 1 since 0 is the label field itself i = 1 #create the expression while i < len(field_list): #since the house number needs a string conversion, we need to have a slightly different expression for the first piece if i == 1: if basename(layer) == "AddressPoints": expression = 'str(!' + field_list[i] + '!) + " " + !' else: expression = '!' + field_list[i] + '! + " " + !' else: expression = expression + field_list[i] + '! + " " + !' i += 1 expression = expression[:-10] userMessage(expression) labelField = a.LABEL userMessage(labelField) if expression != "": lyr = "lyr" MakeFeatureLayer_management(layer, lyr) qry = labelField + " is null or " + labelField + " = '' or " + labelField + " = ' '" #select only the blank ones to update if that's what the user wanted if updateBlanksOnly == "true": SelectLayerByAttribute_management(lyr, "NEW_SELECTION", qry) userMessage("Calculating label...") CalculateField_management(lyr, labelField, expression, "PYTHON_9.3") #make sure no records were left behind SelectLayerByAttribute_management(lyr, "NEW_SELECTION", qry) result = GetCount_management(lyr) count = int(result.getOutput(0)) #if the count is higher than 0, it means the table had null values in some of the concatonated fields if count > 0: gdb = dirname(dirname(layer)) fields = tuple(field_list) #start edit session edit = Editor(gdb) edit.startEditing(False, False) #run update cursor with UpdateCursor(layer, fields, qry) as rows: for row in rows: field_count = len(fields) start_int = 1 label = "" #loop through the fields to see what's null & skip it while start_int < field_count: if row[start_int] is not None: if row[start_int] not in ("", " "): label = label + " " + str(row[start_int]) start_int = start_int + 1 row[0] = label rows.updateRow(row) edit.stopEditing(True) #clean up all labels trim_expression = '" ".join(!' + labelField + '!.split())' CalculateField_management(layer, labelField, trim_expression, "PYTHON_9.3")
def calc_coordinates(fc, updateOnlyBlank): ct = CoordConvertor.CoordTranslator() AddMessage("Calculating coordinates. For large datasets, this process can a while.") #get default address point object a = getFCObject(fc) #set field names based on object xField = a.X yField = a.Y NG = a.USNGRID #establish workspace path = dirname(fc) if '.gdb' in path: place = path.find('.gdb') + 4 else: if '.sde' in path: place = path.find('.sde') + 4 else: place = len(path) - 1 workspace = path[:place] AddMessage(workspace) #Start an edit session edit = 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, True) # Start an edit operation edit.startOperation() fl = "fl" # If necessary, only update blank records if updateOnlyBlank == "true": wc = NG + " IS NULL OR " + NG + " = '' OR " + NG + " = ' '" MakeFeatureLayer_management(fc, fl, wc) else: MakeFeatureLayer_management(fc, fl) #define the field list fields = (xField, yField, NG, "SHAPE@X", "SHAPE@Y") #modify this to access the shape field #get desired spatial reference sr = SpatialReference("WGS 1984") #get current spatial reference sr_org = Describe(fc).SpatialReference #calculate the NG coordinate for each row try: with UpdateCursor(fl, fields) as cursor: for row in cursor: #see if the x/y fields are blank or are populated if row[0] is None or row[0] == 0: #create new point object point = Point() point.X = row[3] point.Y = row[4] #convert to a point geometry pointGeom = PointGeometry(point, sr_org) #reproject the point geometry into WGS 1984 point2 = pointGeom.projectAs(sr, "WGS_1984_(ITRF00)_To_NAD_1983") #turn the point geometry back into a normal point with the "first point" functionality firstPoint = point2.firstPoint #get the x/y position x = firstPoint.X y = firstPoint.Y #update the x & y fields along the way row[0] = x row[1] = y else: x = row[0] y = row[1] #some error trapping, just in case... if x is not None: if y is not None: #convert the x & y coordinates to USNG and update the field row[2] = ct.AsMGRS([y,x], 5, False) cursor.updateRow(row) #release the locks on the data del row del cursor AddMessage("Lat/Long and USNG coordinates successfully updated.") except: AddMessage("Lat/Long and USNG coordinates could not be updated.") finally: # Stop the edit operation. edit.stopOperation() # Stop the edit session and save the changes edit.stopEditing(True) AddMessage("Processing complete.")