Select to view content in your preferred language

Append Tool - ArcGIS API for Python

1497
10
Jump to solution
06-17-2024 01:56 PM
CodyPatterson
MVP Regular Contributor

Hey all,

I'm attempting to work through a project where I take the geometry of a layer, and create a feature using that geometry with a set of attributes that do not match the fields of the destination layer. I attempted to check out the documentation, but it is not helpful for copying features from one layer to another.

How can I copy these features? I do not have access to Arcpy unfortunately or I would have this done already.

I'm open to any ideas!

Thank you in advance!

0 Kudos
1 Solution

Accepted Solutions
Clubdebambos
MVP Regular Contributor

Hi @CodyPatterson,

I know it's been a while since you posted this and you may have found a solution but I'll post one here as it is something I had to achieve recently myself. It does't use append() but uses the edit_features(adds=[])

This one will take the geometry and match fields from one feature layer to another.

from arcgis.gis import GIS

## Access ArcGIS Online
agol = GIS("home")

## the Item id that contains the source feature layer
source_fs_id = "FS_ITEM_ID"

## the Item id that contains the target feature layer to append to
target_fs_id = "FS_ITEM_ID"

## get the source feature layer as a FeatureLayer object
## you could use a URL and the FeatureLayer object instead
source_fl = agol.content.get(source_fs_id).layers[0]

## get the target feature layer as a FeatureLayer object
## you could use a URL and the FeatureLayer object instead
target_fl = agol.content.get(target_fs_id).layers[0]

## create a match dictionary for each field
field_match = {
    "source_field_1" : "target_field_1",
    "source_field_2" : "target_field_2",
    "source_field_3" : "target_field_3",
    "source_field_n" : "target_field_n"
}

## the list of fields for the feature layer query
out_fields = list(field_match.keys())

## return a feature set of the information
source_fset = source_fl.query(
    out_fields=out_fields
)

## for each feature returned
for f in source_fset.features:
    ## remove the OBJECTID (or FID/OID)
    del f.attributes["OBJECTID"]
    ## replace source field names with target field names
    f.attributes = {new_key: value for new_key, value in zip(field_match.values(), f.attributes.values())}

## add (append) the features
target_fl.edit_features(adds=source_fset)

  

Would love to know if you found a solution yourself or if this helps/works for what you needed?

All the best,

Glen

~ learn.finaldraftmapping.com

View solution in original post

10 Replies
BlakeTerhune
MVP Frequent Contributor

The final solution must not use arcpy at all? What format is your source data in and what format do you need the output in?

0 Kudos
CodyPatterson
MVP Regular Contributor

Hey @BlakeTerhune 

Unfortunately it cannot as this map is hosted on AGOL and our Notebooks aren't equipped with Arcpy, even though it would be great. The source data in would be a dictionary, there are 29 fields, but all are nullable, so I was wanting to input just the fields I need, such as city, state, order number and so forth. I also have the geometry of the item I would like to enter, and it has the same spatial reference as the target.

In the end, I would like to collapse the geometry and attributes into a single feature, and then append that feature to the feature layer.

Cody

0 Kudos
BobBooth1
Esri Regular Contributor

Cody,

ArcGIS Notebooks do support ArcPy, when you use an Advanced runtime.

https://www.arcgis.com/home/item.html?id=fe8a61ca94c54e6e8e62c2faed0b68cf

 

0 Kudos
DanPatterson
MVP Esteemed Contributor

arcgis online?

arcgis.features module | ArcGIS API for Python


... sort of retired...
0 Kudos
CodyPatterson
MVP Regular Contributor

Hey @DanPatterson 

This is definitely promising, but I'm failing to find a way to pull the geometry and attributes into a feature, when most attributes are missing. I have a few values that I would like to enter and then all the rest be null, there is an objectID field, but I was hoping that would auto-iterate instead of needing entered, but I'm still not sure.

The geometry is in hand, and it matches the spatial reference of the target layer, but the attributes are my main confusion.

Cody

0 Kudos
DanPatterson
MVP Esteemed Contributor

Sorry, no suggestions for the attributes.


... sort of retired...
0 Kudos
CodyPatterson
MVP Regular Contributor

Hey @DanPatterson 

No worries at all, I've been moving through some of the programming and I'm finding some hints, I have a few ideas and if I figure it out, then I'll update this for people in the future.

Thank you for the suggestions!

Cody

0 Kudos
BobBooth1
Esri Regular Contributor
0 Kudos
Clubdebambos
MVP Regular Contributor

Hi @CodyPatterson,

I know it's been a while since you posted this and you may have found a solution but I'll post one here as it is something I had to achieve recently myself. It does't use append() but uses the edit_features(adds=[])

This one will take the geometry and match fields from one feature layer to another.

from arcgis.gis import GIS

## Access ArcGIS Online
agol = GIS("home")

## the Item id that contains the source feature layer
source_fs_id = "FS_ITEM_ID"

## the Item id that contains the target feature layer to append to
target_fs_id = "FS_ITEM_ID"

## get the source feature layer as a FeatureLayer object
## you could use a URL and the FeatureLayer object instead
source_fl = agol.content.get(source_fs_id).layers[0]

## get the target feature layer as a FeatureLayer object
## you could use a URL and the FeatureLayer object instead
target_fl = agol.content.get(target_fs_id).layers[0]

## create a match dictionary for each field
field_match = {
    "source_field_1" : "target_field_1",
    "source_field_2" : "target_field_2",
    "source_field_3" : "target_field_3",
    "source_field_n" : "target_field_n"
}

## the list of fields for the feature layer query
out_fields = list(field_match.keys())

## return a feature set of the information
source_fset = source_fl.query(
    out_fields=out_fields
)

## for each feature returned
for f in source_fset.features:
    ## remove the OBJECTID (or FID/OID)
    del f.attributes["OBJECTID"]
    ## replace source field names with target field names
    f.attributes = {new_key: value for new_key, value in zip(field_match.values(), f.attributes.values())}

## add (append) the features
target_fl.edit_features(adds=source_fset)

  

Would love to know if you found a solution yourself or if this helps/works for what you needed?

All the best,

Glen

~ learn.finaldraftmapping.com