Comparing Two Feature Classes and Updating One of Them

10489
16
Jump to solution
08-21-2014 01:15 PM
DavidBuehler
Occasional Contributor III

I am trying to automate the production of a feature class with daily updates. I would like to use a Python Script do this. The basic concept is there is a SQL table that is updated with addresses, the script needs to pull that table into a intermediate file geodatabase, geocoded it, compare the geocoded results to the existing SDE feature class, and remove any old entries from the SDE feature class, append any new features, and leave alone any that are the same. I get the first chunk of my script to do what I want it to do.  When I get to the compare and update part, my initial line of thinking will not work in all cases (especially when there are only removals). I know there has to be a more elegant way of doing the compare and update portion. Any suggestions?

 

This is what the portion that does not work all the time:

 

# Put in error trapping in case an error occurs when running tool
CoMGIS_SDE_Warrants = #Path to SDE Feature Class
try:

   # Make a layer from the feature class
   arcpy.MakeFeatureLayer_management(MAW_GeoCode,"newCompare_lyr")

   # Selecting all existing features
   arcpy.SelectLayerByLocation_management("newCompare_lyr", "INTERSECT", CoMGIS_SDE_Warrants, "", "NEW_SELECTION")
  
   # Selecting only new features
   arcpy.SelectLayerByLocation_management("newCompare_lyr", "INTERSECT", CoMGIS_SDE_Warrants, "", "SWITCH_SELECTION")

   # Write the selected features to a new featureclass
   arcpy.Append_management("newCompare_lyr", CoMGIS_SDE_Warrants,"TEST","","")

   arcpy.Delete_management("newCompare_lyr")

   # Make a layer from the Existing Features
   arcpy.MakeFeatureLayer_management(CoMGIS_SDE_Warrants,"existCompare_lyr")

   # Selecting all existing features
   arcpy.SelectLayerByLocation_management("existCompare_lyr", "INTERSECT", MAW_GeoCode, "", "NEW_SELECTION")
  
   # Selecting only Non-Active Warrants
   arcpy.SelectLayerByLocation_management("existCompare_lyr", "INTERSECT", MAW_GeoCode, "", "SWITCH_SELECTION")

   # Delete Non-Active Warrants
   arcpy.DeleteFeatures_management("existCompare_lyr")

   arcpy.Delete_management("existCompare_lyr")
     
except:
   print arcpy.GetMessages()

print "Success"

0 Kudos
16 Replies
DavidBuehler
Occasional Contributor III


Xander,

Thank you very much.  I ran it, tested, and it worked like a charm.  I will spend some time to truly understanding what is all going on in the script you posted.  Thank you again for helping out a newbie at python scripting.

0 Kudos
XanderBakker
Esri Esteemed Contributor

Remember that Riyas Deen‌ did most of the work.

To help you a little in the process of understanding the code, here goes...

There are a number of functions that can be reused and help to make the code more readable

  • line 3 - 6 (createMatchingFieldList) uses list comprehensions to create a list of the field names in both featureclasses. The lists are converted to sets which van be used with the & to create a set with only those elements that exist in both sets. The List() converts the resulting set to list
  • Line 8 - 15 (createWhereClause) uses the type of the field (the code will only handle string and numeric fields correctly) and the arcpy.AddFieldDelimiters to add quotes or brackets to the field depending on the datasource. This is powerful way of making code run correctly on different types of data (shapefiles, file,  personal and enterprise geodatabases)
  • line 17 and 18 (getPrimaryFieldValues) uses again a list comprehension to create a list of values in a given field. It actually loop through the data and returns the first field r[0] and adds it to a list (hence the square brackets).
  • line 20 and 21 (getSelectCursor) creates a search cursor with the given fields and where clause.
  • line 23 and 24 (diff) returns a list of element which are in list a, but not in list b.

The rest of the code does the job:

  • lines 34 - 40 contains the calls to the various functions (creating the list of fields, the list of values for both featureclasses and determining the difference)
  • lines 42 - 47 creates an insert cursor on the destination and loop through the elements in "additions" and inserts the rows (from the source) into the destination
  • lines 49 to 53 uses an update cursor on the destination to remove those features that are in the destination, but not in the source.

Kind regards, Xander

AimeiChen
Occasional Contributor

Hi Xander,

The python script you shared here was very useful, thanks!

The add function insert new records and delete function remove old records, is it possible to update attribute value if the record exist in both tables/features?

Thanks,

Amy

0 Kudos
XanderBakker
Esri Esteemed Contributor

I suppose that is possible, but what would you like to register in the destination featureclass is a feature ID still exists, but attributes have changed? Should the record be marked as changed or do you want to overwrite the field values? Be aware that only the listed fields (those that both featureclasses have) will be checked to see if attributes changed.

0 Kudos
AimeiChen
Occasional Contributor

Xander,

Thanks for your quick reply!

I have a feature layer, 10 attribute fields were captured in GIS and 20 fields were from City Works and rest were our inputs. In GIS, the feature layer is identical to the 10 fields in the destination features. So I'd like to send GIS updates to the layer automatically (overwrite the 10 field values) and keep updating/editing the rest attributes. Is it possible to do that?

Thanks,

Amy

0 Kudos
DavidBuehler
Occasional Contributor III

Aimei,

Did you figure this out?

0 Kudos
AimeiChen
Occasional Contributor

David,

my solution is exporting the feature layer into File geo database, split it into three layers and update them accordingly. then merge them into one.

Thanks,

Aimei