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.
- Flux live V2: ~340.000 evenimente/zi (date din 26 mai 2026, în creștere); arhivă clasică V1: 549.182 înregistrări
- Motor de detecție spoofing cu 7 indicatori
- Predicție ML: V1 — Classic (LightGBM, ~82% acuratețe, AUC 0.91) recomandat momentan; V2 — Live în reantrenare pe noul set de date
- Actualizare în timp real via streaming TCP asincron
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ă
https://geoveil.ro
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)
Returnează evenimentele de interferență pentru o stație și un interval de date.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| station_code | string | req | Codul stației (ex: SULI) |
| start_date | date | req | Data start (YYYY-MM-DD) |
| end_date | date | req | Data sfârșit (YYYY-MM-DD) |
[
{
"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)
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.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| station_code | string | opt | Filtrare pe stație (ex: SULI) |
| limit | int | opt | Număr maxim de rânduri returnate (ORDER BY datetime DESC). Recomandat: 3000 când station_code este prezent. |
[
{
"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)
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.
Niciun parametru. Returnează toate stațiile active în ultima oră.
[
{
"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âmp | Descriere |
|---|---|
| station_code | Codul stației (ex: SULI) |
| stationid | ID numeric intern |
| count | Total evenimente în ultima oră |
| dom_rfpath | Banda RF dominantă (ex: L1) |
| min_powerloss | Cea mai mare pierdere de putere (dBm, cel mai negativ) |
| buckets | Array de 6 valori: număr evenimente per fereastră de 10 minute (cronologic) |
| threat_type | Tipul de amenințare spoofing (null dacă fără analiză azi) |
| confidence | Scor de încredere analiză spoofing (0–1) |
| severity | HIGH / MEDIUM / LOW / null |
GET /ce — Evenimente corelate inter-stații (V2)
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).
| Parametru | Tip | Descriere | |
|---|---|---|---|
| start_date | date | req | Data start |
| end_date | date | req | Data sfârșit |
| min_stations | int | opt | Număr minim stații (implicit: 2) |
[
{
"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)
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ă.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| station_code | string | req | Codul stației |
| start_date | date | req | Data start |
| end_date | date | req | Data sfârșit |
[
{
"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..."
},
...
]
| Valoare | Descriere |
|---|---|
| spoofing_candidate | Semnal cu caracteristici de spoofing (7 indicatori activi) |
| matched_spectrum | Spectru care coincide cu o sursă de spoofing cunoscut |
| meaconing | Reemisie întârziată (meaconing) |
| clean | Fără amenințare detectată |
GET /analytics — Statistici agregate (V2)
Statistici agregate: top stații după constelație, distribuție frecvențe, heatmap oră×zi, scatter BW/PL, trend zilnic, weekday/weekend.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| days | int | opt | Număr zile înapoi (implicit: 30) |
GET /trends — Tendințe și matrice corelații (V2)
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)
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.
| Câmp | Tip | Descriere | |
|---|---|---|---|
| station_code | string | req | Codul stației (ex: "SULI") |
| datetime | string | req | ISO 8601 (ex: "2026-05-26T14:00") |
POST /api/predict
Content-Type: application/json
{
"station_code": "SULI",
"datetime": "2026-05-26T14:00"
}
{
"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
Starea curentă a modelului LightGBM: dacă este antrenat, în curs de antrenare, acuratețe, importanța caracteristicilor.
{
"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
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").
{
"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
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.
Niciun body necesar.
{ "status": "retraining started" }
{ "error": "Training already in progress" }
GET /i — Evenimente (V1 Classic)
Endpoint clasic — returnează evenimentele pentru o stație, cu câmpuri în format moștenire. Folosit de graficul polar V1.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| statie | string | req | Numele stației (ex: Sulina) |
| start_date | date | req | Data start (YYYY-MM-DD) |
| end_date | date | req | Data sfârșit (YYYY-MM-DD) |
[
{
"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)
Statistici agregate per bandă RF: număr apariții, CF min/max, BW max, PL max, interval temporal.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| statie | string | req | Numele stației |
| start_date | date | req | Data start |
| end_date | date | req | Data sfârșit |
GET /correlated — Corelate (V1)
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ă).
| Parametru | Tip | Descriere | |
|---|---|---|---|
| start_date | date | req | Data start |
| end_date | date | req | Data sfârșit |
GET /vadase — Date VADASE (V1)
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.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| statie | string | req | Numele stației |
| start_date | date | req | Data start |
| end_date | date | req | Data sfârșit |
[
{
"DataOra": "2026-04-05T14:00:00",
"East_mm": 2.3,
"North_mm": -1.1,
"Up_mm": 4.7
},
...
]
Benzi RF
| Bandă | Frecvență (MHz) | Constelație | Descriere |
|---|---|---|---|
| L1 | 1575.42 | GPS | Banda principală GPS, cea mai vulnerabilă la interferențe |
| L2 | 1227.60 | GPS | Banda secundară GPS, utilizată pentru corecții ionosferice |
| L5 | 1176.45 | GPS / Galileo | Bandă de siguranță civilă |
| E1 | 1575.42 | Galileo | Banda principală Galileo (co-locată cu L1 GPS) |
| GLONASS L1 | 1598.0625–1605.375 | GLONASS | FDMA, canale 1–6 |
| GLONASS L2 | 1242.9375–1248.625 | GLONASS | FDMA secundar |
Coduri de eroare
| Cod HTTP | Semnificație |
|---|---|
| 200 | Succes |
| 400 | Parametri lipsă sau invalizi |
| 401 | Cheie API necesară (endpoint protejat, ex: /flush) |
| 404 | Stație negăsită sau niciun eveniment |
| 409 | Conflict (ex: model deja în antrenare) |
| 429 | Prea multe cereri — limită de rată depășită (vezi Limite de utilizare) |
| 500 | Eroare internă server (verificați logs) |
| 503 | Serviciu indisponibil (model nu este antrenat) |
Limite de utilizare (rate limiting)
Endpoint-urile publice sunt limitate pe adresă IP pentru a proteja infrastructura. Limitele aplicate:
| Endpoint | Limită |
|---|---|
/i, /ce, /sa, /lh/summary | 60 / minut |
/lh | 120 / minut |
/analytics, /trends | 10 / minut |
/api/predict, /api/predict/v1 | 20 / minut |
/flush admin | 10 / oră |
| alte endpoint-uri | 200 / 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")