Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
formatting changes
Browse files
app.py
CHANGED
@@ -35,59 +35,127 @@ def get_value(df, colname):
|
|
35 |
def format_whisp_statistics(df):
|
36 |
"""Format WhispAPI statistics into readable text for end-users"""
|
37 |
try:
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
admin_level = get_value(df, "Admin_Level_1")
|
40 |
-
|
|
|
|
|
41 |
try:
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
44 |
except:
|
45 |
-
area_text = str(
|
46 |
|
47 |
risk_level = get_value(df, "risk_level")
|
48 |
risk_pcrop = get_value(df, "risk_pcrop")
|
49 |
risk_acrop = get_value(df, "risk_acrop")
|
50 |
risk_timber = get_value(df, "risk_timber")
|
51 |
-
|
52 |
|
53 |
-
# Helper function to format risk levels
|
54 |
def format_risk(risk_val):
|
55 |
-
if
|
56 |
-
|
57 |
-
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
return str(risk_val)
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
- **Country**: {country}
|
65 |
- **Administrative Region**: {admin_level}
|
66 |
- **Total Area**: {area_text}
|
67 |
|
68 |
-
## ⚠️ **Risk Assessment**
|
69 |
-
*Risk levels
|
70 |
|
71 |
-
- **Overall
|
72 |
-
- **Permanent
|
73 |
-
*
|
74 |
-
- **Annual
|
75 |
-
*
|
76 |
-
- **Timber
|
77 |
-
*
|
78 |
|
79 |
-
## 🌳 **
|
80 |
-
*
|
81 |
|
82 |
-
|
83 |
-
|
|
|
84 |
|
85 |
---
|
86 |
-
💡 **
|
|
|
|
|
|
|
|
|
87 |
"""
|
88 |
return output
|
89 |
except Exception as e:
|
90 |
-
return f"❌ Error
|
91 |
|
92 |
def handle_geojson_upload(file):
|
93 |
"""Handle GeoJSON file upload and call WHISP API"""
|
|
|
35 |
def format_whisp_statistics(df):
|
36 |
"""Format WhispAPI statistics into readable text for end-users"""
|
37 |
try:
|
38 |
+
# Country code mapping for better display
|
39 |
+
country_codes = {
|
40 |
+
'HND': 'Honduras',
|
41 |
+
'GTM': 'Guatemala',
|
42 |
+
'ECU': 'Ecuador',
|
43 |
+
'COL': 'Colombia',
|
44 |
+
'PER': 'Peru',
|
45 |
+
'BRA': 'Brazil',
|
46 |
+
'BOL': 'Bolivia',
|
47 |
+
'CRI': 'Costa Rica',
|
48 |
+
'PAN': 'Panama',
|
49 |
+
'NIC': 'Nicaragua'
|
50 |
+
}
|
51 |
+
|
52 |
+
country_raw = get_value(df, "Country")
|
53 |
+
country = country_codes.get(country_raw, country_raw)
|
54 |
admin_level = get_value(df, "Admin_Level_1")
|
55 |
+
area_raw = get_value(df, "Area")
|
56 |
+
|
57 |
+
# Format area with proper rounding and units
|
58 |
try:
|
59 |
+
area_num = float(area_raw)
|
60 |
+
if area_num < 1:
|
61 |
+
area_text = f"{area_num:.3f} hectares"
|
62 |
+
elif area_num < 100:
|
63 |
+
area_text = f"{area_num:.2f} hectares"
|
64 |
+
else:
|
65 |
+
area_text = f"{area_num:,.1f} hectares"
|
66 |
except:
|
67 |
+
area_text = str(area_raw) if area_raw != "Not available" else "Not available"
|
68 |
|
69 |
risk_level = get_value(df, "risk_level")
|
70 |
risk_pcrop = get_value(df, "risk_pcrop")
|
71 |
risk_acrop = get_value(df, "risk_acrop")
|
72 |
risk_timber = get_value(df, "risk_timber")
|
73 |
+
def_after_2020_raw = get_value(df, "TMF_def_after_2020")
|
74 |
|
75 |
+
# Helper function to format risk levels with colors/emojis
|
76 |
def format_risk(risk_val):
|
77 |
+
if not risk_val or risk_val in ["Not available", "not available"]:
|
78 |
+
return "🔍 **Not Available** *(Analysis pending)*"
|
79 |
+
elif isinstance(risk_val, str):
|
80 |
+
risk_lower = risk_val.lower().strip()
|
81 |
+
if risk_lower == "low":
|
82 |
+
return "🟢 **Low Risk**"
|
83 |
+
elif risk_lower == "medium":
|
84 |
+
return "🟡 **Medium Risk**"
|
85 |
+
elif risk_lower == "high":
|
86 |
+
return "🟠 **High Risk**"
|
87 |
+
elif risk_lower == "very high":
|
88 |
+
return "🔴 **Very High Risk**"
|
89 |
+
elif risk_lower == "more_info_needed":
|
90 |
+
return "📊 **Assessment Pending** *(More data needed)*"
|
91 |
+
else:
|
92 |
+
return f"ℹ️ **{risk_val.title()}**"
|
93 |
return str(risk_val)
|
94 |
|
95 |
+
# Format deforestation data
|
96 |
+
def format_deforestation(def_val):
|
97 |
+
if not def_val or def_val in ["Not available", "not available"]:
|
98 |
+
return "🔍 **No Data Available**"
|
99 |
+
try:
|
100 |
+
def_num = float(def_val)
|
101 |
+
if def_num == 0:
|
102 |
+
return "✅ **No Recent Deforestation Detected**"
|
103 |
+
elif def_num < 0.1:
|
104 |
+
return f"⚠️ **{def_num:.3f} hectares detected**"
|
105 |
+
else:
|
106 |
+
return f"⚠️ **{def_num:.2f} hectares detected**"
|
107 |
+
except:
|
108 |
+
return f"ℹ️ **{def_val}**"
|
109 |
+
|
110 |
+
# Create EUDR compliance assessment
|
111 |
+
def get_compliance_status(def_after_2020):
|
112 |
+
try:
|
113 |
+
def_num = float(def_after_2020)
|
114 |
+
if def_num == 0:
|
115 |
+
return "✅ **COMPLIANT** - No recent deforestation detected"
|
116 |
+
elif def_num > 0:
|
117 |
+
return "⚠️ **REQUIRES ATTENTION** - Recent deforestation detected"
|
118 |
+
except:
|
119 |
+
return "🔍 **ASSESSMENT NEEDED** - Insufficient data for compliance determination"
|
120 |
+
|
121 |
+
deforestation_formatted = format_deforestation(def_after_2020_raw)
|
122 |
+
compliance_status = get_compliance_status(def_after_2020_raw)
|
123 |
+
|
124 |
+
output = f"""🌍 **Geographic Analysis Results**
|
125 |
+
|
126 |
+
## 📍 **Location Details**
|
127 |
- **Country**: {country}
|
128 |
- **Administrative Region**: {admin_level}
|
129 |
- **Total Area**: {area_text}
|
130 |
|
131 |
+
## ⚠️ **Deforestation Risk Assessment**
|
132 |
+
*Risk levels are based on historical patterns, environmental factors, and land use data*
|
133 |
|
134 |
+
- **Overall Risk**: {format_risk(risk_level)}
|
135 |
+
- **Permanent Crops**: {format_risk(risk_pcrop)}
|
136 |
+
*Coffee, cocoa, palm oil, fruit trees*
|
137 |
+
- **Annual Crops**: {format_risk(risk_acrop)}
|
138 |
+
*Soy, corn, rice, vegetables*
|
139 |
+
- **Timber Extraction**: {format_risk(risk_timber)}
|
140 |
+
*Logging and wood harvesting*
|
141 |
|
142 |
+
## 🌳 **EUDR Compliance Analysis**
|
143 |
+
*Based on Tropical Moist Forest satellite monitoring*
|
144 |
|
145 |
+
**Recent Deforestation (2020-Present):** {deforestation_formatted}
|
146 |
+
|
147 |
+
**EUDR Compliance Status:** {compliance_status}
|
148 |
|
149 |
---
|
150 |
+
### 💡 **Key Insights**
|
151 |
+
|
152 |
+
- **For Suppliers**: {compliance_status.split(' - ')[1] if ' - ' in compliance_status else 'Review compliance requirements carefully'}
|
153 |
+
- **Risk Factors**: Focus on {', '.join([t.split('*')[1].strip('*') for t in [risk_pcrop, risk_acrop, risk_timber] if 'High' in format_risk(t)])} if any high-risk activities detected
|
154 |
+
- **Next Steps**: {"Conduct additional due diligence if recent deforestation is detected" if "ATTENTION" in compliance_status else "Continue monitoring and maintain documentation"}
|
155 |
"""
|
156 |
return output
|
157 |
except Exception as e:
|
158 |
+
return f"❌ **Analysis Error**\n\nUnable to process the geographic data: {str(e)}\n\n📋 **Troubleshooting:**\n- Verify your GeoJSON file format\n- Check file size (should be < 10MB)\n- Ensure coordinates are valid\n\nPlease try uploading again or contact support."
|
159 |
|
160 |
def handle_geojson_upload(file):
|
161 |
"""Handle GeoJSON file upload and call WHISP API"""
|