pranit144's picture
Upload 56 files
429a26d verified
{% extends "base.html" %}
{% block title %}Add Farm - Farm Management Portal{% endblock %}
{% block extra_css %}
<style>
#map {
height: 400px;
width: 100%;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
.form-section {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
}
</style>
{% endblock %}
{% block content %}
<div class="container mt-4">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-success text-white">
<h4><i class="fas fa-plus me-2"></i>Add New Farm</h4>
</div>
<div class="card-body">
<form method="POST" id="farmForm">
<div class="row">
<!-- Farm Details -->
<div class="col-md-6">
<div class="form-section">
<h5><i class="fas fa-seedling me-2"></i>Farm Details</h5>
<div class="mb-3">
<label for="farm_name" class="form-label">Farm Name *</label>
<input type="text" class="form-control" id="farm_name" name="farm_name" required>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="farm_size" class="form-label">Farm Size (Acres) *</label>
<input type="number" class="form-control" id="farm_size" name="farm_size" step="0.01" min="0.1" required>
</div>
<div class="col-md-6 mb-3">
<label for="irrigation_type" class="form-label">Irrigation Type *</label>
<select class="form-select" id="irrigation_type" name="irrigation_type" required>
<option value="">Select Irrigation</option>
<option value="Drip">Drip Irrigation</option>
<option value="Sprinkler">Sprinkler</option>
<option value="Flood">Flood Irrigation</option>
<option value="Rain-fed">Rain-fed</option>
<option value="Bore-well">Bore-well</option>
</select>
</div>
</div>
<div class="mb-3">
<label for="farm_type" class="form-label">Farm Type *</label>
<select class="form-select" id="farm_type" name="farm_type" required onchange="toggleFarmSections()">
<option value="">Select Farm Type</option>
<option value="crop">Crop Farming</option>
<option value="dairy">Dairy Farm</option>
<option value="poultry">Poultry Farm</option>
<option value="goat">Goat Farming</option>
<option value="pig">Pig Farming</option>
<option value="fishery">Fish Farming</option>
<option value="mixed">Mixed Farming</option>
</select>
</div>
<!-- Crop Farming Section -->
<div class="mb-3" id="crop-section" style="display: none;">
<label class="form-label">Crop Types *</label>
<div class="row">
<div class="col-md-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="Rice" id="crop_rice" name="crop_types">
<label class="form-check-label" for="crop_rice">Rice</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="Wheat" id="crop_wheat" name="crop_types">
<label class="form-check-label" for="crop_wheat">Wheat</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="Cotton" id="crop_cotton" name="crop_types">
<label class="form-check-label" for="crop_cotton">Cotton</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="Sugarcane" id="crop_sugarcane" name="crop_types">
<label class="form-check-label" for="crop_sugarcane">Sugarcane</label>
</div>
</div>
<div class="col-md-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="Maize" id="crop_maize" name="crop_types">
<label class="form-check-label" for="crop_maize">Maize</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="Vegetables" id="crop_vegetables" name="crop_types">
<label class="form-check-label" for="crop_vegetables">Vegetables</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="Fruits" id="crop_fruits" name="crop_types">
<label class="form-check-label" for="crop_fruits">Fruits</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="Pulses" id="crop_pulses" name="crop_types">
<label class="form-check-label" for="crop_pulses">Pulses</label>
</div>
</div>
</div>
</div>
<!-- Livestock Section -->
<div class="mb-3" id="livestock-section" style="display: none;">
<label class="form-label">Livestock Details</label>
<div class="row">
<div class="col-md-6 mb-3">
<label for="livestock_types" class="form-label">Livestock Types</label>
<select class="form-select" id="livestock_types" name="livestock_types" multiple>
<option value="Cows">Cows</option>
<option value="Buffalo">Buffalo</option>
<option value="Chickens">Chickens</option>
<option value="Ducks">Ducks</option>
<option value="Goats">Goats</option>
<option value="Sheep">Sheep</option>
<option value="Pigs">Pigs</option>
<option value="Fish">Fish</option>
</select>
<div class="form-text">Hold Ctrl to select multiple types</div>
</div>
<div class="col-md-6 mb-3">
<label for="livestock_count" class="form-label">Total Livestock Count</label>
<input type="number" class="form-control" id="livestock_count" name="livestock_count" min="1">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="housing_type" class="form-label">Housing Type</label>
<select class="form-select" id="housing_type" name="housing_type">
<option value="">Select Housing Type</option>
<option value="Open">Open Housing</option>
<option value="Semi-Open">Semi-Open Housing</option>
<option value="Closed">Closed Housing</option>
<option value="Cage">Cage System</option>
<option value="Free-Range">Free Range</option>
<option value="Pond">Pond System</option>
</select>
</div>
<div class="col-md-6 mb-3">
<label for="feeding_system" class="form-label">Feeding System</label>
<select class="form-select" id="feeding_system" name="feeding_system">
<option value="">Select Feeding System</option>
<option value="Grazing">Grazing</option>
<option value="Stall-fed">Stall Feeding</option>
<option value="Mixed">Mixed System</option>
<option value="Automatic">Automatic Feeding</option>
<option value="Manual">Manual Feeding</option>
</select>
</div>
</div>
<div class="mb-3">
<label for="breed_info" class="form-label">Breed Information</label>
<textarea class="form-control" id="breed_info" name="breed_info" rows="2" placeholder="Describe the breeds of livestock you have..."></textarea>
</div>
</div>
<!-- Detailed crops table: name, area, sowing month -->
<div class="mb-3" id="crop-details-section" style="display: none;">
<label class="form-label">Crops (name, area in acres, sowing month) *</label>
<div class="table-responsive">
<table class="table table-bordered" id="crops-table-add">
<thead>
<tr>
<th>Crop Name</th>
<th>Area (acres)</th>
<th>Sowing Month</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="crops-tbody-add">
<tr>
<td><input type="text" class="form-control" name="crop_name[]" required></td>
<td><input type="number" class="form-control" name="crop_area[]" step="0.01" min="0" required></td>
<td>
<select class="form-select" name="crop_month[]" required>
<option value="">Select Month</option>
<option>January</option>
<option>February</option>
<option>March</option>
<option>April</option>
<option>May</option>
<option>June</option>
<option>July</option>
<option>August</option>
<option>September</option>
<option>October</option>
<option>November</option>
<option>December</option>
</select>
</td>
<td><button type="button" class="btn btn-danger btn-sm remove-crop">Remove</button></td>
</tr>
</tbody>
</table>
<button type="button" id="add-crop-row" class="btn btn-success">Add Crop</button>
</div>
</div>
<!-- Soil Data Section -->
<h5><i class="fas fa-mountain me-2"></i>Soil Information</h5>
<div class="mb-3">
<label for="soil_type" class="form-label">Soil Type</label>
<select class="form-select" id="soil_type" name="soil_type">
<option value="">Select Soil Type</option>
<option value="Black">Black Soil</option>
<option value="Red">Red Soil</option>
<option value="Clay">Clay Soil</option>
<option value="Sandy">Sandy Soil</option>
<option value="Loamy">Loamy Soil</option>
</select>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="ph_level" class="form-label">pH Level</label>
<input type="number" class="form-control" id="ph_level" name="ph_level" step="0.1" min="0" max="14">
</div>
<div class="col-md-6 mb-3">
<label for="moisture_percentage" class="form-label">Moisture %</label>
<input type="number" class="form-control" id="moisture_percentage" name="moisture_percentage" step="0.1" min="0" max="100">
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label for="nitrogen_level" class="form-label">Nitrogen (ppm)</label>
<input type="number" class="form-control" id="nitrogen_level" name="nitrogen_level" step="0.1" min="0">
</div>
<div class="col-md-4 mb-3">
<label for="phosphorus_level" class="form-label">Phosphorus (ppm)</label>
<input type="number" class="form-control" id="phosphorus_level" name="phosphorus_level" step="0.1" min="0">
</div>
<div class="col-md-4 mb-3">
<label for="potassium_level" class="form-label">Potassium (ppm)</label>
<input type="number" class="form-control" id="potassium_level" name="potassium_level" step="0.1" min="0">
</div>
</div>
</div>
</div>
<!-- Map Section -->
<div class="col-md-6">
<div class="form-section">
<h5><i class="fas fa-map-marker-alt me-2"></i>Farm Location</h5>
<div class="mb-3">
<div id="map"></div>
</div>
<div class="row mb-3">
<div class="col-6">
<button type="button" id="startDrawingBtn" class="btn btn-success w-100">
<i class="fas fa-draw-polygon me-2"></i>Draw Boundary
</button>
</div>
<div class="col-6">
<button type="button" id="clearDrawingBtn" class="btn btn-danger w-100">
<i class="fas fa-trash me-2"></i>Clear
</button>
</div>
</div>
<div class="alert alert-info" id="drawingStatus">
<i class="fas fa-info-circle me-2"></i>
Click "Draw Boundary" and mark your farm area on the map.
</div>
<div class="row">
<div class="col-6">
<label for="latitude" class="form-label">Latitude *</label>
<input type="number" class="form-control" id="latitude" name="latitude" step="0.000001" readonly required>
</div>
<div class="col-6">
<label for="longitude" class="form-label">Longitude *</label>
<input type="number" class="form-control" id="longitude" name="longitude" step="0.000001" readonly required>
</div>
</div>
<!-- Hidden fields for coordinates data -->
<input type="hidden" id="field_coordinates" name="field_coordinates">
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-12 text-center">
<button type="submit" class="btn btn-success btn-lg me-3" id="submitBtn" disabled>
<i class="fas fa-save me-2"></i>Save Farm
</button>
<a href="{{ url_for('farmer_dashboard') }}" class="btn btn-secondary btn-lg">
<i class="fas fa-arrow-left me-2"></i>Back to Dashboard
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBvVLjWmCja331H8SuIZ4UlJdZytuYkC6Y&libraries=drawing,places&callback=initMap" async defer></script>
<script>
// Toggle farm sections based on farm type
function toggleFarmSections() {
const farmType = document.getElementById('farm_type').value;
const cropSection = document.getElementById('crop-section');
const livestockSection = document.getElementById('livestock-section');
const cropDetailsSection = document.getElementById('crop-details-section');
// Hide all sections first
cropSection.style.display = 'none';
livestockSection.style.display = 'none';
cropDetailsSection.style.display = 'none';
// Show relevant sections based on farm type
if (farmType === 'crop' || farmType === 'mixed') {
cropSection.style.display = 'block';
cropDetailsSection.style.display = 'block';
}
if (farmType === 'dairy' || farmType === 'poultry' || farmType === 'goat' ||
farmType === 'pig' || farmType === 'fishery' || farmType === 'mixed') {
livestockSection.style.display = 'block';
// Auto-select appropriate livestock types based on farm type
const livestockSelect = document.getElementById('livestock_types');
for (let option of livestockSelect.options) {
option.selected = false; // Clear previous selections
}
switch(farmType) {
case 'dairy':
for (let option of livestockSelect.options) {
if (option.value === 'Cows' || option.value === 'Buffalo') {
option.selected = true;
}
}
break;
case 'poultry':
for (let option of livestockSelect.options) {
if (option.value === 'Chickens' || option.value === 'Ducks') {
option.selected = true;
}
}
break;
case 'goat':
for (let option of livestockSelect.options) {
if (option.value === 'Goats') {
option.selected = true;
}
}
break;
case 'pig':
for (let option of livestockSelect.options) {
if (option.value === 'Pigs') {
option.selected = true;
}
}
break;
case 'fishery':
for (let option of livestockSelect.options) {
if (option.value === 'Fish') {
option.selected = true;
}
}
break;
}
}
}
let map, drawingManager, polygon;
let isDrawing = false;
function initMap() {
// Initialize map (centered on India)
map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 20.5937, lng: 78.9629 },
zoom: 5,
mapTypeControl: true,
fullscreenControl: true,
streetViewControl: true
});
// Initialize drawing manager
drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: null,
drawingControl: false,
polygonOptions: {
fillColor: '#4CAF50',
fillOpacity: 0.3,
strokeWeight: 2,
strokeColor: '#4CAF50',
clickable: true,
editable: true
}
});
drawingManager.setMap(map);
// Helper: compute approximate area in acres from polygon vertices
function computeAreaAcresFromLatLngArray(latlngArray) {
// latlngArray: [{lat, lng}, ...]
if (!latlngArray || latlngArray.length < 3) return 0;
// Compute average latitude
let latSum = 0;
latlngArray.forEach(p => latSum += p.lat);
const latAvg = latSum / latlngArray.length;
const latAvgRad = latAvg * Math.PI / 180.0;
const metersPerDegLat = 111132.92;
const metersPerDegLon = 111320.0 * Math.cos(latAvgRad);
// Convert to planar meters
const pts = latlngArray.map(p => ({
x: p.lng * metersPerDegLon,
y: p.lat * metersPerDegLat
}));
// Shoelace
let area = 0;
for (let i = 0; i < pts.length; i++) {
const j = (i + 1) % pts.length;
area += pts[i].x * pts[j].y - pts[j].x * pts[i].y;
}
area = Math.abs(area) / 2.0; // in m^2
// convert to acres
const acres = area / 4046.8564224;
return Math.round(acres * 10000) / 10000; // 4 decimal places
}
// Event listener for polygon completion
drawingManager.addListener('polygoncomplete', function(poly) {
if (polygon) {
polygon.setMap(null);
}
polygon = poly;
// Get polygon coordinates
const coordinates = [];
const vertices = polygon.getPath();
for (let i = 0; i < vertices.getLength(); i++) {
const xy = vertices.getAt(i);
coordinates.push([xy.lng(), xy.lat()]);
}
// Convert coordinates to objects with lat,lng for easier processing
const latlngObjects = coordinates.map(c => ({ lat: c[1], lng: c[0] }));
// Store coordinates
document.getElementById('field_coordinates').value = JSON.stringify(latlngObjects);
// Calculate center point
const bounds = new google.maps.LatLngBounds();
vertices.forEach(vertex => bounds.extend(vertex));
const center = bounds.getCenter();
// Update latitude and longitude fields
document.getElementById('latitude').value = center.lat();
document.getElementById('longitude').value = center.lng();
// Compute area and update farm_size input automatically
const acres = computeAreaAcresFromLatLngArray(latlngObjects);
if (acres > 0) {
document.getElementById('farm_size').value = acres;
}
// Update status
document.getElementById('drawingStatus').innerHTML =
'<i class="fas fa-check-circle me-2"></i>Farm boundary marked successfully!';
document.getElementById('drawingStatus').className = 'alert alert-success';
// Enable submit button
document.getElementById('submitBtn').disabled = false;
// Stop drawing mode
drawingManager.setDrawingMode(null);
isDrawing = false;
// Update button text
document.getElementById('startDrawingBtn').innerHTML =
'<i class="fas fa-edit me-2"></i>Edit Boundary';
});
}
// Start drawing
document.getElementById('startDrawingBtn').addEventListener('click', function() {
if (!isDrawing) {
drawingManager.setDrawingMode(google.maps.drawing.OverlayType.POLYGON);
isDrawing = true;
this.innerHTML = '<i class="fas fa-stop me-2"></i>Stop Drawing';
this.className = 'btn btn-warning w-100';
} else {
drawingManager.setDrawingMode(null);
isDrawing = false;
this.innerHTML = '<i class="fas fa-draw-polygon me-2"></i>Draw Boundary';
this.className = 'btn btn-success w-100';
}
});
// Clear drawing
document.getElementById('clearDrawingBtn').addEventListener('click', function() {
if (polygon) {
polygon.setMap(null);
polygon = null;
}
// Clear form fields
document.getElementById('field_coordinates').value = '';
document.getElementById('latitude').value = '';
document.getElementById('longitude').value = '';
// Reset status
document.getElementById('drawingStatus').innerHTML =
'<i class="fas fa-info-circle me-2"></i>Click "Draw Boundary" and mark your farm area on the map.';
document.getElementById('drawingStatus').className = 'alert alert-info';
// Disable submit button
document.getElementById('submitBtn').disabled = true;
// Reset drawing mode
drawingManager.setDrawingMode(null);
isDrawing = false;
// Reset button
const drawBtn = document.getElementById('startDrawingBtn');
drawBtn.innerHTML = '<i class="fas fa-draw-polygon me-2"></i>Draw Boundary';
drawBtn.className = 'btn btn-success w-100';
});
// Form validation
document.getElementById('farmForm').addEventListener('submit', function(e) {
const cropTypes = document.querySelectorAll('input[name="crop_types"]:checked');
if (cropTypes.length === 0) {
e.preventDefault();
alert('Please select at least one crop type.');
return false;
}
if (!document.getElementById('latitude').value || !document.getElementById('longitude').value) {
e.preventDefault();
alert('Please mark your farm location on the map.');
return false;
}
});
// Crop rows management (add/remove)
document.getElementById('add-crop-row').addEventListener('click', function() {
const tbody = document.getElementById('crops-tbody-add');
const row = document.createElement('tr');
row.innerHTML = `
<td><input type="text" class="form-control" name="crop_name[]" required></td>
<td><input type="number" class="form-control" name="crop_area[]" step="0.01" min="0" required></td>
<td>
<select class="form-select" name="crop_month[]" required>
<option value="">Select Month</option>
<option>January</option>
<option>February</option>
<option>March</option>
<option>April</option>
<option>May</option>
<option>June</option>
<option>July</option>
<option>August</option>
<option>September</option>
<option>October</option>
<option>November</option>
<option>December</option>
</select>
</td>
<td><button type="button" class="btn btn-danger btn-sm remove-crop">Remove</button></td>
`;
tbody.appendChild(row);
// Attach remove handler
row.querySelector('.remove-crop').addEventListener('click', function() {
if (tbody.children.length > 1) row.remove();
else alert('At least one crop is required');
});
});
// Attach remove handler to initial row(s)
document.querySelectorAll('#crops-tbody-add .remove-crop').forEach(btn => {
btn.addEventListener('click', function() {
const tbody = document.getElementById('crops-tbody-add');
if (tbody.children.length > 1) this.closest('tr').remove();
else alert('At least one crop is required');
});
});
// Get user location
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
const userLocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
map.setCenter(userLocation);
map.setZoom(15);
});
}
</script>
{% endblock %}