aee0f09db8
- Datafabrik: Dockerfile fix, agentorkestrering fungerar - Vision: Identify-modell, FAISS, OCR alla testade - API: Alla 7 integrationstester passerade - Upplösare: Entitetsupplösning verifierad
193 lines
5.6 KiB
Python
193 lines
5.6 KiB
Python
"""
|
|
RIVP Pilot 1 - Real Infrastructure Monitoring
|
|
Reads from SQLite database with real road network and generated observations
|
|
"""
|
|
from fastapi import APIRouter
|
|
import sqlite3
|
|
import os
|
|
from typing import List, Optional
|
|
from datetime import datetime
|
|
|
|
router = APIRouter(prefix="/rivp-pilot1", tags=["rivp_pilot1"])
|
|
|
|
DB_PATH = "/home/bernt/.openclaw/workspace/rivp-pilot-1/rivp.db"
|
|
|
|
def get_db():
|
|
conn = sqlite3.connect(DB_PATH)
|
|
conn.row_factory = sqlite3.Row
|
|
return conn
|
|
|
|
@router.get("/public/roads")
|
|
async def get_roads(county: Optional[str] = None, road_type: Optional[str] = None):
|
|
"""Get all roads with optional filtering"""
|
|
conn = get_db()
|
|
c = conn.cursor()
|
|
|
|
query = "SELECT * FROM roads WHERE 1=1"
|
|
params = []
|
|
|
|
if county:
|
|
query += " AND county = ?"
|
|
params.append(county)
|
|
if road_type:
|
|
query += " AND type = ?"
|
|
params.append(road_type)
|
|
|
|
query += " ORDER BY county, name"
|
|
|
|
c.execute(query, params)
|
|
roads = [dict(row) for row in c.fetchall()]
|
|
|
|
# Get observation count for each road
|
|
for road in roads:
|
|
c.execute("SELECT COUNT(*) FROM observations WHERE road_id = ?", (road['id'],))
|
|
road['observation_count'] = c.fetchone()[0]
|
|
|
|
conn.close()
|
|
return {
|
|
"total": len(roads),
|
|
"counties": list(set(r['county'] for r in roads)),
|
|
"roads": roads
|
|
}
|
|
|
|
@router.get("/public/observations")
|
|
async def get_observations(road_id: Optional[int] = None,
|
|
observation_type: Optional[str] = None,
|
|
severity: Optional[str] = None,
|
|
source: Optional[str] = None,
|
|
verified_only: bool = False):
|
|
"""Get observations with filtering"""
|
|
conn = get_db()
|
|
c = conn.cursor()
|
|
|
|
query = """
|
|
SELECT o.*, r.name as road_name, r.county
|
|
FROM observations o
|
|
JOIN roads r ON o.road_id = r.id
|
|
WHERE 1=1
|
|
"""
|
|
params = []
|
|
|
|
if road_id:
|
|
query += " AND o.road_id = ?"
|
|
params.append(road_id)
|
|
if observation_type:
|
|
query += " AND o.observation_type = ?"
|
|
params.append(observation_type)
|
|
if severity:
|
|
query += " AND o.severity = ?"
|
|
params.append(severity)
|
|
if source:
|
|
query += " AND o.source = ?"
|
|
params.append(source)
|
|
if verified_only:
|
|
query += " AND o.verified = 1"
|
|
|
|
query += " ORDER BY o.detected_date DESC"
|
|
|
|
c.execute(query, params)
|
|
observations = [dict(row) for row in c.fetchall()]
|
|
|
|
conn.close()
|
|
return {
|
|
"total": len(observations),
|
|
"observations": observations
|
|
}
|
|
|
|
@router.get("/public/dashboard")
|
|
async def get_dashboard():
|
|
"""Get dashboard statistics"""
|
|
conn = get_db()
|
|
c = conn.cursor()
|
|
|
|
# Total roads
|
|
c.execute("SELECT COUNT(*) FROM roads")
|
|
total_roads = c.fetchone()[0]
|
|
|
|
# Total observations
|
|
c.execute("SELECT COUNT(*) FROM observations")
|
|
total_observations = c.fetchone()[0]
|
|
|
|
# By type
|
|
c.execute("SELECT type, COUNT(*) FROM roads GROUP BY type")
|
|
roads_by_type = {row[0]: row[1] for row in c.fetchall()}
|
|
|
|
# By county
|
|
c.execute("SELECT county, COUNT(*) FROM roads GROUP BY county ORDER BY COUNT(*) DESC")
|
|
roads_by_county = [{"county": row[0], "count": row[1]} for row in c.fetchall()]
|
|
|
|
# Observations by type
|
|
c.execute("SELECT observation_type, COUNT(*) FROM observations GROUP BY observation_type")
|
|
obs_by_type = {row[0]: row[1] for row in c.fetchall()}
|
|
|
|
# Observations by source
|
|
c.execute("SELECT source, COUNT(*) FROM observations GROUP BY source")
|
|
obs_by_source = {row[0]: row[1] for row in c.fetchall()}
|
|
|
|
# Observations by severity
|
|
c.execute("SELECT severity, COUNT(*) FROM observations GROUP BY severity")
|
|
obs_by_severity = {row[0]: row[1] for row in c.fetchall()}
|
|
|
|
# Verified vs unverified
|
|
c.execute("SELECT verified, COUNT(*) FROM observations GROUP BY verified")
|
|
verification = {row[0]: row[1] for row in c.fetchall()}
|
|
|
|
# Average confidence
|
|
c.execute("SELECT AVG(confidence) FROM observations")
|
|
avg_confidence = c.fetchone()[0]
|
|
|
|
# Recent observations (last 30 days)
|
|
c.execute("""
|
|
SELECT COUNT(*) FROM observations
|
|
WHERE detected_date >= date('now', '-30 days')
|
|
""")
|
|
recent_obs = c.fetchone()[0]
|
|
|
|
conn.close()
|
|
|
|
return {
|
|
"roads": {
|
|
"total": total_roads,
|
|
"by_type": roads_by_type,
|
|
"by_county": roads_by_county[:10]
|
|
},
|
|
"observations": {
|
|
"total": total_observations,
|
|
"by_type": obs_by_type,
|
|
"by_source": obs_by_source,
|
|
"by_severity": obs_by_severity,
|
|
"verification": verification,
|
|
"average_confidence": round(avg_confidence, 2),
|
|
"last_30_days": recent_obs
|
|
}
|
|
}
|
|
|
|
@router.get("/public/map-data")
|
|
async def get_map_data(county: Optional[str] = None):
|
|
"""Get observation data for map visualization"""
|
|
conn = get_db()
|
|
c = conn.cursor()
|
|
|
|
query = """
|
|
SELECT o.id, o.latitude, o.longitude, o.observation_type,
|
|
o.confidence, o.severity, o.detected_date, o.verified,
|
|
r.name as road_name, r.county
|
|
FROM observations o
|
|
JOIN roads r ON o.road_id = r.id
|
|
WHERE 1=1
|
|
"""
|
|
params = []
|
|
|
|
if county:
|
|
query += " AND r.county = ?"
|
|
params.append(county)
|
|
|
|
c.execute(query, params)
|
|
points = [dict(row) for row in c.fetchall()]
|
|
|
|
conn.close()
|
|
return {
|
|
"total": len(points),
|
|
"points": points
|
|
}
|