Wall06 commited on
Commit
b87b2ad
·
verified ·
1 Parent(s): d1a9828

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -121
app.py CHANGED
@@ -5,160 +5,142 @@ import plotly.express as px
5
  import qrcode
6
  from io import BytesIO
7
 
8
- # --- CALCULATION LOGIC --- #
9
- def calculate_risk(water, land, noise):
10
- score = 0
11
-
12
- # Water Quality
13
- if water == "Clean":
14
- score += 1
15
- elif water == "Moderate":
16
- score += 2
17
- else:
18
- score += 3
19
-
20
- # Land Disturbance
21
- if land == "Low":
22
- score += 1
23
- elif land == "Medium":
24
- score += 2
25
- else:
26
- score += 3
27
-
28
- # Noise Level
29
- if noise == "Low":
30
- score += 1
31
- elif noise == "Medium":
32
- score += 2
33
- else:
34
- score += 3
35
-
36
- if score <= 4:
37
- return score, "Low Risk"
38
- elif score <= 6:
39
- return score, "Moderate Risk"
40
- else:
41
- return score, "High Risk"
42
 
 
 
 
43
 
44
- # --- MAIN PROCESSING FUNCTION --- #
45
- def analyze_biodiversity(water, land, noise, species, habitat):
46
-
47
- # ------- Fetch Species Summary (Wikipedia API) ------- #
48
  wiki_url = "https://en.wikipedia.org/w/api.php"
49
  params = {
50
  "action": "query",
51
  "format": "json",
52
  "prop": "extracts",
53
- "titles": species.replace(" ", "_"),
54
- "explaintext": True,
55
  }
56
- res = requests.get(wiki_url, params=params).json()
57
- pages = res.get("query", {}).get("pages", {})
 
58
  page = next(iter(pages.values()))
59
- extract = page.get("extract", "")
60
 
61
- # Ensure 200+ words
 
 
62
  words = extract.split()
63
  if len(words) < 200:
64
- extract = extract + " " + (
65
- "This species plays an essential ecological role in its habitat. "
66
- "Environmental pressures such as water pollution, land disturbance, and noise "
67
- "can significantly affect its survival and reproductive behavior. "
68
- ) * 10
69
-
70
- summary = " ".join(extract.split()[:350])
71
-
72
-
73
- # ------- Calculate Impact Score ------- #
74
- score, level = calculate_risk(water, land, noise)
75
-
76
- impact_text = f"""
77
- ### 🌿 Environmental Impact Assessment
78
- **Species:** {species}
79
- **Habitat:** {habitat}
80
-
81
- The environmental parameters you entered indicate a **{level}** biodiversity risk level (Score: {score}/9).
82
- Water quality, land disturbance, and noise levels directly influence population survival, reproduction, food availability, and mobility of **{species}**.
83
-
84
- Based on the current inputs, the habitat stability for this species is **{level.lower()}**, meaning that conservation attention is **{'critical' if level=='High Risk' else 'recommended'}**.
85
-
86
- This assessment is combined with scientific information retrieved from public ecological databases.
87
  """
88
 
 
 
 
 
 
 
 
 
89
 
90
- # ------- Fetch Occurrence Map (GBIF API) ------- #
91
- gbif_url = f"https://api.gbif.org/v1/occurrence/search?scientificName={species}&limit=200"
92
- gbif_data = requests.get(gbif_url).json()
93
- records = gbif_data.get("results", [])
 
94
 
95
- if records:
96
- df = pd.DataFrame([
97
- {"lat": rec.get("decimalLatitude"), "lon": rec.get("decimalLongitude")}
98
- for rec in records if rec.get("decimalLatitude") and rec.get("decimalLongitude")
99
- ])
100
- fig = px.scatter_mapbox(df, lat="lat", lon="lon", height=380, zoom=1)
101
  fig.update_layout(mapbox_style="open-street-map")
102
  else:
103
  fig = None
104
 
105
-
106
- # ------- QR Code ------- #
 
 
 
107
  qr_img = BytesIO()
108
- qr_data = f"BioVigilus Report\nSpecies: {species}\nHabitat: {habitat}\nRisk Level: {level}"
109
- qrcode.make(qr_data).save(qr_img)
110
  qr_img.seek(0)
111
 
 
112
 
113
- # Final combined output
114
- full_summary = impact_text + "\n\n### 📘 Species Summary\n" + summary
115
-
116
- return full_summary, fig, qr_img
117
-
118
-
119
-
120
-
121
- # ---------------- UI (BEAUTIFUL) ---------------- #
122
 
123
  css = """
124
- body {background:#E8F6F3;}
125
- .gr-box {border-radius:20px; box-shadow:0 4px 15px rgba(0,0,0,0.1); padding:15px;}
126
- .gr-button {background:#1B7F5F; color:white; border-radius:14px; font-weight:bold;}
127
- .gr-button:hover {background:#26A27D;}
 
 
 
 
 
 
 
 
 
 
128
  """
129
 
130
- with gr.Blocks(css=css) as demo:
131
- gr.Markdown("<h1 style='text-align:center;color:#1B7F5F;'>🌱 BioVigilus</h1>")
132
- gr.Markdown("<p style='text-align:center;color:#444;'>Latin Name • Environmental Biodiversity Intelligence</p>")
133
 
134
- with gr.Box():
135
- gr.Markdown("## Enter Environmental Parameters")
136
 
137
- with gr.Row():
138
- water = gr.Dropdown(["Clean", "Moderate", "Polluted"], label="Water Quality")
139
- land = gr.Dropdown(["Low", "Medium", "High"], label="Land Disturbance")
140
- noise = gr.Dropdown(["Low", "Medium", "High"], label="Noise Level")
141
 
142
- with gr.Row():
143
- species = gr.Textbox(label="Species Name", placeholder="e.g., Panthera tigris")
144
- habitat = gr.Textbox(label="Habitat Type", placeholder="e.g., Tropical Forest, Grassland")
 
145
 
146
- process = gr.Button("Generate Biodiversity Analysis")
 
 
147
 
148
- with gr.Row():
149
- with gr.Column(scale=3):
150
- full_out = gr.Markdown(label="Full Environmental + Species Report")
151
-
152
- with gr.Column(scale=2):
153
- map_out = gr.Plot(label="Species Distribution Map")
154
-
155
- with gr.Column(scale=1):
156
- qr_out = gr.Image(label="QR Code")
157
-
158
- process.click(
159
- analyze_biodiversity,
160
- inputs=[water, land, noise, species, habitat],
161
- outputs=[full_out, map_out, qr_out]
162
  )
163
 
164
  demo.launch()
 
5
  import qrcode
6
  from io import BytesIO
7
 
8
+ # ================================================================
9
+ # Helper Function: Species Summary + Map + QR Code
10
+ # ================================================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ def process_species_data(species_name, habitat, water_disturbance, land_disturbance, noise_level):
13
+ if not species_name:
14
+ return "Please enter a species name.", None, None
15
 
16
+ # ======================
17
+ # 1. Fetch Wikipedia Summary (Full Extract)
18
+ # ======================
 
19
  wiki_url = "https://en.wikipedia.org/w/api.php"
20
  params = {
21
  "action": "query",
22
  "format": "json",
23
  "prop": "extracts",
24
+ "titles": species_name.replace(" ", "_"),
25
+ "explaintext": True
26
  }
27
+
28
+ response = requests.get(wiki_url, params=params).json()
29
+ pages = response.get("query", {}).get("pages", {})
30
  page = next(iter(pages.values()))
 
31
 
32
+ extract = page.get("extract", "No summary available for this species.")
33
+
34
+ # Ensure at least 200 words
35
  words = extract.split()
36
  if len(words) < 200:
37
+ extract += "\n\n" + (
38
+ "This species plays a crucial ecological role, influencing biodiversity, habitat structure, "
39
+ "and environmental balance. Its presence often reflects the health of local ecosystems, and "
40
+ "changes in population trends can indicate environmental stress. Conservation efforts are "
41
+ "frequently focused on such species due to their importance in maintaining natural stability. "
42
+ * 3
43
+ )
44
+
45
+ summary = " ".join(words[:350]) # around 300–350 words
46
+
47
+ # Add environmental interpretation
48
+ summary += f"""
49
+
50
+ Environmental Impact Assessment (Based on User Inputs):
51
+ - Water Disturbance Level: {water_disturbance}/100
52
+ - Land Disturbance Level: {land_disturbance}/100
53
+ - Noise Level: {noise_level}/100
54
+ - Habitat Type: {habitat}
55
+
56
+ Higher disturbance values indicate increased pressure on this species' survival and reproduction.
 
 
 
57
  """
58
 
59
+ # ======================
60
+ # 2. Fetch GBIF Occurrence Data (Map API)
61
+ # ======================
62
+ gbif_url = f"https://api.gbif.org/v1/occurrence/search?scientificName={species_name}&limit=200"
63
+ gbif_res = requests.get(gbif_url).json()
64
+
65
+ results = gbif_res.get("results", [])
66
+ coords = []
67
 
68
+ for r in results:
69
+ lat = r.get("decimalLatitude")
70
+ lon = r.get("decimalLongitude")
71
+ if lat and lon:
72
+ coords.append({"lat": lat, "lon": lon})
73
 
74
+ if coords:
75
+ df = pd.DataFrame(coords)
76
+ fig = px.scatter_mapbox(df, lat="lat", lon="lon", zoom=1, height=400)
 
 
 
77
  fig.update_layout(mapbox_style="open-street-map")
78
  else:
79
  fig = None
80
 
81
+ # ======================
82
+ # 3. QR Code Generator
83
+ # ======================
84
+ qr_data = f"BioVigilus Report\nSpecies: {species_name}\nHabitat: {habitat}\nSummary: {summary[:150]}..."
85
+
86
  qr_img = BytesIO()
87
+ qr = qrcode.make(qr_data)
88
+ qr.save(qr_img)
89
  qr_img.seek(0)
90
 
91
+ return summary, fig, qr_img
92
 
93
+ # ================================================================
94
+ # Custom CSS for Beautiful UI
95
+ # ================================================================
 
 
 
 
 
 
96
 
97
  css = """
98
+ body { background-color: #f2f7f4 !important; }
99
+ .gradio-container { font-family: 'Poppins', sans-serif; }
100
+
101
+ h1 {
102
+ color: #2e7d32 !important;
103
+ font-weight: 700;
104
+ }
105
+
106
+ .custom-box {
107
+ background: white;
108
+ padding: 20px;
109
+ border-radius: 15px;
110
+ box-shadow: 0 4px 15px rgba(0,0,0,0.1);
111
+ }
112
  """
113
 
114
+ # ================================================================
115
+ # Gradio UI (Corrected for v4)
116
+ # ================================================================
117
 
118
+ with gr.Blocks() as demo:
119
+ demo.load_css(css)
120
 
121
+ gr.Markdown("<h1 style='text-align:center;'>🌿 BioVigilus — Biodiversity Impact Analyzer</h1>")
122
+ gr.Markdown("<p style='text-align:center; font-size:18px;'>Analyze species, habitats, and environmental stress factors with real-time data.</p>")
 
 
123
 
124
+ with gr.Row():
125
+ with gr.Column(elem_classes="custom-box"):
126
+ species_name = gr.Textbox(label="Species Name", placeholder="e.g., Panthera tigris")
127
+ habitat = gr.Textbox(label="Habitat Type", placeholder="Forest / Grassland / Wetland")
128
 
129
+ water = gr.Slider(0, 100, label="Water Disturbance Level")
130
+ land = gr.Slider(0, 100, label="Land Disturbance Level")
131
+ noise = gr.Slider(0, 100, label="Noise Level")
132
 
133
+ analyze_btn = gr.Button("Analyze", variant="primary")
134
+
135
+ with gr.Column(elem_classes="custom-box"):
136
+ summary_output = gr.Textbox(label="Species Summary", lines=15)
137
+ map_output = gr.Plot(label="Distribution Map")
138
+ qr_output = gr.Image(label="QR Code")
139
+
140
+ analyze_btn.click(
141
+ process_species_data,
142
+ inputs=[species_name, habitat, water, land, noise],
143
+ outputs=[summary_output, map_output, qr_output]
 
 
 
144
  )
145
 
146
  demo.launch()