public static void LoadMap() { var strRoute = string.Empty; MainThread.BeginInvokeOnMainThread(async() => { try { var options = new PickOptions { PickerTitle = "Please select a map file", FileTypes = new FilePickerFileType(new Dictionary <DevicePlatform, IEnumerable <string> > { /**///What is mime type for mbtiles ?!? //{ DevicePlatform.Android, new string[] { "mbtiles"} }, { DevicePlatform.Android, null }, }) }; var sourceFile = await FilePicker.PickAsync(options); if (sourceFile != null) { string destinationFile = MainActivity.rootPath + "/MBTiles/" + sourceFile.FileName; if (File.Exists(destinationFile)) { Show_Dialog msg1 = new Show_Dialog(MainActivity.mContext); if (await msg1.ShowDialog($"Overwrite", $"Overwrite '{sourceFile.FileName}'", Android.Resource.Attribute.DialogIcon, true, Show_Dialog.MessageResult.NO, Show_Dialog.MessageResult.YES) == Show_Dialog.MessageResult.NO) { return; } } File.Copy(sourceFile.FullPath, destinationFile, true); Fragments.Fragment_map.map.Layers.Add(CreateMbTilesLayer(destinationFile, sourceFile.FileName)); Show_Dialog msg2 = new Show_Dialog(MainActivity.mContext); await msg2.ShowDialog($"Done", $"Map Imported and Loaded", Android.Resource.Attribute.DialogIcon, true, Show_Dialog.MessageResult.NONE, Show_Dialog.MessageResult.OK); } } catch (Exception ex) { Log.Information($"Failed to import map file: '{ex}'"); } }); }
protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); m_br = new StreamAudio.SongDoneReceiver(); m_br.MainAct = this; m_tracks = new JavaList <Track>(); ListView trackList = FindViewById <ListView>(Resource.Id.TrackList); TrackListArrayAdapter adapter = new TrackListArrayAdapter(this, m_tracks); trackList.Adapter = adapter; trackList.ItemClick += async(sender, e) => { Show_Dialog diag = new Show_Dialog(this); Show_Dialog.MessageResult result = await diag.ShowDialog("", "Delete this track?", false, false, Show_Dialog.MessageResult.YES, Show_Dialog.MessageResult.NO); if (result == Show_Dialog.MessageResult.YES) { m_tracks.RemoveAt(e.Position); m_upd.SendToServer(m_tracks); RefreshTracklist(); bool wasPlaying = Services.StreamingBackgroundService.IsPlaying; HandleMusicAction(Services.StreamingBackgroundService.ActionStop, m_tracks); if (wasPlaying) { PlayIfSongAvailable(); } } }; Button addTrack = FindViewById <Button>(Resource.Id.AddTrack); addTrack.Click += (sender, e) => { Intent addTrackIntent = new Intent(this, typeof(AddTrackActivity)); addTrackIntent.PutStringArrayListExtra("BASE_URL", new string[] { m_baseurl }); StartActivity(addTrackIntent); }; Button play = FindViewById <Button>(Resource.Id.Play); play.Click += (sender, e) => PlayIfSongAvailable(); Button pause = FindViewById <Button>(Resource.Id.Pause); pause.Click += (sender, e) => HandleMusicAction(Services.StreamingBackgroundService.ActionPause, m_tracks); Button stop = FindViewById <Button>(Resource.Id.Stop); stop.Click += (sender, e) => HandleMusicAction(Services.StreamingBackgroundService.ActionStop, m_tracks); m_baseurl = "http://10.142.9.106/"; m_upd = new TrackListUpdater(m_baseurl + "cgi-bin/getpage.cgi"); m_upd.Update(m_tracks); RegisterReceiver(m_br, new IntentFilter("PlaylistSyncClientAndroid.Services.SONG_IS_DONE")); var timer = new System.Threading.Timer((e) => { string old_url = ""; if (m_tracks.Count > 0) { old_url = m_tracks[0].Url; } m_upd.Update(m_tracks); if (m_tracks.Count > 0) { if (old_url != m_tracks[0].Url && Services.StreamingBackgroundService.IsPlaying) { HandleMusicAction(Services.StreamingBackgroundService.ActionStop, m_tracks); PlayIfSongAvailable(); } } else { HandleMusicAction(Services.StreamingBackgroundService.ActionStop, m_tracks); } if (Services.StreamingBackgroundService.IsPlaying) { Track t = m_tracks[0]; t.NowPlaying = "▶ "; m_tracks[0] = t; } m_upd.SendToServer(m_tracks); RefreshTracklist(); }, null, 1000, 1000); }
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.activity_gpx, parent, false); GPXViewHolder vh = new GPXViewHolder(itemView, OnClick); vh.img_more.Click += (o, e) => { Android.Support.V7.Widget.PopupMenu popup = new Android.Support.V7.Widget.PopupMenu(parent.Context, vh.img_more); popup.Inflate(Resource.Menu.menu_gpx); popup.MenuItemClick += async(s, args) => { switch (args.Item.ItemId) { case Resource.Id.gpx_menu_followroute: Log.Information($"Follow route '{vh.Name.Text}'"); //Get the route var route = RouteDatabase.GetRouteAsync(vh.Id).Result; GpxClass gpx = GpxClass.FromXml(route.GPX); string mapRoute = Import.GPXtoRoute(gpx.Routes[0]).Item1; //Add GPX to Map Import.AddRouteToMap(mapRoute); //Center on imported route var bounds = gpx.GetBounds(); Point p = Utils.Misc.CalculateCenter((double)bounds.maxlat, (double)bounds.minlon, (double)bounds.minlat, (double)bounds.maxlon); var sphericalMercatorCoordinate = SphericalMercator.FromLonLat(p.X, p.Y); Fragment_map.mapControl.Navigator.CenterOn(sphericalMercatorCoordinate); //Zoom Fragment_map.mapControl.Navigator.ZoomTo(PrefsActivity.MaxZoom); //Switch to map MainActivity.SwitchFragment("Fragment_map", (FragmentActivity)parent.Context); //Start recording RecordTrack.StartTrackTimer(); NavigationView nav = MainActivity.mContext.FindViewById <NavigationView>(Resource.Id.nav_view); var item_nav = nav.Menu.FindItem(Resource.Id.nav_recordtrack); item_nav.SetTitle("Stop Recording"); break; case Resource.Id.gpx_menu_showonmap: Log.Information($"Show route on map '{vh.Name.Text}'"); //Get the route var route_1 = RouteDatabase.GetRouteAsync(vh.Id).Result; GpxClass gpx_1 = GpxClass.FromXml(route_1.GPX); string mapRoute_1 = Import.GPXtoRoute(gpx_1.Routes[0]).Item1; //Add GPX to Map Import.AddRouteToMap(mapRoute_1); //Center on imported route var bounds_1 = gpx_1.GetBounds(); Point p_1 = Utils.Misc.CalculateCenter((double)bounds_1.maxlat, (double)bounds_1.minlon, (double)bounds_1.minlat, (double)bounds_1.maxlon); var sphericalMercatorCoordinate_1 = SphericalMercator.FromLonLat(p_1.X, p_1.Y); Fragment_map.mapControl.Navigator.CenterOn(sphericalMercatorCoordinate_1); //Zoom Fragment_map.mapControl.Navigator.ZoomTo(PrefsActivity.MaxZoom); //Switch to map MainActivity.SwitchFragment("Fragment_map", (FragmentActivity)parent.Context); break; case Resource.Id.gpx_menu_deleteroute: Log.Information($"Delete route '{vh.Name.Text}'"); Show_Dialog msg1 = new Show_Dialog(MainActivity.mContext); if (await msg1.ShowDialog($"Delete", $"Delete '{vh.Name.Text}' ?", Android.Resource.Attribute.DialogIcon, true, Show_Dialog.MessageResult.YES, Show_Dialog.MessageResult.NO) == Show_Dialog.MessageResult.YES) { _ = Data.RouteDatabase.DeleteRouteAsync(vh.Id); mGpxData.RemoveAt(vh.AdapterPosition); NotifyDataSetChanged(); } break; case Resource.Id.gpx_menu_reverseroute: Log.Information($"Reverse route '{vh.Name.Text}'"); //Get the route var route_to_reverse = RouteDatabase.GetRouteAsync(vh.Id).Result; GpxClass gpx_to_reverse = GpxClass.FromXml(route_to_reverse.GPX); gpx_to_reverse.Routes[0].rtept.Reverse(); //Reverse and save as new entry route_to_reverse.Name += " - reversed"; route_to_reverse.Description += " - reversed"; route_to_reverse.Id = 0; route_to_reverse.GPX = gpx_to_reverse.ToXml(); RouteDatabase.SaveRouteAsync(route_to_reverse).Wait(); //Update RecycleView with new entry int i = Fragment_gpx.mAdapter.mGpxData.Add(route_to_reverse); Fragment_gpx.mAdapter.NotifyItemInserted(i); break; case Resource.Id.gpx_menu_exportgpx: Log.Information($"Export route '{vh.Name.Text}'"); //Get the route var route_to_export = RouteDatabase.GetRouteAsync(vh.Id).Result; GpxClass gpx_to_export = GpxClass.FromXml(route_to_export.GPX); /**/ //Ask user for name and folder string gpxPath = Path.Combine(MainActivity.rootPath, "Exported -" + DateTime.Now.ToString("yyyy-MM-dd HH-mm") + ".gpx"); gpx_to_export.ToFile(gpxPath); break; case Resource.Id.gpx_menu_saveofflinemap: Log.Information($"Download and save offline map '{vh.Name.Text}'"); Toast.MakeText(parent.Context, "save offline map " + vh.AdapterPosition.ToString(), ToastLength.Short).Show(); break; } }; popup.Show(); }; return(vh); } private void OnClick(int obj) { ItemClick?.Invoke(this, obj); } /*public static void MAdapter_ItemClick(object sender, int e) * { * int gpxNum = e + 1; * Toast.MakeText(MainActivity.mContext, "This is route/track number " + gpxNum, ToastLength.Short).Show(); * }*/ } }
public static ILayer GetRoute() { var strRoute = string.Empty; MainThread.BeginInvokeOnMainThread(async() => { bool DownloadOfflineMap = false; GpxClass gpxData = await PickAndParse(); if (gpxData == null) { return; } //Does the user want maps downloaded for offline usage? Show_Dialog msg1 = new Show_Dialog(MainActivity.mContext); if (await msg1.ShowDialog($"Offline Map", $"Download map for offline usage?", Android.Resource.Attribute.DialogIcon, true, Show_Dialog.MessageResult.YES, Show_Dialog.MessageResult.NO) == Show_Dialog.MessageResult.YES) { DownloadOfflineMap = true; } foreach (rteType route in gpxData.Routes) { //Get Route and distance from GPX var t = GPXtoRoute(route); string mapRoute = t.Item1; float mapDistanceKm = t.Item2; //Create a standalone GPX var newGPX = new GpxClass() { Metadata = new metadataType() { name = route.name, desc = route.desc, }, }; newGPX.Routes.Add(route); //Add to route DB var r = new Route { Name = route.name, Distance = mapDistanceKm, Ascent = 0, /**///Fix this Description = route.desc, GPX = newGPX.ToXml(), }; RouteDatabase.SaveRouteAsync(r).Wait(); //Update RecycleView with new entry int i = Fragment_gpx.mAdapter.mGpxData.Add(r); Fragment_gpx.mAdapter.NotifyItemInserted(i); //Does the user want the maps downloaded? if (DownloadOfflineMap) { var bounds = route.GetBounds(); //map.BoundsLeft = -37.5718; map.BoundsRight = -37.5076; map.BoundsBottom = 145.5424; map.BoundsTop = 145.5189; //Left: -10.2455, Top: 110.5426 Right: -43.2748, Bottom: 154.3179 Models.Map map = new Models.Map { Name = Regex.Replace(route.name, @"[^\u0000-\u007F]+", ""), //Removes non-ascii characters from filename ZoomMin = PrefsActivity.MinZoom, ZoomMax = PrefsActivity.MaxZoom, BoundsLeft = (double)bounds.minlat, BoundsBottom = (double)bounds.maxlon, BoundsRight = (double)bounds.maxlat, BoundsTop = (double)bounds.minlon }; //Download map await DownloadRasterImageMap.DownloadMap(map); //Load map string dbPath = MainActivity.rootPath + "/MBTiles/" + map.Name + ".mbtiles"; Log.Information($"Loading '{dbPath}' as layer name '{map.Name}'"); Fragment_map.map.Layers.Add(OfflineMaps.CreateMbTilesLayer(dbPath, map.Name)); } //Add to map AddRouteToMap(mapRoute); /*var mbTilesTileSource = new MbTilesTileSource(new SQLiteConnectionString(file, true), null, MbTilesType.Overlay, true, true); * var mbTilesLayer = new TileLayer(mbTilesTileSource) { Name = file }; * MainActivity.map.Layers.Add(mbTilesLayer);*/ } Show_Dialog msg3 = new Show_Dialog(MainActivity.mContext); await msg3.ShowDialog($"Done", $"GPX Import Completed", Android.Resource.Attribute.DialogIcon, true, Show_Dialog.MessageResult.NONE, Show_Dialog.MessageResult.OK); }); return(null); }
private static async Task <GpxClass> PickAndParse() { try { var options = new PickOptions { PickerTitle = "Please select a GPX file", FileTypes = new FilePickerFileType(new Dictionary <DevicePlatform, IEnumerable <string> > { /**///What is mime type for GPX files?!? //{ DevicePlatform.Android, new string[] { "gpx/gpx"} }, { DevicePlatform.Android, null }, }) }; var result = await FilePicker.PickAsync(options); if (result == null) { return(null); } Console.WriteLine("FileName: " + result.FileName + ", FilePath: " + result.FullPath); if (result.FileName.EndsWith("gpx", StringComparison.OrdinalIgnoreCase) == false) { return(null); } var stream = await result.OpenReadAsync(); string contents = string.Empty; using (var reader = new StreamReader(stream)) { contents = reader.ReadToEnd(); } GpxClass gpx = GpxClass.FromXml(contents); var bounds = gpx.GetBounds(); Console.WriteLine("Waypoints.Count: " + gpx.Waypoints.Count.ToString()); Console.WriteLine("Routes.Count: " + gpx.Routes.Count.ToString()); Console.WriteLine("Track.Count: " + gpx.Tracks.Count.ToString()); Console.WriteLine("Lower Left - MinLat: " + bounds.minlat.ToString() + ", MaxLon: " + bounds.maxlon.ToString()); Console.WriteLine("Top Right - MaxLat: " + bounds.maxlat.ToString() + ", MinLon: " + bounds.minlon.ToString()); string r = "routes"; if (gpx.Routes.Count == 1) { r = "route"; } string t = "tracks"; if (gpx.Tracks.Count == 1) { t = "track"; } Show_Dialog msg1 = new Show_Dialog(MainActivity.mContext); if (await msg1.ShowDialog($"{result.FileName}", $"Found {gpx.Routes.Count} {r} and {gpx.Tracks.Count} {t}. Import?", Android.Resource.Attribute.DialogIcon, true, Show_Dialog.MessageResult.YES, Show_Dialog.MessageResult.NO) != Show_Dialog.MessageResult.YES) { return(null); } return(gpx); } catch (Exception) { // The user canceled or something went wrong } return(null); }