Here's what I'm trying to do. I have a feature service (FS1) which contains inspections. These inspections can be identified by values in the following fields: plantation, years_planted, date_of_inspection & inspection_number.
Feature service 2 (FS2) contains 1 row per plantation and planting year (e.g. Ferndale:2024, Ferndale:2025, etc.) and a number of fields to record if an inspection has been completed or not based on a regular cycle.
Below is a list of values from FS1's inspection_number field and their corresponding field name from FS2.
'2 weeks': 'insp_2_weeks'
'4 weeks': 'insp_4_weeks'
'6 weeks': 'insp_6_weeks'
'8 weeks': 'insp_8_weeks'
When an inspection is done in FS1, the corresponding row in FS2 should be updated to record that it has happened by updating the corresponding inspection_number field with "username on inspection_date".
Below is the code I have so far. I know it works up to Line 80 based on print statements returned. I can't seem to get it to match up the features from FS1 (lots of inspections) with FS2 (inspection tracking) though, and once matched, update the corresponding inspection_number field.
# URLs of the feature services
fs1_url = "https://services-ap1.arcgis.com/xyzxyzxyzxyzx/arcgis/rest/services/featureservice1/FeatureServer/0"
fs2_url = "https://services-ap1.arcgis.com/xyzxyzxyzxyzx/arcgis/rest/services/featureservice2/FeatureServer/0"
import datetime
from arcgis.gis import GIS
from arcgis.features import FeatureLayer
import certifi
import urllib3
import ssl
import warnings
from urllib3.exceptions import InsecureRequestWarning
# Create a default SSL context with certificate verification
ssl_context = ssl.create_default_context(cafile=certifi.where())
http = urllib3.PoolManager(ssl_context=ssl_context)
# Make a request to verify the setup
response = http.request('GET', 'https://myorg.arcgis.com')
print("http response: " + str(response.status))
# Suppress only the single InsecureRequestWarning from urllib3 if necessary
warnings.simplefilter('ignore', InsecureRequestWarning)
# Create GIS object
print("Connecting to AGOL")
client_id = 'xyzxyzxyzxyzx'
client_secret = 'xyzxyzxyzxyzx'
gis = GIS("https://myorg.arcgis.com", client_id=client_id, client_secret=client_secret)
print("Logged in as: " + gis.properties.user.username)
# Access the feature layers
fs1_layer = FeatureLayer(fs1_url)
print(fs1_layer)
fs2_layer = FeatureLayer(fs2_url)
print(fs2_layer)
#def update_feature_services(fs1_layer, fs2_layer):
# Mapping of inspection_number values to field names in fs2
inspection_mapping = {
'2 weeks': 'insp_2_weeks',
'4 weeks': 'insp_4_weeks',
'6 weeks': 'insp_6_weeks',
'8 weeks': 'insp_8_weeks',
'10 weeks': 'insp_10_weeks',
'12 weeks': 'insp_12_weeks',
'4 months': 'insp_4_months',
'5 months': 'insp_5_months',
'6 months': 'insp_6_months',
'9 months': 'insp_9_months',
'12 months': 'insp_12_months',
'15 months': 'insp_15_months',
'18 months': 'insp_18_months',
'21 months': 'insp_21_months',
'24 months': 'insp_24_months'
}
# Query to get all features from fs1 without geometry
fs1_features = fs1_layer.query(where="inspection_number <> 'Ad-hoc Inspection'", out_fields=['objectid', 'globalid', 'date_of_inspection', 'plantation', 'years_planted', 'username', 'inspection_number'], return_geometry=False).features
print(f"Input features found")
# Query to get all features from fs2 without geometry
fs2_features = fs2_layer.query(out_fields="*", return_geometry=False).features
print(f"Target features found")
# Iterate over each feature in fs1
for fs1_feature in fs1_features:
attributes = fs1_feature.attributes
plantation = attributes['plantation']
years_planted = attributes['years_planted']
inspection_number = attributes['inspection_number']
username = attributes['username']
print(f"\nPlantation: {plantation}, PYear: {years_planted}, Inspection: {inspection_number}, User: {username}")
# Convert date_of_inspection to string and extract the date part
if attributes['date_of_inspection']:
inspection_date = datetime.datetime.fromtimestamp(attributes['date_of_inspection'] / 1000).strftime("%Y/%m/%d")
print(f"Checking {username} on {inspection_date}")
# Find the corresponding feature in fs2
for fs2_feature in fs2_features:
fs2_attributes = fs2_feature.attributes
if fs2_attributes['Plantation'] == plantation and fs2_attributes['PlantingYear'] == years_planted:
# Get the corresponding field name in fs2
field_name = inspection_mapping.get(inspection_number)
print(f"Inspection: {field_name}")
if field_name and not fs2_attributes[field_name]:
# Update the matching field with 'username on date' text
fs2_attributes[field_name] = f"{username} on {inspection_date}"
fs2_layer.edit_features(updates=[fs2_feature])
print(f"Updated {username} on {inspection_date}")
I feel like maybe this would be better done using arcpy.da.searchcursor or something like that, but I'm not proficient in wielding that code yet.
Visual representation of the data below (the dates don't align, but you should get the idea). Repeated inspections should trigger updates to a series of fields in a row.
