Skip to content
QsumaPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

------------------------------------------------------------

🧩 Ejemplos de Extensión Común

------------------------------------------------------------

1. Añadir un nuevo setting

Paso 1: Agrega el campo en AppSettings y su persistencia.

class AppSettings {
	final bool newFeatureEnabled;
	// ...
	const AppSettings({
		this.newFeatureEnabled = false,
		// ...
	});
	// Añade en copyWith, persist, load, y claves de SharedPreferences
}

Paso 2: Expón el setter en SettingsNotifier:

void setNewFeatureEnabled(bool v) => _update(state.copyWith(newFeatureEnabled: v));

Paso 3: Añade el control en la UI (ejemplo en SettingsPagePlaceholder):

_buildSwitchTile(
	'Nueva función',
	'Activa la nueva funcionalidad',
	Icons.new_releases,
	settings.newFeatureEnabled,
	notifier.setNewFeatureEnabled,
)

2. Añadir una nueva preferencia de ruta

Paso 1: Agrega la opción en AppSettings.routePreference y en la UI (dropdown). Paso 2: Actualiza el mapeo en RoutingEngine para soportar la nueva preferencia.

switch (preference) {
	case 'avoidFerries':
		params['exclude'] = 'ferry';
		break;
	// ...
}

Paso 3: Añade la lógica en la UI para mostrar el nuevo tipo de ruta.

3. Añadir un nuevo campo a vehículos

Paso 1: Modifica el modelo en features/vehicles/domain/vehicle_profile.dart:

@freezed
class VehicleProfile with _$VehicleProfile {
	const factory VehicleProfile({
		required String id,
		required String name,
		double? dragCoefficient,
		// ...
	}) = _VehicleProfile;
}

Paso 2: Ejecuta flutter pub run build_runner build para regenerar modelos. Paso 3: Añade el campo en la UI de gestión de vehículos.

4. Añadir un nuevo idioma/localización

Paso 1: Crea lib/l10n/app_fr.arb (por ejemplo para francés). Paso 2: Añade las traducciones necesarias. Paso 3: Ejecuta flutter gen-l10n para generar el soporte. Paso 4: Añade Locale('fr') a supportedLocales en main.dart.

5. Añadir un test unitario para lógica nueva

Paso 1: Crea un archivo en test/ (ej: test/new_logic_test.dart). Paso 2: Escribe el test:

import 'package:flutter_test/flutter_test.dart';
import 'package:ev_map/lib/core/new_logic.dart';

void main() {
	test('Nueva lógica funciona', () {
		expect(miFuncion(2), 4);
	});
}

6. Añadir un nuevo tipo de alternativa de ruta

Paso 1: Extiende RouteAlternative en route_models.dart si necesitas nuevos campos. Paso 2: Actualiza la lógica de generación en el engine y la UI para mostrar el nuevo dato.


Estos ejemplos cubren los casos más comunes de extensión. Para cualquier cambio mayor, sigue el patrón de separación por dominio y mantén la documentación actualizada en el README.

------------------------------------------------------------

🛠️ Developer Guide & Onboarding

------------------------------------------------------------

📦 Project Structure

lib/
	main.dart                # App entrypoint, navigation, localization
	core/                    # AppSettings, logger, offline map service, color utils
	features/
		routing/               # Routing engine, models, UI, Mapbox integration
			data/                # MapboxDirectionsRepository
			domain/              # RoutePlan models (freezed)
			presentation/        # Route planning UI & providers
		vehicles/              # Vehicle profiles, EV curves (freezed)
	l10n/                    # Localization ARB files, generated localizations
	navigation/              # Map globals
	search/                  # Search delegate
	widgets/                 # Reusable UI widgets (search pill)
test/
	...                      # Unit and integration tests

⚙️ State Management

  • Riverpod for all app state (settings, routing, offline, etc).
  • Settings persisted via SharedPreferences (core/app_settings.dart).
  • Routing state in features/routing/routing_notifier.dart.

🌐 Localization (i18n)

  • ARB files: lib/l10n/app_en.arb, app_es.arb.
  • Add new language: create app_xx.arb, run flutter gen-l10n.
  • All UI strings use AppLocalizations (see main.dart).

🚗 Routing Engine

  • Abstracted via RoutingEngine interface.
  • Implementations: MockRoutingEngine (offline/synthetic), MapboxDirectionsRoutingEngine (real API).
  • Preference mapping: fastest/shortest/eco/avoidTolls/avoidHighways.
  • Geometry decoded with custom polyline6 logic.

🔋 Vehicles

  • Vehicle profiles and EV curves in features/vehicles/domain/ (freezed models).
  • Extend by adding new fields to vehicle_profile.dart and regenerate with build_runner.

🗺️ Offline Maps

  • Managed via core/offline_map_service.dart.
  • Settings in AppSettings (offlineEnabled, offlineMaxCacheMb).

🧪 Testing

  • All tests in test/ folder.
  • Run with flutter test.
  • Si los tests se cuelgan: verifica inicialización de plugins, añade TestWidgetsFlutterBinding.ensureInitialized() al inicio del test.
  • Para lógica Dart pura, extrae funciones fuera de clases de widgets.

➕ Extending the App

  • Para añadir settings: actualiza AppSettings, SettingsNotifier, y la UI en SettingsPagePlaceholder.
  • Para nuevas funciones de rutas: extiende RoutingEngine, actualiza la UI en RoutePlanningPage.
  • Para analíticas de vehículos: actualiza modelos en features/vehicles/domain/, añade UI en presentación de vehículos.

🛠️ Troubleshooting

  • Si falla la localización: revisa los archivos ARB y ejecuta flutter gen-l10n.
  • Si falla el routing: revisa .env para el token de Mapbox, verifica red, el fallback a mock engine es automático.
  • Si los tests se cuelgan: aísla con un test trivial, revisa dependencias de plugins, asegura inicialización correcta del binding.

🚀 Onboarding for New Developers

  • Clona el repo, crea .env con el token de Mapbox.
  • Ejecuta flutter pub get.
  • Explora main.dart para el entrypoint y navegación.
  • Revisa core/app_settings.dart para settings y persistencia.
  • Lógica de rutas: comienza con features/routing/routing_notifier.dart y routing_engine.dart.
  • UI: ve a features/routing/presentation/route_planning_page.dart y ModernMapPage en main.dart.
  • Para localización, revisa lib/l10n/ y su uso en widgets de UI.
  • Para vehículos, revisa features/vehicles/domain/vehicle_profile.dart.
  • Para mapas offline, revisa core/offline_map_service.dart.

📚 Further Reading & Contribution

🤝 Support, Feedback & Contribution

Abre issues o pull requests para bugs, mejoras o nuevas funcionalidades. Documenta cualquier decisión arquitectónica nueva en este README para futuros mantenedores.

EV-Map - Modern Electric Vehicle Navigation App

A comprehensive Flutter application for electric vehicle navigation, route planning, and charging station management, built with modern UI/UX based on professional navigation app standards.

✨ Features

🗺️ Modern Navigation Interface

  • Real-time Navigation: Turn-by-turn directions with visual indicators
  • Trip Information Cards: Distance remaining, arrival time, and battery predictions
  • Interactive Controls: Route termination, fullscreen mode, and audio navigation
  • Professional Dark Theme: Modern dark UI optimized for in-vehicle use

🛣️ Intelligent Route Planning

  • Destination Search: Smart search functionality for route planning
  • Charging Stop Integration: Automatic charging station recommendations
  • Battery Level Monitoring: Real-time battery predictions for each route segment
  • Route History: Organized history of previous trips with details

🔋 Vehicle Management

  • EV Battery Monitoring: Visual battery level indicators with color coding
  • Vehicle Profiles: Support for multiple electric vehicles
  • Range Calculations: Accurate range estimates based on vehicle specifications
  • Charging Status: Real-time charging information and predictions

⚙️ Smart Preferences

  • Theme Customization: Dark/light theme toggle
  • Notification Settings: Customizable alerts for charging and navigation
  • Location Services: Precise location tracking with permission management
  • User Preferences: Personalized settings for optimal user experience

🧭 Smart Camera & Map Interaction Logic

Robust, smooth camera behavior designed to avoid jank and accidental recenters while preserving user control.

Core Behaviors:

  • Dual Mode Tracking: Automatic live tracking (_isTrackingLocation) pauses instantly when the user interacts (pointer down) and resumes only after a controlled recenter.
  • Interaction Detection: Low-level Listener (pointer events) replaces gesture stacks to eliminate gesture conflicts and ensure precise start/end interaction timing.
  • Deferred Auto Recenter: A timer (2.5s) starts when the user stops touching the map; on expiry it animates back to the last known position with a cinematic easeTo (tag: AutoRecenter).
  • Single Animation Guard: _animateCamera() centralizes all camera motions and enforces a concurrency lock via _cameraAnimating to prevent overlapping easeTo calls (root cause of frame-by-frame stutter).
  • Throttled Live Tracking: While tracking is active, location stream updates are rate-limited (≥900 ms, _locationUpdateMinIntervalMs) and skipped if an animation is in progress—removing micro step animations.
  • Distance-Based Center Detection: _checkIfCameraCentered() compares camera center vs user location (≤50 m threshold) to decide if the floating recenter button should show or hide.
  • Floating Recenter Button: Appears only when user moved the map away; on press it (1) cancels any pending auto timer, (2) temporarily disables tracking, (3) performs a smooth easeTo (tag: BtnRecenter), (4) re-enables tracking and hides itself.
  • Fallback Safety: If the main auto recenter animation throws, a fallback animation (AutoRecenterFallback) runs with simpler parameters.
  • State Isolation: No animation directly manipulates unrelated UI—camera logic lives in a contained flow making refactors safer.
  • Extensible Tags: All camera motions emit start/end logs with a semantic tag to simplify profiling and regression diagnosis.

Design Invariants (Do NOT break):

  • Never call mapboxMap.easeTo directly—always use _animateCamera() to preserve concurrency guarantees and logging.
  • Always set _isTrackingLocation = false before a manual or button-initiated recenter to avoid the live stream fighting the animation.
  • Respect the 50 m centering heuristic unless UX requirements change; adjust both logic and docs together.
  • Keep throttling interval aligned with (or slightly below) the shortest tracking animation duration to avoid overlap.

Modification Guidelines:

  • To add new camera behaviors (e.g., route preview), create a new tag (e.g., RoutePreview) and invoke _animateCamera()—do not duplicate animation code.
  • If changing animation durations, evaluate whether _locationUpdateMinIntervalMs must also change.
  • If adjusting interaction logic, ensure pointer down cancels timers and pointer up restarts them; otherwise auto recenter may trigger prematurely.

Resumen (Español): La cámara implementa un sistema inteligente con: detección directa de interacción táctil, temporizador diferido para recentrado automático, botón flotante contextual, guardia de concurrencia para animaciones, y limitación de frecuencia de actualizaciones de ubicación para evitar movimientos a saltos. Toda animación pasa por _animateCamera() que serializa transiciones y emite logs para depuración.

This section exists to prevent future regressions in smoothness and interaction feel—update it with any behavioral change.

🏗️ Technical Architecture

Core Technologies

  • Flutter SDK: 3.32.6+ for cross-platform development
  • Mapbox Integration: Professional mapping and navigation services
  • Riverpod State Management: Robust state management with error handling
  • Material Design 3: Modern UI components and theming

Key Components

ModernEvMapApp()          // Main app with bottom navigation
├── ModernMapPage()       // Navigation interface with real-time info
├── ModernRoutesPage()    // Route history and trip planning
├── ModernVehiclesPage()  // EV management and battery monitoring
└── ModernProfilePage()   // Settings and user preferences

Navigation Structure

  • Bottom Navigation: 4-tab interface (Map, Routes, Vehicles, Profile)
  • Route Search: Integrated search with charging station recommendations
  • Interactive Elements: Responsive buttons with user feedback
  • State Persistence: Maintains app state across sessions

🎨 UI/UX Design

Color Scheme

  • Primary Background: #1A1A1A (Professional dark)
  • Secondary Background: #2A2A2A (Card surfaces)
  • Accent Color: #007AFF (Apple-style blue)
  • Success Indicators: Green for battery/charging status
  • Warning Indicators: Orange/red for low battery alerts

Design Principles

  • Dark-First Design: Optimized for in-vehicle use and night driving
  • High Contrast: Excellent readability in all lighting conditions
  • Touch-Friendly: Large interactive elements for easy mobile use
  • Information Hierarchy: Clear visual hierarchy for navigation data

🔧 Setup & Installation

Prerequisites

  • Flutter SDK 3.32.6+
  • Android SDK with API level 35+
  • Mapbox account and API token

Environment Configuration

  1. Create .env file in project root:
MAPBOX_PUBLIC_TOKEN=your_mapbox_token_here
API_BASE_URL=https://api.mapbox.com
  1. Install dependencies:
flutter pub get
  1. Run on device:
flutter run -d your_device_id

📱 Device Compatibility

Tested Devices

  • Samsung Galaxy S24 Ultra: Full functionality confirmed
  • Android 15 (API 35): Primary target platform
  • iOS Support: Compatible with iOS 12.0+

Performance Optimization

  • NDK 27.0.12077973: Optimized native performance
  • Gradle Build: Streamlined build process
  • Memory Management: Efficient state management with Riverpod

🚀 Modern UI Implementation

Based on professional navigation app references, the UI includes:

Navigation Interface

  • Gradient header with turn-by-turn directions
  • Information cards showing distance, time, and battery
  • Action buttons for route control
  • Real-time trip monitoring

Route Planning

  • Smart destination search
  • Visual route overview with charging stops
  • Battery level predictions at each stop
  • Interactive trip planning tools

Vehicle Dashboard

  • Visual battery level indicators
  • Vehicle specifications display
  • Range calculations and predictions
  • Multiple vehicle support

Settings & Preferences

  • Modern switch controls
  • Organized settings categories
  • Clear descriptions for each option
  • Responsive feedback for user actions

🛠️ Development Status

Completed Features ✅

  • Modern bottom navigation interface
  • Professional dark theme implementation
  • Interactive navigation controls
  • Route planning with charging integration
  • Vehicle management dashboard
  • Settings and preferences panel
  • Real-time battery monitoring
  • Mapbox API integration
  • Error handling and fallbacks

🧭 Routing Engine & Mapbox Directions Integration

The app abstracts routing behind a RoutingEngine interface with two implementations:

  • MockRoutingEngine: Provides synthetic geometries and deterministic alternative statistics for offline/demo usage.
  • MapboxDirectionsRoutingEngine: Real integration with Mapbox Directions (driving-traffic profile) returning polyline6 geometries and enriched metadata.

Environment Variables

Configure tokens in a root .env file (already loaded in main()):

MAPBOX_DIRECTIONS_TOKEN=pk.your_mapbox_token
# Fallback names also recognized:
MAPBOX_ACCESS_TOKEN=pk.alt_token

If neither token is present the app automatically falls back to the mock engine—no crashes, the UI still shows alternatives (synthetic).

Preference Mapping

User route preference (stored in AppSettings.routePreference) maps to Mapbox query parameters:

  • fastest / shortest / eco (default): no exclude
  • avoidTolls: exclude=toll
  • avoidHighways: exclude=motorway

Geometry

  • Requests use geometries=polyline6 and overview=full.
  • Decoded via a custom decodePolyline6 helper; malformed input truncates gracefully instead of throwing.

Enhanced Heuristics

When requestSteps=true, the engine parses leg steps to infer:

  • hasTolls: Matches keywords (toll, peaje).
  • usesHighway: Regex on step name/ref (autopista, motorway, highway, A\d, M\d, I-\d, etc.). If steps were not requested, a conservative placeholder heuristic assigns tolls/highway flags based on index for diversity.

Energy Model (Interim)

energyKwh = distanceKm * consumptionKwhPerKm with speed-based multiplier:

  • 100 km/h → +12%

  • 60–100 km/h → +5% Future improvements: incorporate elevation gain (Mapbox Terrain), temperature, vehicle-specific drag coefficients and battery SOC.

Error Handling & Fallback

Common Mapbox code responses are mapped to localized messages:

  • NoRoute → "No se encontró ruta."
  • NoSegment → "No hay segmento de carretera cercano al punto."
  • InvalidInput → "Entrada inválida..."
  • Unauthorized → Token issues. Any error (network, parsing, unexpected structure) triggers synthetic fallback routes so the UI remains usable. RoutingState.errorMessage surfaces feedback through a transient in-map card.

Testing

Added tests validating:

  • Polyline6 decoding sanity.
  • Preference → exclude query mapping.
  • Fallback geometry preservation on simulated network failure.

To run tests:

flutter test

Extending

  • To add richer annotations (e.g., congestion, elevation), request annotations=congestion,maxspeed and extend parsing.
  • For EV-optimized routing (charging stops), consider Mapbox EV Routing or integrate an external planner; adapt engine to post-process via intermediate waypoints.

Security Notes

  • Keep tokens out of version control (.gitignore .env).
  • Rotate compromised tokens promptly; unauthorized errors will surface in-app.

Interactive Elements ✅

  • Button press feedback with snackbars
  • Navigation between app sections
  • Route search functionality
  • Settings toggles and controls
  • User preference management

📞 Support & Feedback

The modern UI implementation is based on professional navigation app standards and provides a comprehensive electric vehicle navigation experience. All interactive elements are functional with user feedback, and the app maintains a professional appearance suitable for in-vehicle use.

For technical support or feature requests, the codebase is well-documented with clear component separation and maintainable architecture.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages