Skip to content

Commit cf953c8

Browse files
author
Alexander Krutov
committed
Some fixes, added new events and properties
1 parent ccba9ca commit cf953c8

5 files changed

Lines changed: 184 additions & 37 deletions

File tree

DemoApp/FormMain.cs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ private ICollection<GeoPoint> ReadPointsFromResource(string resourceName)
137137
private void UpdateWindowTitle()
138138
{
139139
GeoPoint g = mapControl.Mouse;
140-
this.Text = $"Longitude = {DegreeToString(g.Longitude, "W", "E")} / Latitude = {DegreeToString(g.Latitude, "S", "N")} / Zoom = {mapControl.ZoomLevel}";
140+
this.Text = $"Mouse = {g} / Zoom = {mapControl.ZoomLevel} / Bounding Box = TL:{mapControl.TopLeft}, TR:{mapControl.TopRight}, BR:{mapControl.BottomRight}, BL:{mapControl.BottomLeft}";
141141
}
142142

143143
private void mapControl_MouseMove(object sender, MouseEventArgs e)
@@ -184,26 +184,8 @@ private void mapControl_DoubleClick(object sender, EventArgs e)
184184
{
185185
var coord = mapControl.Mouse;
186186
StringBuilder sb = new StringBuilder();
187-
sb.AppendLine($"Latitude: {DegreeToString(coord.Latitude, "S", "N")}");
188-
sb.AppendLine($"Longitude: {DegreeToString(coord.Longitude, "W", "E")}");
187+
sb.AppendLine($"Location: {coord}");
189188
MessageBox.Show(sb.ToString(), "Info");
190189
}
191-
192-
private string DegreeToString(double coordinate, string negativeSym, string positiveSym)
193-
{
194-
string sym = coordinate < 0d ? negativeSym : positiveSym;
195-
coordinate = Math.Abs(coordinate);
196-
double d = Math.Floor(coordinate);
197-
coordinate -= d;
198-
coordinate *= 60;
199-
double m = Math.Floor(coordinate);
200-
coordinate -= m;
201-
coordinate *= 60;
202-
double s = coordinate;
203-
string dd = d.ToString();
204-
string mm = m.ToString().PadLeft(2, '0');
205-
string ss = s.ToString("00.00", CultureInfo.InvariantCulture);
206-
return $"{dd}° {mm}' {ss}\" {sym}";
207-
}
208190
}
209191
}

MapControl/GeoPoint.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace System.Windows.Forms
1+
using System.Globalization;
2+
3+
namespace System.Windows.Forms
24
{
35
/// <summary>
46
/// Represents point on the Earth surface with geographical coordinates
@@ -25,5 +27,28 @@ public GeoPoint(float longitude, float latitude)
2527
Longitude = longitude;
2628
Latitude = latitude;
2729
}
30+
31+
/// <inheritdoc/>
32+
public override string ToString()
33+
{
34+
return $"{DegreeToString(Longitude, "W", "E")}, {DegreeToString(Latitude, "S", "N")}";
35+
}
36+
37+
private static string DegreeToString(double coordinate, string negativeSym, string positiveSym)
38+
{
39+
string sym = coordinate < 0d ? negativeSym : positiveSym;
40+
coordinate = Math.Abs(coordinate);
41+
double d = Math.Floor(coordinate);
42+
coordinate -= d;
43+
coordinate *= 60;
44+
double m = Math.Floor(coordinate);
45+
coordinate -= m;
46+
coordinate *= 60;
47+
double s = coordinate;
48+
string dd = d.ToString();
49+
string mm = m.ToString().PadLeft(2, '0');
50+
string ss = s.ToString("00.00", CultureInfo.InvariantCulture);
51+
return $"{dd}° {mm}' {ss}\" {sym}";
52+
}
2853
}
2954
}

MapControl/MapControl.cs

Lines changed: 112 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Diagnostics;
55
using System.Drawing;
66
using System.Drawing.Drawing2D;
7+
using System.Drawing.Imaging;
78
using System.IO;
89
using System.Linq;
910
using System.Threading;
@@ -93,7 +94,8 @@ public int ZoomLevel
9394
if (value < 0 || value > 19)
9495
throw new ArgumentException($"{value} is an incorrect value for {nameof(ZoomLevel)} property. Value should be in range from 0 to 19.");
9596

96-
SetZoomLevel(value, new Point(Width / 2, Height / 2));
97+
SetZoomLevel(value, new Point(Width / 2, Height / 2));
98+
CenterChanged?.Invoke(this, EventArgs.Empty);
9799
}
98100
}
99101

@@ -205,7 +207,8 @@ public ITileServer TileServer
205207
ZoomLevel = TileServer.MinZoomLevel;
206208
}
207209

208-
Invalidate();
210+
Invalidate();
211+
TileServerChanged?.Invoke(this, EventArgs.Empty);
209212
}
210213
}
211214

@@ -218,8 +221,8 @@ public GeoPoint Center
218221
{
219222
get
220223
{
221-
float x = NormalizeTileNumber(-(_Offset.X - Width / 2) / TILE_SIZE);
222-
float y = -(_Offset.Y - Height / 2) / TILE_SIZE;
224+
float x = NormalizeTileNumber(-(float)(_Offset.X - Width / 2) / TILE_SIZE);
225+
float y = -(float)(_Offset.Y - Height / 2) / TILE_SIZE;
223226
return TileToWorldPos(x, y);
224227
}
225228
set
@@ -228,11 +231,11 @@ public GeoPoint Center
228231
_Offset.X = -(int)(center.X * TILE_SIZE) + Width / 2;
229232
_Offset.Y = -(int)(center.Y * TILE_SIZE) + Height / 2;
230233
_Offset.X = (int)(_Offset.X % FullMapSizeInPixels);
231-
Invalidate();
234+
Invalidate();
235+
CenterChanged?.Invoke(this, EventArgs.Empty);
232236
}
233237
}
234238

235-
236239
/// <summary>
237240
/// Gets geographical coordinates of the current position of mouse.
238241
/// </summary>
@@ -248,6 +251,66 @@ public GeoPoint Mouse
248251
}
249252
}
250253

254+
/// <summary>
255+
/// Gets geographical coordinates of the top left point of the map
256+
/// </summary>
257+
[Browsable(false)]
258+
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
259+
public GeoPoint TopLeft
260+
{
261+
get
262+
{
263+
float x = NormalizeTileNumber(-(float)(_Offset.X) / TILE_SIZE);
264+
float y = -(float)(_Offset.Y) / TILE_SIZE;
265+
return TileToWorldPos(x, y);
266+
}
267+
}
268+
269+
/// <summary>
270+
/// Gets geographical coordinates of the top right point of the map
271+
/// </summary>
272+
[Browsable(false)]
273+
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
274+
public GeoPoint TopRight
275+
{
276+
get
277+
{
278+
float x = NormalizeTileNumber(-(float)(_Offset.X - Width) / TILE_SIZE);
279+
float y = -(float)(_Offset.Y) / TILE_SIZE;
280+
return TileToWorldPos(x, y);
281+
}
282+
}
283+
284+
/// <summary>
285+
/// Gets geographical coordinates of the bottom left point of the map
286+
/// </summary>
287+
[Browsable(false)]
288+
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
289+
public GeoPoint BottomLeft
290+
{
291+
get
292+
{
293+
float x = NormalizeTileNumber(-(float)(_Offset.X) / TILE_SIZE);
294+
float y = -(float)(_Offset.Y - Height) / TILE_SIZE;
295+
return TileToWorldPos(x, y);
296+
}
297+
}
298+
299+
/// <summary>
300+
/// Gets geographical coordinates of the bottom right point of the map
301+
/// </summary>
302+
[Browsable(false)]
303+
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
304+
public GeoPoint BottomRight
305+
{
306+
get
307+
{
308+
float x = NormalizeTileNumber(-(float)(_Offset.X - Width) / TILE_SIZE);
309+
float y = -(float)(_Offset.Y - Height) / TILE_SIZE;
310+
return TileToWorldPos(x, y);
311+
}
312+
}
313+
251314
/// <summary>
252315
/// Gets collection of markers to be displayed on the map.
253316
/// </summary>
@@ -332,6 +395,12 @@ public override Color ForeColor
332395
}
333396
}
334397

398+
/// <summary>
399+
/// Image attributes to be applied to a tile image when drawing.
400+
/// </summary>
401+
[Description("Image attributes to be applied to a tile image when drawing."), Category("Appearance")]
402+
public ImageAttributes TileImageAttributes { get; set; } = null;
403+
335404
/// <summary>
336405
/// Raised when marker is drawn on the map.
337406
/// </summary>
@@ -346,6 +415,21 @@ public override Color ForeColor
346415
/// Raised when polygon is drawn on the map.
347416
/// </summary>
348417
public event EventHandler<DrawPolygonEventArgs> DrawPolygon;
418+
419+
/// <summary>
420+
/// Raised when <see cref="Center"/> property value is changed.
421+
/// </summary>
422+
public event EventHandler<EventArgs> CenterChanged;
423+
424+
/// <summary>
425+
/// Raised when <see cref="Mouse"/> property value is changed.
426+
/// </summary>
427+
public event EventHandler<EventArgs> MouseChanged;
428+
429+
/// <summary>
430+
/// Raised when <see cref="TileServer"/> property value is changed.
431+
/// </summary>
432+
public event EventHandler<EventArgs> TileServerChanged;
349433

350434
/// <summary>
351435
/// Creates new <see cref="MapControl"/> control.
@@ -439,7 +523,8 @@ protected override void OnSizeChanged(EventArgs e)
439523
_LinkLabel.Top = Height - _LinkLabel.Height;
440524

441525
AdjustMapBounds();
442-
Invalidate();
526+
Invalidate();
527+
CenterChanged?.Invoke(this, EventArgs.Empty);
443528
}
444529

445530
/// <summary>
@@ -487,12 +572,14 @@ protected override void OnMouseMove(MouseEventArgs e)
487572
_Offset.Y = Height;
488573

489574
AdjustMapBounds();
490-
491-
Invalidate();
575+
Invalidate();
576+
CenterChanged?.Invoke(this, EventArgs.Empty);
492577
}
493578

494579
_LastMouse.X = e.X;
495580
_LastMouse.Y = e.Y;
581+
582+
MouseChanged?.Invoke(this, EventArgs.Empty);
496583

497584
base.OnMouseMove(e);
498585
}
@@ -513,8 +600,8 @@ protected override void OnMouseWheel(MouseEventArgs e)
513600
SetZoomLevel(z, new Point(e.X, e.Y));
514601

515602
AdjustMapBounds();
516-
517-
base.OnMouseWheel(e);
603+
base.OnMouseWheel(e);
604+
CenterChanged?.Invoke(this, EventArgs.Empty);
518605
}
519606

520607
/// <summary>
@@ -744,7 +831,6 @@ private void DrawPolygons(Graphics gr)
744831
using (GraphicsPath gp = new GraphicsPath())
745832
{
746833
gp.StartFigure();
747-
748834
for (int i = 0; i < polygon.Count; i++)
749835
{
750836
GeoPoint g = polygon.ElementAt(i);
@@ -754,9 +840,12 @@ private void DrawPolygons(Graphics gr)
754840
p = p0.Nearest(p, new PointF(p.X - FullMapSizeInPixels, p.Y), new PointF(p.X + FullMapSizeInPixels, p.Y));
755841
gp.AddLine(p0, p);
756842
}
843+
757844
p0 = p;
758845
}
759846

847+
gp.CloseFigure();
848+
760849
var eventArgs = new DrawPolygonEventArgs()
761850
{
762851
Graphics = gr,
@@ -812,8 +901,15 @@ private void DrawTilePart(Graphics gr, int x, int y, int xRemainder, int yRemain
812901
Rectangle srcRect = new Rectangle(TILE_SIZE / frac * xRemainder, TILE_SIZE / frac * yRemainder, TILE_SIZE / frac, TILE_SIZE / frac);
813902

814903
// Destination rectangle
815-
Rectangle destRect = new Rectangle(p.X, p.Y, TILE_SIZE, TILE_SIZE);
816-
gr.DrawImage(image, destRect, srcRect, GraphicsUnit.Pixel);
904+
Rectangle destRect = new Rectangle(p.X - frac, p.Y - frac, TILE_SIZE + 2 * frac, TILE_SIZE + 2 * frac);
905+
906+
var state = gr.Save();
907+
gr.SmoothingMode = SmoothingMode.HighSpeed;
908+
gr.InterpolationMode = InterpolationMode.NearestNeighbor;
909+
gr.PixelOffsetMode = PixelOffsetMode.HighSpeed;
910+
gr.CompositingQuality = CompositingQuality.HighSpeed;
911+
gr.DrawImage(image, destRect, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, GraphicsUnit.Pixel, TileImageAttributes);
912+
gr.Restore(state);
817913
}
818914

819915
/// <summary>
@@ -828,7 +924,8 @@ private void DrawTile(Graphics gr, int x, int y, Image image)
828924
Point p = new Point();
829925
p.X = _Offset.X + x * TILE_SIZE;
830926
p.Y = _Offset.Y + y * TILE_SIZE;
831-
gr.DrawImageUnscaled(image, p);
927+
928+
gr.DrawImage(image, new Rectangle(p, new Drawing.Size(TILE_SIZE, TILE_SIZE)), 0, 0, TILE_SIZE, TILE_SIZE, GraphicsUnit.Pixel, TileImageAttributes);
832929
}
833930

834931
/// <summary>

MapControl/MapControl.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>net451</TargetFrameworks>
4-
<Version>1.0.1</Version>
4+
<Version>1.0.2</Version>
55
<Product>System.Windows.Forms.MapControl</Product>
66
<Description>Map control for WindowsForms</Description>
77
<Copyright>© Alexander Krutov 2020</Copyright>

MapControl/System.Windows.Forms.MapControl.xml

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)