Spaces:
GIZ
/
Running on CPU Upgrade

File size: 7,301 Bytes
b1d15aa
 
 
 
 
941faf0
 
 
 
 
 
 
 
 
b1d15aa
 
 
 
c0ec585
b1d15aa
 
 
 
 
 
 
 
 
 
 
aa07338
b1d15aa
 
aa07338
b1d15aa
 
 
 
 
 
 
 
 
 
 
 
c0ec585
b1d15aa
c0ec585
b1d15aa
c0ec585
b1d15aa
c0ec585
b1d15aa
 
 
 
 
 
aa07338
b1d15aa
 
 
 
c0ec585
b1d15aa
 
 
c0ec585
b1d15aa
c0ec585
b1d15aa
c0ec585
b1d15aa
c0ec585
b1d15aa
c0ec585
b1d15aa
 
 
 
 
 
 
c0ec585
b1d15aa
 
 
aa07338
b1d15aa
aa07338
b1d15aa
aa07338
b1d15aa
 
 
aa07338
 
 
 
 
 
 
 
 
 
 
 
 
b1d15aa
aa07338
b1d15aa
4a66b7a
37c2e4c
c0ec585
b1d15aa
c0ec585
b1d15aa
c0ec585
 
 
 
b1d15aa
c0ec585
4a66b7a
b1d15aa
c0ec585
 
 
 
 
 
 
57ad147
aa07338
 
b1d15aa
 
 
 
 
 
 
941faf0
 
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
175
176
177
178
179
180
181
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

    Params
    ---------

    df: dataframe with statistical info from whisp api
    colname: column name for which value need be fetched
    
    """
    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 "No disponible"
    
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': 'Brasil',
            'BOL': 'Bolivia',
            'CRI': 'Costa Rica',
            'PAN': 'Panamá',
            '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} hectáreas"
            elif area_num < 100:
                area_text = f"{area_num:.2f} hectáreas"
            else:
                area_text = f"{area_num:,.1f} hectáreas"
        except:
            area_text = str(area_raw) if area_raw != "Not available" else "No disponible"

        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")
        def_before_2020_raw = get_value(df, "TMF_def_before_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 "**No disponible**"
            elif isinstance(risk_val, str):
                risk_lower = risk_val.lower().strip()
                if risk_lower == "low":
                    return "🟢 *riesgo bajo*"
                elif risk_lower == "medium":
                    return "🟡 *riesgo medio*"
                elif risk_lower == "high":
                    return "🟠 *riesgo alto*"
                elif risk_lower == "very high":
                    return "🔴 *riesgo muy alto*"
                elif risk_lower == "more_info_needed":
                    return "*❓Se necesita más información.*"
                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 disponible*"
            try:
                def_num = float(def_val)
                if def_num == 0:
                    return "* 🌳 No se detectó deforestación.*"
                elif def_num < 0.1:
                    return f"🌳 *{def_num:.3f} hectáreas de deforestación*"
                else:
                    return f" 🌳*{def_num:.2f} hectáreas de deforestación*"
            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 "**No se detectó deforestación después de 2020.**"
        #         elif def_num > 0:
        #             return "**Deforestación reciente detectada**"
        #     except:
        #         return "**Datos insuficientes para determinar el cumplimiento"

        deforestation_after_2020_formatted = format_deforestation(def_after_2020_raw)
        deforestation_before_2020_formatted = format_deforestation(def_before_2020_raw)

        # compliance_status = get_compliance_status(def_after_2020_raw)

        output = f""" **Respuesta generada mediante inteligencia artificíal:** \n\n
        
**Resultados del análisis geográfico**  \n\n

La siguiente información ha sido generada por la [WhispAPI creada por Forest Data Partnership (FDaP)](https://openforis.org/solutions/whisp/).

📍 **Detalles de la ubicación**   
- **País**: {country}   \n\n
- **Región administrativa**: {admin_level}   \n\n
- **Área total**: {area_text}  \n\n    

⚠️ **Evaluación del riesgo de deforestación**    
*Los niveles de riesgo se basan en patrones históricos, factores ambientales y datos sobre el uso del suelo.*    \n\n

**Cultivos permanentes** (Café, cacao, aceite de palma, árboles frutales):  \n\n
- {format_risk(risk_pcrop)} \n\n
**Cultivos anuales** (Soja, maíz, arroz, verduras):  \n\n
- {format_risk(risk_acrop)}    \n\n
**Extracción de madera** (Tala y recolección de madera):  \n\n
- {format_risk(risk_timber)}    \n\n

**Deforestación:** \n\n
- {deforestation_before_2020_formatted} detectadas antes de 2020.  \n\n 
- {deforestation_after_2020_formatted} detectadas después de 2020.  \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 through the chatfed-whisp spaces. The API token is taken care by chatfed-whisp
    space """
    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
        )