using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Globalization; using System.IO; using System.Net; using System.Net.NetworkInformation; using System.Threading; using System.Windows.Forms; using System.Xml; using Demo.WindowsForms.CustomMarkers; using GMap.NET; using GMap.NET.MapProviders; using GMap.NET.WindowsForms; using GMap.NET.WindowsForms.Markers; using GMap.NET.WindowsForms.ToolTips; using System.IO.Ports; using System.Data; using System.Text; namespace Demo.WindowsForms { public partial class MainForm : Form { // layers readonly GMapOverlay top = new GMapOverlay(); internal readonly GMapOverlay objects = new GMapOverlay("objects"); internal readonly GMapOverlay routes = new GMapOverlay("routes"); // current marker GMarkerGoogle currentMarker; // etc readonly Random rnd = new Random(); readonly DescendingComparer ComparerIpStatus = new DescendingComparer(); GMapMarkerRect CurentRectMarker = null; string mobileGpsLog = string.Empty; bool isMouseDown = false; PointLatLng start; PointLatLng end; TimeSpan unixTime; GMapRoute currentRoute = null; bool UserAcceptedLicenseOnce = false; public MainForm() { InitializeComponent(); unixTime = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)); if (!DesignMode) { // add your custom map db provider //GMap.NET.CacheProviders.MySQLPureImageCache ch = new GMap.NET.CacheProviders.MySQLPureImageCache(); //ch.ConnectionString = @"server=sql2008;User Id=trolis;Persist Security Info=True;database=gmapnetcache;password=trolis;"; //MainMap.Manager.SecondaryCache = ch; // set your proxy here if need //GMapProvider.WebProxy = new WebProxy("10.2.0.100", 8080); //GMapProvider.WebProxy.Credentials = new NetworkCredential("ogrenci@bilgeadam.com", "bilgeada"); // set cache mode only if no internet avaible if (!Stuff.PingNetwork("pingtest.net")) { MainMap.Manager.Mode = AccessMode.CacheOnly; MessageBox.Show("No internet connection available, going to CacheOnly mode.", "GMap.NET - Demo.WindowsForms", MessageBoxButtons.OK, MessageBoxIcon.Warning); } // config map - MDKEdit - init values ?? MainMap.MapProvider = GMapProviders.OpenStreetMap; MainMap.Position = new PointLatLng(39.751248, -83.809848); MainMap.MinZoom = 0; MainMap.MaxZoom = 24; MainMap.Zoom = 15; //MainMap.ScaleMode = ScaleModes.Fractional; /// map events MainMap.OnTileLoadStart += new TileLoadStart(MainMap_OnTileLoadStart); MainMap.OnTileLoadComplete += new TileLoadComplete(MainMap_OnTileLoadComplete); MainMap.OnMapZoomChanged += new MapZoomChanged(MainMap_OnMapZoomChanged); MainMap.OnMapTypeChanged += new MapTypeChanged(MainMap_OnMapTypeChanged); MainMap.OnMarkerClick += new MarkerClick(MainMap_OnMarkerClick); MainMap.OnMarkerEnter += new MarkerEnter(MainMap_OnMarkerEnter); MainMap.OnMarkerLeave += new MarkerLeave(MainMap_OnMarkerLeave); MainMap.OnRouteEnter += new RouteEnter(MainMap_OnRouteEnter); MainMap.OnRouteLeave += new RouteLeave(MainMap_OnRouteLeave); MainMap.Manager.OnTileCacheComplete += new TileCacheComplete(OnTileCacheComplete); MainMap.Manager.OnTileCacheStart += new TileCacheStart(OnTileCacheStart); MainMap.Manager.OnTileCacheProgress += new TileCacheProgress(OnTileCacheProgress); MainMap.MouseMove += new MouseEventHandler(MainMap_MouseMove); MainMap.MouseDown += new MouseEventHandler(MainMap_MouseDown); MainMap.MouseUp += new MouseEventHandler(MainMap_MouseUp); // get map types #if !MONO // mono doesn't handle it, so we 'lost' provider list ;] comboBoxMapType.ValueMember = "Name"; comboBoxMapType.DataSource = GMapProviders.List; comboBoxMapType.SelectedItem = MainMap.MapProvider; #endif // acccess mode comboBoxMode.DataSource = Enum.GetValues(typeof(AccessMode)); comboBoxMode.SelectedItem = MainMap.Manager.Mode; // get position textBoxLat.Text = MainMap.Position.Lat.ToString(CultureInfo.InvariantCulture); textBoxLng.Text = MainMap.Position.Lng.ToString(CultureInfo.InvariantCulture); // get cache modes checkBoxUseRouteCache.Checked = MainMap.Manager.UseRouteCache; // get zoom trackBarZoomLevel.Minimum = MainMap.MinZoom * 100; trackBarZoomLevel.Maximum = MainMap.MaxZoom * 100; trackBarZoomLevel.TickFrequency = 100; #if DEBUG xboxGrid.Checked = true; #endif ToolStripManager.Renderer = new BSE.Windows.Forms.Office2007Renderer(); /// add custom layers MainMap.Overlays.Add(routes); MainMap.Overlays.Add(objects); MainMap.Overlays.Add(top); routes.Routes.CollectionChanged += new GMap.NET.ObjectModel.NotifyCollectionChangedEventHandler(Routes_CollectionChanged); objects.Markers.CollectionChanged += new GMap.NET.ObjectModel.NotifyCollectionChangedEventHandler(Markers_CollectionChanged); // set current marker currentMarker = new GMarkerGoogle(MainMap.Position, GMarkerGoogleType.arrow); currentMarker.IsHitTestVisible = false; currentMarker.ToolTipText = "Current Marker"; top.Markers.Add(currentMarker); if (objects.Markers.Count > 0) { MainMap.ZoomAndCenterMarkers(null); } try { GMapOverlay overlay = DeepClone(objects); Debug.WriteLine("ISerializable status for markers: OK"); GMapOverlay overlay3 = DeepClone(routes); Debug.WriteLine("ISerializable status for routes: OK"); } catch (Exception ex) { Debug.WriteLine("ISerializable failure: " + ex.Message); #if DEBUG if (Debugger.IsAttached) { Debugger.Break(); } #endif } } } //runs during init - MDKfunctional public T DeepClone(T obj) { using (var ms = new System.IO.MemoryStream()) { var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); formatter.Serialize(ms, obj); ms.Position = 0; return (T)formatter.Deserialize(ms); } } // runs on form load - MDKfunctional private void MainForm_Load(object sender, EventArgs e) { trackBarZoomLevel.Value = (int)MainMap.Zoom * 100; Activate(); TopMost = true; TopMost = false; PrepareGraphs(); } //updates the count of markers - MDKfunctional void Markers_CollectionChanged(object sender, GMap.NET.ObjectModel.NotifyCollectionChangedEventArgs e) { //textBoxMarkerCount.Text = objects.Markers.Count.ToString(); } //updates the count of routes - MDKfunctional void Routes_CollectionChanged(object sender, GMap.NET.ObjectModel.NotifyCollectionChangedEventArgs e) { textBoxrouteCount.Text = routes.Routes.Count.ToString(); } #region -- map events -- // details unknown- MDKfunctional void OnTileCacheComplete() { Debug.WriteLine("OnTileCacheComplete"); long size = 0; int db = 0; try { DirectoryInfo di = new DirectoryInfo(MainMap.CacheLocation); var dbs = di.GetFiles("*.gmdb", SearchOption.AllDirectories); foreach (var d in dbs) { size += d.Length; db++; } } catch { } if (!IsDisposed) { MethodInvoker m = delegate { textBoxCacheSize.Text = string.Format(CultureInfo.InvariantCulture, "{0} db in {1:00} MB", db, size / (1024.0 * 1024.0)); textBoxCacheStatus.Text = "all tiles saved!"; }; Invoke(m); } } //details unknown - MDKfunctional void OnTileCacheStart() { Debug.WriteLine("OnTileCacheStart"); if (!IsDisposed) { MethodInvoker m = delegate { textBoxCacheStatus.Text = "saving tiles..."; }; // MDKEdit //Invoke(m); } } //details unknown - MDKfunctional void OnTileCacheProgress(int left) { if (!IsDisposed) { MethodInvoker m = delegate { textBoxCacheStatus.Text = left + " tile to save..."; }; Invoke(m); } } //runs when cursor leaves a marker - MDKfunctional void MainMap_OnMarkerLeave(GMapMarker item) { if (item is GMapMarkerRect) { CurentRectMarker = null; GMapMarkerRect rc = item as GMapMarkerRect; rc.Pen.Color = Color.Blue; Debug.WriteLine("OnMarkerLeave: " + item.Position); } } //runs when cursor enters a marker - MDKfunctional void MainMap_OnMarkerEnter(GMapMarker item) { if (item is GMapMarkerRect) { GMapMarkerRect rc = item as GMapMarkerRect; rc.Pen.Color = Color.Red; CurentRectMarker = rc; Debug.WriteLine("OnMarkerEnter: " + item.Position); } } //runs when cursor leaves a route - MDKfunctional void MainMap_OnRouteLeave(GMapRoute item) { currentRoute = null; item.Stroke.Color = Color.MidnightBlue; Debug.WriteLine("OnRouteLeave: " + item.Name); } //runs when cursor enters a route - MDKfunctional void MainMap_OnRouteEnter(GMapRoute item) { currentRoute = item; item.Stroke.Color = Color.Red; Debug.WriteLine("OnRouteEnter: " + item.Name); } // - MDKfunctional void MainMap_OnMapTypeChanged(GMapProvider type) { comboBoxMapType.SelectedItem = type; trackBarZoomLevel.Minimum = MainMap.MinZoom * 100; trackBarZoomLevel.Maximum = MainMap.MaxZoom * 100; } //updates current marker coordinate dislpay - MDKfunctional void MainMap_MouseUp(object sender, MouseEventArgs e) { // MDKAdd textBoxLatCurrent.Text = currentMarker.Position.Lat.ToString(); textBoxLngCurrent.Text = currentMarker.Position.Lng.ToString(); if (e.Button == MouseButtons.Left) { isMouseDown = false; } } // - MDKfunctional void MainMap_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { isMouseDown = true; if (currentMarker.IsVisible) { currentMarker.Position = MainMap.FromLocalToLatLng(e.X, e.Y); // MDKAdd textBoxLatCurrent.Text = currentMarker.Position.Lat.ToString(); textBoxLngCurrent.Text = currentMarker.Position.Lng.ToString(); var px = MainMap.MapProvider.Projection.FromLatLngToPixel(currentMarker.Position.Lat, currentMarker.Position.Lng, (int)MainMap.Zoom); var tile = MainMap.MapProvider.Projection.FromPixelToTileXY(px); Debug.WriteLine("MouseDown: geo: " + currentMarker.Position + " | px: " + px + " | tile: " + tile); } } } // move current marker with left holding - MDKfunctional void MainMap_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left && isMouseDown) { if (CurentRectMarker == null) { if (currentMarker.IsVisible) { // MDKAdd textBoxLatCurrent.Text = currentMarker.Position.Lat.ToString(); textBoxLngCurrent.Text = currentMarker.Position.Lng.ToString(); currentMarker.Position = MainMap.FromLocalToLatLng(e.X, e.Y); } } else // move rect marker { PointLatLng pnew = MainMap.FromLocalToLatLng(e.X, e.Y); int? pIndex = (int?)CurentRectMarker.Tag; if (pIndex.HasValue) { //if (pIndex < polygon.Points.Count) //{ // polygon.Points[pIndex.Value] = pnew; // MainMap.UpdatePolygonLocalPosition(polygon); //} } if (currentMarker.IsVisible) { currentMarker.Position = pnew; // MDKAdd textBoxLatCurrent.Text = currentMarker.Position.Lat.ToString(); textBoxLngCurrent.Text = currentMarker.Position.Lng.ToString(); } CurentRectMarker.Position = pnew; if (CurentRectMarker.InnerMarker != null) { CurentRectMarker.InnerMarker.Position = pnew; } } MainMap.Refresh(); // force instant invalidation // MDKAdd textBoxLatCurrent.Refresh(); textBoxLngCurrent.Refresh(); } } // MapZoomChanged - MDKfunctional void MainMap_OnMapZoomChanged() { trackBarZoomLevel.Value = (int)(MainMap.Zoom * 100.0); textBoxZoomCurrent.Text = MainMap.Zoom.ToString(); } // click on a marker - MDKfunctional void MainMap_OnMarkerClick(GMapMarker item, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { if (item is GMapMarkerRect) { GeoCoderStatusCode status; var pos = GMapProviders.GoogleMap.GetPlacemark(item.Position, out status); if (status == GeoCoderStatusCode.G_GEO_SUCCESS && pos != null) { GMapMarkerRect v = item as GMapMarkerRect; { v.ToolTipText = pos.Value.Address; } MainMap.Invalidate(false); } } else { //if (item.Tag != null) //{ // if (currentTransport != null) // { // currentTransport.ToolTipMode = MarkerTooltipMode.OnMouseOver; // currentTransport = null; // } // currentTransport = item; // currentTransport.ToolTipMode = MarkerTooltipMode.Always; //} } } } // loader start loading tiles - MDKfunctional void MainMap_OnTileLoadStart() { MethodInvoker m = delegate() { panelMenu.Text = "Menu: loading tiles..."; }; try { BeginInvoke(m); } catch { } } // loader end loading tiles - MDKfunctional void MainMap_OnTileLoadComplete(long ElapsedMilliseconds) { MainMap.ElapsedMilliseconds = ElapsedMilliseconds; MethodInvoker m = delegate() { panelMenu.Text = "Menu, last load in " + MainMap.ElapsedMilliseconds + "ms"; textBoxMemory.Text = string.Format(CultureInfo.InvariantCulture, "{0:0.00} MB of {1:0.00} MB", MainMap.Manager.MemoryCache.Size, MainMap.Manager.MemoryCache.Capacity); }; try { BeginInvoke(m); } catch { } } #endregion #region -- menu panels expanders -- // - MDKfunctional private void xPanderPanel1_Click(object sender, EventArgs e) { xPanderPanelList1.Expand(xPanderPanelMain); } // - MDKfunctional private void xPanderPanelCache_Click(object sender, EventArgs e) { xPanderPanelList1.Expand(xPanderPanelCache); } // - MDKfunctional private void xPanderPanelInfo_Click(object sender, EventArgs e) { xPanderPanelList1.Expand(xPanderPanelInfo); } #endregion #region -- ui events -- // change map type - MDKfunctional private void comboBoxMapType_DropDownClosed(object sender, EventArgs e) { if (!UserAcceptedLicenseOnce) { if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + Path.DirectorySeparatorChar + "License.txt")) { string ctn = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + Path.DirectorySeparatorChar + "License.txt"); int li = ctn.IndexOf("License"); string txt = ctn.Substring(li); var d = new Demo.WindowsForms.Forms.Message(); d.richTextBox1.Text = txt; if (DialogResult.Yes == d.ShowDialog()) { UserAcceptedLicenseOnce = true; this.Text += " - license accepted by " + Environment.UserName + " at " + DateTime.Now; } } else { // user deleted License.txt ;} UserAcceptedLicenseOnce = true; } } if (UserAcceptedLicenseOnce) { MainMap.MapProvider = comboBoxMapType.SelectedItem as GMapProvider; } else { MainMap.MapProvider = GMapProviders.OpenStreetMap; comboBoxMapType.SelectedItem = MainMap.MapProvider; } } // change mdoe - MDKfunctional private void comboBoxMode_DropDownClosed(object sender, EventArgs e) { MainMap.Manager.Mode = (AccessMode)comboBoxMode.SelectedValue; MainMap.ReloadMap(); } // zoom - MDKfunctional private void trackBar1_ValueChanged(object sender, EventArgs e) { MainMap.Zoom = trackBarZoomLevel.Value / 100.0; } // go to coordinates- MDKfunctional private void btnGoToCoords_Click(object sender, EventArgs e) { try { double lat = double.Parse(textBoxLat.Text, CultureInfo.InvariantCulture); double lng = double.Parse(textBoxLng.Text, CultureInfo.InvariantCulture); MainMap.Position = new PointLatLng(lat, lng); } catch (Exception ex) { MessageBox.Show("incorrect coordinate format: " + ex.Message); } } // reload map - MDKfunctional private void btnReload_Click(object sender, EventArgs e) { MainMap.ReloadMap(); } // cache config - MDKfunctional private void checkBoxUseCache_CheckedChanged(object sender, EventArgs e) { MainMap.Manager.UseRouteCache = checkBoxUseRouteCache.Checked; MainMap.Manager.UseGeocoderCache = checkBoxUseRouteCache.Checked; MainMap.Manager.UsePlacemarkCache = checkBoxUseRouteCache.Checked; MainMap.Manager.UseDirectionsCache = checkBoxUseRouteCache.Checked; } // set route start - MDKfunctional bool hasStartMarker = false; private void buttonSetStart_Click(object sender, EventArgs e) { start = currentMarker.Position; // - MDKAdd GMarkerGoogle m = new GMarkerGoogle(currentMarker.Position, GMarkerGoogleType.green_small); //prevent multiple start markers from existing if(hasStartMarker){ objects.Markers.RemoveAt(0); } //add the marker m.ToolTipText = "Start"; m.ToolTipMode = MarkerTooltipMode.Always; objects.Markers.Insert(0, m); hasStartMarker = true; } // set route end - MDKfunctional bool hasEndMarker = false; private void buttonSetEnd_Click(object sender, EventArgs e) { end = currentMarker.Position; // - MDKAdd GMarkerGoogle m = new GMarkerGoogle(currentMarker.Position, GMarkerGoogleType.red_small); //prevent multiple start markers from existing if (hasEndMarker) { objects.Markers.RemoveAt(1); } m.ToolTipText = "End"; m.ToolTipMode = MarkerTooltipMode.Always; //add the marker if (hasStartMarker) { objects.Markers.Insert(1, m); } else { objects.Markers.Insert(0, m); } hasEndMarker = true; } // add route - MDKfunctional private void btnAddRoute_Click(object sender, EventArgs e) { RoutingProvider rp = MainMap.MapProvider as RoutingProvider; if (rp == null) { rp = GMapProviders.GoogleMap; // use google if provider does not implement routing } MapRoute route = rp.GetRoute(start, end, false, false, (int)MainMap.Zoom); if (route != null) { // add route GMapRoute r = new GMapRoute(route.Points, route.Name); r.IsHitTestVisible = true; routes.Routes.Add(r); // add route start/end marks GMapMarker m1 = new GMarkerGoogle(start, GMarkerGoogleType.green_big_go); m1.ToolTipText = "Start: " + route.Name; m1.ToolTipMode = MarkerTooltipMode.Always; GMapMarker m2 = new GMarkerGoogle(end, GMarkerGoogleType.red_big_stop); m2.ToolTipText = "End: " + end.ToString(); m2.ToolTipMode = MarkerTooltipMode.Always; objects.Markers.Add(m1); objects.Markers.Add(m2); } } // add marker on current position - MDKfunctional private void addUserMarker(object sender, EventArgs e) { GMarkerGoogle m = new GMarkerGoogle(currentMarker.Position, GMarkerGoogleType.blue_small); m.ToolTipText = "User"; m.ToolTipMode = MarkerTooltipMode.Always; objects.Markers.Add(m); } // add marker from APRS transmission - MDKEdit - TODO: Function not needed; addUserMarker() replaces it ?? private void addMarkerFromButton(object sender, EventArgs e) { GMarkerGoogle m = new GMarkerGoogle(currentMarker.Position, GMarkerGoogleType.blue_small); m.ToolTipText = "Tracker"; m.ToolTipMode = MarkerTooltipMode.Always; objects.Markers.Add(m); } // clear routes - MDKfunctional private void btnClearRoutes_Click(object sender, EventArgs e) { routes.Routes.Clear(); //remove start/end markes of this route string markerText = ""; int count = objects.Markers.Count; for (int i = count-1; i >= 0; i--) { markerText = objects.Markers[i].ToolTipText.ToString(); if (markerText.StartsWith("Start")) { objects.Markers.RemoveAt(i); } else if (markerText.StartsWith("End")) { objects.Markers.RemoveAt(i); //objects.Markers[i].Dispose(); } } hasEndMarker = false; hasStartMarker = false; } // clear markers - MDKfunctional private void btnClearMarkers_Click(object sender, EventArgs e) { //preserve stert/end markes of this route string markerText = ""; int count = objects.Markers.Count; for (int i = (count - 1); i >= 0; i--) { markerText = objects.Markers[i].ToolTipText.ToString(); if (markerText.StartsWith("User")) { objects.Markers.RemoveAt(i); } } } //clears all markers and routes - MDKfunctional private void btnClearAll_Click(object sender, EventArgs e) { objects.Markers.Clear(); routes.Routes.Clear(); hasEndMarker = false; hasStartMarker = false; } // show current marker - MDKfunctional private void checkBoxCurrentMarker_CheckedChanged(object sender, EventArgs e) { currentMarker.IsVisible = xboxCurrentMarker.Checked; } // can drag - MDKfunctional private void checkBoxCanDrag_CheckedChanged(object sender, EventArgs e) { MainMap.CanDragMap = xboxCanDrag.Checked; } // zoom to max for markers - MDKfunctional private void button7_Click(object sender, EventArgs e) { MainMap.ZoomAndCenterMarkers("objects"); } // saves current map view - MDKfunctional private void btnSaveView_Click(object sender, EventArgs e) { try { using (SaveFileDialog sfd = new SaveFileDialog()) { sfd.Filter = "PNG (*.png)|*.png"; sfd.FileName = "GMap.NET image"; Image tmpImage = MainMap.ToImage(); if (tmpImage != null) { using (tmpImage) { if (sfd.ShowDialog() == DialogResult.OK) { tmpImage.Save(sfd.FileName); MessageBox.Show("Image saved: " + sfd.FileName, "GMap.NET", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } } } catch (Exception ex) { MessageBox.Show("Image failed to save: " + ex.Message, "GMap.NET", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // debug tile grid - MDKfunctional private void showGridlines(object sender, EventArgs e) { MainMap.ShowTileGridLines = xboxGrid.Checked; } // saves image of selected area - MDKfunctional private void btnGetStatic_Click(object sender, EventArgs e) { StaticImage st = new StaticImage(this); st.Owner = this; st.Show(); } // key-up events - MDKfunctional private void MainForm_KeyUp(object sender, KeyEventArgs e) { int offset = -22; if (e.KeyCode == Keys.Left) { MainMap.Offset(-offset, 0); } else if (e.KeyCode == Keys.Right) { MainMap.Offset(offset, 0); } else if (e.KeyCode == Keys.Up) { MainMap.Offset(0, -offset); } else if (e.KeyCode == Keys.Down) { MainMap.Offset(0, offset); } else if (e.KeyCode == Keys.Delete) { if (currentRoute != null) { routes.Routes.Remove(currentRoute); currentRoute = null; } if (CurentRectMarker != null) { objects.Markers.Remove(CurentRectMarker); if (CurentRectMarker.InnerMarker != null) { objects.Markers.Remove(CurentRectMarker.InnerMarker); } CurentRectMarker = null; //RegeneratePolygon(); } } else if (e.KeyCode == Keys.Escape) { MainMap.Bearing = 0; //if (currentTransport != null && !MainMap.IsMouseOverMarker) //{ // currentTransport.ToolTipMode = MarkerTooltipMode.OnMouseOver; // currentTransport = null; //} } } // key-press events - MDKfunctional private void MainForm_KeyPress(object sender, KeyPressEventArgs e) { if (MainMap.Focused) { if (e.KeyChar == '+') { MainMap.Zoom = ((int)MainMap.Zoom) + 1; } else if (e.KeyChar == '-') { MainMap.Zoom = ((int)(MainMap.Zoom + 0.99)) - 1; } else if (e.KeyChar == 'a') { MainMap.Bearing--; } else if (e.KeyChar == 'z') { MainMap.Bearing++; } } } //changes zoom - MDKfunctional private void buttonZoomUp_Click(object sender, EventArgs e) { MainMap.Zoom = ((int)MainMap.Zoom) + 1; } //changes zoom - MDKfunctional private void buttonZoomDown_Click(object sender, EventArgs e) { MainMap.Zoom = ((int)(MainMap.Zoom + 0.99)) - 1; } #endregion #region -- caching -- // import map data - MDKfunctional private void btnCacheImport_Click(object sender, EventArgs e) { MainMap.ShowImportDialog(); } // export map data - MDKfunctional private void btnCacheExport_Click(object sender, EventArgs e) { MainMap.ShowExportDialog(); } // prefetch - MDKfunctional private void btnCachePrefetch_Click(object sender, EventArgs e) { RectLatLng area = MainMap.SelectedArea; if (!area.IsEmpty) { int zoom = (int)MainMap.Zoom; DialogResult res = MessageBox.Show("Ready ripp at Zoom = " + zoom + " and greater?", "GMap.NET Cache", MessageBoxButtons.YesNoCancel); if (res == DialogResult.Yes) { for (int i = zoom; i <= 17; i++) { using (TilePrefetcher obj = new TilePrefetcher()) { obj.Owner = this; obj.ShowCompleteMessage = false; obj.Start(area, i, MainMap.MapProvider, 100); } } } } else { MessageBox.Show("Select map area holding ALT", "GMap.NET", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } // clear cache - MDKfunctional private void btnCacheClear_Click(object sender, EventArgs e) { if (MessageBox.Show("Are You sure?", "Clear GMap.NET cache?", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) { try { MainMap.Manager.PrimaryCache.DeleteOlderThan(DateTime.Now, null); MessageBox.Show("Done. Cache is clear."); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } // open disk cache location - MDKfunctional private void btnCacheLocationOpen_Click(object sender, EventArgs e) { try { string argument = "/select, \"" + MainMap.CacheLocation + "TileDBv5\""; System.Diagnostics.Process.Start("explorer.exe", argument); } catch (Exception ex) { MessageBox.Show("Failed to open: " + ex.Message, "GMap.NET", MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion #region chart click events //this method clears the background of all charts private void ResetChartColors() { chrtTopLeft.BackColor = Color.LightGray; chrtTopRight.BackColor = Color.LightGray; chrtBottomLeft.BackColor = Color.LightGray; chrtBottomRight.BackColor = Color.LightGray; } ///TODO: check min/max/average with real data //highlight Top Left chart on click and set text box values based on this chart private void chrtTopLeft_Click(object sender, EventArgs e) { ResetChartColors(); chrtTopLeft.BackColor = Color.Gray; tboxChartData.Text = "Altitude"; tboxCurrent.Text = tboxAtmoAltitude.Text; tboxAverage.Text = (velocitySum / chrtBottomRight.Series.FindByName("altitudeTrend").Points.Count).ToString(); tboxMax.Text = chrtBottomRight.Series.FindByName("altitudeTrend").Points.FindMaxByValue().ToString(); tboxMin.Text = chrtBottomRight.Series.FindByName("altitudeTrend").Points.FindMinByValue().ToString(); } //highlight Top Right chart on click and set text box values based on this chart private void chrtTopRight_Click(object sender, EventArgs e) { ResetChartColors(); chrtTopRight.BackColor = Color.Gray; tboxChartData.Text = "Humidity"; tboxCurrent.Text = tboxAtmoHumidity.Text; tboxAverage.Text = (humiditySum / chrtBottomRight.Series.FindByName("humidityTrend").Points.Count).ToString(); tboxMax.Text = chrtBottomRight.Series.FindByName("humidityTrend").Points.FindMaxByValue().ToString(); tboxMin.Text = chrtBottomRight.Series.FindByName("humidityTrend").Points.FindMinByValue().ToString(); } //highlight Bottom Left chart on click and set text box values based on this chart private void chrtBottomLeft_Click(object sender, EventArgs e) { ResetChartColors(); chrtBottomLeft.BackColor = Color.Gray; tboxChartData.Text = "Pressure"; tboxCurrent.Text = tboxAtmoPressure.Text; tboxAverage.Text = (pressureSum / chrtBottomRight.Series.FindByName("pressureTrend").Points.Count).ToString(); tboxMax.Text = chrtBottomRight.Series.FindByName("pressureTrend").Points.FindMaxByValue().ToString(); tboxMin.Text = chrtBottomRight.Series.FindByName("pressureTrend").Points.FindMinByValue().ToString(); } //highlight Bottom Right chart on click and set text box values based on this chart private void chrtBottomRight_Click(object sender, EventArgs e) { ResetChartColors(); chrtBottomRight.BackColor = Color.Gray; tboxChartData.Text = "Velocity"; tboxCurrent.Text = tboxMasterVelocity.Text; tboxAverage.Text = (velocitySum / chrtBottomRight.Series.FindByName("velocityTrend").Points.Count).ToString(); tboxMax.Text = chrtBottomRight.Series.FindByName("velocityTrend").Points.FindMaxByValue().ToString(); tboxMin.Text = chrtBottomRight.Series.FindByName("velocityTrend").Points.FindMinByValue().ToString(); } #endregion #region transmission handling //variable declarations string latitude; string longitude; bool firstTransmissionDatum = false; double velocitySum = 0; double humiditySum = 0; double altitudeSum = 0; double pressureSum = 0; //runs on init public void PrepareGraphs(){ //set up for graphs MDKEdit // http://www.youtube.com/watch?v=zTod4-Fg6Ew - split containers // http://www.youtube.com/watch?v=bMXtgPk875I - chart controls chrtTopLeft.ChartAreas.Add("altitudeArea"); chrtTopLeft.Series.Add("altitudeTrend"); chrtTopRight.ChartAreas.Add("humidityArea"); chrtTopRight.Series.Add("humidityTrend"); chrtBottomLeft.Series.Add("pressureTrend"); chrtBottomLeft.ChartAreas.Add("pressureArea"); chrtBottomRight.ChartAreas.Add("velocityArea"); chrtBottomRight.Series.Add("velocityTrend"); // declare all series, data points to be modified dynamically at run //---------prep altitude area BEGIN chrtTopLeft.Series["altitudeTrend"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; chrtTopLeft.Series["altitudeTrend"].Color = Color.Green; System.Windows.Forms.DataVisualization.Charting.AxisName.X.Equals("Time"); System.Windows.Forms.DataVisualization.Charting.AxisName.Y.Equals("Altitude"); ///required initial value chrtTopLeft.Series["altitudeTrend"].Points.AddXY(0, 140); //---------prep altitude area END //-----------prep humidity area BEGIN chrtTopRight.Series["humidityTrend"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; chrtTopRight.Series["humidityTrend"].Color = Color.Red; System.Windows.Forms.DataVisualization.Charting.AxisName.X.Equals("Time"); System.Windows.Forms.DataVisualization.Charting.AxisName.Y.Equals("Humidity"); ///required initial value chrtTopRight.Series["humidityTrend"].Points.AddXY(0, 50); //-----------prep humidity area END //-----------prep pressure area BEGIN chrtBottomLeft.Series["pressureTrend"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; chrtBottomLeft.Series["pressureTrend"].Color = Color.Blue; System.Windows.Forms.DataVisualization.Charting.AxisName.X.Equals("Time"); System.Windows.Forms.DataVisualization.Charting.AxisName.Y.Equals("Pressure"); ///required initial value chrtBottomLeft.Series["pressureTrend"].Points.AddXY(0, 100000); //-----------prep pressure area END //----------prep velocity area BEGIN chrtBottomRight.Series["velocityTrend"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; chrtBottomRight.Series["velocityTrend"].Color = Color.Green; System.Windows.Forms.DataVisualization.Charting.AxisName.X.Equals("Time"); System.Windows.Forms.DataVisualization.Charting.AxisName.Y.Equals("Altitude"); ///required initial value chrtBottomRight.Series["velocityTrend"].Points.AddXY(0, 0); //----------prep velocity area END //put chart displays in a ready state ResetChartColors(); } //parses transmissions and saves data to CSV file public void ParseIncomingData(string rawDataReceived) { //check to see if data should be processed if (!cboxCollectData.Checked ) { AddTextDelegate("Transmission not saved: " + rawDataReceived +"\r\n"); return; } else if (!rawDataReceived.StartsWith("KD8TDF")) { AddTextDelegate("Foreign transmission: " + rawDataReceived + "\r\n"); return; } /* sample stansmissions * KD8TDF-9>APRS,WIDE2-1:/191950zN/WO/ T79 S00 V H99.99 _ | * KD8TDF-9>APRS,WIDE2-1:/151916z3944.87N/08348.75WO005/0.013 SV:09 A-30.5 B45.64 C99542 */ //find and store latitude string int indexStart = rawDataReceived.IndexOf("z"); int indexEnd = rawDataReceived.IndexOf("N/"); latitude = rawDataReceived.Substring(indexStart + 1, indexEnd - indexStart - 1); //find and store longitude string indexStart = rawDataReceived.IndexOf("N/"); indexEnd = rawDataReceived.IndexOf("WO"); longitude = rawDataReceived.Substring(indexStart + 2, indexEnd - indexStart - 2); //remove APRS overhead from string string transmissionCommentField= rawDataReceived.Substring(rawDataReceived.IndexOf(" ")); //place each datum in its own variable string[] dataTransmission; dataTransmission = transmissionCommentField.Split('~'); //variables for processing datums string typeCode; string data; string csvData = ""; string testString = ""; //loop through all datums in the transmission and send them to the chart builder for (int i = 0; i < dataTransmission.Length; i++) { if (i == 0) { firstTransmissionDatum = true; } else { firstTransmissionDatum = false; } //remove unwanted characters dataTransmission[i] = dataTransmission[i].Trim(); //zero not always trasmitted properly so add '0.0' to any transmission with no data if (dataTransmission[i].Length == 1) { dataTransmission[i] += "0"; } //pull out data and data type and send to processing function typeCode = dataTransmission[i].Substring(0, 1); if (typeCode != "e") { testString = dataTransmission[i].Substring(1); data = dataTransmission[i].Substring(1); processTransmissionDatum(typeCode, data); //append data to string for CSV write csvData += typeCode + data + ","; } else { AddTextDelegate("Error Message: " + dataTransmission[i].Substring(1) + "\r\n"); } } //handle case of no GPS fix if (latitude == "" || longitude == "") { AddTextDelegate("No GPS fix: "); } else { //marker added here so extra accuracy can be added addTrackerMarker(latitude, longitude); } //display transmission in message box AddTextDelegate(rawDataReceived + "\r\n"); //write the data to CSV file WriteToCSV(csvData); } //method to process data from transmissions (usually chart inserts) private void processTransmissionDatum(string dataType, string data) { //TODO: add inserts for all charts. altitude is finished and is a template ///data types organized by listing in google doc //MASTER MODULE DATA VALUES ChartDelegate(dataType, data); } //write the data to CSV file -- usually seniordesign-ui\Demo.WindowsForms\bin\Debug private void WriteToCSV(string data) { string path = Directory.GetCurrentDirectory(); string filename = path+"\\TransmissionData" + unixTime.Milliseconds + ".csv"; using (StreamWriter writer = new StreamWriter(filename, true)) { writer.WriteLine(data); } } //must change lat/long coords to properly place map marker float conv_coords(float in_coords) { //Initialize the location. float f = in_coords; // Get the first two digits by turning f into an integer, then doing an integer divide by 100; // firsttowdigits should be 77 at this point. int firsttwodigits = ((int)f) / 100; //This assumes that f < 10000. float nexttwodigits = f - (float)(firsttwodigits * 100); float theFinalAnswer = (float)(firsttwodigits + nexttwodigits / 60.0); return theFinalAnswer; } //must change lat/long coords to properly place map marker public decimal DmsToDD(double d, double m = 0, double s = 0) { return Convert.ToDecimal((d + (m / 60) + (s / 3600)) * (d < 0 ? -1 : 1)); } // add marker from an APRS transmission - MDKEdit private void addTrackerMarker(string lat, string lng) { double latitude = double.Parse(lat), longitude = double.Parse(lng); PointLatLng APRSloc = new PointLatLng(); APRSloc.Lat = conv_coords((float)latitude); APRSloc.Lng = conv_coords((float)longitude)*-1; GMarkerGoogle m = new GMarkerGoogle(APRSloc, GMarkerGoogleType.blue_small); m.ToolTipText = "Tracker"; m.ToolTipMode = MarkerTooltipMode.Always; objects.Markers.Add(m); } //places text in the message box delegate void SetTextDelegate(string value); public void AddTextDelegate(string value) { if (InvokeRequired) { Invoke(new SetTextDelegate(AddTextDelegate), value); } else { tboxMessageBox.AppendText(value);// += value; textBoxMarkerCount.Text = objects.Markers.Count.ToString(); } } //this is where most of the transmission processing is done delegate void ChartDataDelegate(string dataType, string data); public void ChartDelegate(string dataType, string data) { if (InvokeRequired) { Invoke(new ChartDataDelegate(ChartDelegate), dataType, data); } else { if (firstTransmissionDatum) { ClearTboxColor(); } ///UNIVERSAL DATA TYPES if (dataType.Equals("t")) //board temperature { string dataString = data.ToString(); if (dataString.StartsWith("9")) //Master Module { tboxMasterBoardTemp.Text = dataString.Substring(1); tboxMasterBoardTemp.BackColor = Color.Chartreuse; } else if (dataString.StartsWith("0")) //Atmo Module { tboxAtmoBoardTemp.Text = dataString.Substring(1); tboxAtmoBoardTemp.BackColor = Color.Chartreuse; } else if (dataString.StartsWith("1")) //Geiger Module { tboxGeigerBoardTemp.Text = dataString.Substring(1); tboxGeigerBoardTemp.BackColor = Color.Chartreuse; } else if (dataString.StartsWith("2")) //Camera Module { tboxCameraBoardTemp.Text = dataString.Substring(1); tboxCameraBoardTemp.BackColor = Color.Chartreuse; } } else if (dataType.Equals("l")) //battery level { string dataString = data.ToString(); if (dataString.StartsWith("9")) //Master Module { tboxMasterBatteryLevel.Text = dataString.Substring(1); tboxMasterBatteryLevel.BackColor = Color.Chartreuse; } else if (dataString.StartsWith("0")) //Atmo Module { tboxAtmoBatteryLevel.Text = dataString.Substring(1); tboxAtmoBatteryLevel.BackColor = Color.Chartreuse; } else if (dataString.StartsWith("1")) //Geiger Module { tboxGeigerBatteryLevel.Text = dataString.Substring(1); tboxGeigerBatteryLevel.BackColor = Color.Chartreuse; } else if (dataString.StartsWith("2")) //Camera Module { tboxCameraBatteryLevel.Text = dataString.Substring(1); tboxCameraBatteryLevel.BackColor = Color.Chartreuse; } } else if (dataType.Equals("i")) //Info Message { AddTextDelegate("Info: " + data + "\r\n"); } ///MASTER MODULE DATA TYPES else if (dataType.Equals("_")) //latitude { //TODO: check math and decimal placement latitude += data.ToString(); tboxMasterLatitude.Text = latitude; tboxMasterLatitude.BackColor = Color.Chartreuse; } else if (dataType.Equals("|")) //longitude { //TODO: check math and decimal placement longitude += data.ToString(); tboxMasterLongitude.Text = longitude; tboxMasterLongitude.BackColor = Color.Chartreuse; } else if (dataType.Equals("h")) //HDOP { tboxMasterHDOP.Text = data.ToString(); tboxMasterHDOP.BackColor = Color.Chartreuse; } else if (dataType.Equals("v")) //Velocity { chrtBottomRight.Series.FindByName("velocityTrend").Points.AddY(double.Parse(data)); velocitySum += double.Parse(data); tboxMasterVelocity.Text = data.ToString(); tboxMasterVelocity.BackColor = Color.Chartreuse; } else if (dataType.Equals("s")) //satellites in view { tboxMasterSatellites.Text = data.ToString(); tboxMasterSatellites.BackColor = Color.Chartreuse; } ///ATMOSPHERIC MODULE DATA VALUES else if (dataType.Equals("C")) //Air Temperature { tboxAtmoAirTemp.Text = data.ToString(); tboxAtmoAirTemp.BackColor = Color.Chartreuse; } else if (dataType.Equals("L")) //Ambient Light { tboxAtmoLight.Text = data.ToString(); tboxAtmoLight.BackColor = Color.Chartreuse; } else if (dataType.Equals("H")) //Humidity { chrtTopRight.Series.FindByName("humidityTrend").Points.AddY(double.Parse(data)); humiditySum += double.Parse(data); tboxAtmoHumidity.Text = data.ToString(); tboxAtmoHumidity.BackColor = Color.Chartreuse; } else if (dataType.Equals("P")) //Pressure { chrtBottomLeft.Series.FindByName("pressureTrend").Points.AddY(double.Parse(data)); pressureSum += double.Parse(data); tboxAtmoPressure.Text = data.ToString(); tboxAtmoPressure.BackColor = Color.Chartreuse; } else if (dataType.Equals("A")) //Altitude { chrtTopLeft.Series.FindByName("altitudeTrend").Points.AddY(double.Parse(data)); altitudeSum += double.Parse(data); tboxAtmoAltitude.Text = data.ToString(); tboxAtmoAltitude.BackColor = Color.Chartreuse; } ///GEIGER MODULE DATA VALUES else if (dataType.Equals("R")) //radiation (CPM) { tboxGeigerRads.Text = data.ToString(); tboxGeigerRads.BackColor = Color.Chartreuse; } /// CAMERA MODULE DATA VALUES //INVALID DATA TYPE else { AddTextDelegate("Info: " + data + "\r\n"); } } } private void ClearTboxColor() { //tboxAtmoHumidity.BorderStyle = BorderStyle.FixedSingle; tboxMasterBoardTemp.BackColor = Color.White; tboxAtmoBoardTemp.BackColor = Color.White; tboxGeigerBoardTemp.BackColor = Color.White; tboxCameraBoardTemp.BackColor = Color.White; tboxMasterBatteryLevel.BackColor = Color.White; tboxAtmoBatteryLevel.BackColor = Color.White; tboxGeigerBatteryLevel.BackColor = Color.White; tboxCameraBatteryLevel.BackColor = Color.White; tboxMasterLatitude.BackColor = Color.White; tboxMasterLongitude.BackColor = Color.White; tboxMasterHDOP.BackColor = Color.White; tboxMasterVelocity.BackColor = Color.White; tboxMasterSatellites.BackColor = Color.White; tboxAtmoAirTemp.BackColor = Color.White; tboxAtmoLight.BackColor = Color.White; tboxAtmoHumidity.BackColor = Color.White; tboxAtmoPressure.BackColor = Color.White; tboxAtmoAltitude.BackColor = Color.White; tboxGeigerRads.BackColor = Color.White; return; } #endregion #region testing //click event on the test button //currently simulates serial inputs string testData; int testIteration = 0; double testLat = 39.751248, testLng = -83.809848, testVelocity = 5.8, testAltitude = 100, testPressure = 700, testHumidity = 38; private void btnTest_Click(object sender, EventArgs e) { testLat += GetRandomNumber(-.005, .015); testLng += GetRandomNumber(-.005, .015); testVelocity += GetRandomNumber(1, 15); testAltitude += GetRandomNumber(50, 150); testPressure -= GetRandomNumber(10, 50); testHumidity -= GetRandomNumber(1, 3); switch (testIteration) { case 0: testData = "KD8TDF-9>APRS,WIDE2-1:/151916z" + testLat + "N/" + testLng + "WO005/0.013 V" + testVelocity + " A" + testAltitude+" H"+testHumidity+" P"+testPressure; ParseIncomingData(testData); break; case 1: testData = "KD8TDF-9>APRS,WIDE2-1:/151916z" + testLat + "N/" + testLng + "WO005/0.013 V" + testVelocity + " A" + testAltitude + " H" + testHumidity + " P" + testPressure; ParseIncomingData(testData); break; case 2: testData = "KD8TDF-9>APRS,WIDE2-1:/151916z" + testLat + "N/" + testLng + "WO005/0.013 V" + testVelocity + " A" + testAltitude + " H" + testHumidity + " P" + testPressure; ParseIncomingData(testData); break; case 3: testData = "KD8TDF-9>APRS,WIDE2-1:/151916z" + testLat + "N/" + testLng + "WO005/0.013 V" + testVelocity + " A" + testAltitude + " H" + testHumidity + " P" + testPressure; ParseIncomingData(testData); break; case 4: testData = "KD8TDF-9>APRS,WIDE2-1:/151916z" + testLat + "N/" + testLng + "WO005/0.013 V" + testVelocity + " A" + testAltitude + " H" + testHumidity + " P" + testPressure; ParseIncomingData(testData); break; case 5: testData = "KD8TDF-9>APRS,WIDE2-1:/151916z" + testLat + "N/" + testLng + "WO005/0.013 V" + testVelocity + " A" + testAltitude + " H" + testHumidity + " P" + testPressure; ParseIncomingData(testData); break; case 6: testData = "KD8TDF-9>APRS,WIDE2-1:/151916z" + testLat + "N/" + testLng + "WO005/0.013 V" + testVelocity + " A" + testAltitude + " H" + testHumidity + " P" + testPressure; ParseIncomingData(testData); break; case 7: testData = "KD8TDF-9>APRS,WIDE2-1:/151916z" + testLat + "N/" + testLng + "WO005/0.013 V" + testVelocity + " A" + testAltitude + " H" + testHumidity + " P" + testPressure; ParseIncomingData(testData); break; case 8: testData = "KD8TDF-9>APRS,WIDE2-1:/151916z" + testLat + "N/" + testLng + "WO005/0.013 V" + testVelocity + " A" + testAltitude + " H" + testHumidity + " P" + testPressure; ParseIncomingData(testData); break; case 9: testData = "KD8TDF-9>APRS,WIDE2-1:/151916z" + testLat + "N/" + testLng + "WO005/0.013 V" + testVelocity + " A" + testAltitude + " H" + testHumidity + " P" + testPressure; ParseIncomingData(testData); break; default: break; } testIteration++; } public double GetRandomNumber(double minimum, double maximum) { Random random = new Random(); return random.NextDouble() * (maximum - minimum) + minimum; } #endregion } } //TODO: CSV logging, offline caching //weekly changes: chart text display, map functionality[routes, layout, markers], find/remove unused code, // figured out caching but still needs to be tested