Ethan,
Thanks for responding so quickly. I didn’t expect a response until tomorrow. I really appreciate it. However, I am still having the issue. I was already using ZoomLevelSnappingMode None, as I said in my first post. I hadn’t tried #2, but that did not change anything for me when I tried it. #3 is impossible for my requirements. Let’s just say that using Meter would require a lot of rewriting of code that I would rather scoop my eyes out with a spoon or at the very least look for another Mapping solution. I NEED to use LAT/LON and display the map extent that I want.
Since my attachment didn’t work for you (sorry about that), I will copy and paste the relevant code here. To reiterate, this is from the GPStoGoogleMapDesktopSampleForWinForms example downloaded from the TG 10.X Product Center. The first thing I did was make the winformsMap1 square in the designer, adjusting the other components to allow the entire map to be visible.
I edited the MainForm.cs like:
using System;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite;
using ThinkGeo.MapSuite.Drawing;
using ThinkGeo.MapSuite.Layers;
using ThinkGeo.MapSuite.Shapes;
using ThinkGeo.MapSuite.Styles;
using ThinkGeo.MapSuite.WinForms;
namespace GPStoGoogleMapDesktop
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void TestForm_Load(object sender, EventArgs e)
{
try {
// winformsMap1.MapUnit = GeographyUnit.Meter;
winformsMap1.MapUnit = GeographyUnit.DecimalDegree;
winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 198, 255, 255));
winformsMap1.ZoomLevelSet = new SphericalMercatorZoomLevelSet();
winformsMap1.ZoomLevelSnapping = ZoomLevelSnappingMode.None;
GoogleMapsOverlay googleOverlay = new GoogleMapsOverlay(); //(@"Insert your key here!", @"C:\GoogleCache");
googleOverlay.MapType = ThinkGeo.MapSuite.WinForms.GoogleMapsMapType.Hybrid;
winformsMap1.Overlays.Add(googleOverlay);
// This sets the zoom levels to map to Googles. We next make sure we snap to the zoomlevels
// winformsMap1.ZoomLevelSet = new SphericalMercatorZoomLevelSet();
winformsMap1.ZoomLevelSet = new ThinkGeo.MapSuite.Layers.ZoomLevelSet();
InMemoryFeatureLayer pointLayer = new InMemoryFeatureLayer();
pointLayer.Open();
pointLayer.Columns.Add(new FeatureSourceColumn("Text"));
pointLayer.Close();
//Sets the projection parameters to go from Geodetic (EPSG 4326) or decimal degrees to Google Map projection (Spherical Mercator).
Proj4Projection proj4 = new Proj4Projection();
// proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);
//proj4.ExternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString();
proj4.InternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString();
proj4.ExternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);
//Applies the projection to the InMemoryFeatureLayer so that the point in decimal degrees (Longitude/Latitude) can be
//match the projection of Google Map.
//pointLayer.FeatureSource.Projection = proj4;
proj4.Open();
googleOverlay.ProjectionFromSphericalMercator = proj4;
//Values in Longitude and Latitude.
double Longitude = -95.2809;
double Latitude = 38.9543;
//Creates the feature made of a PointShape with the Longitude and Latitude values.
Feature GPSFeature = new Feature(new PointShape(Longitude, Latitude));
//Format the Longitude and Latitude into a nice string as Degrees Minutes and Seconds
string LongLat = DecimalDegreesHelper.GetDegreesMinutesSecondsStringFromDecimalDegreePoint(GPSFeature);
//Sets the InMemoryFeatureLayer to have it displayed with Square symbol and with text.
GPSFeature.ColumnValues.Add("Text", LongLat);
pointLayer.InternalFeatures.Add(GPSFeature);
pointLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimplePointStyle(PointSymbolType.Square,
GeoColor.StandardColors.Red, GeoColor.StandardColors.Black, 2, 12);
pointLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("Text", "Arial", 12, DrawingFontStyles.Bold,
GeoColor.StandardColors.Black, GeoColor.StandardColors.White, 3, -10, 10);
pointLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
LayerOverlay pointOverlay = new LayerOverlay();
pointOverlay.Layers.Add("PointLayer", pointLayer);
winformsMap1.Overlays.Add("PointOverlay", pointOverlay);
//Sets the extend of the map based on the GPS point.
//proj4.Open();
Vertex projVertex = new Vertex(Longitude, Latitude);
//proj4.Close();
double extendWidth = 2300;
double extendHeight = 1200;
/* winformsMap1.CurrentExtent = new RectangleShape((projVertex.X - extendWidth), (projVertex.Y + extendHeight),
(projVertex.X + extendWidth), (projVertex.Y - extendHeight));*/
// winformsMap1.CurrentExtent = new RectangleShape(-123.02060015736, 45.6005019300307, -122.75149324264, 45.4119034420553);
bool usePoint = true;
if (usePoint)
{
winformsMap1.CurrentExtent.UpperLeftPoint.X = -123.02060015736;
winformsMap1.CurrentExtent.UpperLeftPoint.Y = 45.6005019300307;
winformsMap1.CurrentExtent.LowerRightPoint.X = -122.75149324264;
winformsMap1.CurrentExtent.LowerRightPoint.Y = 45.4119034420553;
}
else
{
winformsMap1.CurrentExtent = new RectangleShape(-123.02060015736, 45.6005019300307, -122.75149324264, 45.4119034420553);
}
winformsMap1.Refresh();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void winformsMap1_MouseMove(object sender, MouseEventArgs e)
{
//Displays the X and Y in screen coordinates.
statusStrip1.Items["toolStripStatusLabelScreen"].Text = "X:" + e.X + " Y:" + e.Y;
//Gets the PointShape in world coordinates from screen coordinates.
PointShape pointShape = ExtentHelper.ToWorldCoordinate(winformsMap1.CurrentExtent, new ScreenPointF(e.X, e.Y), winformsMap1.Width, winformsMap1.Height);
//Displays world coordinates.
statusStrip1.Items["toolStripStatusLabelWorld"].Text = "(world) X:" + Math.Round(pointShape.X, 4) + " Y:" + Math.Round(pointShape.Y, 4);
}
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
The MainForm.Designer.cs looks like:
namespace GPStoGoogleMapDesktop
{
partial class MainForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.btnClose = new System.Windows.Forms.Button();
this.ImageListToolbar = new System.Windows.Forms.ImageList(this.components);
this.winformsMap1 = new ThinkGeo.MapSuite.WinForms.WinformsMap();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabelScreen = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripStatusLabelWorld = new System.Windows.Forms.ToolStripStatusLabel();
this.statusStrip1.SuspendLayout();
this.SuspendLayout();
//
// btnClose
//
this.btnClose.Location = new System.Drawing.Point(603, 434);
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(75, 23);
this.btnClose.TabIndex = 1;
this.btnClose.Text = "Close";
this.btnClose.UseVisualStyleBackColor = true;
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
//
// ImageListToolbar
//
this.ImageListToolbar.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("ImageListToolbar.ImageStream")));
this.ImageListToolbar.TransparentColor = System.Drawing.Color.Transparent;
this.ImageListToolbar.Images.SetKeyName(0, "");
this.ImageListToolbar.Images.SetKeyName(1, "");
this.ImageListToolbar.Images.SetKeyName(2, "");
this.ImageListToolbar.Images.SetKeyName(3, "");
this.ImageListToolbar.Images.SetKeyName(4, "");
this.ImageListToolbar.Images.SetKeyName(5, "");
this.ImageListToolbar.Images.SetKeyName(6, "");
this.ImageListToolbar.Images.SetKeyName(7, "");
this.ImageListToolbar.Images.SetKeyName(8, "");
this.ImageListToolbar.Images.SetKeyName(9, "");
this.ImageListToolbar.Images.SetKeyName(10, "");
this.ImageListToolbar.Images.SetKeyName(11, "");
this.ImageListToolbar.Images.SetKeyName(12, "");
this.ImageListToolbar.Images.SetKeyName(13, "");
this.ImageListToolbar.Images.SetKeyName(14, "");
this.ImageListToolbar.Images.SetKeyName(15, "");
this.ImageListToolbar.Images.SetKeyName(16, "");
this.ImageListToolbar.Images.SetKeyName(17, "");
this.ImageListToolbar.Images.SetKeyName(18, "");
this.ImageListToolbar.Images.SetKeyName(19, "");
this.ImageListToolbar.Images.SetKeyName(20, "");
this.ImageListToolbar.Images.SetKeyName(21, "");
this.ImageListToolbar.Images.SetKeyName(22, "");
this.ImageListToolbar.Images.SetKeyName(23, "");
this.ImageListToolbar.Images.SetKeyName(24, "");
this.ImageListToolbar.Images.SetKeyName(25, "");
this.ImageListToolbar.Images.SetKeyName(26, "");
this.ImageListToolbar.Images.SetKeyName(27, "");
this.ImageListToolbar.Images.SetKeyName(28, "");
this.ImageListToolbar.Images.SetKeyName(29, "");
this.ImageListToolbar.Images.SetKeyName(30, "");
this.ImageListToolbar.Images.SetKeyName(31, "tool_icon_color_picker.png");
this.ImageListToolbar.Images.SetKeyName(32, "btn_layer_up.png");
this.ImageListToolbar.Images.SetKeyName(33, "btn_layer_down.png");
//
// winformsMap1
//
this.winformsMap1.BackColor = System.Drawing.Color.White;
this.winformsMap1.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.Default;
this.winformsMap1.DrawingQuality = ThinkGeo.MapSuite.Drawing.DrawingQuality.Default;
this.winformsMap1.Location = new System.Drawing.Point(12, 12);
this.winformsMap1.MapFocusMode = ThinkGeo.MapSuite.WinForms.MapFocusMode.Default;
this.winformsMap1.MapResizeMode = ThinkGeo.MapSuite.Shapes.MapResizeMode.PreserveScale;
this.winformsMap1.MapUnit = ThinkGeo.MapSuite.GeographyUnit.DecimalDegree;
this.winformsMap1.MaximumScale = 80000000000000D;
this.winformsMap1.MinimumScale = 200D;
this.winformsMap1.Name = "winformsMap1";
this.winformsMap1.Size = new System.Drawing.Size(666, 666);
this.winformsMap1.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
this.winformsMap1.TabIndex = 2;
this.winformsMap1.Text = "winformsMap1";
this.winformsMap1.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
this.winformsMap1.ThreadingMode = ThinkGeo.MapSuite.WinForms.MapThreadingMode.Default;
this.winformsMap1.ZoomLevelSnapping = ThinkGeo.MapSuite.WinForms.ZoomLevelSnappingMode.Default;
this.winformsMap1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.winformsMap1_MouseMove);
//
// statusStrip1
//
this.statusStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Visible;
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabelScreen,
this.toolStripStatusLabelWorld});
this.statusStrip1.Location = new System.Drawing.Point(0, 684);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(690, 22);
this.statusStrip1.TabIndex = 46;
this.statusStrip1.Text = "statusStrip1";
//
// toolStripStatusLabelScreen
//
this.toolStripStatusLabelScreen.AutoSize = false;
this.toolStripStatusLabelScreen.BorderSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)((System.Windows.Forms.ToolStripStatusLabelBorderSides.Left | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)));
this.toolStripStatusLabelScreen.BorderStyle = System.Windows.Forms.Border3DStyle.SunkenInner;
this.toolStripStatusLabelScreen.Name = "toolStripStatusLabelScreen";
this.toolStripStatusLabelScreen.Size = new System.Drawing.Size(70, 17);
this.toolStripStatusLabelScreen.Text = "toolStripStatusLabel1";
//
// toolStripStatusLabelWorld
//
this.toolStripStatusLabelWorld.AutoSize = false;
this.toolStripStatusLabelWorld.BorderSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)((System.Windows.Forms.ToolStripStatusLabelBorderSides.Left | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)));
this.toolStripStatusLabelWorld.Name = "toolStripStatusLabelWorld";
this.toolStripStatusLabelWorld.Size = new System.Drawing.Size(188, 17);
this.toolStripStatusLabelWorld.Text = "toolStripStatusLabel1";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(690, 706);
this.Controls.Add(this.statusStrip1);
this.Controls.Add(this.winformsMap1);
this.Controls.Add(this.btnClose);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "MainForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Code Community Project-GPS to Google Map Desktop";
this.Load += new System.EventHandler(this.TestForm_Load);
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnClose;
internal System.Windows.Forms.ImageList ImageListToolbar;
private ThinkGeo.MapSuite.WinForms.WinformsMap winformsMap1;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelScreen;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelWorld;
}
}
Those are the only changes that I made to the sample project. That should be enough to see what I am talking about. You’ll also notice the change in behavior in changing the CurrentExtent depending on the method that sets the Extent. Personally, I am not sure why the map is deciding that it knows better than I do what the extent and the aspect ratio should be. If I want to display 5 square meters, the map shouldn’t decide that I really want to show 5.5 meters by 5 meters. Plus, there is the difference in behavior between setting the points vs setting it as a whole rectangle. One gives me the answer I want; the other does not. This seems like a bug to me, not a feature.
I will attempt to attach the project, while also attaching the two .cs files that are copied above.
Thanks again for your help. I am extremely frustrated at the moment since this problem is a show stopper for getting our updated maps out. This seems like it might make me miss deadlines, and I will have to pay those consequences. If I have to spend month or two redoing all my code to ensure that everything is now in meters and lines up the way I want, that will be too costly. I might as well start over with a different map vendor if that makes sense. I am trying to stress “convert to meters as a map unit” is not a solution.
GPStoGoogleMapDesktopSampleforWinForms.zip (1011.8 KB) You will have to download the packages again from Nuget. It is too large to upload otherwise.
MainForm.cs (6.4 KB)MainForm.designer.cs (9.5 KB)
Thanks again for your help. I really do appreciate it.