# 📚 REFERENCIA DE APIs - BeeLifeMaps

## 🎯 FUNCIONES PRINCIPALES DEL SISTEMA

### `getAllParcelasInArea(center, radiusKm)`
**Archivo**: `analysis_real.js` líneas 353-500
**Propósito**: Motor principal de obtención de datos SIGPAC
**Parámetros**:
- `center`: {lat: number, lng: number} - Centro del análisis
- `radiusKm`: number - Radio en kilómetros (default: 5)
**Retorna**: Promise<Array<Parcela>>
**Caché**: Implementa caché automático por ubicación+radio

```javascript
// Ejemplo de uso
const parcelas = await getAllParcelasInArea({lat: 40.4168, lng: -3.7038}, 2.5);
console.log(`Encontradas ${parcelas.length} parcelas`);
```

### `calculateRealScore(point, cultivo, superficie, sistema)`
**Archivo**: `analysis_real.js` líneas 1500-1700
**Propósito**: Calcula valor apícola de un punto específico
**Parámetros**:
- `point`: {lat: number, lng: number} - Coordenadas del punto
- `cultivo`: string - Código o nombre del cultivo
- `superficie`: number - Superficie en hectáreas
- `sistema`: string - "REGADÍO" o "SECANO"
**Retorna**: number (0.0-1.0) - Valor apícola calculado

```javascript
// Ejemplo de cálculo
const score = calculateRealScore(
  {lat: 40.4168, lng: -3.7038},
  "GIRASOL",
  5.2,
  "REGADÍO"
);
// Retorna: 0.85 (85% idoneidad)
```

### `performDeepAnalysis(forcedCenter, maxPoints)`
**Archivo**: `analysis_real.js` líneas 880-928
**Propósito**: Ejecuta análisis profundo completo
**Parámetros**:
- `forcedCenter`: LatLng opcional - Centro forzado
- `maxPoints`: number opcional - Máximo puntos a analizar
**Proceso**: 4 pasos con popup de progreso
**Resultado**: Visualización de top 10 zonas recomendadas

### `calcularZonasRecomendadas(parcelas, center, radiusKm)`
**Archivo**: `analysis_real.js` líneas 980-1024
**Propósito**: Zonificación inteligente por densidad
**Algoritmo**: Grid 0.001° + agregación espacial
**Retorna**: Array<Zona> ordenado por score (top 10)

## 🌾 SISTEMA DE EVALUACIÓN DE CULTIVOS

### `getCultivoValue(cultivo)`
**Archivo**: `analysis_real.js` líneas 1400-1500
**Propósito**: Obtiene valor base por tipo de cultivo
**Mapeo de cultivos**:

```javascript
const CULTIVO_VALUES = {
  // Excelentes (0.35-0.40)
  'CÍTRICOS': 0.40, 'NARANJO': 0.40, 'LIMONERO': 0.40,
  'OLIVAR': 0.35, 'OLIVO': 0.35, 'ACEITUNA': 0.35,
  'GIRASOL': 0.38, 'ALMENDRO': 0.37,
  
  // Buenos (0.25-0.34)
  'VIÑEDO': 0.30, 'UVAS': 0.30, 'VID': 0.30,
  'FRUTALES': 0.28, 'MANZANO': 0.28, 'PERAL': 0.28,
  'AROMÁTICAS': 0.32, 'LAVANDA': 0.35, 'ROMERO': 0.30,
  
  // Aceptables (0.15-0.24)
  'CEREALES': 0.18, 'TRIGO': 0.18, 'CEBADA': 0.17,
  'LEGUMINOSAS': 0.22, 'HABAS': 0.25, 'GUISANTES': 0.23,
  'PASTIZAL': 0.20, 'PASTO': 0.20, 'PRADERA': 0.19,
  
  // Bajos (0.05-0.14)
  'MAÍZ': 0.10, 'REMOLACHA': 0.08, 'PATATA': 0.12,
  'INDUSTRIAL': 0.05, 'URBANO': 0.02
};
```

### `getFloralIndex(cultivo, mes)`
**Archivo**: `analysis_real.js` líneas 1600-1800
**Propósito**: Índice floral estacional (0.0-1.0)
**Calendario fenológico por cultivo**:

```javascript
const FENOLOGIA = {
  'ALMENDRO': [0.1, 0.9, 0.8, 0.3, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1],
  'CÍTRICOS': [0.0, 0.0, 0.2, 0.8, 0.9, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
  'GIRASOL':  [0.0, 0.0, 0.0, 0.0, 0.2, 0.4, 0.8, 0.9, 0.6, 0.1, 0.0, 0.0],
  'OLIVAR':   [0.0, 0.0, 0.0, 0.2, 0.8, 0.9, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0],
  'VIÑEDO':   [0.0, 0.0, 0.1, 0.4, 0.7, 0.8, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0]
};
```

## 🗺️ SISTEMA DE MAPAS Y VISUALIZACIÓN

### Configuración Leaflet
```javascript
// Inicialización del mapa
const map = L.map('map').setView([40.4168, -3.7038], 6);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
```

### Capas SIGPAC
```javascript
// URLs de servicios WMS
const SIGPAC_BASE = "https://www.ign.es/wms-inspire/pnoa-ma";
const SIGPAC_WFS = "https://servicios.idee.es/wfs-inspire/ocupacion-suelo";

// Capas disponibles
const LAYERS = {
  recintos: 'AU.Sigpac:recinto',
  cultivos: 'AU.Sigpac:linea_declaracion', 
  elementos: 'AU.Sigpac:elemento_paisaje',
  cauces: 'AU.Sigpac:franja_proteccion_cauce'
};
```

### Marcadores Dinámicos
```javascript
// Creación de iconos por score
function createBeeIcon(score) {
  const color = score >= 70 ? '#228B22' : score >= 50 ? '#32CD32' : '#FFD700';
  return L.divIcon({
    html: `<div style="background: ${color}; border-radius: 50%; width: 24px; height: 24px;">🐝</div>`,
    className: 'bee-marker',
    iconSize: [28, 28],
    iconAnchor: [14, 14]
  });
}
```

## 🔍 CONSULTAS A APIS EXTERNAS

### SIGPAC GetFeatureInfo
```javascript
async function consultarSIGPAC(lat, lng) {
  const bbox = calculateBbox(lat, lng, 0.001); // ~100m radio
  const url = `${SIGPAC_BASE}?SERVICE=WMS&REQUEST=GetFeatureInfo&BBOX=${bbox}&WIDTH=256&HEIGHT=256&I=128&J=128&FORMAT=image/png&INFO_FORMAT=text/html&LAYERS=AU.Sigpac:recinto&SRS=EPSG:3857`;
  
  const response = await fetch(url);
  const html = await response.text();
  return parseHTMLResponse(html);
}
```

### Nominatim Geocoding
```javascript
async function buscarLocalidad(query) {
  const url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&countrycodes=es&limit=1`;
  const response = await fetch(url);
  const data = await response.json();
  return data[0] ? {lat: parseFloat(data[0].lat), lng: parseFloat(data[0].lon)} : null;
}
```

### Google Earth Engine (Backend)
```javascript
// server/index.js - Endpoint Dynamic World
app.get('/dynamic-world', async (req, res) => {
  const {bounds, prob} = req.query;
  const image = ee.ImageCollection('GOOGLE/DYNAMICWORLD/V1')
    .filterBounds(ee.Geometry.Rectangle(bounds))
    .select('label')
    .reduce(ee.Reducer.mode());
    
  const url = image.getThumbURL({
    min: 0, max: 8,
    palette: ['419bdf', '397d49', '88b053', '7a87c6', 'e49635', 'dfc35a', 'c4281b', 'a59b8f', 'b39fe1'],
    dimensions: 512
  });
  
  res.json({url});
});
```

## 🎨 SISTEMA DE POPUPS Y UI

### Popup Responsivo
```javascript
function createDetailedPopup(zona, ranking) {
  return `
    <div style="width: 60vw; max-width: none; min-width: 400px;">
      <h4 style="text-align: center; color: #2563eb;">
        🐝 Zona Apícola Recomendada #${ranking}
      </h4>
      <div style="background: #f8f9fa; padding: 10px; border-radius: 6px;">
        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px;">
          <div><strong>Cultivo:</strong> ${zona.cultivo}</div>
          <div><strong>Sistema:</strong> ${zona.sistema}</div>
          <div><strong>Superficie:</strong> ${zona.superficie} ha</div>
          <div><strong>Score:</strong> ${Math.round(zona.score * 100)}%</div>
        </div>
      </div>
      <div style="border-left: 4px solid #3b82f6; padding-left: 12px; margin: 12px 0;">
        <div style="font-weight: bold; color: #1e40af;">🔍 Análisis Detallado</div>
        <div style="font-size: 13px; line-height: 1.4;">${zona.explicacion}</div>
      </div>
    </div>`;
}
```

### Progress Popup
```javascript
function updateProgressPopup(current, total, percentage, details) {
  const popup = document.getElementById('progress-popup');
  popup.innerHTML = `
    <div style="text-align: center;">
      <h3>🔬 Análisis en Progreso</h3>
      <div style="background: #e5e7eb; border-radius: 10px; height: 20px; margin: 10px 0;">
        <div style="background: #3b82f6; height: 100%; border-radius: 10px; width: ${percentage}%;"></div>
      </div>
      <p>${current}/${total} pasos completados (${percentage}%)</p>
      <p style="color: #666;">${details}</p>
    </div>`;
}
```

## 💾 SISTEMA DE CACHÉ Y OPTIMIZACIÓN

### Caché de Análisis
```javascript
const analysisCache = new Map();

function getCacheKey(center, radius) {
  return `${center.lat.toFixed(4)}_${center.lng.toFixed(4)}_${radius}`;
}

function setCachedData(key, data) {
  analysisCache.set(key, {
    data: data,
    timestamp: Date.now(),
    expires: Date.now() + (30 * 60 * 1000) // 30 minutos
  });
}
```

### Batch Processing
```javascript
async function processBatchPoints(points, batchSize = 10) {
  const results = [];
  for (let i = 0; i < points.length; i += batchSize) {
    const batch = points.slice(i, i + batchSize);
    const batchResults = await Promise.all(
      batch.map(point => consultarSIGPAC(point.lat, point.lng))
    );
    results.push(...batchResults);
    
    // Delay entre batches para evitar rate limiting
    if (i + batchSize < points.length) {
      await new Promise(resolve => setTimeout(resolve, 100));
    }
  }
  return results;
}
```

## 📊 LOGGING Y DEBUGGING

### Sistema de Logs
```javascript
let analysisLog = [];

function logAnalysis(message, data = null) {
  const entry = {
    timestamp: new Date().toISOString(),
    message: message,
    data: data ? JSON.stringify(data, null, 2) : null
  };
  
  analysisLog.push(entry);
  console.log(`[${entry.timestamp}] ${message}`, data || '');
}

function exportAnalysisLog() {
  const content = analysisLog.map(entry => 
    `[${entry.timestamp}] ${entry.message}${entry.data ? '\n' + entry.data : ''}`
  ).join('\n\n');
  
  const blob = new Blob([content], {type: 'text/plain'});
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `analisis_apicola_${new Date().toISOString().slice(0,19).replace(/:/g,'-')}.log`;
  a.click();
}
```

## ⚡ EVENTOS Y LISTENERS

### Event Handlers Principales
```javascript
// Búsqueda de localidad
document.getElementById('go').addEventListener('click', async () => {
  const query = document.getElementById('q').value;
  const coords = await buscarLocalidad(query);
  if (coords) {
    map.setView([coords.lat, coords.lng], 12);
    updateCircle(coords, getCurrentRadius());
  }
});

// Exploración rápida
document.getElementById('toggle-paisaje').addEventListener('click', async () => {
  showPaisaje = !showPaisaje;
  if (showPaisaje) {
    const center = currentCircle ? currentCircle.getLatLng() : map.getCenter();
    await findBeeLocationsByGeography(center, currentCircle.getBounds());
  } else {
    clearBeeMarkers();
  }
});

// Análisis profundo
document.getElementById('run-analysis').addEventListener('click', async () => {
  const center = currentCircle ? currentCircle.getLatLng() : map.getCenter();
  await performDeepAnalysis(center);
});
```

---

**📝 NOTA**: Esta referencia cubre las funciones principales. Para detalles específicos de implementación, consultar los archivos fuente correspondientes.
