GeoVeil API Documentation

GeoVeil expune două versiuni de API pentru accesul la datele de interferențe GNSS ale Sistemului ROMPOS (86 stații active, 83 cu analiză spectrală), operat de ANCPI prin Centrul Național de Cartografie (CNC). V2 este API-ul principal, cu date în timp real, analiză spoofing și predicție ML. V1 este API-ul clasic cu perspective istorice și date VADASE.

Prezentare generală

Sistemul ROMPOS cuprinde 86 de stații CORS active, operat de ANCPI prin Centrul Național de Cartografie (CNC). GeoVeil se conectează la 83 de stații cu capabilitate de analiză spectrală (NovAtel OEM7), care transmit în timp real fluxuri ITDETECTSTATUSA și SPECTRUMANALYSIS, procesate pentru detectarea interferențelor, spoofing-ului și meaconingului. 74 de stații dețin licență VADASE pentru analiza deplasărilor poziționale.

Autentificare

API-urile sunt publice și nu necesită autentificare pentru operațiunile de citire. Endpoint-urile administrative nu sunt documentate public și necesită autentificare.

URL-uri de bază

V2 — Live (principal)
https://geoveil.ro
V1 — Classic
https://app.rompos.ro/api/v1

Formate

Toate răspunsurile sunt în format application/json. Datele temporale sunt în format ISO 8601 UTC. Frecvențele sunt în MHz, lățimile de bandă în MHz, pierderile de putere în dBm.

GET /i — Evenimente de interferență (V2)

V2
GET /i Events by station + date range

Returnează evenimentele de interferență pentru o stație și un interval de date.

Parametri
ParametruTipDescriere
station_codestringreqCodul stației (ex: SULI)
start_datedatereqData start (YYYY-MM-DD)
end_datedatereqData sfârșit (YYYY-MM-DD)
Răspuns
[
  {
    "id": 12345,
    "stationid": "SULI",
    "datetime": "2026-05-26T14:23:00Z",
    "rfpath": "L1",
    "centfreq_mhz": 1575.42,
    "bandwidth_mhz": 10.0,
    "powerloss_dbm": -42.5,
    "hestpowspecdens_dbmhz": -95.3
  },
  ...
]

GET /lh — Ultima oră (V2)

V2
GET /lh All events in the last 60 minutes

Returnează evenimentele brute din ultima oră. Fără parametri returnează toate stațiile (poate fi mare — 100k+ evenimente). Cu station_code filtrează pe stație; limit capătă numărul de rânduri (recomandat când se deschide modalul de stație). Pentru vizualizări agregate, preferați /lh/summary.

Parametri opționali
ParametruTipDescriere
station_codestringoptFiltrare pe stație (ex: SULI)
limitintoptNumăr maxim de rânduri returnate (ORDER BY datetime DESC). Recomandat: 3000 când station_code este prezent.
Răspuns
[
  {
    "stationid": "SULI",
    "datetime": "2026-05-26T12:14:00Z",
    "rfpath": "L1",
    "centfreq_mhz": 1575.42,
    "bandwidth_mhz": 8.0,
    "powerloss_dbm": -38.2,
    "hestpowspecdens_dbmhz": -92.1
  },
  ...
]

GET /lh/summary — Rezumat ultima oră (V2)

V2
GET /lh/summary Per-station aggregated summary of the last hour

Returnează un rând per stație activă cu statistici pre-agregate: număr evenimente, banda dominantă, pierdere minimă de putere, 6 bucket-uri temporale de 10 minute și cel mai bun rezultat de analiză spoofing. Ideal pentru pagina de amenințări — returnează ~32 rânduri în loc de 100k+ evenimente brute.

Parametri

Niciun parametru. Returnează toate stațiile active în ultima oră.

Răspuns
[
  {
    "station_code": "SULI",
    "stationid": 64,
    "count": 4823,
    "dom_rfpath": "L1",
    "min_powerloss": -61.4,
    "buckets": [820, 910, 750, 890, 780, 673],
    "threat_type": "spoofing_candidate",
    "confidence": 0.87,
    "severity": "HIGH"
  },
  ...
]
Câmpuri răspuns
CâmpDescriere
station_codeCodul stației (ex: SULI)
stationidID numeric intern
countTotal evenimente în ultima oră
dom_rfpathBanda RF dominantă (ex: L1)
min_powerlossCea mai mare pierdere de putere (dBm, cel mai negativ)
bucketsArray de 6 valori: număr evenimente per fereastră de 10 minute (cronologic)
threat_typeTipul de amenințare spoofing (null dacă fără analiză azi)
confidenceScor de încredere analiză spoofing (0–1)
severityHIGH / MEDIUM / LOW / null

GET /ce — Evenimente corelate inter-stații (V2)

V2
GET /ce Cross-station correlated events

Detectează grupuri de evenimente cu aceeași frecvență și lățime de bandă pe mai multe stații în intervalul specificat (corelație inter-stații).

Parametri
ParametruTipDescriere
start_datedatereqData start
end_datedatereqData sfârșit
min_stationsintoptNumăr minim stații (implicit: 2)
Răspuns
[
  {
    "centfreq_mhz": 1575.42,
    "bandwidth_mhz": 10.0,
    "station_count": 5,
    "stations": ["SULI", "BBUC", "DEVA", "TIMI", "ARAD"],
    "first_seen": "2026-05-26T12:00:00Z",
    "last_seen": "2026-05-26T14:30:00Z"
  },
  ...
]

GET /sa — Analiză spoofing (V2)

V2
GET /sa Spoofing analysis — 7-indicator engine

Returnează analiza spoofing pentru stație și interval. Motorul evaluează 7 indicatori: temporali, spațiali, multi-bandă, putere spectrală, corelație inter-stații, tipar de frecvență și derivă temporală.

Parametri
ParametruTipDescriere
station_codestringreqCodul stației
start_datedatereqData start
end_datedatereqData sfârșit
Răspuns
[
  {
    "stationid": "SULI",
    "datetime": "2026-05-26T14:23:00Z",
    "centfreq_mhz": 1575.42,
    "threat_type": "spoofing_candidate",
    "confidence": 0.87,
    "severity": "HIGH",
    "temporal_score": 0.9,
    "spatial_score": 0.75,
    "multiband_score": 0.8,
    "psd_score": 0.85,
    "correlation_score": 0.7,
    "freq_pattern_score": 0.9,
    "drift_score": 0.65,
    "analysis_notes": "Strong temporal clustering with spatial spread..."
  },
  ...
]
Tipuri de amenințare
ValoareDescriere
spoofing_candidateSemnal cu caracteristici de spoofing (7 indicatori activi)
matched_spectrumSpectru care coincide cu o sursă de spoofing cunoscut
meaconingReemisie întârziată (meaconing)
cleanFără amenințare detectată

GET /analytics — Statistici agregate (V2)

V2
GET /analytics Aggregated statistics for dashboards

Statistici agregate: top stații după constelație, distribuție frecvențe, heatmap oră×zi, scatter BW/PL, trend zilnic, weekday/weekend.

Parametri opționali
ParametruTipDescriere
daysintoptNumăr zile înapoi (implicit: 30)
V2
GET /trends Daily counts + correlation matrix

Număr zilnic de evenimente + matrice de co-apariții stație×stație (stații active în aceeași zi).

POST /api/predict — Predicție ML (V2)

V2
POST /api/predict ML interference prediction

Generează predicție de interferență pe 24h pentru o stație și o oră specifică. Returnează probabilitate, prognoză orară, predicții per bandă RF și informații despre model.

Body (JSON)
CâmpTipDescriere
station_codestringreqCodul stației (ex: "SULI")
datetimestringreqISO 8601 (ex: "2026-05-26T14:00")
Exemplu request
POST /api/predict
Content-Type: application/json

{
  "station_code": "SULI",
  "datetime": "2026-05-26T14:00"
}
Răspuns
{
  "station_code": "SULI",
  "datetime": "2026-05-26T14:00:00",
  "probability": 73.0,
  // 0–100 scale (not 0–1)
  "expected_events": 45,
  "forecast_24h": [
    { "hour": 14, "probability": 73.0, "expected_events": 45 },
    { "hour": 15, "probability": 68.0, "expected_events": 38 },
    ...
  ],
  "band_predictions": [
    {
      "rfpath": "L1",
      "centfreq_mhz": 1575.42,
      "avg_bw": 8.2,
      "avg_pl": -42.1,
      "avg_psd": -94.3,
      "occurrences": 2841,
      "pct": 58.9
    },
    {
      "rfpath": "L2",
      "centfreq_mhz": 1227.60,
      "avg_bw": 6.1,
      "avg_pl": -51.0,
      "avg_psd": -97.2,
      "occurrences": 1204,
      "pct": 24.9
    },
    ...
  ],
  "model_info": {
    "model": "v1",
    "classifier_accuracy": 0.823,
    "classifier_auc": 0.909,
    "classifier_f1": 0.828,
    "training_samples": 549182,
    "trained_at": "2026-05-26T19:24:00Z"
  }
}

GET /api/predict/status

V2
GET /api/predict/status Model training status + accuracy

Starea curentă a modelului LightGBM: dacă este antrenat, în curs de antrenare, acuratețe, importanța caracteristicilor.

Răspuns
{
  "trained": true,
  "is_training": false,
  "accuracy": {
    "classifier_accuracy": 0.823,
    "classifier_auc": 0.909,
    "classifier_f1": 0.828,
    "regressor_mae": 127,
    "regressor_r2": 0.81
  },
  "training_samples": 549182,
  "stations_with_baseline": 83,
  "training_time": 480.3,
  // seconds
  "feature_importance": {
    "hour": 0.312,
    "station_avg_psd": 0.198,
    "dow": 0.154,
    "baseline_eph": 0.121,
    "hour_sin": 0.089,
    ...
  },
  "trained_at": "2026-05-26T19:24:00Z"
}

GET /api/predict/compare

V2
GET /api/predict/compare Side-by-side LightGBM vs LSTM metrics

Comparație metrici LightGBM vs LSTM cu câștigătorul per metrică. Dacă LSTM este în curs de antrenare, câmpul is_training este true și training_progress conține progresul curent (ex: "Epoch 32/60").

Răspuns
{
  "lightgbm": {
    "trained": true,
    "is_training": false,
    "accuracy": {
      "classifier_accuracy": 0.823,
      "classifier_auc": 0.909,
      "classifier_f1": 0.828,
      "regressor_mae": 127,
      "regressor_r2": 0.81
    }
  },
  "lstm": {
    "trained": true,
    "is_training": false,
    "training_progress": null,
    "accuracy": {
      "classifier_accuracy": 0.919,
      "classifier_auc": 0.969,
      "classifier_f1": 0.811,
      "regressor_mae": 18.69
    }
  },
  "winner": {
    "accuracy": "lightgbm",
    "auc": "lightgbm",
    "f1": "lightgbm",
    "mae": "lstm"
  }
}

POST /api/predict/retrain

V2
POST /api/predict/retrain Force LightGBM retraining

Declanșează re-antrenarea forțată a modelului LightGBM. Antrenarea LSTM este declanșată automat după finalizare. Returnează 409 dacă o antrenare este deja în curs.

Body

Niciun body necesar.

Răspuns (succes)
{ "status": "retraining started" }
Răspuns (409 — deja în antrenare)
{ "error": "Training already in progress" }

GET /i — Evenimente (V1 Classic)

V1
GET /i Events by station name (legacy format)

Endpoint clasic — returnează evenimentele pentru o stație, cu câmpuri în format moștenire. Folosit de graficul polar V1.

Parametri
ParametruTipDescriere
statiestringreqNumele stației (ex: Sulina)
start_datedatereqData start (YYYY-MM-DD)
end_datedatereqData sfârșit (YYYY-MM-DD)
Răspuns (câmpuri V1)
[
  {
    "DataOra": "2026-04-05T14:23:00",
    "DataOra_fin": "2026-04-05T14:45:00",
    "BandaRF": "L1",
    "Frecv_cent_MHz": 1575.42,
    "LunBanda_MHz": 10.0,
    "Pie_put_est_dBm": -42.5
  },
  ...
]

GET /stats — Statistici sistematice (V1)

V1
GET /stats Systematic interference statistics

Statistici agregate per bandă RF: număr apariții, CF min/max, BW max, PL max, interval temporal.

Parametri
ParametruTipDescriere
statiestringreqNumele stației
start_datedatereqData start
end_datedatereqData sfârșit

GET /correlated — Corelate (V1)

V1
GET /correlated Cross-station correlation (V1 logic)

Evenimente cu aceeași frecvență detectate simultan pe mai multe stații (corelație inter-stații). Implementare diferită față de V2 /ce (folosit pentru referință istorică).

Parametri
ParametruTipDescriere
start_datedatereqData start
end_datedatereqData sfârșit

GET /vadase — Date VADASE (V1)

V1
GET /vadase VADASE displacement data

Date de deplasare VADASE (Variometric Approach for Displacement Analysis Standing algoriEthm) pentru detectarea modificărilor de poziție ale stațiilor GNSS. Disponibil pentru 74 de stații din Sistemul ROMPOS cu licență VADASE activă. Util pentru corelarea interferențelor cu deplasările poziționale.

Parametri
ParametruTipDescriere
statiestringreqNumele stației
start_datedatereqData start
end_datedatereqData sfârșit
Răspuns
[
  {
    "DataOra": "2026-04-05T14:00:00",
    "East_mm": 2.3,
    "North_mm": -1.1,
    "Up_mm": 4.7
  },
  ...
]

Benzi RF

BandăFrecvență (MHz)ConstelațieDescriere
L11575.42GPSBanda principală GPS, cea mai vulnerabilă la interferențe
L21227.60GPSBanda secundară GPS, utilizată pentru corecții ionosferice
L51176.45GPS / GalileoBandă de siguranță civilă
E11575.42GalileoBanda principală Galileo (co-locată cu L1 GPS)
GLONASS L11598.0625–1605.375GLONASSFDMA, canale 1–6
GLONASS L21242.9375–1248.625GLONASSFDMA secundar

Coduri de eroare

Cod HTTPSemnificație
200Succes
400Parametri lipsă sau invalizi
401Cheie API necesară (endpoint protejat, ex: /flush)
404Stație negăsită sau niciun eveniment
409Conflict (ex: model deja în antrenare)
429Prea multe cereri — limită de rată depășită (vezi Limite de utilizare)
500Eroare internă server (verificați logs)
503Serviciu indisponibil (model nu este antrenat)

Limite de utilizare (rate limiting)

Endpoint-urile publice sunt limitate pe adresă IP pentru a proteja infrastructura. Limitele aplicate:

EndpointLimită
/i, /ce, /sa, /lh/summary60 / minut
/lh120 / minut
/analytics, /trends10 / minut
/api/predict, /api/predict/v120 / minut
/flush admin10 / oră
alte endpoint-uri200 / minut (implicit)

La depășirea limitei, API-ul răspunde cu HTTP 429 Too Many Requests și corpul {"error": "Rate limit exceeded", "retry_after": "..."} — respectați antetul/valoarea de retry înainte de a reîncerca.

Pentru interogări intensive (ex: toate stațiile zilnic), lăsați minim 500 ms între request-uri și preferați endpoint-urile agregate (/analytics, /lh/summary) în loc de interogări individuale per stație.

Exemple

cURL — Predicție pentru Sulina

curl -X POST https://geoveil.ro/api/predict \
  -H "Content-Type: application/json" \
  -d '{"station_code":"SULI","datetime":"2026-05-26T14:00"}'

Python — Last-hour events (stație specifică, limitat)

import requests

resp = requests.get(
    "https://geoveil.ro/lh",
    params={"station_code": "SULI", "limit": 3000}
)
events = resp.json()
for e in events:
    print(f"{e['datetime']}  {e['rfpath']}  {e['centfreq_mhz']} MHz")

JavaScript — Last-hour summary (toate stațiile)

const resp = await fetch("https://geoveil.ro/lh/summary");
const stations = await resp.json();
const threats = stations.filter(s => s.threat_type === "spoofing_candidate");
console.log(`${threats.length} stații cu candidați de spoofing în ultima oră`);

JavaScript — Cross-station correlated

const today = new Date().toISOString().split('T')[0];
const resp = await fetch(
  `https://geoveil.ro/ce?start_date=${today}&end_date=${today}&min_stations=3`
);
const correlated = await resp.json();
console.log(`${correlated.length} correlated event groups today`);

Python — V1 Polar chart data

import requests

resp = requests.get(
  "https://app.rompos.ro/api/v1/i",
  params={"statie": "Sulina", "start_date": "2026-04-05", "end_date": "2026-04-05"}
)
events = resp.json()
for e in events:
    print(f"{e['DataOra']}  {e['BandaRF']}  {e['Frecv_cent_MHz']} MHz")