Merging multiple feature layers into one layer

7712
3
07-19-2019 09:08 AM
KatelynNiesen
New Contributor

I'm working on a project in ArcPro 2.3 that has multiple independent feature layers, as in over 50, that need to be combined into one working feature layer. At the moment, each layer is a simple hand-drawn polygon. The polygons all regard the same category of data so I would ideally like to have the layers combined for easier processing, as well as all attribute data into one table. I plan to eventually join a data set to the combined attribute table, hence the need for the feature layers to all be on one layer. 

Anyway, does anyone know of a tool or workflow that I could go about for combining the large amount of feature layers into one layer? 

Apologies if this is unclear.

Thank you!

Tags (2)
0 Kudos
3 Replies
GeoJosh
Esri Regular Contributor

Hey Katelyn,

ArcGIS Online has the Merge Layers tool, which sounds like it may work for you.

Merge Layers—ArcGIS Online Help | ArcGIS

Since you mentioned you are working in Pro, you could use the Merge tool but you would first have to export all existing data to file geodatabases, and use the resulting feature classes as inputs since the tool doesn't take feature layers as inputs.

Merge—Data Management toolbox | ArcGIS Desktop 

I hope this helps a little!


Best,

Josh

0 Kudos
Amazgajewski
New Contributor

Hi Josh, 

This is not really helpful for the use case she described because you can only join two layers at once using that tool. In this case she is trying to take multiple layers to combine in to one composite layer. A better answer would be to use model builder and make the structure iterative. Unfortunately, I don't think there is really a good tool for this straight out of the box. I would go to GIS stack exchange and try to build a simple script using the python editor but that's a bit more advanced. I've run in to this same issue!!

DamB99
by
New Contributor

I know that this post is ancient but still am very surprised that nobody replied to this simple question. Am posting here for a reference.

The easiest option is to create a New Group Layer with specific name in my case is aaa. Then put all your layers under this Group layer (see the attached image)

Then open Python Window (View > Python Window) and type the content below as appropriate

 

#proj = arcpy.mp.ArcGISProject('CURRENT')
# First check which data frame is relevant to you. 
#for i in proj.listMaps():
#    print(i.name)
# in my case it prints 
#BaseMap 
#Map
#So the one I want to loop through is second item in a list so [1], first (in this case BaseMap is [0], third would be [2] ...
# Define which project file are you processing. In this case current
proj = arcpy.mp.ArcGISProject('CURRENT')
# Select your Map Frame
mf = proj.listMaps()[1]
# Get list of all Layers, Group Layers under this Map Frame
mfl = mf.listLayers()
lyr_names = [] # To create an empty list to later contain list of names
# Loop through the full list of layers
for ly in mfl:
    # Checking that it is a correct Group Layer
    if ly.isGroupLayer and ly.name == "aaa":
        # just for your reference. completely unecessary
        print(ly)# it will print aaa in this case
        # adding all layers to the list of layers within this Group Layer
        lyrs = ly.listLayers()
        # Obtaining names of these layers
        for lyr in lyrs:
            # You have to use longName to get not just layer name but also that is within Group layer in this case aaa. You can also use just object so lyr_names.append(lyr)
            lyr_names.append(lyr.longName)
# in my case result for lyr_names is 
#['aaa\\a__5C1bii_SOx', 'aaa\\a__5C1bii_PM10', 'aaa\\a__5C1bii_PM2_5', 'aaa\\a__5C1bii_NOx', 'aaa\\a__5C1bii_NMVOC', 'aaa\\a__5C1bii_CO', 'aaa\\a__5D2_CH4', 'aaa\\a__5D1_CH4', 'aaa\\a__5C1bv_SOx', 'aaa\\a__5C1bv_PM10', 'aaa\\a__5C1bv_NOx', 'aaa\\a__5C1bv_NMVOC', 'aaa\\a__5C1bv_CO', 'aaa\\a__5C1biii_SOx', 'aaa\\a__5C1biii_NOx', 'aaa\\a__5C1biii_NMVOC', 'aaa\\a__5C1biii_CO']
# then simply use Merge tool
#arcpy.management.Merge(lyr_names,YOUR_OUTPUT_PATH_NAME e.g.)
# In case you want to add Source information (layer name) to output add "ADD_SOURCE_INFO"
#arcpy.management.Merge(lyr_names,YOUR_OUTPUT_PATH_NAME e.g.,"ADD_SOURCE_INFO") 
arcpy.management.Merge(lyr_names,r"D:\testing\testing2022\test.gdb\bbb")

 

Just in case you need to preserve the file name or string from file name (like it was in my case) here below is some additional code showing how to do it.

 

# the same as above code until this part below for lyr in lyrs
for lyr in lyrs:
    print(lyr)
    # in my case all layers start with a__ e.g. a__5C1bii_PM2_5
    lyr1 = lyr.name.split("a__")
    # you get back also the Group Layer which is of course not the actual layer
    if lyr1 != "aaa":
        lyr1= lyr1[1]
        # All other files have after a__ exactly two underscores the first is NFR code and the second is the pollutant. Exception is PM2_5
        if "PM2_5" in lyr1:
            # Irrelevant for this showcase so have removed the actual content
        else:
            # Which pollutant 
            lyr2 = lyr1.split("_")[1]
            # NFR code
            lyr3 = lyr1.split("_")[0]
            # Add columns first one is NFR (Text with 15 length and Field Alias 'Nomenclature For Reporting' and second is with correct name of the pollutant obtained from the layer name e.g. CO, PM10 ... and is Double 
            # if filename would be a__5C1bii_CO then this below would be filled out as
            #arcpy.management.AddFields(r"aaa\a__5C1bii_CO",  "NFR TEXT 'Nomenclature For Reporting' 15 # #; CO DOUBLE CO  # # #", None)
            # 
            arcpy.management.AddFields("{0}".format(lyr),  "NFR TEXT 'Nomenclature For Reporting' 15 # #; {0} DOUBLE {0}  # # #".format(lyr2), None)
            # Now calculate pollutant field with correct value obtained from (existing) grid_code column 
            arcpy.management.CalculateField("{0}".format(lyr), "{0}".format(lyr2), "!grid_code!", "PYTHON3", '', "TEXT", "NO_ENFORCE_DOMAINS")
            # calculate field with the value obtained from file/layer name
            arcpy.management.CalculateField("{0}".format(lyr), "NFR", "'{0}'".format(lyr3), "PYTHON3", '', "TEXT", "NO_ENFORCE_DOMAINS")
            # Pay attention to the "'{0}'" part. If you want to populate field (calculate field) with a string you have to enclose the {0} part in single qoutes! if you would populate field with a number (short, long, float or double) no single quotes would be necessary. So this code above would be
            # arcpy.management.CalculateField("{0}".format(lyr), "NFR", "{0}".format(lyr3), "PYTHON3", '', "TEXT", "NO_ENFORCE_DOMAINS")
            # Ignore the "TEXT" part of the code. ArcGIS is not using it because you are calculating the existing column. This parameter is used only if you are calculating into a new (non existing) column

 

Based on my experience when you have multiple files having the same source (in my case were hundreds of rasters converted to points) and you want to join you usually want to preserve filename or you need to add/populate columns with values from the file name.