Spaces:
GIZ
/
Running on CPU Upgrade

File size: 7,338 Bytes
b1d15aa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a983dfd
 
 
b1d15aa
 
a983dfd
b1d15aa
a983dfd
 
 
 
 
 
 
b1d15aa
a983dfd
 
b1d15aa
a983dfd
b1d15aa
a983dfd
b1d15aa
 
 
01090e9
 
 
b1d15aa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
167
168
169
170
171
172
173
174
import gradio as gr
from gradio_client import Client, handle_file
import pandas as pd

def get_value(df, colname):
    """Fetch value from WhispAPI-style Column/Value dataframe"""
    if "Column" in df.columns and "Value" in df.columns:
        match = df.loc[df["Column"] == colname, "Value"]
        if not match.empty:
            return match.values[0]
    return "Not available"
    
def format_whisp_statistics(df):
    """Format WhispAPI statistics into readable text for end-users"""
    try:
        # Country code mapping for better display
        country_codes = {
            'HND': 'Honduras',
            'GTM': 'Guatemala', 
            'ECU': 'Ecuador',
            'COL': 'Colombia',
            'PER': 'Peru',
            'BRA': 'Brazil',
            'BOL': 'Bolivia',
            'CRI': 'Costa Rica',
            'PAN': 'Panama',
            'NIC': 'Nicaragua'
        }
        
        country_raw = get_value(df, "Country")
        country = country_codes.get(country_raw, country_raw)
        admin_level = get_value(df, "Admin_Level_1")
        area_raw = get_value(df, "Area")
        
        # Format area with proper rounding and units
        try:
            area_num = float(area_raw)
            if area_num < 1:
                area_text = f"{area_num:.3f} hectares"
            elif area_num < 100:
                area_text = f"{area_num:.2f} hectares"
            else:
                area_text = f"{area_num:,.1f} hectares"
        except:
            area_text = str(area_raw) if area_raw != "Not available" else "Not available"

        risk_level = get_value(df, "risk_level")
        risk_pcrop = get_value(df, "risk_pcrop")
        risk_acrop = get_value(df, "risk_acrop")
        risk_timber = get_value(df, "risk_timber")
        def_after_2020_raw = get_value(df, "TMF_def_after_2020")

        # Helper function to format risk levels with colors/emojis
        def format_risk(risk_val):
            if not risk_val or risk_val in ["Not available", "not available"]:
                return "๐Ÿ” **Not Available** *(Analysis pending)*"
            elif isinstance(risk_val, str):
                risk_lower = risk_val.lower().strip()
                if risk_lower == "low":
                    return "๐ŸŸข **Low Risk**"
                elif risk_lower == "medium":
                    return "๐ŸŸก **Medium Risk**"
                elif risk_lower == "high":
                    return "๐ŸŸ  **High Risk**"
                elif risk_lower == "very high":
                    return "๐Ÿ”ด **Very High Risk**"
                elif risk_lower == "more_info_needed":
                    return "๐Ÿ“Š **Assessment Pending** *(More data needed)*"
                else:
                    return f"โ„น๏ธ **{risk_val.title()}**"
            return str(risk_val)

        # Format deforestation data
        def format_deforestation(def_val):
            if not def_val or def_val in ["Not available", "not available"]:
                return "๐Ÿ” **No Data Available**"
            try:
                def_num = float(def_val)
                if def_num == 0:
                    return "โœ… **No Recent Deforestation Detected**"
                elif def_num < 0.1:
                    return f"โš ๏ธ **{def_num:.3f} hectares detected**"
                else:
                    return f"โš ๏ธ **{def_num:.2f} hectares detected**"
            except:
                return f"โ„น๏ธ **{def_val}**"

        # Create EUDR compliance assessment
        def get_compliance_status(def_after_2020):
            try:
                def_num = float(def_after_2020)
                if def_num == 0:
                    return "โœ… **COMPLIANT** - No recent deforestation detected"
                elif def_num > 0:
                    return "โš ๏ธ **REQUIRES ATTENTION** - Recent deforestation detected"
            except:
                return "๐Ÿ” **ASSESSMENT NEEDED** - Insufficient data for compliance determination"

        deforestation_formatted = format_deforestation(def_after_2020_raw)
        compliance_status = get_compliance_status(def_after_2020_raw)

        output = f"""๐ŸŒ **Geographic Analysis Results**

๐Ÿ“ **Location Details**   
- **Country**: {country}   \n\n
- **Administrative Region**: {admin_level}   \n\n
- **Total Area**: {area_text}  \n\n    

โš ๏ธ **Deforestation Risk Assessment**    
*Risk levels are based on historical patterns, environmental factors, and land use data*    \n\n

- **Overall Risk**: {format_risk(risk_level)}     \n\n
- **Permanent Crops** : {format_risk(risk_pcrop)}    \n\n
  *Coffee, cocoa, palm oil, fruit trees*     \n\n
- **Annual Crops**: {format_risk(risk_acrop)}    \n\n
  *Soy, corn, rice, vegetables* \n\n 
- **Timber Extraction**: {format_risk(risk_timber)}    \n\n
  *Logging and wood harvesting* \n\n 

๐ŸŒณ **EUDR Compliance Analysis**    \n\n 
*Based on Tropical Moist Forest satellite monitoring*     \n\n 

**Recent Deforestation (2020-Present):** {deforestation_formatted}     \n\n 

**EUDR Compliance Status:** {compliance_status}    \n\n 

---
๐Ÿ’ก **Key Insights**
\t **For Suppliers**: {compliance_status.split(' - ')[1] if ' - ' in compliance_status else 'Review compliance requirements carefully'} \n\n 
\t **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 \n\n 
\t **Next Steps**: {"Conduct additional due diligence if recent deforestation is detected" if "ATTENTION" in compliance_status else "Continue monitoring and maintain documentation"} \n\n 
"""
        return output
    except Exception as e:
        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."

def handle_geojson_upload(file):
    """Handle GeoJSON file upload and call WHISP API"""
    if file is not None:
        try:
            # Initialize WHISP API client
            client = Client("https://giz-chatfed-whisp.hf.space/")
            
            # Call the API with the uploaded file
            result = client.predict(
                file=handle_file(file.name),
                api_name="/get_statistics"
            )
            
            # Convert result to DataFrame
            df = pd.DataFrame(result['data'], columns=result['headers'])
            
            # Format statistics into readable text
            formatted_stats = format_whisp_statistics(df)
            
            return (
                formatted_stats,  # Keep formatted statistics for chat
                gr.update(visible=True),  # Keep status visible
                gr.update(visible=False)  # Always hide results table
            )
            
        except Exception as e:
            error_msg = f"โŒ Error processing GeoJSON file: {str(e)}"
            return (
                error_msg,
                gr.update(visible=True),  # upload_status
                gr.update(visible=False)  # results_table
            )
    else:
        return (
            "",
            gr.update(visible=False),  # upload_status
            gr.update(visible=False)   # results_table
        )