← Volver a proyectosProyecto Destacado

Road Report

FlutterFastAPIPostgreSQLGeolocatorRiverpod

Aplicacion movil ciudadana para reportar infracciones de transporte publico en tiempo real. El sistema captura evidencia georeferenciada y valida automaticamente los reportes usando multiples fuentes de datos.

Contexto

El transporte publico en muchas ciudades latinoamericanas presenta problemas de seguridad: exceso de velocidad, paradas en lugares prohibidos, y comportamiento temerario. Los ciudadanos no tenian una forma efectiva de reportar estas situaciones con evidencia verificable.

Funcionalidades

Grabacion de Rutas GPS

La app captura continuamente la posicion del usuario mientras viaja:

class RouteRecorder {
  final List<RoutePoint> _points = [];
  StreamSubscription? _subscription;

  void startRecording() {
    _subscription = Geolocator.getPositionStream(
      locationSettings: LocationSettings(
        accuracy: LocationAccuracy.high,
        distanceFilter: 10, // metros
      ),
    ).listen((position) {
      _points.add(RoutePoint(
        lat: position.latitude,
        lng: position.longitude,
        speed: position.speed, // m/s
        timestamp: DateTime.now(),
      ));

      // Detectar exceso de velocidad
      if (position.speed > SPEED_LIMIT_MPS) {
        _triggerSpeedAlert(position);
      }
    });
  }
}

Deteccion de Exceso de Velocidad

Zona Limite Alerta
Urbana 50 km/h Amarilla
Escolar 30 km/h Roja
Autopista 120 km/h Amarilla

El sistema compara la velocidad actual contra limites conocidos de la zona y genera alertas automaticas que el usuario puede confirmar como reporte.

Captura de Evidencia

  • Fotos: Captura de patente, interior del vehiculo
  • Video: Clips cortos de situaciones peligrosas
  • Audio: Grabacion de ambiente
  • Metadata: GPS, timestamp, velocidad, direccion

Sistema de Scoring

Cada reporte recibe un puntaje de confiabilidad basado en:

def calculate_report_score(report: Report) -> float:
    score = 0.0

    # Evidencia multimedia
    if report.has_photo: score += 20
    if report.has_video: score += 30

    # Consistencia GPS
    if report.route_data:
        gps_quality = calculate_gps_consistency(report.route_data)
        score += gps_quality * 20

    # Historico del usuario
    user_reliability = get_user_reliability_score(report.user_id)
    score += user_reliability * 15

    # Corroboracion
    similar_reports = find_similar_reports(report)
    if len(similar_reports) > 0:
        score += min(len(similar_reports) * 5, 15)

    return min(score, 100)

Arquitectura

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   Flutter    │────▶│   FastAPI    │────▶│  PostgreSQL  │
│     App      │     │   Backend    │     │   + PostGIS  │
└──────────────┘     └──────────────┘     └──────────────┘
       │                    │
       │                    ▼
       │             ┌──────────────┐
       └────────────▶│     S3       │
         (media)     │   Storage    │
                     └──────────────┘

Backend FastAPI

@router.post("/reports")
async def create_report(
    report: ReportCreate,
    background_tasks: BackgroundTasks,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    # Crear reporte
    db_report = Report(**report.dict(), user_id=current_user.id)
    db.add(db_report)
    db.commit()

    # Procesar en background
    background_tasks.add_task(
        process_report_score,
        report_id=db_report.id
    )
    background_tasks.add_task(
        check_similar_reports,
        report_id=db_report.id
    )

    return db_report

Estado con Riverpod

final activeRouteProvider = StateNotifierProvider<RouteNotifier, RouteState>(
  (ref) => RouteNotifier(),
);

final nearbyReportsProvider = FutureProvider.family<List<Report>, LatLng>(
  (ref, location) async {
    final api = ref.read(apiProvider);
    return api.getNearbyReports(location, radiusKm: 1);
  },
);

Desafios Tecnicos

Precision GPS en Movimiento

El GPS puede ser impreciso en vehiculos en movimiento. Implementamos: - Filtro de Kalman para suavizar la ruta - Descarte de puntos con precision > 20 metros - Interpolacion para gaps de senal

Consumo de Bateria

La grabacion continua de GPS consume bateria. Optimizaciones: - Distance filter de 10m (no cada segundo) - Batch upload cuando hay WiFi - Modo "dormido" cuando no hay movimiento

Validacion de Reportes Falsos

Para evitar reportes maliciosos: - Scoring automatico basado en multiples factores - Verificacion cruzada con otros usuarios - Historico de confiabilidad por usuario - Moderacion manual para reportes con score bajo

Resultados

  • 500+ usuarios activos en beta
  • 2,000+ reportes procesados
  • 85% de reportes con score > 70
  • < 5% de reportes identificados como falsos
← Volver a proyectosVer todos →