using LocationTrackerApp.Components; using LocationTrackerApp.Models; namespace LocationTrackerApp; public partial class MainPage : ContentPage { private bool _isTracking = false; private List _trackedLocations = new(); public MainPage() { InitializeComponent(); InitializeMap(); } private void InitializeMap() { // The OpenStreetMapView initializes itself with a default location // Add some dummy location data to demonstrate heat map functionality AddDummyLocationData(); } private void AddDummyLocationData() { // Add dummy location data around San Francisco Bay Area to demonstrate heat map var dummyLocations = new List { // Golden Gate Bridge area (high frequency) new LocationData { Latitude = 37.8199, Longitude = -122.4783, Timestamp = DateTime.UtcNow.AddMinutes(-30) }, new LocationData { Latitude = 37.8200, Longitude = -122.4780, Timestamp = DateTime.UtcNow.AddMinutes(-29) }, new LocationData { Latitude = 37.8201, Longitude = -122.4777, Timestamp = DateTime.UtcNow.AddMinutes(-28) }, new LocationData { Latitude = 37.8198, Longitude = -122.4785, Timestamp = DateTime.UtcNow.AddMinutes(-27) }, new LocationData { Latitude = 37.8202, Longitude = -122.4775, Timestamp = DateTime.UtcNow.AddMinutes(-26) }, // Fisherman's Wharf area (medium frequency) new LocationData { Latitude = 37.8080, Longitude = -122.4177, Timestamp = DateTime.UtcNow.AddMinutes(-25) }, new LocationData { Latitude = 37.8085, Longitude = -122.4175, Timestamp = DateTime.UtcNow.AddMinutes(-24) }, new LocationData { Latitude = 37.8082, Longitude = -122.4180, Timestamp = DateTime.UtcNow.AddMinutes(-23) }, // Union Square area (medium frequency) new LocationData { Latitude = 37.7879, Longitude = -122.4075, Timestamp = DateTime.UtcNow.AddMinutes(-22) }, new LocationData { Latitude = 37.7882, Longitude = -122.4078, Timestamp = DateTime.UtcNow.AddMinutes(-21) }, new LocationData { Latitude = 37.7877, Longitude = -122.4072, Timestamp = DateTime.UtcNow.AddMinutes(-20) }, // Mission District area (low frequency) new LocationData { Latitude = 37.7599, Longitude = -122.4148, Timestamp = DateTime.UtcNow.AddMinutes(-19) }, new LocationData { Latitude = 37.7602, Longitude = -122.4150, Timestamp = DateTime.UtcNow.AddMinutes(-18) }, // Castro District area (low frequency) new LocationData { Latitude = 37.7611, Longitude = -122.4350, Timestamp = DateTime.UtcNow.AddMinutes(-17) }, // SOMA area (medium frequency) new LocationData { Latitude = 37.7749, Longitude = -122.4194, Timestamp = DateTime.UtcNow.AddMinutes(-16) }, new LocationData { Latitude = 37.7752, Longitude = -122.4197, Timestamp = DateTime.UtcNow.AddMinutes(-15) }, new LocationData { Latitude = 37.7747, Longitude = -122.4191, Timestamp = DateTime.UtcNow.AddMinutes(-14) }, new LocationData { Latitude = 37.7750, Longitude = -122.4194, Timestamp = DateTime.UtcNow.AddMinutes(-13) }, // Financial District area (high frequency) new LocationData { Latitude = 37.7946, Longitude = -122.3998, Timestamp = DateTime.UtcNow.AddMinutes(-12) }, new LocationData { Latitude = 37.7949, Longitude = -122.4001, Timestamp = DateTime.UtcNow.AddMinutes(-11) }, new LocationData { Latitude = 37.7944, Longitude = -122.3995, Timestamp = DateTime.UtcNow.AddMinutes(-10) }, new LocationData { Latitude = 37.7952, Longitude = -122.4004, Timestamp = DateTime.UtcNow.AddMinutes(-9) }, new LocationData { Latitude = 37.7947, Longitude = -122.3999, Timestamp = DateTime.UtcNow.AddMinutes(-8) }, new LocationData { Latitude = 37.7950, Longitude = -122.4002, Timestamp = DateTime.UtcNow.AddMinutes(-7) }, // North Beach area (low frequency) new LocationData { Latitude = 37.8044, Longitude = -122.4098, Timestamp = DateTime.UtcNow.AddMinutes(-6) }, // Chinatown area (medium frequency) new LocationData { Latitude = 37.7941, Longitude = -122.4078, Timestamp = DateTime.UtcNow.AddMinutes(-5) }, new LocationData { Latitude = 37.7944, Longitude = -122.4081, Timestamp = DateTime.UtcNow.AddMinutes(-4) }, new LocationData { Latitude = 37.7938, Longitude = -122.4075, Timestamp = DateTime.UtcNow.AddMinutes(-3) }, // Marina District area (low frequency) new LocationData { Latitude = 37.8026, Longitude = -122.4430, Timestamp = DateTime.UtcNow.AddMinutes(-2) }, // Presidio area (low frequency) new LocationData { Latitude = 37.7989, Longitude = -122.4662, Timestamp = DateTime.UtcNow.AddMinutes(-1) } }; _trackedLocations.AddRange(dummyLocations); UpdateLocationCount(); } private void UpdateLocationCount() { LocationCountLabel.Text = $"Locations: {_trackedLocations.Count}"; } private async void OnStartTrackingClicked(object? sender, EventArgs e) { try { if (!_isTracking) { // Request location permissions var status = await Permissions.RequestAsync(); if (status != PermissionStatus.Granted) { await DisplayAlert("Permission Required", "Location permission is required to track your location.", "OK"); return; } // Start location tracking _isTracking = true; StartTrackingBtn.Text = "Tracking..."; StartTrackingBtn.BackgroundColor = Colors.Orange; StopTrackingBtn.IsEnabled = true; // Simulate location tracking _ = Task.Run(async () => await SimulateLocationTracking()); } } catch (Exception ex) { await DisplayAlert("Error", $"Failed to start tracking: {ex.Message}", "OK"); } } private void OnStopTrackingClicked(object? sender, EventArgs e) { try { if (_isTracking) { _isTracking = false; StartTrackingBtn.Text = "Start Tracking"; StartTrackingBtn.BackgroundColor = Colors.Green; StopTrackingBtn.IsEnabled = false; } } catch (Exception ex) { DisplayAlert("Error", $"Failed to stop tracking: {ex.Message}", "OK"); } } private async Task SimulateLocationTracking() { while (_isTracking) { try { // Get current location var location = await Geolocation.GetLocationAsync(); if (location != null) { // Update UI on main thread MainThread.BeginInvokeOnMainThread(async () => { // Add location to tracked locations var locationData = new LocationData { Latitude = location.Latitude, Longitude = location.Longitude, Timestamp = DateTime.UtcNow }; _trackedLocations.Add(locationData); UpdateLocationCount(); // Add pin to OpenStreetMap await MainMap.AddLocationPinAsync(location, $"Current Location {_trackedLocations.Count}", 0.8); }); } } catch (Exception ex) { // Handle location errors System.Diagnostics.Debug.WriteLine($"Location error: {ex.Message}"); } // Wait 5 seconds before next update await Task.Delay(5000); } } private async void OnCenterMapClicked(object? sender, EventArgs e) { try { // Request location permissions if not already granted var status = await Permissions.CheckStatusAsync(); if (status != PermissionStatus.Granted) { status = await Permissions.RequestAsync(); if (status != PermissionStatus.Granted) { await DisplayAlert("Permission Required", "Location permission is required to center the map.", "OK"); return; } } // Get current location var location = await Geolocation.GetLocationAsync(); if (location != null) { // Clear existing pins await MainMap.ClearMapAsync(); // Add a pin for current location await MainMap.AddLocationPinAsync(location, $"Your Location\nLat: {location.Latitude:F6}\nLng: {location.Longitude:F6}", 1.0); await DisplayAlert("Location Found", $"Map centered on your location:\nLat: {location.Latitude:F6}\nLng: {location.Longitude:F6}", "OK"); } else { await DisplayAlert("Error", "Unable to get your current location.", "OK"); } } catch (Exception ex) { await DisplayAlert("Error", $"Failed to center map: {ex.Message}", "OK"); } } private async void OnHeatMapClicked(object? sender, EventArgs e) { try { if (_trackedLocations.Any()) { // Load tracked locations into the heat map await MainMap.LoadLocationDataAsync(_trackedLocations); await DisplayAlert("Heat Map", $"Heat map updated with {_trackedLocations.Count} locations.\n\nAreas with higher frequency appear in red/yellow, lower frequency in blue.", "OK"); } else { await DisplayAlert("No Data", "No location data available. Start tracking to create a heat map.", "OK"); } } catch (Exception ex) { await DisplayAlert("Error", $"Failed to update heat map: {ex.Message}", "OK"); } } private async void OnClearDemoClicked(object? sender, EventArgs e) { try { var result = await DisplayAlert("Clear Demo Data", "Are you sure you want to clear all demo location data?", "Yes", "No"); if (result) { _trackedLocations.Clear(); await MainMap.ClearMapAsync(); UpdateLocationCount(); await DisplayAlert("Demo Cleared", "All demo location data has been cleared.", "OK"); } } catch (Exception ex) { await DisplayAlert("Error", $"Failed to clear demo data: {ex.Message}", "OK"); } } private async void OnResetMapClicked(object? sender, EventArgs e) { try { await MainMap.ClearMapAsync(); await DisplayAlert("Map Reset", "Map has been reset to default view.", "OK"); } catch (Exception ex) { await DisplayAlert("Error", $"Failed to reset map: {ex.Message}", "OK"); } } }