Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Soil Analysis Dashboard</title> | |
<!-- Tailwind CSS --> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<!-- Animate.css for UI animations --> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/> | |
<!-- Leaflet CSS --> | |
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" /> | |
<!-- Marked.js for Markdown rendering --> | |
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> | |
<style> | |
/* Custom styles for enhanced UI */ | |
body { | |
background-color: #f0fff4; | |
} | |
#map { | |
height: 400px; | |
} | |
.card { | |
background-color: #ffffff; | |
border: 2px solid #4ade80; | |
border-radius: 0.75rem; | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
} | |
.btn-custom { | |
background-color: #22c55e; | |
border: none; | |
color: white; | |
} | |
.btn-custom:hover { | |
background-color: #16a34a; | |
} | |
.table-custom th, .table-custom td { | |
text-align: center; | |
padding: 0.75rem; | |
} | |
</style> | |
</head> | |
<body class="min-h-screen"> | |
<!-- Navigation Bar --> | |
<div class="container mx-auto my-8 px-4"> | |
<header class="mb-8"> | |
<h1 class="text-5xl font-extrabold text-center text-green-800 animate_animated animate_fadeInDown"> | |
Soil Analysis Dashboard | |
</h1> | |
</header> | |
<!-- Location Selection Card --> | |
<div class="card p-6 mb-8 animate_animated animate_fadeIn"> | |
<h2 class="text-3xl font-bold text-green-700 mb-4">Select Location</h2> | |
<div class="mb-6"> | |
<div class="flex"> | |
<input type="text" id="location-search" class="flex-grow p-3 border border-green-300 rounded-l-md focus:outline-none" placeholder="Search location (e.g., New Delhi)"> | |
<button class="px-4 py-3 bg-green-500 hover:bg-green-600 text-white rounded-r-md" type="button" id="search-btn">Search</button> | |
</div> | |
</div> | |
<div class="flex flex-col md:flex-row gap-6"> | |
<!-- Map Section --> | |
<div class="md:w-2/3"> | |
<div id="map" class="rounded-lg"></div> | |
</div> | |
<!-- Coordinates Input --> | |
<div class="md:w-1/3"> | |
<form id="location-form" class="space-y-4"> | |
<div> | |
<label for="lat" class="block text-lg font-medium text-green-700">Latitude:</label> | |
<input type="text" id="lat" name="lat" class="mt-1 block w-full p-2 border border-green-300 rounded-md" placeholder="Enter latitude"> | |
</div> | |
<div> | |
<label for="lon" class="block text-lg font-medium text-green-700">Longitude:</label> | |
<input type="text" id="lon" name="lon" class="mt-1 block w-full p-2 border border-green-300 rounded-md" placeholder="Enter longitude"> | |
</div> | |
<div class="flex flex-wrap gap-3"> | |
<button type="button" id="current-location" class="px-4 py-2 bg-gray-500 hover:bg-gray-600 text-white rounded-md">Use Current Location</button> | |
<button type="button" id="fetch-report" class="px-4 py-2 bg-green-500 hover:bg-green-600 text-white rounded-md">Fetch Soil Report</button> | |
</div> | |
</form> | |
</div> | |
</div> | |
</div> | |
<!-- Soil Report Section --> | |
<div id="soil-report-section" class="mb-8 hidden animate_animated animate_fadeInUp"> | |
<h2 class="text-4xl font-bold text-green-800 mb-6">Soil Report</h2> | |
<!-- Soil Classification --> | |
<div id="classification-report" class="mb-8"></div> | |
<!-- Soil Properties --> | |
<div id="properties-report" class="mb-8"></div> | |
</div> | |
<!-- Gemini Analysis Section --> | |
<div id="analysis-section" class="mb-8 hidden animate_animated animate_fadeInUp"> | |
<h2 class="text-4xl font-bold text-green-800 mb-6">Soil Analysis & Recommendations</h2> | |
<div class="mb-4"> | |
<label for="language" class="form-label">Response Language</label> | |
<select class="form-control" id="language" name="language" required> | |
<option value="English">English</option> | |
<option value="Hindi">Hindi</option> | |
<option value="Bengali">Bengali</option> | |
<option value="Telugu">Telugu</option> | |
<option value="Marathi">Marathi</option> | |
<option value="Tamil">Tamil</option> | |
<option value="Gujarati">Gujarati</option> | |
<option value="Urdu">Urdu</option> | |
<option value="Kannada">Kannada</option> | |
<option value="Odia">Odia</option> | |
<option value="Malayalam">Malayalam</option> | |
</select> | |
</div> | |
<div class="mb-4"> | |
<button type="button" id="analyze-soil" class="px-6 py-3 btn-custom rounded-md text-lg">Analyze Soil</button> | |
</div> | |
<!-- The analysis-result div is rendered using Markdown --> | |
<div id="analysis-result" class="prose max-w-none"></div> | |
</div> | |
</div> | |
<!-- jQuery --> | |
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> | |
<!-- Leaflet JS --> | |
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script> | |
<script> | |
// Initialize Leaflet map | |
var map = L.map('map').setView([29.25, 76.45], 8); | |
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { | |
attribution: '© OpenStreetMap contributors' | |
}).addTo(map); | |
var marker; | |
// Update latitude and longitude inputs when clicking on the map | |
map.on('click', function(e) { | |
var lat = e.latlng.lat.toFixed(6); | |
var lon = e.latlng.lng.toFixed(6); | |
$('#lat').val(lat); | |
$('#lon').val(lon); | |
if (marker) { | |
marker.setLatLng(e.latlng); | |
} else { | |
marker = L.marker(e.latlng).addTo(map); | |
} | |
}); | |
// Use current geolocation | |
$('#current-location').on('click', function() { | |
if (navigator.geolocation) { | |
navigator.geolocation.getCurrentPosition(function(position) { | |
var lat = position.coords.latitude.toFixed(6); | |
var lon = position.coords.longitude.toFixed(6); | |
$('#lat').val(lat); | |
$('#lon').val(lon); | |
var latlng = L.latLng(lat, lon); | |
map.setView(latlng, 10); | |
if (marker) { | |
marker.setLatLng(latlng); | |
} else { | |
marker = L.marker(latlng).addTo(map); | |
} | |
}); | |
} else { | |
alert("Geolocation is not supported by this browser."); | |
} | |
}); | |
// Location search using OpenStreetMap Nominatim API | |
$('#search-btn').on('click', function() { | |
var query = $('#location-search').val(); | |
if (!query) { | |
alert("Please enter a location to search."); | |
return; | |
} | |
$.ajax({ | |
url: "https://nominatim.openstreetmap.org/search", | |
data: { q: query, format: "json" }, | |
success: function(data) { | |
if (data && data.length > 0) { | |
var lat = parseFloat(data[0].lat).toFixed(6); | |
var lon = parseFloat(data[0].lon).toFixed(6); | |
$('#lat').val(lat); | |
$('#lon').val(lon); | |
var latlng = L.latLng(lat, lon); | |
map.setView(latlng, 10); | |
if (marker) { | |
marker.setLatLng(latlng); | |
} else { | |
marker = L.marker(latlng).addTo(map); | |
} | |
} else { | |
alert("Location not found."); | |
} | |
}, | |
error: function() { | |
alert("Error fetching location data."); | |
} | |
}); | |
}); | |
// Global variables to store soil report data for later analysis | |
window.soilReportData = null; | |
window.currentLat = null; | |
window.currentLon = null; | |
// Fetch soil report from the backend | |
$('#fetch-report').on('click', function() { | |
var lat = $('#lat').val(); | |
var lon = $('#lon').val(); | |
if (!lat || !lon) { | |
alert("Please provide valid latitude and longitude."); | |
return; | |
} | |
$.ajax({ | |
url: '/get_soil_report', | |
method: 'POST', | |
contentType: 'application/json', | |
data: JSON.stringify({ lat: lat, lon: lon }), | |
success: function(response) { | |
// Build Soil Classification HTML | |
var classificationHtml = '<h3 class="text-2xl font-bold text-green-700 mb-4">Soil Classification</h3>'; | |
classificationHtml += '<p class="text-xl mb-2"><span class="font-semibold">Type:</span> ' + response.classification.soil_type + '</p>'; | |
if (response.classification.soil_probabilities.length > 0) { | |
classificationHtml += '<table class="min-w-full table-custom border-collapse mb-4"><thead class="bg-green-100"><tr><th class="border border-green-300">Soil Type</th><th class="border border-green-300">Probability (%)</th></tr></thead><tbody>'; | |
response.classification.soil_probabilities.forEach(function(item) { | |
classificationHtml += '<tr><td class="border border-green-300 p-2">' + item[0] + '</td><td class="border border-green-300 p-2">' + item[1] + '</td></tr>'; | |
}); | |
classificationHtml += '</tbody></table>'; | |
} | |
$('#classification-report').html(classificationHtml); | |
// Build Soil Properties HTML with a Description column | |
var propertiesHtml = '<h3 class="text-2xl font-bold text-green-700 mb-4">Soil Properties</h3>'; | |
propertiesHtml += '<table class="min-w-full table-custom border-collapse mb-4"><thead class="bg-green-100"><tr><th class="border border-green-300">Parameter</th><th class="border border-green-300">Value</th><th class="border border-green-300">Unit</th><th class="border border-green-300">Description</th></tr></thead><tbody>'; | |
response.properties.forEach(function(prop) { | |
propertiesHtml += '<tr><td class="border border-green-300 p-2">' + prop.parameter + '</td><td class="border border-green-300 p-2">' + prop.value + '</td><td class="border border-green-300 p-2">' + prop.unit + '</td><td class="border border-green-300 p-2">' + prop.description + '</td></tr>'; | |
}); | |
propertiesHtml += '</tbody></table>'; | |
$('#properties-report').html(propertiesHtml); | |
// Store report data for later analysis and reveal the report section | |
window.soilReportData = response; | |
window.currentLat = lat; | |
window.currentLon = lon; | |
$('#soil-report-section').removeClass('hidden'); | |
$('#analysis-section').removeClass('hidden'); | |
}, | |
error: function() { | |
alert("Error fetching soil report. Please try again."); | |
} | |
}); | |
}); | |
// Analyze soil and render Gemini analysis response in Markdown | |
$('#analyze-soil').on('click', function() { | |
if (!window.soilReportData) { | |
alert("Please fetch the soil report first."); | |
return; | |
} | |
var requestData = { | |
soil_report: window.soilReportData, | |
lat: window.currentLat, | |
lon: window.currentLon, | |
language: $('#language').val() // Include selected language in the request | |
}; | |
$.ajax({ | |
url: '/analyze_soil', | |
method: 'POST', | |
contentType: 'application/json', | |
data: JSON.stringify(requestData), | |
success: function(response) { | |
var analysisText = response.analysis; | |
// Ensure the response is treated as Markdown | |
var renderedHTML = marked.parse(analysisText); | |
$('#analysis-result').html(renderedHTML); | |
}, | |
error: function() { | |
alert("Error analyzing soil data. Please try again."); | |
} | |
}); | |
}); | |
</script> | |
</body> | |
</html> |