You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

103 lines
3.1 KiB

import express from 'express';
import axios from 'axios';
import { getSentinelData, calculateNDVI, generateFieldPatternNDVI } from '../utils/sentinel.js';
const router = express.Router();
// Analyze field health
router.post('/analyze', async (req, res) => {
try {
const { polygon, date } = req.body;
if (!polygon || !polygon.coordinates) {
return res.status(400).json({ error: 'Polygon coordinates are required' });
}
console.log('Analyzing polygon:', polygon.coordinates[0].length, 'points');
// Получаем спутниковые данные
const satelliteData = await getSentinelData(polygon, date);
// Вычисляем NDVI
const ndviResult = await calculateNDVI(satelliteData);
// Генерируем статистику
const stats = generateNDVIStats(ndviResult.ndviValues);
// Для демонстрации используем сгенерированное изображение с паттернами
const demoImage = generateFieldPatternNDVI(400, 400);
res.json({
success: true,
data: {
ndviImage: demoImage, // Используем демо изображение
stats: stats,
date: satelliteData.date || new Date().toISOString().split('T')[0],
area: calculateArea(polygon),
polygon: polygon // Сохраняем полигон для истории
}
});
} catch (error) {
console.error('Error in NDVI analysis:', error);
res.status(500).json({
error: 'Analysis failed',
message: error.message
});
}
});
// Остальные функции остаются без изменений...
// Generate NDVI statistics
function generateNDVIStats(ndviValues) {
const validValues = ndviValues.filter(v => !isNaN(v) && v >= -1 && v <= 1);
if (validValues.length === 0) {
return {
mean: 0,
min: 0,
max: 0,
healthy: 0,
moderate: 0,
poor: 0
};
}
const mean = validValues.reduce((a, b) => a + b, 0) / validValues.length;
const min = Math.min(...validValues);
const max = Math.max(...validValues);
// Categorize vegetation health
const healthy = validValues.filter(v => v > 0.6).length / validValues.length * 100;
const moderate = validValues.filter(v => v > 0.3 && v <= 0.6).length / validValues.length * 100;
const poor = validValues.filter(v => v <= 0.3).length / validValues.length * 100;
return {
mean: parseFloat(mean.toFixed(3)),
min: parseFloat(min.toFixed(3)),
max: parseFloat(max.toFixed(3)),
healthy: parseFloat(healthy.toFixed(1)),
moderate: parseFloat(moderate.toFixed(1)),
poor: parseFloat(poor.toFixed(1))
};
}
// Calculate area in hectares (simplified)
function calculateArea(polygon) {
const coords = polygon.coordinates[0];
let area = 0;
for (let i = 0; i < coords.length - 1; i++) {
const [x1, y1] = coords[i];
const [x2, y2] = coords[i + 1];
area += (x1 * y2 - x2 * y1);
}
area = Math.abs(area) / 2;
// Convert to hectares (approximate)
const areaHectares = area * 10000;
return parseFloat(areaHectares.toFixed(2));
}
export default router;