-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathw2w_delta.py
More file actions
168 lines (127 loc) · 5.39 KB
/
w2w_delta.py
File metadata and controls
168 lines (127 loc) · 5.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import pandas as pd
import numpy as np
from arcgis.gis import GIS
from arcgis import features
from IPython.display import display
from copy import deepcopy
try:
gis = GIS("", "", "")
print('Success!')
except:
print('Failed to login. Check credentials and network connection and try again.')
def sort_descending(layerlist):
lyrnames = []
for lyr in layerlist:
lyrnames.append(lyr.properties.name)
sorted_names = np.argsort(lyrnames)[::-1]
return list(np.array(layerlist)[sorted_names])
# function to output the index of a field
def find_field(layer, fieldname):
fields = layer.manager.properties.fields
for indx, field_props in enumerate(fields):
if field_props.get('name') == fieldname:
fieldname_indx = indx
return fieldname_indx
break
return 'Unable to find field'
# create function to create fc_w2w_delta or FID_copy field
def add_fields(layer, field='fc_w2w_delta'):
newfields = ['fc_w2w_delta', 'FID_copy']
if field not in newfields:
raise ValueError(f'Invalid field name. Expected one of {newfields}.')
currentfields = layer.manager.properties.fields
fc_field = currentfields[find_field(layer, 'fc')]
field_to_copy = fc_field # copying twice bc copying the FID field yielded an error
fields_to_be_added = []
new_field = dict(deepcopy(field_to_copy))
new_field["name"] = field.lower()
new_field["alias"] = field
if field == 'FID_copy':
new_field["type"] = 'esriFieldTypeInteger'
# new_field["isUnique"] = True # not needed, but IDK why...
fields_to_be_added.append(new_field)
try:
layer.manager.add_to_definition({'fields':fields_to_be_added})
except:
raise
# retrieve CERES_Canopy_WFL1 feature class
canopy = gis.content.get('')
# receive input from user what field to calculate vine growth deltas for
error_counter = 0
while error_counter == 0:
field = input("What field are you calculating vine growth delta? Enter 58cd, 137CC, or 137CS")
if field == '58cd':
error_counter = 1
elif field == '137CC':
error_counter = 1
elif field == '137CS':
error_counter = 1
else:
print('Invalid field number. Try again.')
print(f'field # is {field}.')
layernames = []
for lyr in canopy.layers:
layernames.append(lyr.properties.name)
# add layers corresponding to field #
layers_in_field = [layer for layer in canopy.layers if field in layer.properties.name]
# sorts layers from most to least recent
sort_descending(layers_in_field)
# getting vine growth measurements from same plot, diff times
current_week = layers_in_field[0]
prev_week = layers_in_field[1]
current_database = current_week.query().sdf
prev_database = prev_week.query().sdf
# add fc_w2w_delta and FID_copy fields
add_fields(current_week, 'fc_w2w_delta')
add_fields(current_week, 'FID_copy')
# reload layer in the notebook to see the new fields
canopy = gis.content.get('')
layers_in_field = [layer for layer in canopy.layers if field in layer.properties.name]
sort_descending(layers_in_field)
current_week = layers_in_field[0]
prev_week = layers_in_field[1]
current_database = current_week.query().sdf
prev_database = prev_week.query().sdf
for i in current_week.properties.fields:
print(i.name)
# to delete fields
# current_week.manager.delete_from_definition({'fields': [dict(current_week.manager.properties.fields[find_field(current_week, 'fid_copy')]), dict(current_week.manager.properties.fields[find_field(current_week, 'fc_w2w_delta')])]})
# copy FID values to FID_copy
current_week.calculate(where="FID >= 0", calc_expression={"field": "fid_copy", "sqlExpression": "FID"})
# delete the spatial join layer. Only use if need to re-rerun.
# sj_temp.delete()
# join current and prev weeks' layers
sj_temp = features.analysis.join_features(current_week, prev_week, spatial_relationship='identicalto', output_name="sj_temp")
# display the spatially-joined db
sj_temp.layers[0].query().sdf
# calculate fc_w2w_delta on sj layer
sj_temp.layers[0].calculate(where="fid_copy >= 0", calc_expression={"field": "fc_w2w_delta", "sqlExpression": "fc - fc_1"})
sj_temp.layers[0].query().sdf
# sort features by FID, ascending
sj_features = sj_temp.layers[0].query(order_by_fields = 'fid_copy ASC').features
# copy fc_w2w_delta values from sj_temp to current_week
for value in sj_features:
delta_by_fid = value.attributes['fc_w2w_delta']
current_week.calculate(where=f'FID = {value.attributes["fid_copy"]}', calc_expression={'field': 'fc_w2w_delta', 'sqlExpression': f'{delta_by_fid}'})
# current_week.query().sdf
# confirm fc_w2w_delta from current_week matches with the sj layer
# if so, safe to delete the sj layer
# if not, delete sj_temp layer and redo
diff_counter = 0
for oid, item in enumerate(current_week.query().features):
if item.attributes['fc_w2w_delta'] == sj_features[oid].attributes['fc_w2w_delta']:
continue
else:
diff_counter += 1
print('fc_w2w_delta mismatch. Redo calculation.')
break
if diff_counter == 0:
print('All fc_w2w_delta\' s match!')
# delete the spatial join layer. Only use if diff_counter != 0.
# sj_temp.delete()
# find and delete the fid_copy field
fid_copy_indx = find_field(current_week, 'fid_copy')
current_week.manager.delete_from_definition({'fields': [dict(current_week.manager.properties.fields[fid_copy_indx])]})
# delete spatial join layer
sj_temp.delete()
del sj_temp, sj_features