13
13
# You should have received a copy of the GNU Affero General Public License
14
14
# along with this program. If not, see https://www.gnu.org/licenses/.
15
15
16
- # local libraries
17
- import soil_id .config
16
+ import collections
17
+ import csv
18
+ import io
18
19
19
- from . db import (
20
- get_WRB_descriptions ,
21
- getSG_descriptions ,
22
- )
20
+ # Standard libraries
21
+ import logging
22
+ import re
23
+ from dataclasses import dataclass
23
24
24
- from . color import (
25
- calculate_deltaE2000 ,
26
- )
25
+ # Third-party libraries
26
+ import numpy as np
27
+ import pandas as pd
27
28
28
- from .services import get_soilgrids_classification_data , get_soilgrids_property_data
29
+ # Load .env file
30
+ from dotenv import load_dotenv
31
+ from scipy .stats import norm
32
+
33
+ # local libraries
34
+ import soil_id .config
29
35
36
+ from .color import calculate_deltaE2000
37
+ from .db import get_WRB_descriptions , getSG_descriptions
38
+ from .services import get_soilgrids_classification_data , get_soilgrids_property_data
30
39
from .utils import (
40
+ adjust_depth_interval ,
31
41
agg_data_layer ,
32
42
assign_max_distance_scores ,
33
43
calculate_location_score ,
39
49
getSand ,
40
50
getTexture ,
41
51
gower_distances ,
52
+ max_comp_depth ,
42
53
pedon_color ,
43
54
silt_calc ,
44
- max_comp_depth ,
45
- adjust_depth_interval ,
46
55
)
47
56
48
- # Standard libraries
49
- import logging
50
- import collections
51
- import csv
52
- import io
53
- import re
54
- from dataclasses import dataclass
55
-
56
- # Third-party libraries
57
- import numpy as np
58
- import pandas as pd
59
- from scipy .stats import norm
60
-
61
- # Load .env file
62
- from dotenv import load_dotenv
63
57
load_dotenv ()
64
58
65
59
@@ -93,7 +87,7 @@ def list_soils_global(lon, lat):
93
87
lon ,
94
88
lat ,
95
89
# Temporarily change file path
96
- file_path = ' /mnt/c/LandPKS_API_SoilID-master/global/wise30sec_poly_simp_soil.gpkg' ,
90
+ file_path = " /mnt/c/LandPKS_API_SoilID-master/global/wise30sec_poly_simp_soil.gpkg" ,
97
91
# file_path=config.WISE_PATH,
98
92
# layer_name=None,
99
93
buffer_dist = 10000 ,
@@ -211,11 +205,13 @@ def list_soils_global(lon, lat):
211
205
comp_key = muhorzdata_pd ["cokey" ].unique ().tolist ()
212
206
213
207
# Subset mucompdata_pd by new compname_key and add suffix to name if there are duplicates
214
- mucompdata_pd = mucompdata_pd .loc [mucompdata_pd [' cokey' ].isin (comp_key )].reset_index (drop = True )
208
+ mucompdata_pd = mucompdata_pd .loc [mucompdata_pd [" cokey" ].isin (comp_key )].reset_index (drop = True )
215
209
mucompdata_pd ["compname_grp" ] = mucompdata_pd ["compname" ]
216
210
217
211
# Sort by 'distance_score' (descending) and 'distance' (ascending), then reset the index
218
- mucompdata_pd = mucompdata_pd .sort_values (['distance_score' , 'distance' ], ascending = [False , True ]).reset_index (drop = True )
212
+ mucompdata_pd = mucompdata_pd .sort_values (
213
+ ["distance_score" , "distance" ], ascending = [False , True ]
214
+ ).reset_index (drop = True )
219
215
220
216
# Add suffix to duplicate names
221
217
name_counts = collections .Counter (mucompdata_pd ["compname" ])
@@ -250,9 +246,7 @@ def list_soils_global(lon, lat):
250
246
251
247
for group_key , group in muhorzdata_group_cokey :
252
248
profile = (
253
- group .sort_values (by = "hzdept_r" )
254
- .drop_duplicates (keep = "first" )
255
- .reset_index (drop = True )
249
+ group .sort_values (by = "hzdept_r" ).drop_duplicates (keep = "first" ).reset_index (drop = True )
256
250
)
257
251
258
252
# profile depth
@@ -276,10 +270,14 @@ def list_soils_global(lon, lat):
276
270
[
277
271
sand_pct_intpl [["c_sandpct_intpl_grp" ]], # DataFrame
278
272
clay_pct_intpl [["c_claypct_intpl_grp" ]], # DataFrame
279
- cf_pct_intpl [["c_cfpct_intpl_grp" ]], # DataFrame
280
- pd .DataFrame (profile .compname .unique (), columns = ["compname" ]), # Convert to DataFrame
281
- pd .DataFrame (profile .cokey .unique (), columns = ["cokey" ]), # Convert to DataFrame
282
- pd .DataFrame (profile .comppct_r .unique (), columns = ["comppct" ]), # Convert to DataFrame
273
+ cf_pct_intpl [["c_cfpct_intpl_grp" ]], # DataFrame
274
+ pd .DataFrame (
275
+ profile .compname .unique (), columns = ["compname" ]
276
+ ), # Convert to DataFrame
277
+ pd .DataFrame (profile .cokey .unique (), columns = ["cokey" ]), # Convert to DataFrame
278
+ pd .DataFrame (
279
+ profile .comppct_r .unique (), columns = ["comppct" ]
280
+ ), # Convert to DataFrame
283
281
],
284
282
axis = 1 ,
285
283
)
@@ -301,17 +299,33 @@ def list_soils_global(lon, lat):
301
299
}
302
300
)
303
301
304
- snd_d , hz_depb = agg_data_layer (sand_pct_intpl .c_sandpct_intpl , bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ], depth = True )
305
- cly_d = agg_data_layer (clay_pct_intpl .c_claypct_intpl , bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ], depth = False )
302
+ snd_d , hz_depb = agg_data_layer (
303
+ sand_pct_intpl .c_sandpct_intpl ,
304
+ bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ],
305
+ depth = True ,
306
+ )
307
+ cly_d = agg_data_layer (
308
+ clay_pct_intpl .c_claypct_intpl ,
309
+ bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ],
310
+ depth = False ,
311
+ )
306
312
txt_d = [
307
313
getTexture (row = None , sand = s , silt = (100 - (s + c )), clay = c ) for s , c in zip (snd_d , cly_d )
308
314
]
309
315
txt_d = pd .Series (txt_d , index = snd_d .index )
310
316
311
- rf_d = agg_data_layer (cf_pct_intpl .c_cfpct_intpl , bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ], depth = False )
312
- cec_d = agg_data_layer (cec_intpl .c_cec_intpl , bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ], depth = False )
313
- ph_d = agg_data_layer (ph_intpl .c_ph_intpl , bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ], depth = False )
314
- ec_d = agg_data_layer (ec_intpl .c_ec_intpl , bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ], depth = False )
317
+ rf_d = agg_data_layer (
318
+ cf_pct_intpl .c_cfpct_intpl , bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ], depth = False
319
+ )
320
+ cec_d = agg_data_layer (
321
+ cec_intpl .c_cec_intpl , bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ], depth = False
322
+ )
323
+ ph_d = agg_data_layer (
324
+ ph_intpl .c_ph_intpl , bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ], depth = False
325
+ )
326
+ ec_d = agg_data_layer (
327
+ ec_intpl .c_ec_intpl , bottom = c_bottom_temp ["c_very_bottom" ].iloc [0 ], depth = False
328
+ )
315
329
316
330
# Fill NaN values and append to lists
317
331
for data_list , data in zip (
@@ -370,9 +384,9 @@ def list_soils_global(lon, lat):
370
384
]
371
385
soilIDRank_output_pd = pd .concat (soilIDRank_output , axis = 0 ).reset_index (drop = True )
372
386
373
- mucompdata_cond_prob = mucompdata_pd .sort_values (
374
- "distance_score" , ascending = False
375
- ). reset_index ( drop = True )
387
+ mucompdata_cond_prob = mucompdata_pd .sort_values ("distance_score" , ascending = False ). reset_index (
388
+ drop = True
389
+ )
376
390
377
391
# Generate the Rank_Loc column values
378
392
rank_id = 1
@@ -500,16 +514,7 @@ def list_soils_global(lon, lat):
500
514
)
501
515
)
502
516
for row in zip (
503
- ID ,
504
- Site ,
505
- hz_lyrs ,
506
- snd_lyrs ,
507
- cly_lyrs ,
508
- txt_lyrs ,
509
- rf_lyrs ,
510
- cec_lyrs ,
511
- ph_lyrs ,
512
- ec_lyrs
517
+ ID , Site , hz_lyrs , snd_lyrs , cly_lyrs , txt_lyrs , rf_lyrs , cec_lyrs , ph_lyrs , ec_lyrs
513
518
)
514
519
]
515
520
@@ -567,7 +572,7 @@ def rank_soils_global(
567
572
rfvDepth ,
568
573
lab_Color ,
569
574
bedrock ,
570
- cracks
575
+ cracks ,
571
576
):
572
577
# ------------------------------------------------------------------------------------------------
573
578
# ------ Load in user data --------#
@@ -687,9 +692,7 @@ def rank_soils_global(
687
692
688
693
# Construct final dataframe with adjusted data
689
694
p_compname = pd .Series ("sample_pedon" , index = np .arange (len (p_sandpct_intpl )))
690
- p_hz_data = pd .concat (
691
- [p_compname , p_sandpct_intpl , p_claypct_intpl , p_cfg_intpl ], axis = 1
692
- )
695
+ p_hz_data = pd .concat ([p_compname , p_sandpct_intpl , p_claypct_intpl , p_cfg_intpl ], axis = 1 )
693
696
p_hz_data .columns = [
694
697
"compname" ,
695
698
"sandpct_intpl" ,
@@ -1169,12 +1172,9 @@ def rank_soils_global(
1169
1172
and "leptosols" in row ["compname" ].lower ()
1170
1173
):
1171
1174
D_final_loc .at [i , "Score_Data_Loc" ] = 1.001
1172
- elif (
1173
- (bedrock is None or bedrock > 50 )
1174
- and any (
1175
- term in row ["compname" ].lower ()
1176
- for term in ["lithosols" , "leptosols" , "rendzinas" , "rankers" ]
1177
- )
1175
+ elif (bedrock is None or bedrock > 50 ) and any (
1176
+ term in row ["compname" ].lower ()
1177
+ for term in ["lithosols" , "leptosols" , "rendzinas" , "rankers" ]
1178
1178
):
1179
1179
D_final_loc .at [i , "Score_Data_Loc" ] = 0.001
1180
1180
@@ -1243,9 +1243,7 @@ def rank_soils_global(
1243
1243
"Score_Data_Loc" ,
1244
1244
"distance_score" ,
1245
1245
]
1246
- ].fillna (
1247
- 0.0
1248
- )
1246
+ ].fillna (0.0 )
1249
1247
1250
1248
# Construct the output format
1251
1249
Rank = [
@@ -1280,6 +1278,7 @@ def rank_soils_global(
1280
1278
1281
1279
return output_data
1282
1280
1281
+
1283
1282
##################################################################################################
1284
1283
# getSoilGridsGlobal #
1285
1284
##################################################################################################
@@ -1355,7 +1354,9 @@ def sg_list(lon, lat):
1355
1354
# The code assumes each property repeats over the same set of depths.
1356
1355
n_depths = len (df_top_depth )
1357
1356
if len (names ) % n_depths != 0 :
1358
- logging .warning ("Number of property names isn't a multiple of the number of depths. Check data." )
1357
+ logging .warning (
1358
+ "Number of property names isn't a multiple of the number of depths. Check data."
1359
+ )
1359
1360
df_names = pd .DataFrame (names , columns = ["prop" ])
1360
1361
1361
1362
# 5. Combine everything into a single DataFrame.
@@ -1374,7 +1375,7 @@ def sg_list(lon, lat):
1374
1375
index = "bottom_depth" ,
1375
1376
columns = "prop" ,
1376
1377
values = "value" ,
1377
- aggfunc = "first" # Change the aggregator if needed
1378
+ aggfunc = "first" , # Change the aggregator if needed
1378
1379
)
1379
1380
except Exception as e :
1380
1381
logging .error (f"Error pivoting the data: { e } " )
@@ -1427,7 +1428,23 @@ def sg_list(lon, lat):
1427
1428
TAXNWRB_pd .index = [f"Rank{ i + 1 } " for i in range (ranks_needed )]
1428
1429
except Exception as e :
1429
1430
logging .error (f"Error processing WRB classification: { e } " )
1430
- TAXNWRB_pd = pd .DataFrame ({
1431
+ TAXNWRB_pd = pd .DataFrame (
1432
+ {
1433
+ "WRB_tax" : ["" ],
1434
+ "Prob" : ["" ],
1435
+ "Description_en" : ["" ],
1436
+ "Management_en" : ["" ],
1437
+ "Description_es" : ["" ],
1438
+ "Management_es" : ["" ],
1439
+ "Description_ks" : ["" ],
1440
+ "Management_ks" : ["" ],
1441
+ "Description_fr" : ["" ],
1442
+ "Management_fr" : ["" ],
1443
+ }
1444
+ )
1445
+ else :
1446
+ TAXNWRB_pd = pd .DataFrame (
1447
+ {
1431
1448
"WRB_tax" : ["" ],
1432
1449
"Prob" : ["" ],
1433
1450
"Description_en" : ["" ],
@@ -1438,20 +1455,8 @@ def sg_list(lon, lat):
1438
1455
"Management_ks" : ["" ],
1439
1456
"Description_fr" : ["" ],
1440
1457
"Management_fr" : ["" ],
1441
- })
1442
- else :
1443
- TAXNWRB_pd = pd .DataFrame ({
1444
- "WRB_tax" : ["" ],
1445
- "Prob" : ["" ],
1446
- "Description_en" : ["" ],
1447
- "Management_en" : ["" ],
1448
- "Description_es" : ["" ],
1449
- "Management_es" : ["" ],
1450
- "Description_ks" : ["" ],
1451
- "Management_ks" : ["" ],
1452
- "Description_fr" : ["" ],
1453
- "Management_fr" : ["" ],
1454
- })
1458
+ }
1459
+ )
1455
1460
1456
1461
# 12. Gather aggregated values for each property
1457
1462
depths = sg_data_w ["hzdepb_r" ]
@@ -1461,10 +1466,7 @@ def sg_list(lon, lat):
1461
1466
pH_pd = sg_data_w ["phh2o" ]
1462
1467
cec_pd = sg_data_w ["cec" ]
1463
1468
# 13. Additional texture calculations from aggregated values
1464
- texture_pd = pd .DataFrame ({
1465
- "sand" : sand_pd ,
1466
- "clay" : clay_pd
1467
- })
1469
+ texture_pd = pd .DataFrame ({"sand" : sand_pd , "clay" : clay_pd })
1468
1470
texture_pd ["sand" ] = pd .to_numeric (texture_pd ["sand" ], errors = "coerce" )
1469
1471
texture_pd ["clay" ] = pd .to_numeric (texture_pd ["clay" ], errors = "coerce" )
1470
1472
texture_pd ["silt" ] = texture_pd .apply (silt_calc , axis = 1 )
@@ -1530,7 +1532,4 @@ def sg_list(lon, lat):
1530
1532
},
1531
1533
}
1532
1534
1533
- return {
1534
- "metadata" : metadata ,
1535
- "soilGrids" : SoilGrids
1536
- }
1535
+ return {"metadata" : metadata , "soilGrids" : SoilGrids }
0 commit comments