|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8" /> |
|
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
|
<title>Pest Outbreak Prediction System</title> |
|
|
|
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" /> |
|
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" /> |
|
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css" /> |
|
<style> |
|
body { |
|
background: #f2f2f2; |
|
margin: 0; |
|
padding: 0; |
|
} |
|
.container-custom { |
|
max-width: 1200px; |
|
margin: 2rem auto; |
|
padding: 1rem; |
|
background: #ffffff; |
|
border-radius: 8px; |
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1); |
|
} |
|
#map { |
|
height: 400px; |
|
border-radius: 0.75rem; |
|
box-shadow: 0 8px 16px rgba(0,0,0,0.1); |
|
} |
|
.form-section { |
|
background: #ffffff; |
|
border-radius: 0.75rem; |
|
box-shadow: 0 8px 16px rgba(0,0,0,0.1); |
|
padding: 2rem; |
|
margin-bottom: 1.5rem; |
|
transition: transform 0.3s ease, box-shadow 0.3s ease; |
|
} |
|
.form-section:hover { |
|
transform: translateY(-4px); |
|
box-shadow: 0 12px 24px rgba(0,0,0,0.15); |
|
} |
|
h1, h4 { |
|
color: #2e7d32; |
|
text-align: center; |
|
} |
|
|
|
.weather-card { |
|
background: #ffffff; |
|
border-radius: 0.5rem; |
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1); |
|
padding: 1rem; |
|
text-align: center; |
|
transition: transform 0.2s; |
|
} |
|
.weather-card:hover { |
|
transform: translateY(-4px); |
|
} |
|
.weather-title { |
|
font-weight: 600; |
|
color: #2e7d32; |
|
margin-bottom: 0.5rem; |
|
} |
|
|
|
#soilPropertiesTable table { |
|
width: 100%; |
|
border-collapse: collapse; |
|
} |
|
#soilPropertiesTable th, #soilPropertiesTable td { |
|
padding: 0.75rem; |
|
border: 1px solid #e2e8f0; |
|
text-align: center; |
|
} |
|
#soilPropertiesTable th { |
|
background-color: #81c784; |
|
color: #fff; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="container container-custom py-8"> |
|
<h1 class="text-4xl font-bold mb-8">Pest Outbreak Prediction System</h1> |
|
|
|
<form id="farmForm" action="/predict" method="post"> |
|
|
|
<div class="form-section"> |
|
<h4 class="text-2xl font-semibold mb-4">Select Farm Location</h4> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> |
|
|
|
<div> |
|
<div id="map"></div> |
|
</div> |
|
|
|
<div class="flex flex-col justify-center space-y-4 p-4"> |
|
<div> |
|
<label class="font-medium" for="manual_lat">Latitude:</label> |
|
<input type="number" step="0.000001" id="manual_lat" class="form-control" placeholder="Enter latitude" /> |
|
</div> |
|
<div> |
|
<label class="font-medium" for="manual_lon">Longitude:</label> |
|
<input type="number" step="0.000001" id="manual_lon" class="form-control" placeholder="Enter longitude" /> |
|
</div> |
|
<button type="button" id="updateLocationBtn" class="btn btn-primary shadow-md hover:shadow-lg transition duration-300"> |
|
Update Location |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<input type="hidden" id="latitude" name="latitude" /> |
|
<input type="hidden" id="longitude" name="longitude" /> |
|
</div> |
|
|
|
|
|
<div class="form-section"> |
|
<h4 class="text-2xl font-semibold mb-4">Weather Data</h4> |
|
<div id="weatherDataContainer" class="grid grid-cols-1 md:grid-cols-4 gap-4"> |
|
<div class="col-span-full text-center text-gray-600"> |
|
Weather data will appear here after you select or update a location. |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
|
|
<div class="form-section"> |
|
<h4 class="text-2xl font-semibold mb-4">Additional Agricultural Inputs</h4> |
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4"> |
|
<div> |
|
<label class="font-medium" for="crop_type">Crop Type:</label> |
|
<select class="form-control" id="crop_type" name="crop_type"> |
|
<option value="rice">Rice</option> |
|
<option value="wheat">Wheat</option> |
|
<option value="maize">Maize</option> |
|
<option value="cotton">Cotton</option> |
|
<option value="sugarcane">Sugarcane</option> |
|
<option value="soybean">Soybean</option> |
|
<option value="millet">Millet</option> |
|
<option value="pulses">Pulses</option> |
|
<option value="potato">Potato</option> |
|
<option value="tomato">Tomato</option> |
|
<option value="onion">Onion</option> |
|
<option value="garlic">Garlic</option> |
|
<option value="groundnut">Groundnut</option> |
|
<option value="barley">Barley</option> |
|
<option value="jute">Jute</option> |
|
<option value="tea">Tea</option> |
|
<option value="coffee">Coffee</option> |
|
<option value="sorghum">Sorghum</option> |
|
<option value="turmeric">Turmeric</option> |
|
<option value="ginger">Ginger</option> |
|
</select> |
|
</div> |
|
<div> |
|
<label class="font-medium" for="sowing_date">Plant Sowing Date:</label> |
|
<input type="date" class="form-control" id="sowing_date" name="sowing_date" /> |
|
</div> |
|
<div> |
|
<label class="font-medium" for="harvest_date">Expected Harvest Date:</label> |
|
<input type="date" class="form-control" id="harvest_date" name="harvest_date" /> |
|
</div> |
|
<div> |
|
<label class="font-medium" for="growth_stage">Current Growth Stage:</label> |
|
<select class="form-control" id="growth_stage" name="growth_stage"> |
|
<option value="sowing">Sowing</option> |
|
<option value="germination">Germination</option> |
|
<option value="vegetative">Vegetative</option> |
|
<option value="flowering">Flowering</option> |
|
<option value="fruiting">Fruiting</option> |
|
<option value="harvest">Harvest</option> |
|
</select> |
|
</div> |
|
<div> |
|
<label class="font-medium" for="irrigation_freq">Irrigation Frequency:</label> |
|
<select class="form-control" id="irrigation_freq" name="irrigation_freq"> |
|
<option value="daily">Daily</option> |
|
<option value="alternate">Alternate Day</option> |
|
<option value="twice_week">Twice a Week</option> |
|
<option value="weekly">Weekly</option> |
|
</select> |
|
</div> |
|
<div> |
|
<label class="font-medium" for="irrigation_method">Irrigation Method:</label> |
|
<select class="form-control" id="irrigation_method" name="irrigation_method"> |
|
<option value="drip">Drip</option> |
|
<option value="sprinkler">Sprinkler</option> |
|
<option value="flood">Flood</option> |
|
<option value="manual">Manual</option> |
|
</select> |
|
</div> |
|
<div> |
|
<label class="font-medium" for="soil_type">Soil Type:</label> |
|
<select class="form-control" id="soil_type" name="soil_type"> |
|
<option value="red">Red</option> |
|
<option value="black">Black</option> |
|
<option value="clay">Clay</option> |
|
<option value="sandy">Sandy</option> |
|
<option value="loamy">Loamy</option> |
|
</select> |
|
</div> |
|
<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> |
|
</div> |
|
|
|
|
|
<input type="hidden" id="max_temp_hidden" name="max_temp" /> |
|
<input type="hidden" id="min_temp_hidden" name="min_temp" /> |
|
<input type="hidden" id="current_temp_hidden" name="current_temp" /> |
|
<input type="hidden" id="humidity_hidden" name="humidity" /> |
|
<input type="hidden" id="rainfall_hidden" name="rain" /> |
|
<input type="hidden" id="soil_moisture_hidden" name="soil_moisture" /> |
|
<input type="hidden" id="wind_speed_hidden" name="wind_speed" /> |
|
<input type="hidden" id="cloud_cover_hidden" name="cloud_cover" /> |
|
|
|
<div class="form-section text-center"> |
|
<button type="submit" class="btn btn-success btn-lg shadow-xl transform hover:scale-105 transition duration-300"> |
|
Predict Pest Outbreak |
|
</button> |
|
</div> |
|
</form> |
|
</div> |
|
|
|
|
|
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> |
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script> |
|
|
|
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script> |
|
|
|
<script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script> |
|
<script> |
|
|
|
var map = L.map('map').setView([20.5937, 78.9629], 5); |
|
L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { |
|
attribution: 'Tiles © Esri', |
|
maxZoom: 18, |
|
}).addTo(map); |
|
|
|
|
|
var geocoder = L.Control.Geocoder.nominatim(); |
|
|
|
|
|
L.Control.geocoder({ |
|
geocoder: geocoder, |
|
defaultMarkGeocode: false |
|
}) |
|
.on('markgeocode', function(e) { |
|
var bbox = e.geocode.bbox; |
|
var center = e.geocode.center; |
|
map.fitBounds(bbox); |
|
setMarker(center); |
|
}) |
|
.addTo(map); |
|
|
|
var marker; |
|
function setMarker(latlng) { |
|
if (marker) { |
|
marker.setLatLng(latlng); |
|
} else { |
|
marker = L.marker(latlng).addTo(map); |
|
} |
|
|
|
document.getElementById('latitude').value = latlng.lat.toFixed(6); |
|
document.getElementById('longitude').value = latlng.lng.toFixed(6); |
|
document.getElementById('manual_lat').value = latlng.lat.toFixed(6); |
|
document.getElementById('manual_lon').value = latlng.lng.toFixed(6); |
|
|
|
|
|
fetchWeatherData(latlng.lat, latlng.lng); |
|
} |
|
|
|
map.on('click', function(e) { |
|
setMarker(e.latlng); |
|
}); |
|
|
|
|
|
document.getElementById('updateLocationBtn').addEventListener('click', function(){ |
|
const lat = parseFloat(document.getElementById('manual_lat').value); |
|
const lon = parseFloat(document.getElementById('manual_lon').value); |
|
if(!isNaN(lat) && !isNaN(lon)){ |
|
const latlng = L.latLng(lat, lon); |
|
map.setView(latlng, 10); |
|
setMarker(latlng); |
|
} else { |
|
alert("Please enter valid latitude and longitude values."); |
|
} |
|
}); |
|
|
|
|
|
function fetchWeatherData(lat, lng) { |
|
fetch(`/get_weather_data?lat=${lat}&lon=${lng}`) |
|
.then(response => response.json()) |
|
.then(data => { |
|
|
|
const container = document.getElementById('weatherDataContainer'); |
|
container.innerHTML = ` |
|
<div class="weather-card"> |
|
<div class="weather-title">Max Temp</div> |
|
<div>${data.max_temp !== null ? data.max_temp + " °C" : "Not available"}</div> |
|
</div> |
|
<div class="weather-card"> |
|
<div class="weather-title">Min Temp</div> |
|
<div>${data.min_temp !== null ? data.min_temp + " °C" : "Not available"}</div> |
|
</div> |
|
<div class="weather-card"> |
|
<div class="weather-title">Current Temp</div> |
|
<div>${data.current_temp !== null ? data.current_temp + " °C" : "Not available"}</div> |
|
</div> |
|
<div class="weather-card"> |
|
<div class="weather-title">Humidity</div> |
|
<div>${data.humidity !== null ? data.humidity.toFixed(1) + " %" : "Not available"}</div> |
|
</div> |
|
<div class="weather-card"> |
|
<div class="weather-title">Rain</div> |
|
<div>${data.rainfall !== null ? data.rainfall + " mm" : "Not available"}</div> |
|
</div> |
|
<div class="weather-card"> |
|
<div class="weather-title">Soil Moisture</div> |
|
<div>${data.soil_moisture !== null ? data.soil_moisture.toFixed(1) + " %" : "Not available"}</div> |
|
</div> |
|
<div class="weather-card"> |
|
<div class="weather-title">Wind Speed</div> |
|
<div>${data.wind_speed !== null ? data.wind_speed + " km/h" : "Not available"}</div> |
|
</div> |
|
<div class="weather-card"> |
|
<div class="weather-title">Cloud Cover</div> |
|
<div>${data.cloud_cover !== null ? data.cloud_cover.toFixed(1) + " %" : "Not available"}</div> |
|
</div> |
|
`; |
|
|
|
|
|
document.getElementById('max_temp_hidden').value = data.max_temp ?? ""; |
|
document.getElementById('min_temp_hidden').value = data.min_temp ?? ""; |
|
document.getElementById('current_temp_hidden').value = data.current_temp ?? ""; |
|
document.getElementById('humidity_hidden').value = data.humidity ?? ""; |
|
document.getElementById('rainfall_hidden').value = data.rainfall ?? ""; |
|
document.getElementById('soil_moisture_hidden').value = data.soil_moisture ?? ""; |
|
document.getElementById('wind_speed_hidden').value = data.wind_speed ?? ""; |
|
document.getElementById('cloud_cover_hidden').value = data.cloud_cover ?? ""; |
|
}) |
|
.catch(error => console.error('Error fetching weather data:', error)); |
|
} |
|
|
|
|
|
function fetchSoilProperties(lat, lng) { |
|
fetch(`/get_soil_properties?lat=${lat}&lon=${lng}`) |
|
.then(response => response.json()) |
|
.then(data => { |
|
if(data.soil_properties) { |
|
let tableHTML = "<table><thead><tr><th>Parameter</th><th>Value</th><th>Unit</th></tr></thead><tbody>"; |
|
data.soil_properties.forEach(function(item) { |
|
tableHTML += `<tr><td>${item[0]}</td><td>${item[1]}</td><td>${item[2]}</td></tr>`; |
|
}); |
|
tableHTML += "</tbody></table>"; |
|
document.getElementById("soilTableContainer").innerHTML = tableHTML; |
|
} else { |
|
document.getElementById("soilTableContainer").innerHTML = "<p class='text-center text-gray-600'>No soil data available.</p>"; |
|
} |
|
}) |
|
.catch(error => console.error('Error fetching soil properties:', error)); |
|
} |
|
</script> |
|
</body> |
|
</html> |
|
|