2019-03-19 21:09:03 +00:00
|
|
|
|
|
|
|
|
|
namespace GMap.NET.WindowsForms
|
|
|
|
|
{
|
|
|
|
|
using System;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Drawing.Drawing2D;
|
|
|
|
|
using System.Drawing.Imaging;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using GMap.NET;
|
|
|
|
|
using GMap.NET.Internals;
|
|
|
|
|
using GMap.NET.ObjectModel;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Drawing.Text;
|
|
|
|
|
using GMap.NET.MapProviders;
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using GMap.NET.Projections;
|
|
|
|
|
#else
|
|
|
|
|
using OpenNETCF.ComponentModel;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// GMap.NET control for Windows Forms
|
|
|
|
|
/// </summary>
|
|
|
|
|
public partial class GMapControl : UserControl, Interface
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs when clicked on marker
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event MarkerClick OnMarkerClick;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs when clicked on polygon
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event PolygonClick OnPolygonClick;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs when clicked on route
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event RouteClick OnRouteClick;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs on mouse enters route area
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event RouteEnter OnRouteEnter;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs on mouse leaves route area
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event RouteLeave OnRouteLeave;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs when mouse selection is changed
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event SelectionChange OnSelectionChange;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs on mouse enters marker area
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event MarkerEnter OnMarkerEnter;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs on mouse leaves marker area
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event MarkerLeave OnMarkerLeave;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs on mouse enters Polygon area
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event PolygonEnter OnPolygonEnter;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs on mouse leaves Polygon area
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event PolygonLeave OnPolygonLeave;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// list of overlays, should be thread safe
|
|
|
|
|
/// </summary>
|
|
|
|
|
public readonly ObservableCollectionThreadSafe<GMapOverlay> Overlays = new ObservableCollectionThreadSafe<GMapOverlay>();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// max zoom
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
[Description("maximum zoom level of map")]
|
|
|
|
|
public int MaxZoom
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.maxZoom;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.maxZoom = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// min zoom
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
[Description("minimum zoom level of map")]
|
|
|
|
|
public int MinZoom
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.minZoom;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.minZoom = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// map zooming type for mouse wheel
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
[Description("map zooming type for mouse wheel")]
|
|
|
|
|
public MouseWheelZoomType MouseWheelZoomType
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.MouseWheelZoomType;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.MouseWheelZoomType = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// text on empty tiles
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string EmptyTileText = "We are sorry, but we don't\nhave imagery at this zoom\nlevel for this region.";
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// pen for empty tile borders
|
|
|
|
|
/// </summary>
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
public Pen EmptyTileBorders = new Pen(Brushes.White, 1);
|
|
|
|
|
#else
|
|
|
|
|
public Pen EmptyTileBorders = new Pen(Color.White, 1);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
public bool ShowCenter = true;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// pen for scale info
|
|
|
|
|
/// </summary>
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
public Pen ScalePen = new Pen(Brushes.Blue, 1);
|
|
|
|
|
public Pen CenterPen = new Pen(Brushes.Red, 1);
|
|
|
|
|
#else
|
|
|
|
|
public Pen ScalePen = new Pen(Color.Blue, 1);
|
|
|
|
|
public Pen CenterPen = new Pen(Color.Red, 1);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// area selection pen
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Pen SelectionPen = new Pen(Brushes.Blue, 2);
|
|
|
|
|
|
|
|
|
|
Brush SelectedAreaFill = new SolidBrush(Color.FromArgb(33, Color.RoyalBlue));
|
|
|
|
|
Color selectedAreaFillColor = Color.FromArgb(33, Color.RoyalBlue);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// background of selected area
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
[Description("background color od the selected area")]
|
|
|
|
|
public Color SelectedAreaFillColor
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return selectedAreaFillColor;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if(selectedAreaFillColor != value)
|
|
|
|
|
{
|
|
|
|
|
selectedAreaFillColor = value;
|
|
|
|
|
|
|
|
|
|
if(SelectedAreaFill != null)
|
|
|
|
|
{
|
|
|
|
|
SelectedAreaFill.Dispose();
|
|
|
|
|
SelectedAreaFill = null;
|
|
|
|
|
}
|
|
|
|
|
SelectedAreaFill = new SolidBrush(selectedAreaFillColor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HelperLineOptions helperLineOption = HelperLineOptions.DontShow;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// draw lines at the mouse pointer position
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public HelperLineOptions HelperLineOption
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return helperLineOption;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
helperLineOption = value;
|
|
|
|
|
renderHelperLine = (helperLineOption == HelperLineOptions.ShowAlways);
|
|
|
|
|
if(Core.IsStarted)
|
|
|
|
|
{
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Pen HelperLinePen = new Pen(Color.Blue, 1);
|
|
|
|
|
bool renderHelperLine = false;
|
|
|
|
|
|
|
|
|
|
protected override void OnKeyDown(KeyEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(HelperLineOption == HelperLineOptions.ShowOnModifierKey)
|
|
|
|
|
{
|
|
|
|
|
renderHelperLine = (e.Modifiers == Keys.Shift || e.Modifiers == Keys.Alt);
|
|
|
|
|
if(renderHelperLine)
|
|
|
|
|
{
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
base.OnKeyDown(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnKeyUp(KeyEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(HelperLineOption == HelperLineOptions.ShowOnModifierKey)
|
|
|
|
|
{
|
|
|
|
|
renderHelperLine = (e.Modifiers == Keys.Shift || e.Modifiers == Keys.Alt);
|
|
|
|
|
if(!renderHelperLine)
|
|
|
|
|
{
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
base.OnKeyUp(e);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
Brush EmptytileBrush = new SolidBrush(Color.Navy);
|
|
|
|
|
Color emptyTileColor = Color.Navy;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// color of empty tile background
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
[Description("background color of the empty tile")]
|
|
|
|
|
public Color EmptyTileColor
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return emptyTileColor;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if(emptyTileColor != value)
|
|
|
|
|
{
|
|
|
|
|
emptyTileColor = value;
|
|
|
|
|
|
|
|
|
|
if(EmptytileBrush != null)
|
|
|
|
|
{
|
|
|
|
|
EmptytileBrush.Dispose();
|
|
|
|
|
EmptytileBrush = null;
|
|
|
|
|
}
|
|
|
|
|
EmptytileBrush = new SolidBrush(emptyTileColor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if PocketPC
|
|
|
|
|
readonly Brush TileGridLinesTextBrush = new SolidBrush(Color.Red);
|
|
|
|
|
readonly Brush TileGridMissingTextBrush = new SolidBrush(Color.White);
|
|
|
|
|
readonly Brush CopyrightBrush = new SolidBrush(Color.Navy);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// show map scale info
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool MapScaleInfoEnabled = false;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// enables filling empty tiles using lower level images
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool FillEmptyTiles = true;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// if true, selects area just by holding mouse and moving
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool DisableAltForSelection = false;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// retry count to get tile
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public int RetryLoadTile
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.RetryLoadTile;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.RetryLoadTile = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// how many levels of tiles are staying decompresed in memory
|
|
|
|
|
/// </summary>
|
2020-04-10 15:36:18 +00:00
|
|
|
|
[Browsable(true)]
|
2019-03-19 21:09:03 +00:00
|
|
|
|
public int LevelsKeepInMemmory
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.LevelsKeepInMemmory;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.LevelsKeepInMemmory = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// map dragg button
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
public MouseButtons DragButton = MouseButtons.Right;
|
|
|
|
|
|
|
|
|
|
private bool showTileGridLines = false;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// shows tile gridlines
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
[Description("shows tile gridlines")]
|
|
|
|
|
public bool ShowTileGridLines
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return showTileGridLines;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
showTileGridLines = value;
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// current selected area in map
|
|
|
|
|
/// </summary>
|
|
|
|
|
private RectLatLng selectedArea;
|
|
|
|
|
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public RectLatLng SelectedArea
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return selectedArea;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
selectedArea = value;
|
|
|
|
|
|
|
|
|
|
if(Core.IsStarted)
|
|
|
|
|
{
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// map boundaries
|
|
|
|
|
/// </summary>
|
|
|
|
|
public RectLatLng? BoundsOfMap = null;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// enables integrated DoubleBuffer for running on windows mobile
|
|
|
|
|
/// </summary>
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
public bool ForceDoubleBuffer = false;
|
|
|
|
|
readonly bool MobileMode = false;
|
|
|
|
|
#else
|
|
|
|
|
readonly bool ForceDoubleBuffer = true;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// stops immediate marker/route/polygon invalidations;
|
|
|
|
|
/// call Refresh to perform single refresh and reset invalidation state
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool HoldInvalidation = false;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// call this to stop HoldInvalidation and perform single forced instant refresh
|
|
|
|
|
/// </summary>
|
|
|
|
|
public override void Refresh()
|
|
|
|
|
{
|
|
|
|
|
HoldInvalidation = false;
|
|
|
|
|
|
|
|
|
|
lock(Core.invalidationLock)
|
|
|
|
|
{
|
|
|
|
|
Core.lastInvalidation = DateTime.Now;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.Refresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !DESIGN
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// enque built-in thread safe invalidation
|
|
|
|
|
/// </summary>
|
|
|
|
|
public new void Invalidate()
|
|
|
|
|
{
|
|
|
|
|
if(Core.Refresh != null)
|
|
|
|
|
{
|
|
|
|
|
Core.Refresh.Set();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
private bool _GrayScale = false;
|
|
|
|
|
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
public bool GrayScaleMode
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return _GrayScale;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
_GrayScale = value;
|
|
|
|
|
ColorMatrix = (value == true ? ColorMatrixs.GrayScale : null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool _Negative = false;
|
|
|
|
|
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
public bool NegativeMode
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return _Negative;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
_Negative = value;
|
|
|
|
|
ColorMatrix = (value == true ? ColorMatrixs.Negative : null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ColorMatrix colorMatrix;
|
|
|
|
|
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public ColorMatrix ColorMatrix
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return colorMatrix;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
colorMatrix = value;
|
|
|
|
|
if(GMapProvider.TileImageProxy != null && GMapProvider.TileImageProxy is WindowsFormsImageProxy)
|
|
|
|
|
{
|
|
|
|
|
(GMapProvider.TileImageProxy as WindowsFormsImageProxy).ColorMatrix = value;
|
|
|
|
|
if(Core.IsStarted)
|
|
|
|
|
{
|
|
|
|
|
ReloadMap();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// internal stuff
|
|
|
|
|
internal readonly Core Core = new Core();
|
|
|
|
|
|
|
|
|
|
internal readonly Font CopyrightFont = new Font(FontFamily.GenericSansSerif, 7, FontStyle.Regular);
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
internal readonly Font MissingDataFont = new Font(FontFamily.GenericSansSerif, 11, FontStyle.Bold);
|
|
|
|
|
#else
|
|
|
|
|
internal readonly Font MissingDataFont = new Font(FontFamily.GenericSansSerif, 8, FontStyle.Regular);
|
|
|
|
|
#endif
|
|
|
|
|
// geändert 29.11.2012 DL2ALF
|
|
|
|
|
Font ScaleFont = new Font(FontFamily.GenericSansSerif, 8, FontStyle.Bold);
|
|
|
|
|
// Font ScaleFont = new Font(FontFamily.GenericSansSerif, 5, FontStyle.Italic);
|
|
|
|
|
internal readonly StringFormat CenterFormat = new StringFormat();
|
|
|
|
|
internal readonly StringFormat BottomFormat = new StringFormat();
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
readonly ImageAttributes TileFlipXYAttributes = new ImageAttributes();
|
|
|
|
|
#endif
|
|
|
|
|
double zoomReal;
|
|
|
|
|
Bitmap backBuffer;
|
|
|
|
|
Graphics gxOff;
|
|
|
|
|
|
|
|
|
|
#if !DESIGN
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// construct
|
|
|
|
|
/// </summary>
|
|
|
|
|
public GMapControl()
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(!DesignModeInConstruct && !IsDesignerHosted)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
Manager.SQLitePing();
|
|
|
|
|
|
|
|
|
|
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
|
|
|
|
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
|
|
|
|
this.SetStyle(ControlStyles.UserPaint, true);
|
|
|
|
|
this.SetStyle(ControlStyles.Opaque, true);
|
|
|
|
|
ResizeRedraw = true;
|
|
|
|
|
|
|
|
|
|
TileFlipXYAttributes.SetWrapMode(WrapMode.TileFlipXY);
|
|
|
|
|
|
|
|
|
|
// only one mode will be active, to get mixed mode create new ColorMatrix
|
|
|
|
|
GrayScaleMode = GrayScaleMode;
|
|
|
|
|
NegativeMode = NegativeMode;
|
|
|
|
|
#endif
|
|
|
|
|
GMapProvider.TileImageProxy = WindowsFormsImageProxy.Instance;
|
|
|
|
|
|
|
|
|
|
Core.SystemType = "WindowsForms";
|
|
|
|
|
|
|
|
|
|
RenderMode = RenderMode.GDI_PLUS;
|
|
|
|
|
|
|
|
|
|
CenterFormat.Alignment = StringAlignment.Center;
|
|
|
|
|
CenterFormat.LineAlignment = StringAlignment.Center;
|
|
|
|
|
|
|
|
|
|
BottomFormat.Alignment = StringAlignment.Center;
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
BottomFormat.LineAlignment = StringAlignment.Far;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if(GMaps.Instance.IsRunningOnMono)
|
|
|
|
|
{
|
|
|
|
|
// no imports to move pointer
|
|
|
|
|
MouseWheelZoomType = GMap.NET.MouseWheelZoomType.MousePositionWithoutCenter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Overlays.CollectionChanged += new NotifyCollectionChangedEventHandler(Overlays_CollectionChanged);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Overlays_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(e.NewItems != null)
|
|
|
|
|
{
|
|
|
|
|
foreach(GMapOverlay obj in e.NewItems)
|
|
|
|
|
{
|
|
|
|
|
if(obj != null)
|
|
|
|
|
{
|
|
|
|
|
obj.Control = this;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(Core.IsStarted && !HoldInvalidation)
|
|
|
|
|
{
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void invalidatorEngage(object sender, ProgressChangedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// update objects when map is draged/zoomed
|
|
|
|
|
/// </summary>
|
|
|
|
|
internal void ForceUpdateOverlays()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
HoldInvalidation = true;
|
|
|
|
|
|
|
|
|
|
foreach(GMapOverlay o in Overlays)
|
|
|
|
|
{
|
|
|
|
|
if(o.IsVisibile)
|
|
|
|
|
{
|
|
|
|
|
o.ForceUpdate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
Refresh();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// render map in GDI+
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="g"></param>
|
|
|
|
|
void DrawMap(Graphics g)
|
|
|
|
|
{
|
|
|
|
|
if(Core.updatingBounds || MapProvider == EmptyProvider.Instance || MapProvider == null)
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine("Core.updatingBounds");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Core.tileDrawingListLock.AcquireReaderLock();
|
|
|
|
|
Core.Matrix.EnterReadLock();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
foreach(var tilePoint in Core.tileDrawingList)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
Core.tileRect.Location = tilePoint.PosPixel;
|
|
|
|
|
if(ForceDoubleBuffer)
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(MobileMode)
|
|
|
|
|
{
|
|
|
|
|
Core.tileRect.Offset(Core.renderOffset);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
Core.tileRect.Offset(Core.renderOffset);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
Core.tileRect.OffsetNegative(Core.compensationOffset);
|
|
|
|
|
|
|
|
|
|
//if(Core.currentRegion.IntersectsWith(Core.tileRect) || IsRotated)
|
|
|
|
|
{
|
|
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
|
|
Tile t = Core.Matrix.GetTileWithNoLock(Core.Zoom, tilePoint.PosXY);
|
|
|
|
|
if(t.NotEmpty)
|
|
|
|
|
{
|
|
|
|
|
// render tile
|
|
|
|
|
{
|
|
|
|
|
foreach(WindowsFormsImage img in t.Overlays)
|
|
|
|
|
{
|
2021-12-23 15:18:53 +00:00
|
|
|
|
try
|
2019-03-19 21:09:03 +00:00
|
|
|
|
{
|
2021-12-23 15:18:53 +00:00
|
|
|
|
if (img != null && img.Img != null)
|
|
|
|
|
{
|
|
|
|
|
if (!found)
|
|
|
|
|
found = true;
|
2019-03-19 21:09:03 +00:00
|
|
|
|
|
2021-12-23 15:18:53 +00:00
|
|
|
|
if (!img.IsParent)
|
|
|
|
|
{
|
2019-03-19 21:09:03 +00:00
|
|
|
|
#if !PocketPC
|
2021-12-23 15:18:53 +00:00
|
|
|
|
g.DrawImage(img.Img, Core.tileRect.X, Core.tileRect.Y, Core.tileRectBearing.Width, Core.tileRectBearing.Height);
|
2019-03-19 21:09:03 +00:00
|
|
|
|
#else
|
2021-12-23 15:18:53 +00:00
|
|
|
|
g.DrawImage(img.Img, (int) Core.tileRect.X, (int) Core.tileRect.Y);
|
2019-03-19 21:09:03 +00:00
|
|
|
|
#endif
|
2021-12-23 15:18:53 +00:00
|
|
|
|
}
|
2019-03-19 21:09:03 +00:00
|
|
|
|
#if !PocketPC
|
2021-12-23 15:18:53 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// TODO: move calculations to loader thread
|
|
|
|
|
System.Drawing.RectangleF srcRect = new System.Drawing.RectangleF((float)(img.Xoff * (img.Img.Width / img.Ix)), (float)(img.Yoff * (img.Img.Height / img.Ix)), (img.Img.Width / img.Ix), (img.Img.Height / img.Ix));
|
|
|
|
|
System.Drawing.Rectangle dst = new System.Drawing.Rectangle((int)Core.tileRect.X, (int)Core.tileRect.Y, (int)Core.tileRect.Width, (int)Core.tileRect.Height);
|
|
|
|
|
|
|
|
|
|
g.DrawImage(img.Img, dst, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, GraphicsUnit.Pixel, TileFlipXYAttributes);
|
|
|
|
|
}
|
2019-03-19 21:09:03 +00:00
|
|
|
|
#endif
|
2021-12-23 15:18:53 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("GMapControl: Error while drwing Image: " + ex.Message);
|
2019-03-19 21:09:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
else if(FillEmptyTiles && MapProvider.Projection is MercatorProjection)
|
|
|
|
|
{
|
|
|
|
|
#region -- fill empty lines --
|
|
|
|
|
int zoomOffset = 1;
|
|
|
|
|
Tile parentTile = Tile.Empty;
|
|
|
|
|
long Ix = 0;
|
|
|
|
|
|
|
|
|
|
while(!parentTile.NotEmpty && zoomOffset < Core.Zoom && zoomOffset <= LevelsKeepInMemmory)
|
|
|
|
|
{
|
|
|
|
|
Ix = (long)Math.Pow(2, zoomOffset);
|
|
|
|
|
parentTile = Core.Matrix.GetTileWithNoLock(Core.Zoom - zoomOffset++, new GPoint((int)(tilePoint.PosXY.X / Ix), (int)(tilePoint.PosXY.Y / Ix)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(parentTile.NotEmpty)
|
|
|
|
|
{
|
|
|
|
|
long Xoff = Math.Abs(tilePoint.PosXY.X - (parentTile.Pos.X * Ix));
|
|
|
|
|
long Yoff = Math.Abs(tilePoint.PosXY.Y - (parentTile.Pos.Y * Ix));
|
|
|
|
|
|
|
|
|
|
// render tile
|
|
|
|
|
{
|
|
|
|
|
foreach(WindowsFormsImage img in parentTile.Overlays)
|
|
|
|
|
{
|
|
|
|
|
if(img != null && img.Img != null && !img.IsParent)
|
|
|
|
|
{
|
|
|
|
|
if(!found)
|
|
|
|
|
found = true;
|
|
|
|
|
|
|
|
|
|
System.Drawing.RectangleF srcRect = new System.Drawing.RectangleF((float)(Xoff * (img.Img.Width / Ix)), (float)(Yoff * (img.Img.Height / Ix)), (img.Img.Width / Ix), (img.Img.Height / Ix));
|
|
|
|
|
System.Drawing.Rectangle dst = new System.Drawing.Rectangle((int)Core.tileRect.X, (int)Core.tileRect.Y, (int)Core.tileRect.Width, (int)Core.tileRect.Height);
|
|
|
|
|
|
|
|
|
|
g.DrawImage(img.Img, dst, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, GraphicsUnit.Pixel, TileFlipXYAttributes);
|
|
|
|
|
g.FillRectangle(SelectedAreaFill, dst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
// add text if tile is missing
|
|
|
|
|
if(!found)
|
|
|
|
|
{
|
|
|
|
|
lock(Core.FailedLoads)
|
|
|
|
|
{
|
|
|
|
|
var lt = new LoadTask(tilePoint.PosXY, Core.Zoom);
|
|
|
|
|
if(Core.FailedLoads.ContainsKey(lt))
|
|
|
|
|
{
|
|
|
|
|
var ex = Core.FailedLoads[lt];
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
g.FillRectangle(EmptytileBrush, new RectangleF(Core.tileRect.X, Core.tileRect.Y, Core.tileRect.Width, Core.tileRect.Height));
|
|
|
|
|
|
|
|
|
|
g.DrawString("Exception: " + ex.Message, MissingDataFont, Brushes.Red, new RectangleF(Core.tileRect.X + 11, Core.tileRect.Y + 11, Core.tileRect.Width - 11, Core.tileRect.Height - 11));
|
|
|
|
|
|
|
|
|
|
g.DrawString(EmptyTileText, MissingDataFont, Brushes.Blue, new RectangleF(Core.tileRect.X, Core.tileRect.Y, Core.tileRect.Width, Core.tileRect.Height), CenterFormat);
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
g.FillRectangle(EmptytileBrush, new System.Drawing.Rectangle((int) Core.tileRect.X, (int) Core.tileRect.Y, (int) Core.tileRect.Width, (int) Core.tileRect.Height));
|
|
|
|
|
|
|
|
|
|
g.DrawString("Exception: " + ex.Message, MissingDataFont, TileGridMissingTextBrush, new RectangleF(Core.tileRect.X + 11, Core.tileRect.Y + 11, Core.tileRect.Width - 11, Core.tileRect.Height - 11));
|
|
|
|
|
|
|
|
|
|
g.DrawString(EmptyTileText, MissingDataFont, TileGridMissingTextBrush, new RectangleF(Core.tileRect.X, Core.tileRect.Y + Core.tileRect.Width / 2 + (ShowTileGridLines ? 11 : -22), Core.tileRect.Width, Core.tileRect.Height), BottomFormat);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
g.DrawRectangle(EmptyTileBorders, (int)Core.tileRect.X, (int)Core.tileRect.Y, (int)Core.tileRect.Width, (int)Core.tileRect.Height);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(ShowTileGridLines)
|
|
|
|
|
{
|
|
|
|
|
g.DrawRectangle(EmptyTileBorders, (int)Core.tileRect.X, (int)Core.tileRect.Y, (int)Core.tileRect.Width, (int)Core.tileRect.Height);
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
g.DrawString((tilePoint.PosXY == Core.centerTileXYLocation ? "CENTER: " : "TILE: ") + tilePoint, MissingDataFont, Brushes.Red, new RectangleF(Core.tileRect.X, Core.tileRect.Y, Core.tileRect.Width, Core.tileRect.Height), CenterFormat);
|
|
|
|
|
#else
|
|
|
|
|
g.DrawString((tilePoint.PosXY == Core.centerTileXYLocation ? "" : "TILE: ") + tilePoint, MissingDataFont, TileGridLinesTextBrush, new RectangleF(Core.tileRect.X, Core.tileRect.Y, Core.tileRect.Width, Core.tileRect.Height), CenterFormat);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
Core.Matrix.LeaveReadLock();
|
|
|
|
|
Core.tileDrawingListLock.ReleaseReaderLock();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// updates markers local position
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="marker"></param>
|
|
|
|
|
public void UpdateMarkerLocalPosition(GMapMarker marker)
|
|
|
|
|
{
|
|
|
|
|
GPoint p = FromLatLngToLocal(marker.Position);
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(!MobileMode)
|
|
|
|
|
{
|
|
|
|
|
p.OffsetNegative(Core.renderOffset);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
var f = new System.Drawing.Point((int)(p.X + marker.Offset.X), (int)(p.Y + marker.Offset.Y));
|
|
|
|
|
marker.LocalPosition = f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// updates routes local position
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="route"></param>
|
|
|
|
|
public void UpdateRouteLocalPosition(GMapRoute route)
|
|
|
|
|
{
|
|
|
|
|
route.LocalPoints.Clear();
|
|
|
|
|
|
|
|
|
|
foreach(GMap.NET.PointLatLng pg in route.Points)
|
|
|
|
|
{
|
|
|
|
|
GPoint p = FromLatLngToLocal(pg);
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(!MobileMode)
|
|
|
|
|
{
|
|
|
|
|
p.OffsetNegative(Core.renderOffset);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// if(IsRotated)
|
|
|
|
|
// {
|
|
|
|
|
//#if !PocketPC
|
|
|
|
|
// System.Drawing.Point[] tt = new System.Drawing.Point[] { new System.Drawing.Point(p.X, p.Y) };
|
|
|
|
|
// rotationMatrix.TransformPoints(tt);
|
|
|
|
|
// var f = tt[0];
|
|
|
|
|
|
|
|
|
|
// p.X = f.X;
|
|
|
|
|
// p.Y = f.Y;
|
|
|
|
|
//#endif
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
route.LocalPoints.Add(p);
|
|
|
|
|
}
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
route.UpdateGraphicsPath();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// updates polygons local position
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="polygon"></param>
|
|
|
|
|
public void UpdatePolygonLocalPosition(GMapPolygon polygon)
|
|
|
|
|
{
|
|
|
|
|
polygon.LocalPoints.Clear();
|
|
|
|
|
|
|
|
|
|
foreach(GMap.NET.PointLatLng pg in polygon.Points)
|
|
|
|
|
{
|
|
|
|
|
GPoint p = FromLatLngToLocal(pg);
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(!MobileMode)
|
|
|
|
|
{
|
|
|
|
|
p.OffsetNegative(Core.renderOffset);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// if(IsRotated)
|
|
|
|
|
// {
|
|
|
|
|
//#if !PocketPC
|
|
|
|
|
// System.Drawing.Point[] tt = new System.Drawing.Point[] { new System.Drawing.Point(p.X, p.Y) };
|
|
|
|
|
// rotationMatrix.TransformPoints(tt);
|
|
|
|
|
// var f = tt[0];
|
|
|
|
|
|
|
|
|
|
// p.X = f.X;
|
|
|
|
|
// p.Y = f.Y;
|
|
|
|
|
//#endif
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
polygon.LocalPoints.Add(p);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// sets zoom to max to fit rect
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="rect"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool SetZoomToFitRect(RectLatLng rect)
|
|
|
|
|
{
|
|
|
|
|
if(lazyEvents)
|
|
|
|
|
{
|
|
|
|
|
lazySetZoomToFitRect = rect;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int maxZoom = Core.GetMaxZoomToFitRect(rect);
|
|
|
|
|
if(maxZoom > 0)
|
|
|
|
|
{
|
|
|
|
|
PointLatLng center = new PointLatLng(rect.Lat - (rect.HeightLat / 2), rect.Lng + (rect.WidthLng / 2));
|
|
|
|
|
Position = center;
|
|
|
|
|
|
|
|
|
|
if(maxZoom > MaxZoom)
|
|
|
|
|
{
|
|
|
|
|
maxZoom = MaxZoom;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if((int)Zoom != maxZoom)
|
|
|
|
|
{
|
|
|
|
|
Zoom = maxZoom;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RectLatLng? lazySetZoomToFitRect = null;
|
|
|
|
|
bool lazyEvents = true;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// sets to max zoom to fit all markers and centers them in map
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="overlayId">overlay id or null to check all</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool ZoomAndCenterMarkers(string overlayId)
|
|
|
|
|
{
|
|
|
|
|
RectLatLng? rect = GetRectOfAllMarkers(overlayId);
|
|
|
|
|
if(rect.HasValue)
|
|
|
|
|
{
|
|
|
|
|
return SetZoomToFitRect(rect.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// zooms and centers all route
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="overlayId">overlay id or null to check all</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool ZoomAndCenterRoutes(string overlayId)
|
|
|
|
|
{
|
|
|
|
|
RectLatLng? rect = GetRectOfAllRoutes(overlayId);
|
|
|
|
|
if(rect.HasValue)
|
|
|
|
|
{
|
|
|
|
|
return SetZoomToFitRect(rect.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// zooms and centers route
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="route"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool ZoomAndCenterRoute(MapRoute route)
|
|
|
|
|
{
|
|
|
|
|
RectLatLng? rect = GetRectOfRoute(route);
|
|
|
|
|
if(rect.HasValue)
|
|
|
|
|
{
|
|
|
|
|
return SetZoomToFitRect(rect.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// gets rectangle with all objects inside
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="overlayId">overlay id or null to check all</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public RectLatLng? GetRectOfAllMarkers(string overlayId)
|
|
|
|
|
{
|
|
|
|
|
RectLatLng? ret = null;
|
|
|
|
|
|
|
|
|
|
double left = double.MaxValue;
|
|
|
|
|
double top = double.MinValue;
|
|
|
|
|
double right = double.MinValue;
|
|
|
|
|
double bottom = double.MaxValue;
|
|
|
|
|
|
|
|
|
|
foreach(GMapOverlay o in Overlays)
|
|
|
|
|
{
|
|
|
|
|
if(overlayId == null || o.Id == overlayId)
|
|
|
|
|
{
|
|
|
|
|
if(o.IsVisibile && o.Markers.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
foreach(GMapMarker m in o.Markers)
|
|
|
|
|
{
|
|
|
|
|
if(m.IsVisible)
|
|
|
|
|
{
|
|
|
|
|
// left
|
|
|
|
|
if(m.Position.Lng < left)
|
|
|
|
|
{
|
|
|
|
|
left = m.Position.Lng;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// top
|
|
|
|
|
if(m.Position.Lat > top)
|
|
|
|
|
{
|
|
|
|
|
top = m.Position.Lat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// right
|
|
|
|
|
if(m.Position.Lng > right)
|
|
|
|
|
{
|
|
|
|
|
right = m.Position.Lng;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bottom
|
|
|
|
|
if(m.Position.Lat < bottom)
|
|
|
|
|
{
|
|
|
|
|
bottom = m.Position.Lat;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(left != double.MaxValue && right != double.MinValue && top != double.MinValue && bottom != double.MaxValue)
|
|
|
|
|
{
|
|
|
|
|
ret = RectLatLng.FromLTRB(left, top, right, bottom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// gets rectangle with all objects inside
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="overlayId">overlay id or null to check all</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public RectLatLng? GetRectOfAllRoutes(string overlayId)
|
|
|
|
|
{
|
|
|
|
|
RectLatLng? ret = null;
|
|
|
|
|
|
|
|
|
|
double left = double.MaxValue;
|
|
|
|
|
double top = double.MinValue;
|
|
|
|
|
double right = double.MinValue;
|
|
|
|
|
double bottom = double.MaxValue;
|
|
|
|
|
|
|
|
|
|
foreach(GMapOverlay o in Overlays)
|
|
|
|
|
{
|
|
|
|
|
if(overlayId == null || o.Id == overlayId)
|
|
|
|
|
{
|
|
|
|
|
if(o.IsVisibile && o.Routes.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
foreach(GMapRoute route in o.Routes)
|
|
|
|
|
{
|
|
|
|
|
if(route.IsVisible && route.From.HasValue && route.To.HasValue)
|
|
|
|
|
{
|
|
|
|
|
foreach(PointLatLng p in route.Points)
|
|
|
|
|
{
|
|
|
|
|
// left
|
|
|
|
|
if(p.Lng < left)
|
|
|
|
|
{
|
|
|
|
|
left = p.Lng;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// top
|
|
|
|
|
if(p.Lat > top)
|
|
|
|
|
{
|
|
|
|
|
top = p.Lat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// right
|
|
|
|
|
if(p.Lng > right)
|
|
|
|
|
{
|
|
|
|
|
right = p.Lng;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bottom
|
|
|
|
|
if(p.Lat < bottom)
|
|
|
|
|
{
|
|
|
|
|
bottom = p.Lat;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(left != double.MaxValue && right != double.MinValue && top != double.MinValue && bottom != double.MaxValue)
|
|
|
|
|
{
|
|
|
|
|
ret = RectLatLng.FromLTRB(left, top, right, bottom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// gets rect of route
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="route"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public RectLatLng? GetRectOfRoute(MapRoute route)
|
|
|
|
|
{
|
|
|
|
|
RectLatLng? ret = null;
|
|
|
|
|
|
|
|
|
|
double left = double.MaxValue;
|
|
|
|
|
double top = double.MinValue;
|
|
|
|
|
double right = double.MinValue;
|
|
|
|
|
double bottom = double.MaxValue;
|
|
|
|
|
|
|
|
|
|
if(route.From.HasValue && route.To.HasValue)
|
|
|
|
|
{
|
|
|
|
|
foreach(PointLatLng p in route.Points)
|
|
|
|
|
{
|
|
|
|
|
// left
|
|
|
|
|
if(p.Lng < left)
|
|
|
|
|
{
|
|
|
|
|
left = p.Lng;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// top
|
|
|
|
|
if(p.Lat > top)
|
|
|
|
|
{
|
|
|
|
|
top = p.Lat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// right
|
|
|
|
|
if(p.Lng > right)
|
|
|
|
|
{
|
|
|
|
|
right = p.Lng;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bottom
|
|
|
|
|
if(p.Lat < bottom)
|
|
|
|
|
{
|
|
|
|
|
bottom = p.Lat;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ret = RectLatLng.FromLTRB(left, top, right, bottom);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// gets image of the current view
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public Image ToImage()
|
|
|
|
|
{
|
|
|
|
|
Image ret = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using(Bitmap bitmap = new Bitmap(Width, Height))
|
|
|
|
|
{
|
|
|
|
|
using(Graphics g = Graphics.FromImage(bitmap))
|
|
|
|
|
{
|
|
|
|
|
using(Graphics gg = this.CreateGraphics())
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
g.CopyFromScreen(PointToScreen(new System.Drawing.Point()).X, PointToScreen(new System.Drawing.Point()).Y, 0, 0, new System.Drawing.Size(Width, Height));
|
|
|
|
|
#else
|
|
|
|
|
throw new NotImplementedException("Not implemeted for PocketPC");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert the Image to a png
|
|
|
|
|
using(MemoryStream ms = new MemoryStream())
|
|
|
|
|
{
|
|
|
|
|
bitmap.Save(ms, ImageFormat.Png);
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
ret = Image.FromStream(ms);
|
|
|
|
|
#else
|
|
|
|
|
throw new NotImplementedException("Not implemeted for PocketPC");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
ret = null;
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// offset position in pixels
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="x"></param>
|
|
|
|
|
/// <param name="y"></param>
|
|
|
|
|
public void Offset(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
if(IsHandleCreated)
|
|
|
|
|
{
|
|
|
|
|
// need to fix in rotated mode usinf rotationMatrix
|
|
|
|
|
// ...
|
|
|
|
|
Core.DragOffset(new GPoint(x, y));
|
|
|
|
|
|
|
|
|
|
ForceUpdateOverlays();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region UserControl Events
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
protected bool DesignModeInConstruct
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public bool IsDesignerHosted
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return IsControlDesignerHosted(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsControlDesignerHosted(Control ctrl)
|
|
|
|
|
{
|
|
|
|
|
if(ctrl != null)
|
|
|
|
|
{
|
|
|
|
|
if(ctrl.Site != null)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if(ctrl.Site.DesignMode == true)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(IsControlDesignerHosted(ctrl.Parent))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(IsControlDesignerHosted(ctrl.Parent))
|
|
|
|
|
return true;
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnLoad(e);
|
|
|
|
|
|
|
|
|
|
if(!IsDesignerHosted)
|
|
|
|
|
{
|
|
|
|
|
//MethodInvoker m = delegate
|
|
|
|
|
//{
|
|
|
|
|
// Thread.Sleep(444);
|
|
|
|
|
|
|
|
|
|
//OnSizeChanged(null);
|
|
|
|
|
|
|
|
|
|
if(lazyEvents)
|
|
|
|
|
{
|
|
|
|
|
lazyEvents = false;
|
|
|
|
|
|
|
|
|
|
if(lazySetZoomToFitRect.HasValue)
|
|
|
|
|
{
|
|
|
|
|
SetZoomToFitRect(lazySetZoomToFitRect.Value);
|
|
|
|
|
lazySetZoomToFitRect = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Core.OnMapOpen().ProgressChanged += new ProgressChangedEventHandler(invalidatorEngage);
|
|
|
|
|
ForceUpdateOverlays();
|
|
|
|
|
//};
|
|
|
|
|
//this.BeginInvoke(m);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
//delegate void MethodInvoker();
|
|
|
|
|
bool IsHandleCreated = false;
|
|
|
|
|
|
|
|
|
|
protected override void OnPaintBackground(PaintEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(!IsHandleCreated)
|
|
|
|
|
{
|
|
|
|
|
IsHandleCreated = true;
|
|
|
|
|
|
|
|
|
|
if(lazyEvents)
|
|
|
|
|
{
|
|
|
|
|
lazyEvents = false;
|
|
|
|
|
|
|
|
|
|
if(lazySetZoomToFitRect.HasValue)
|
|
|
|
|
{
|
|
|
|
|
SetZoomToFitRect(lazySetZoomToFitRect.Value);
|
|
|
|
|
lazySetZoomToFitRect = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Core.OnMapOpen().ProgressChanged += new ProgressChangedEventHandler(invalidatorEngage);
|
|
|
|
|
ForceUpdateOverlays();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
protected override void OnCreateControl()
|
|
|
|
|
{
|
|
|
|
|
base.OnCreateControl();
|
|
|
|
|
|
|
|
|
|
var f = ParentForm;
|
|
|
|
|
if(f != null)
|
|
|
|
|
{
|
|
|
|
|
while(f.ParentForm != null)
|
|
|
|
|
{
|
|
|
|
|
f = f.ParentForm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(f != null)
|
|
|
|
|
{
|
|
|
|
|
f.FormClosing += new FormClosingEventHandler(ParentForm_FormClosing);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ParentForm_FormClosing(object sender, FormClosingEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(e.CloseReason == CloseReason.WindowsShutDown || e.CloseReason == CloseReason.TaskManagerClosing)
|
|
|
|
|
{
|
|
|
|
|
Manager.CancelTileCaching();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
protected override void Dispose(bool disposing)
|
|
|
|
|
{
|
|
|
|
|
if(disposing)
|
|
|
|
|
{
|
|
|
|
|
Core.OnMapClose();
|
|
|
|
|
|
|
|
|
|
Overlays.CollectionChanged -= new NotifyCollectionChangedEventHandler(Overlays_CollectionChanged);
|
|
|
|
|
|
|
|
|
|
foreach(var o in Overlays)
|
|
|
|
|
{
|
|
|
|
|
o.Dispose();
|
|
|
|
|
}
|
|
|
|
|
Overlays.Clear();
|
|
|
|
|
|
|
|
|
|
if (ScaleFont != null)
|
|
|
|
|
ScaleFont.Dispose();
|
|
|
|
|
if (ScalePen != null)
|
|
|
|
|
ScalePen.Dispose();
|
|
|
|
|
CenterFormat.Dispose();
|
|
|
|
|
CenterPen.Dispose();
|
|
|
|
|
BottomFormat.Dispose();
|
|
|
|
|
CopyrightFont.Dispose();
|
|
|
|
|
EmptyTileBorders.Dispose();
|
|
|
|
|
EmptytileBrush.Dispose();
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
SelectedAreaFill.Dispose();
|
|
|
|
|
if (SelectionPen != null)
|
|
|
|
|
SelectionPen.Dispose();
|
|
|
|
|
#endif
|
|
|
|
|
if(backBuffer != null)
|
|
|
|
|
{
|
|
|
|
|
backBuffer.Dispose();
|
|
|
|
|
backBuffer = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(gxOff != null)
|
|
|
|
|
{
|
|
|
|
|
gxOff.Dispose();
|
|
|
|
|
gxOff = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
base.Dispose(disposing);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PointLatLng selectionStart;
|
|
|
|
|
PointLatLng selectionEnd;
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
float? MapRenderTransform = null;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
public Color EmptyMapBackground = Color.WhiteSmoke;
|
|
|
|
|
|
|
|
|
|
#if !DESIGN
|
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(ForceDoubleBuffer)
|
|
|
|
|
{
|
|
|
|
|
#region -- manual buffer --
|
|
|
|
|
if(gxOff != null && backBuffer != null)
|
|
|
|
|
{
|
|
|
|
|
// render white background
|
|
|
|
|
gxOff.Clear(EmptyMapBackground);
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(MapRenderTransform.HasValue)
|
|
|
|
|
{
|
|
|
|
|
gxOff.TranslateTransform(Core.renderOffset.X, Core.renderOffset.Y);
|
|
|
|
|
gxOff.ScaleTransform(MapRenderTransform.Value, MapRenderTransform.Value);
|
|
|
|
|
{
|
|
|
|
|
DrawMap(gxOff);
|
|
|
|
|
OnPaintOverlays(gxOff);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(!MobileMode)
|
|
|
|
|
{
|
|
|
|
|
gxOff.TranslateTransform(Core.renderOffset.X, Core.renderOffset.Y);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
DrawMap(gxOff);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OnPaintOverlays(gxOff);
|
|
|
|
|
|
|
|
|
|
e.Graphics.DrawImage(backBuffer, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
e.Graphics.Clear(EmptyMapBackground);
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(MapRenderTransform.HasValue)
|
|
|
|
|
{
|
|
|
|
|
if(!MobileMode)
|
|
|
|
|
{
|
|
|
|
|
var pc = new GPoint(Width / 2, Height / 2);
|
|
|
|
|
var pc2 = pc;
|
|
|
|
|
pc.OffsetNegative(Core.renderOffset);
|
|
|
|
|
pc2.OffsetNegative(pc);
|
|
|
|
|
|
|
|
|
|
e.Graphics.ScaleTransform(MapRenderTransform.Value, MapRenderTransform.Value, MatrixOrder.Append);
|
|
|
|
|
|
|
|
|
|
e.Graphics.TranslateTransform(pc2.X, pc2.Y, MatrixOrder.Append);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
DrawMap(e.Graphics);
|
|
|
|
|
|
|
|
|
|
e.Graphics.ResetTransform();
|
|
|
|
|
if(!MobileMode)
|
|
|
|
|
{
|
|
|
|
|
var pc = Core.renderOffset;
|
|
|
|
|
pc.OffsetNegative(new GPoint(Width / 2, Height / 2));
|
|
|
|
|
e.Graphics.TranslateTransform(Core.renderOffset.X + -pc.X, Core.renderOffset.Y + -pc.Y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OnPaintOverlays(e.Graphics);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(IsRotated)
|
|
|
|
|
{
|
|
|
|
|
#region -- rotation --
|
|
|
|
|
|
|
|
|
|
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
|
|
|
|
|
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
|
|
|
|
|
|
|
|
|
e.Graphics.TranslateTransform((float)(Core.Width / 2.0), (float)(Core.Height / 2.0));
|
|
|
|
|
e.Graphics.RotateTransform(-Bearing);
|
|
|
|
|
e.Graphics.TranslateTransform((float)(-Core.Width / 2.0), (float)(-Core.Height / 2.0));
|
|
|
|
|
|
|
|
|
|
e.Graphics.TranslateTransform(Core.renderOffset.X, Core.renderOffset.Y);
|
|
|
|
|
|
|
|
|
|
DrawMap(e.Graphics);
|
|
|
|
|
OnPaintOverlays(e.Graphics);
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(!MobileMode)
|
|
|
|
|
{
|
|
|
|
|
e.Graphics.TranslateTransform(Core.renderOffset.X, Core.renderOffset.Y);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
DrawMap(e.Graphics);
|
|
|
|
|
OnPaintOverlays(e.Graphics);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.OnPaint(e);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
readonly Matrix rotationMatrix = new Matrix();
|
|
|
|
|
readonly Matrix rotationMatrixInvert = new Matrix();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// updates rotation matrix
|
|
|
|
|
/// </summary>
|
|
|
|
|
void UpdateRotationMatrix()
|
|
|
|
|
{
|
|
|
|
|
PointF center = new PointF(Core.Width / 2, Core.Height / 2);
|
|
|
|
|
|
|
|
|
|
rotationMatrix.Reset();
|
|
|
|
|
rotationMatrix.RotateAt(-Bearing, center);
|
|
|
|
|
|
|
|
|
|
rotationMatrixInvert.Reset();
|
|
|
|
|
rotationMatrixInvert.RotateAt(-Bearing, center);
|
|
|
|
|
rotationMatrixInvert.Invert();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// returs true if map bearing is not zero
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public bool IsRotated
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.IsRotated;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// bearing for rotation of the map
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
public float Bearing
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.bearing;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
//if(Core.bearing != value)
|
|
|
|
|
//{
|
|
|
|
|
// bool resize = Core.bearing == 0;
|
|
|
|
|
// Core.bearing = value;
|
|
|
|
|
|
|
|
|
|
// //if(VirtualSizeEnabled)
|
|
|
|
|
// //{
|
|
|
|
|
// // c.X += (Width - Core.vWidth) / 2;
|
|
|
|
|
// // c.Y += (Height - Core.vHeight) / 2;
|
|
|
|
|
// //}
|
|
|
|
|
|
|
|
|
|
// UpdateRotationMatrix();
|
|
|
|
|
|
|
|
|
|
// if(value != 0 && value % 360 != 0)
|
|
|
|
|
// {
|
|
|
|
|
// Core.IsRotated = true;
|
|
|
|
|
|
|
|
|
|
// if(Core.tileRectBearing.Size == Core.tileRect.Size)
|
|
|
|
|
// {
|
|
|
|
|
// Core.tileRectBearing = Core.tileRect;
|
|
|
|
|
// Core.tileRectBearing.Inflate(1, 1);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// Core.IsRotated = false;
|
|
|
|
|
// Core.tileRectBearing = Core.tileRect;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if(resize)
|
|
|
|
|
// {
|
|
|
|
|
// Core.OnMapSizeChanged(Width, Height);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if(!HoldInvalidation && Core.IsStarted)
|
|
|
|
|
// {
|
|
|
|
|
// ForceUpdateOverlays();
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// override, to render something more
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="g"></param>
|
|
|
|
|
protected virtual void OnPaintOverlays(Graphics g)
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
g.SmoothingMode = SmoothingMode.HighQuality;
|
|
|
|
|
#endif
|
|
|
|
|
foreach(GMapOverlay o in Overlays)
|
|
|
|
|
{
|
|
|
|
|
if(o.IsVisibile)
|
|
|
|
|
{
|
|
|
|
|
o.OnRender(g);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// center in virtual spcace...
|
|
|
|
|
#if DEBUG
|
|
|
|
|
g.DrawLine(ScalePen, -20, 0, 20, 0);
|
|
|
|
|
g.DrawLine(ScalePen, 0, -20, 0, 20);
|
|
|
|
|
|
|
|
|
|
#if PocketPC
|
|
|
|
|
g.DrawString("debug build", CopyrightFont, CopyrightBrush, 2, CopyrightFont.Size);
|
|
|
|
|
#else
|
2020-04-10 15:36:18 +00:00
|
|
|
|
// g.DrawString("debug build", CopyrightFont, Brushes.Blue, 2, CopyrightFont.Height);
|
2019-03-19 21:09:03 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
|
|
|
|
|
if(!MobileMode)
|
|
|
|
|
{
|
|
|
|
|
g.ResetTransform();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!SelectedArea.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
GPoint p1 = FromLatLngToLocal(SelectedArea.LocationTopLeft);
|
|
|
|
|
GPoint p2 = FromLatLngToLocal(SelectedArea.LocationRightBottom);
|
|
|
|
|
|
|
|
|
|
long x1 = p1.X;
|
|
|
|
|
long y1 = p1.Y;
|
|
|
|
|
long x2 = p2.X;
|
|
|
|
|
long y2 = p2.Y;
|
|
|
|
|
|
|
|
|
|
g.DrawRectangle(SelectionPen, x1, y1, x2 - x1, y2 - y1);
|
|
|
|
|
g.FillRectangle(SelectedAreaFill, x1, y1, x2 - x1, y2 - y1);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if(ShowCenter)
|
|
|
|
|
{
|
|
|
|
|
g.DrawLine(CenterPen, Width / 2 - 5, Height / 2, Width / 2 + 5, Height / 2);
|
|
|
|
|
g.DrawLine(CenterPen, Width / 2, Height / 2 - 5, Width / 2, Height / 2 + 5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(renderHelperLine)
|
|
|
|
|
{
|
|
|
|
|
var p = PointToClient(Form.MousePosition);
|
|
|
|
|
|
|
|
|
|
g.DrawLine(HelperLinePen, p.X, 0, p.X, Height);
|
|
|
|
|
g.DrawLine(HelperLinePen, 0, p.Y, Width, p.Y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region -- copyright --
|
|
|
|
|
|
|
|
|
|
if(!string.IsNullOrEmpty(Core.provider.Copyright))
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
g.DrawString(Core.provider.Copyright, CopyrightFont, Brushes.Navy, 3, Height - CopyrightFont.Height - 5);
|
|
|
|
|
#else
|
|
|
|
|
g.DrawString(Core.provider.Copyright, CopyrightFont, CopyrightBrush, 3, Height - CopyrightFont.Size - 15);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region -- draw scale --
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(MapScaleInfoEnabled)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
if(Width > Core.pxRes5000km)
|
|
|
|
|
{
|
|
|
|
|
g.DrawRectangle(ScalePen, 10, 10, Core.pxRes5000km, 10);
|
|
|
|
|
g.DrawString("5000Km", ScaleFont, Brushes.Blue, Core.pxRes5000km + 10, 11);
|
|
|
|
|
}
|
|
|
|
|
if(Width > Core.pxRes1000km)
|
|
|
|
|
{
|
|
|
|
|
g.DrawRectangle(ScalePen, 10, 10, Core.pxRes1000km, 10);
|
|
|
|
|
g.DrawString("1000Km", ScaleFont, Brushes.Blue, Core.pxRes1000km + 10, 11);
|
|
|
|
|
}
|
|
|
|
|
if(Width > Core.pxRes100km && Zoom > 2)
|
|
|
|
|
{
|
|
|
|
|
g.DrawRectangle(ScalePen, 10, 10, Core.pxRes100km, 10);
|
|
|
|
|
g.DrawString("100Km", ScaleFont, Brushes.Blue, Core.pxRes100km + 10, 11);
|
|
|
|
|
}
|
|
|
|
|
if(Width > Core.pxRes10km && Zoom > 5)
|
|
|
|
|
{
|
|
|
|
|
g.DrawRectangle(ScalePen, 10, 10, Core.pxRes10km, 10);
|
|
|
|
|
g.DrawString("10Km", ScaleFont, Brushes.Blue, Core.pxRes10km + 10, 11);
|
|
|
|
|
}
|
|
|
|
|
if(Width > Core.pxRes1000m && Zoom >= 10)
|
|
|
|
|
{
|
|
|
|
|
g.DrawRectangle(ScalePen, 10, 10, Core.pxRes1000m, 10);
|
|
|
|
|
g.DrawString("1000m", ScaleFont, Brushes.Blue, Core.pxRes1000m + 10, 11);
|
|
|
|
|
}
|
|
|
|
|
if(Width > Core.pxRes100m && Zoom > 11)
|
|
|
|
|
{
|
|
|
|
|
g.DrawRectangle(ScalePen, 10, 10, Core.pxRes100m, 10);
|
|
|
|
|
g.DrawString("100m", ScaleFont, Brushes.Blue, Core.pxRes100m + 9, 11);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
// Darstellung ScaleInfo geändert 21.11.2012
|
|
|
|
|
if((Core.pxRes5000km > 0) && (Width > Core.pxRes5000km))
|
|
|
|
|
{
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, 10, 20);
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, Core.pxRes5000km + 10, 10);
|
|
|
|
|
g.DrawLine(ScalePen, Core.pxRes5000km + 10, 10, Core.pxRes5000km + 10, 20);
|
|
|
|
|
g.DrawString("5000Km", ScaleFont, Brushes.Black, Core.pxRes5000km - 40, 13);
|
|
|
|
|
}
|
|
|
|
|
if((Core.pxRes1000km > 0) && (Width > Core.pxRes1000km))
|
|
|
|
|
{
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, 10, 20);
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, Core.pxRes1000km + 10, 10);
|
|
|
|
|
g.DrawLine(ScalePen, Core.pxRes1000km + 10, 10, Core.pxRes1000km + 10, 20);
|
|
|
|
|
g.DrawString("1000Km", ScaleFont, Brushes.Black, Core.pxRes1000km - 40, 13);
|
|
|
|
|
}
|
|
|
|
|
if((Core.pxRes100km > 0) && (Width > Core.pxRes100km) && (Zoom > 5))
|
|
|
|
|
{
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, 10, 20);
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, Core.pxRes100km + 10, 10);
|
|
|
|
|
g.DrawLine(ScalePen, Core.pxRes100km + 10, 10, Core.pxRes100km + 10, 20);
|
|
|
|
|
g.DrawString("100Km", ScaleFont, Brushes.Black, Core.pxRes100km - 35, 13);
|
|
|
|
|
}
|
|
|
|
|
if((Core.pxRes10km > 0) && (Width > Core.pxRes10km) && (Zoom > 8))
|
|
|
|
|
{
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, 10, 20);
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, Core.pxRes10km + 10, 10);
|
|
|
|
|
g.DrawLine(ScalePen, Core.pxRes10km + 10, 10, Core.pxRes10km + 10, 20);
|
|
|
|
|
g.DrawString("10Km", ScaleFont, Brushes.Black, Core.pxRes10km - 30, 13);
|
|
|
|
|
}
|
|
|
|
|
if((Core.pxRes1000m > 0) && (Width > Core.pxRes1000m) && (Zoom >= 12))
|
|
|
|
|
{
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, 10, 20);
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, Core.pxRes1000m + 10, 10);
|
|
|
|
|
g.DrawLine(ScalePen, Core.pxRes1000m + 10, 10, Core.pxRes1000m + 10, 20);
|
|
|
|
|
g.DrawString("1km", ScaleFont, Brushes.Black, Core.pxRes1000m - 25, 13);
|
|
|
|
|
}
|
|
|
|
|
if((Core.pxRes100m > 0) && (Width > Core.pxRes100m) && (Zoom > 14) )
|
|
|
|
|
{
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, 10, 20);
|
|
|
|
|
g.DrawLine(ScalePen, 10, 10, Core.pxRes100m+10, 10);
|
|
|
|
|
g.DrawLine(ScalePen, Core.pxRes100m + 10, 10, Core.pxRes100m + 10, 20);
|
|
|
|
|
g.DrawString("100m", ScaleFont, Brushes.Black, Core.pxRes100m -30, 13);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// shrinks map area, useful just for testing
|
|
|
|
|
/// </summary>
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public bool VirtualSizeEnabled
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.VirtualSizeEnabled;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.VirtualSizeEnabled = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnSizeChanged(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnSizeChanged(e);
|
|
|
|
|
#else
|
|
|
|
|
protected override void OnResize(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnResize(e);
|
|
|
|
|
#endif
|
|
|
|
|
if(Width == 0 || Height == 0)
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine("minimized");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(Width == Core.Width && Height == Core.Height)
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine("maximized");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(!IsDesignerHosted && !DesignModeInConstruct)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
if(ForceDoubleBuffer)
|
|
|
|
|
{
|
|
|
|
|
if(backBuffer != null)
|
|
|
|
|
{
|
|
|
|
|
backBuffer.Dispose();
|
|
|
|
|
backBuffer = null;
|
|
|
|
|
}
|
|
|
|
|
if(gxOff != null)
|
|
|
|
|
{
|
|
|
|
|
gxOff.Dispose();
|
|
|
|
|
gxOff = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
backBuffer = new Bitmap(Width, Height);
|
|
|
|
|
gxOff = Graphics.FromImage(backBuffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(VirtualSizeEnabled)
|
|
|
|
|
{
|
|
|
|
|
Core.OnMapSizeChanged(Core.vWidth, Core.vHeight);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
Core.OnMapSizeChanged(Width, Height);
|
|
|
|
|
}
|
|
|
|
|
//Core.currentRegion = new GRect(-50, -50, Core.Width + 50, Core.Height + 50);
|
|
|
|
|
|
|
|
|
|
if(Visible && IsHandleCreated && Core.IsStarted)
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(IsRotated)
|
|
|
|
|
{
|
|
|
|
|
UpdateRotationMatrix();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
ForceUpdateOverlays();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isSelected = false;
|
|
|
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(!IsMouseOverMarker)
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(e.Button == DragButton && CanDragMap)
|
|
|
|
|
#else
|
|
|
|
|
if(CanDragMap)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
Core.mouseDown = ApplyRotationInversion(e.X, e.Y);
|
|
|
|
|
#else
|
|
|
|
|
Core.mouseDown = new GPoint(e.X, e.Y);
|
|
|
|
|
#endif
|
|
|
|
|
this.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
else if(!isSelected)
|
|
|
|
|
{
|
|
|
|
|
isSelected = true;
|
|
|
|
|
SelectedArea = RectLatLng.Empty;
|
|
|
|
|
selectionEnd = PointLatLng.Empty;
|
|
|
|
|
selectionStart = FromLocalToLatLng(e.X, e.Y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.OnMouseDown(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseUp(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseUp(e);
|
|
|
|
|
|
|
|
|
|
if(isSelected)
|
|
|
|
|
{
|
|
|
|
|
isSelected = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(Core.IsDragging)
|
|
|
|
|
{
|
|
|
|
|
if(isDragging)
|
|
|
|
|
{
|
|
|
|
|
isDragging = false;
|
|
|
|
|
Debug.WriteLine("IsDragging = " + isDragging);
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
this.Cursor = cursorBefore;
|
|
|
|
|
cursorBefore = null;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
Core.EndDrag();
|
|
|
|
|
|
|
|
|
|
if(BoundsOfMap.HasValue && !BoundsOfMap.Value.Contains(Position))
|
|
|
|
|
{
|
|
|
|
|
if(Core.LastLocationInBounds.HasValue)
|
|
|
|
|
{
|
|
|
|
|
Position = Core.LastLocationInBounds.Value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(e.Button == DragButton)
|
|
|
|
|
{
|
|
|
|
|
Core.mouseDown = GPoint.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!selectionEnd.IsEmpty && !selectionStart.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
bool zoomtofit = false;
|
|
|
|
|
|
|
|
|
|
if(!SelectedArea.IsEmpty && Form.ModifierKeys == Keys.Shift)
|
|
|
|
|
{
|
|
|
|
|
zoomtofit = SetZoomToFitRect(SelectedArea);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(OnSelectionChange != null)
|
|
|
|
|
{
|
|
|
|
|
OnSelectionChange(SelectedArea, zoomtofit);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
protected override void OnMouseClick(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(!Core.IsDragging)
|
|
|
|
|
{
|
|
|
|
|
for(int i = Overlays.Count - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
GMapOverlay o = Overlays[i];
|
|
|
|
|
if(o != null && o.IsVisibile)
|
|
|
|
|
{
|
|
|
|
|
foreach(GMapMarker m in o.Markers)
|
|
|
|
|
{
|
|
|
|
|
if(m.IsVisible && m.IsHitTestVisible)
|
|
|
|
|
{
|
|
|
|
|
#region -- check --
|
|
|
|
|
|
|
|
|
|
if((MobileMode && m.LocalArea.Contains(e.X, e.Y)) || (!MobileMode && m.LocalAreaInControlSpace.Contains(e.X, e.Y)))
|
|
|
|
|
{
|
|
|
|
|
if(OnMarkerClick != null)
|
|
|
|
|
{
|
|
|
|
|
OnMarkerClick(m, e);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach(GMapRoute m in o.Routes)
|
|
|
|
|
{
|
|
|
|
|
if(m.IsVisible && m.IsHitTestVisible)
|
|
|
|
|
{
|
|
|
|
|
#region -- check --
|
|
|
|
|
|
|
|
|
|
GPoint rp = new GPoint(e.X, e.Y);
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(!MobileMode)
|
|
|
|
|
{
|
|
|
|
|
rp.OffsetNegative(Core.renderOffset);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if(m.IsInside((int)rp.X, (int)rp.Y))
|
|
|
|
|
{
|
|
|
|
|
if(OnRouteClick != null)
|
|
|
|
|
{
|
|
|
|
|
OnRouteClick(m, e);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach(GMapPolygon m in o.Polygons)
|
|
|
|
|
{
|
|
|
|
|
if(m.IsVisible && m.IsHitTestVisible)
|
|
|
|
|
{
|
|
|
|
|
#region -- check --
|
|
|
|
|
if(m.IsInside(FromLocalToLatLng(e.X, e.Y)))
|
|
|
|
|
{
|
|
|
|
|
if(OnPolygonClick != null)
|
|
|
|
|
{
|
|
|
|
|
OnPolygonClick(m, e);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//m_mousepos = e.Location;
|
|
|
|
|
//if(HelperLineOption == HelperLineOptions.ShowAlways)
|
|
|
|
|
//{
|
|
|
|
|
// base.Invalidate();
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
base.OnMouseClick(e);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// apply transformation if in rotation mode
|
|
|
|
|
/// </summary>
|
|
|
|
|
GPoint ApplyRotationInversion(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
GPoint ret = new GPoint(x, y);
|
|
|
|
|
|
|
|
|
|
if(IsRotated)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
System.Drawing.Point[] tt = new System.Drawing.Point[] { new System.Drawing.Point(x, y) };
|
|
|
|
|
rotationMatrixInvert.TransformPoints(tt);
|
|
|
|
|
var f = tt[0];
|
|
|
|
|
|
|
|
|
|
ret.X = f.X;
|
|
|
|
|
ret.Y = f.Y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// apply transformation if in rotation mode
|
|
|
|
|
/// </summary>
|
|
|
|
|
GPoint ApplyRotation(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
GPoint ret = new GPoint(x, y);
|
|
|
|
|
|
|
|
|
|
if(IsRotated)
|
|
|
|
|
{
|
|
|
|
|
System.Drawing.Point[] tt = new System.Drawing.Point[] { new System.Drawing.Point(x, y) };
|
|
|
|
|
rotationMatrix.TransformPoints(tt);
|
|
|
|
|
var f = tt[0];
|
|
|
|
|
|
|
|
|
|
ret.X = f.X;
|
|
|
|
|
ret.Y = f.Y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Cursor cursorBefore = Cursors.Default;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the width and height of a rectangle centered on the point the mouse
|
|
|
|
|
/// button was pressed, within which a drag operation will not begin.
|
|
|
|
|
/// </summary>
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
public Size DragSize = SystemInformation.DragSize;
|
|
|
|
|
#else
|
|
|
|
|
public Size DragSize = new Size(4, 4);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseMove(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(!Core.IsDragging && !Core.mouseDown.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
#if PocketPC
|
|
|
|
|
GPoint p = new GPoint(e.X, e.Y);
|
|
|
|
|
#else
|
|
|
|
|
GPoint p = ApplyRotationInversion(e.X, e.Y);
|
|
|
|
|
#endif
|
|
|
|
|
if(Math.Abs(p.X - Core.mouseDown.X) * 2 >= DragSize.Width || Math.Abs(p.Y - Core.mouseDown.Y) * 2 >= DragSize.Height)
|
|
|
|
|
{
|
|
|
|
|
Core.BeginDrag(Core.mouseDown);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(Core.IsDragging)
|
|
|
|
|
{
|
|
|
|
|
if(!isDragging)
|
|
|
|
|
{
|
|
|
|
|
isDragging = true;
|
|
|
|
|
Debug.WriteLine("IsDragging = " + isDragging);
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
cursorBefore = this.Cursor;
|
|
|
|
|
this.Cursor = Cursors.SizeAll;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(BoundsOfMap.HasValue && !BoundsOfMap.Value.Contains(Position))
|
|
|
|
|
{
|
|
|
|
|
// ...
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
Core.mouseCurrent = ApplyRotationInversion(e.X, e.Y);
|
|
|
|
|
#else
|
|
|
|
|
Core.mouseCurrent = new GPoint(e.X, e.Y);
|
|
|
|
|
#endif
|
|
|
|
|
Core.Drag(Core.mouseCurrent);
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(MobileMode)
|
|
|
|
|
{
|
|
|
|
|
ForceUpdateOverlays();
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
ForceUpdateOverlays();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
base.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(isSelected && !selectionStart.IsEmpty && (Form.ModifierKeys == Keys.Alt || Form.ModifierKeys == Keys.Shift || DisableAltForSelection))
|
|
|
|
|
{
|
|
|
|
|
selectionEnd = FromLocalToLatLng(e.X, e.Y);
|
|
|
|
|
{
|
|
|
|
|
GMap.NET.PointLatLng p1 = selectionStart;
|
|
|
|
|
GMap.NET.PointLatLng p2 = selectionEnd;
|
|
|
|
|
|
|
|
|
|
double x1 = Math.Min(p1.Lng, p2.Lng);
|
|
|
|
|
double y1 = Math.Max(p1.Lat, p2.Lat);
|
|
|
|
|
double x2 = Math.Max(p1.Lng, p2.Lng);
|
|
|
|
|
double y2 = Math.Min(p1.Lat, p2.Lat);
|
|
|
|
|
|
|
|
|
|
SelectedArea = new RectLatLng(y1, x1, x2 - x1, y1 - y2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
if(Core.mouseDown.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
for(int i = Overlays.Count - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
GMapOverlay o = Overlays[i];
|
|
|
|
|
if(o != null && o.IsVisibile)
|
|
|
|
|
{
|
|
|
|
|
foreach(GMapMarker m in o.Markers)
|
|
|
|
|
{
|
|
|
|
|
if(m.IsVisible && m.IsHitTestVisible)
|
|
|
|
|
{
|
|
|
|
|
#region -- check --
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if((MobileMode && m.LocalArea.Contains(e.X, e.Y)) || (!MobileMode && m.LocalAreaInControlSpace.Contains(e.X, e.Y)))
|
|
|
|
|
#else
|
|
|
|
|
if(m.LocalArea.Contains(e.X, e.Y))
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
if(!m.IsMouseOver)
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
SetCursorHandOnEnter();
|
|
|
|
|
#endif
|
|
|
|
|
m.IsMouseOver = true;
|
|
|
|
|
IsMouseOverMarker = true;
|
|
|
|
|
|
|
|
|
|
if(OnMarkerEnter != null)
|
|
|
|
|
{
|
|
|
|
|
OnMarkerEnter(m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(m.IsMouseOver)
|
|
|
|
|
{
|
|
|
|
|
m.IsMouseOver = false;
|
|
|
|
|
IsMouseOverMarker = false;
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
RestoreCursorOnLeave();
|
|
|
|
|
#endif
|
|
|
|
|
if(OnMarkerLeave != null)
|
|
|
|
|
{
|
|
|
|
|
OnMarkerLeave(m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
foreach(GMapRoute m in o.Routes)
|
|
|
|
|
{
|
|
|
|
|
if(m.IsVisible && m.IsHitTestVisible)
|
|
|
|
|
{
|
|
|
|
|
#region -- check --
|
|
|
|
|
|
|
|
|
|
GPoint rp = new GPoint(e.X, e.Y);
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(!MobileMode)
|
|
|
|
|
{
|
|
|
|
|
rp.OffsetNegative(Core.renderOffset);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if(m.IsInside((int)rp.X, (int)rp.Y))
|
|
|
|
|
{
|
|
|
|
|
if(!m.IsMouseOver)
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
SetCursorHandOnEnter();
|
|
|
|
|
#endif
|
|
|
|
|
m.IsMouseOver = true;
|
|
|
|
|
IsMouseOverRoute = true;
|
|
|
|
|
|
|
|
|
|
if(OnRouteEnter != null)
|
|
|
|
|
{
|
|
|
|
|
OnRouteEnter(m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(m.IsMouseOver)
|
|
|
|
|
{
|
|
|
|
|
m.IsMouseOver = false;
|
|
|
|
|
IsMouseOverRoute = false;
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
RestoreCursorOnLeave();
|
|
|
|
|
#endif
|
|
|
|
|
if(OnRouteLeave != null)
|
|
|
|
|
{
|
|
|
|
|
OnRouteLeave(m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
foreach(GMapPolygon m in o.Polygons)
|
|
|
|
|
{
|
|
|
|
|
if(m.IsVisible && m.IsHitTestVisible)
|
|
|
|
|
{
|
|
|
|
|
#region -- check --
|
|
|
|
|
if(m.IsInside(FromLocalToLatLng(e.X, e.Y)))
|
|
|
|
|
{
|
|
|
|
|
if(!m.IsMouseOver)
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
SetCursorHandOnEnter();
|
|
|
|
|
#endif
|
|
|
|
|
m.IsMouseOver = true;
|
|
|
|
|
IsMouseOverPolygon = true;
|
|
|
|
|
|
|
|
|
|
if(OnPolygonEnter != null)
|
|
|
|
|
{
|
|
|
|
|
OnPolygonEnter(m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(m.IsMouseOver)
|
|
|
|
|
{
|
|
|
|
|
m.IsMouseOver = false;
|
|
|
|
|
IsMouseOverPolygon = false;
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
RestoreCursorOnLeave();
|
|
|
|
|
#endif
|
|
|
|
|
if(OnPolygonLeave != null)
|
|
|
|
|
{
|
|
|
|
|
OnPolygonLeave(m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(renderHelperLine)
|
|
|
|
|
{
|
|
|
|
|
base.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.OnMouseMove(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
|
|
|
|
|
internal void RestoreCursorOnLeave()
|
|
|
|
|
{
|
|
|
|
|
if(overObjectCount == 0 && cursorBefore != null)
|
|
|
|
|
{
|
|
|
|
|
this.Cursor = this.cursorBefore;
|
|
|
|
|
cursorBefore = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void SetCursorHandOnEnter()
|
|
|
|
|
{
|
|
|
|
|
if(overObjectCount == 0 && Cursor != Cursors.Hand)
|
|
|
|
|
{
|
|
|
|
|
cursorBefore = this.Cursor;
|
|
|
|
|
this.Cursor = Cursors.Hand;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// prevents focusing map if mouse enters it's area
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool DisableFocusOnMouseEnter = false;
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseEnter(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseEnter(e);
|
|
|
|
|
|
|
|
|
|
if(!DisableFocusOnMouseEnter)
|
|
|
|
|
{
|
|
|
|
|
Focus();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// reverses MouseWheel zooming direction
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool InvertedMouseWheelZooming = false;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// lets you zoom by MouseWheel even when pointer is in area of marker
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool IgnoreMarkerOnMouseWheel = false;
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseWheel(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseWheel(e);
|
|
|
|
|
|
|
|
|
|
if((!IsMouseOverMarker || IgnoreMarkerOnMouseWheel) && !Core.IsDragging)
|
|
|
|
|
{
|
|
|
|
|
if(Core.mouseLastZoom.X != e.X && Core.mouseLastZoom.Y != e.Y)
|
|
|
|
|
{
|
|
|
|
|
if(MouseWheelZoomType == MouseWheelZoomType.MousePositionAndCenter)
|
|
|
|
|
{
|
|
|
|
|
Core.position = FromLocalToLatLng(e.X, e.Y);
|
|
|
|
|
}
|
|
|
|
|
else if(MouseWheelZoomType == MouseWheelZoomType.ViewCenter)
|
|
|
|
|
{
|
|
|
|
|
Core.position = FromLocalToLatLng((int)Width / 2, (int)Height / 2);
|
|
|
|
|
}
|
|
|
|
|
else if(MouseWheelZoomType == MouseWheelZoomType.MousePositionWithoutCenter)
|
|
|
|
|
{
|
|
|
|
|
Core.position = FromLocalToLatLng(e.X, e.Y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Core.mouseLastZoom.X = e.X;
|
|
|
|
|
Core.mouseLastZoom.Y = e.Y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set mouse position to map center
|
|
|
|
|
if(MouseWheelZoomType != MouseWheelZoomType.MousePositionWithoutCenter)
|
|
|
|
|
{
|
|
|
|
|
if(!GMaps.Instance.IsRunningOnMono)
|
|
|
|
|
{
|
|
|
|
|
System.Drawing.Point p = PointToScreen(new System.Drawing.Point(Width / 2, Height / 2));
|
|
|
|
|
Stuff.SetCursorPos((int)p.X, (int)p.Y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Core.MouseWheelZooming = true;
|
|
|
|
|
|
|
|
|
|
if(e.Delta > 0)
|
|
|
|
|
{
|
|
|
|
|
if(!InvertedMouseWheelZooming)
|
|
|
|
|
{
|
|
|
|
|
Zoom++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Zoom--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(e.Delta < 0)
|
|
|
|
|
{
|
|
|
|
|
if(!InvertedMouseWheelZooming)
|
|
|
|
|
{
|
|
|
|
|
Zoom--;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Zoom++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Core.MouseWheelZooming = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region IGControl Members
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Call it to empty tile cache & reload tiles
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void ReloadMap()
|
|
|
|
|
{
|
|
|
|
|
Core.ReloadMap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// set current position using keywords
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="keys"></param>
|
|
|
|
|
/// <returns>true if successfull</returns>
|
|
|
|
|
public GeoCoderStatusCode SetCurrentPositionByKeywords(string keys)
|
|
|
|
|
{
|
|
|
|
|
GeoCoderStatusCode status = GeoCoderStatusCode.Unknow;
|
|
|
|
|
|
|
|
|
|
GeocodingProvider gp = MapProvider as GeocodingProvider;
|
|
|
|
|
if(gp == null)
|
|
|
|
|
{
|
|
|
|
|
gp = GMapProviders.OpenStreetMap as GeocodingProvider;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(gp != null)
|
|
|
|
|
{
|
|
|
|
|
var pt = gp.GetPoint(keys, out status);
|
|
|
|
|
if(status == GeoCoderStatusCode.G_GEO_SUCCESS && pt.HasValue)
|
|
|
|
|
{
|
|
|
|
|
Position = pt.Value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// gets world coordinate from local control coordinate
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="x"></param>
|
|
|
|
|
/// <param name="y"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public PointLatLng FromLocalToLatLng(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(MapRenderTransform.HasValue)
|
|
|
|
|
{
|
|
|
|
|
//var xx = (int)(Core.renderOffset.X + ((x - Core.renderOffset.X) / MapRenderTransform.Value));
|
|
|
|
|
//var yy = (int)(Core.renderOffset.Y + ((y - Core.renderOffset.Y) / MapRenderTransform.Value));
|
|
|
|
|
|
|
|
|
|
//PointF center = new PointF(Core.Width / 2, Core.Height / 2);
|
|
|
|
|
|
|
|
|
|
//Matrix m = new Matrix();
|
|
|
|
|
//m.Translate(-Core.renderOffset.X, -Core.renderOffset.Y);
|
|
|
|
|
//m.Scale(MapRenderTransform.Value, MapRenderTransform.Value);
|
|
|
|
|
|
|
|
|
|
//System.Drawing.Point[] tt = new System.Drawing.Point[] { new System.Drawing.Point(x, y) };
|
|
|
|
|
//m.TransformPoints(tt);
|
|
|
|
|
//var z = tt[0];
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
x = (int)(Core.renderOffset.X + ((x - Core.renderOffset.X) / MapRenderTransform.Value));
|
|
|
|
|
y = (int)(Core.renderOffset.Y + ((y - Core.renderOffset.Y) / MapRenderTransform.Value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(IsRotated)
|
|
|
|
|
{
|
|
|
|
|
System.Drawing.Point[] tt = new System.Drawing.Point[] { new System.Drawing.Point(x, y) };
|
|
|
|
|
rotationMatrixInvert.TransformPoints(tt);
|
|
|
|
|
var f = tt[0];
|
|
|
|
|
|
|
|
|
|
if(VirtualSizeEnabled)
|
|
|
|
|
{
|
|
|
|
|
f.X += (Width - Core.vWidth) / 2;
|
|
|
|
|
f.Y += (Height - Core.vHeight) / 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
x = f.X;
|
|
|
|
|
y = f.Y;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return Core.FromLocalToLatLng(x, y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// gets local coordinate from world coordinate
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="point"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public GPoint FromLatLngToLocal(PointLatLng point)
|
|
|
|
|
{
|
|
|
|
|
GPoint ret = Core.FromLatLngToLocal(point);
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
if(MapRenderTransform.HasValue)
|
|
|
|
|
{
|
|
|
|
|
ret.X = (int)(Core.renderOffset.X + ((Core.renderOffset.X - ret.X) * -MapRenderTransform.Value));
|
|
|
|
|
ret.Y = (int)(Core.renderOffset.Y + ((Core.renderOffset.Y - ret.Y) * -MapRenderTransform.Value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(IsRotated)
|
|
|
|
|
{
|
|
|
|
|
System.Drawing.Point[] tt = new System.Drawing.Point[] { new System.Drawing.Point((int)ret.X, (int)ret.Y) };
|
|
|
|
|
rotationMatrix.TransformPoints(tt);
|
|
|
|
|
var f = tt[0];
|
|
|
|
|
|
|
|
|
|
if(VirtualSizeEnabled)
|
|
|
|
|
{
|
|
|
|
|
f.X += (Width - Core.vWidth) / 2;
|
|
|
|
|
f.Y += (Height - Core.vHeight) / 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret.X = f.X;
|
|
|
|
|
ret.Y = f.Y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// shows map db export dialog
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool ShowExportDialog()
|
|
|
|
|
{
|
|
|
|
|
using(FileDialog dlg = new SaveFileDialog())
|
|
|
|
|
{
|
|
|
|
|
dlg.CheckPathExists = true;
|
|
|
|
|
dlg.CheckFileExists = false;
|
|
|
|
|
dlg.AddExtension = true;
|
|
|
|
|
dlg.DefaultExt = "gmdb";
|
|
|
|
|
dlg.ValidateNames = true;
|
|
|
|
|
dlg.Title = "GMap.NET: Export map to db, if file exsist only new data will be added";
|
|
|
|
|
dlg.FileName = "DataExp";
|
|
|
|
|
dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
|
|
|
|
|
dlg.Filter = "GMap.NET DB files (*.gmdb)|*.gmdb";
|
|
|
|
|
dlg.FilterIndex = 1;
|
|
|
|
|
dlg.RestoreDirectory = true;
|
|
|
|
|
|
|
|
|
|
if(dlg.ShowDialog() == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
bool ok = GMaps.Instance.ExportToGMDB(dlg.FileName);
|
|
|
|
|
if(ok)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("Complete!", "GMap.NET", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("Failed!", "GMap.NET", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// shows map dbimport dialog
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool ShowImportDialog()
|
|
|
|
|
{
|
|
|
|
|
using(FileDialog dlg = new OpenFileDialog())
|
|
|
|
|
{
|
|
|
|
|
dlg.CheckPathExists = true;
|
|
|
|
|
dlg.CheckFileExists = false;
|
|
|
|
|
dlg.AddExtension = true;
|
|
|
|
|
dlg.DefaultExt = "gmdb";
|
|
|
|
|
dlg.ValidateNames = true;
|
|
|
|
|
dlg.Title = "GMap.NET: Import to db, only new data will be added";
|
|
|
|
|
dlg.FileName = "DataImport";
|
|
|
|
|
dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
|
|
|
|
|
dlg.Filter = "GMap.NET DB files (*.gmdb)|*.gmdb";
|
|
|
|
|
dlg.FilterIndex = 1;
|
|
|
|
|
dlg.RestoreDirectory = true;
|
|
|
|
|
|
|
|
|
|
if(dlg.ShowDialog() == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
bool ok = GMaps.Instance.ImportFromGMDB(dlg.FileName);
|
|
|
|
|
if(ok)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("Complete!", "GMap.NET", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
|
|
|
ReloadMap();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("Failed!", "GMap.NET", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
[Category("GMap.NET"), DefaultValue(0)]
|
|
|
|
|
public double Zoom
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return zoomReal;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if(zoomReal != value)
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine("ZoomPropertyChanged: " + zoomReal + " -> " + value);
|
|
|
|
|
|
|
|
|
|
if(value > MaxZoom)
|
|
|
|
|
{
|
|
|
|
|
zoomReal = MaxZoom;
|
|
|
|
|
}
|
|
|
|
|
else if(value < MinZoom)
|
|
|
|
|
{
|
|
|
|
|
zoomReal = MinZoom;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
zoomReal = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double remainder = value % 1;
|
|
|
|
|
if(remainder != 0)
|
|
|
|
|
{
|
|
|
|
|
float scaleValue = (float)Math.Pow(2d, remainder);
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
MapRenderTransform = scaleValue;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ZoomStep = Convert.ToInt32(value - remainder);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
MapRenderTransform = null;
|
|
|
|
|
#endif
|
|
|
|
|
ZoomStep = Convert.ToInt32(value);
|
|
|
|
|
zoomReal = ZoomStep;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(Core.IsStarted && !IsDragging)
|
|
|
|
|
{
|
|
|
|
|
ForceUpdateOverlays();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// map zoom level
|
|
|
|
|
/// </summary>
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
internal int ZoomStep
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.Zoom;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if(value > MaxZoom)
|
|
|
|
|
{
|
|
|
|
|
Core.Zoom = MaxZoom;
|
|
|
|
|
}
|
|
|
|
|
else if(value < MinZoom)
|
|
|
|
|
{
|
|
|
|
|
Core.Zoom = MinZoom;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Core.Zoom = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// current map center position
|
|
|
|
|
/// </summary>
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public PointLatLng Position
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.Position;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.Position = value;
|
|
|
|
|
|
|
|
|
|
if(Core.IsStarted)
|
|
|
|
|
{
|
|
|
|
|
ForceUpdateOverlays();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// current position in pixel coordinates
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public GPoint PositionPixel
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.PositionPixel;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// location of cache
|
|
|
|
|
/// </summary>
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public string CacheLocation
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
#if !DESIGN
|
|
|
|
|
return CacheLocator.Location;
|
|
|
|
|
#else
|
|
|
|
|
return string.Empty;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
#if !DESIGN
|
|
|
|
|
CacheLocator.Location = value;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isDragging = false;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// is user dragging map
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public bool IsDragging
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return isDragging;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isMouseOverMarker;
|
|
|
|
|
internal int overObjectCount = 0;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// is mouse over marker
|
|
|
|
|
/// </summary>
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public bool IsMouseOverMarker
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return isMouseOverMarker;
|
|
|
|
|
}
|
|
|
|
|
internal set
|
|
|
|
|
{
|
|
|
|
|
isMouseOverMarker = value;
|
|
|
|
|
overObjectCount += value ? 1 : -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isMouseOverRoute;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// is mouse over route
|
|
|
|
|
/// </summary>
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public bool IsMouseOverRoute
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return isMouseOverRoute;
|
|
|
|
|
}
|
|
|
|
|
internal set
|
|
|
|
|
{
|
|
|
|
|
isMouseOverRoute = value;
|
|
|
|
|
overObjectCount += value ? 1 : -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isMouseOverPolygon;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// is mouse over polygon
|
|
|
|
|
/// </summary>
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public bool IsMouseOverPolygon
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return isMouseOverPolygon;
|
|
|
|
|
}
|
|
|
|
|
internal set
|
|
|
|
|
{
|
|
|
|
|
isMouseOverPolygon = value;
|
|
|
|
|
overObjectCount += value ? 1 : -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// gets current map view top/left coordinate, width in Lng, height in Lat
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public RectLatLng ViewArea
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.ViewArea;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public GMapProvider MapProvider
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.Provider;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if(Core.Provider == null || !Core.Provider.Equals(value))
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine("MapType: " + Core.Provider.Name + " -> " + value.Name);
|
|
|
|
|
|
|
|
|
|
RectLatLng viewarea = SelectedArea;
|
|
|
|
|
if(viewarea != RectLatLng.Empty)
|
|
|
|
|
{
|
|
|
|
|
Position = new PointLatLng(viewarea.Lat - viewarea.HeightLat / 2, viewarea.Lng + viewarea.WidthLng / 2);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
viewarea = ViewArea;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Core.Provider = value;
|
|
|
|
|
|
|
|
|
|
if(Core.IsStarted)
|
|
|
|
|
{
|
|
|
|
|
if(Core.zoomToArea)
|
|
|
|
|
{
|
|
|
|
|
// restore zoomrect as close as possible
|
|
|
|
|
if(viewarea != RectLatLng.Empty && viewarea != ViewArea)
|
|
|
|
|
{
|
|
|
|
|
int bestZoom = Core.GetMaxZoomToFitRect(viewarea);
|
|
|
|
|
if(bestZoom > 0 && Zoom != bestZoom)
|
|
|
|
|
{
|
|
|
|
|
Zoom = bestZoom;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ForceUpdateOverlays();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// is routes enabled
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
public bool RoutesEnabled
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.RoutesEnabled;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.RoutesEnabled = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// is polygons enabled
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
public bool PolygonsEnabled
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.PolygonsEnabled;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.PolygonsEnabled = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// is markers enabled
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
public bool MarkersEnabled
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.MarkersEnabled;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.MarkersEnabled = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// can user drag map
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Category("GMap.NET")]
|
|
|
|
|
public bool CanDragMap
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.CanDragMap;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Core.CanDragMap = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// map render mode
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public RenderMode RenderMode
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Core.RenderMode;
|
|
|
|
|
}
|
|
|
|
|
internal set
|
|
|
|
|
{
|
|
|
|
|
Core.RenderMode = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// gets map manager
|
|
|
|
|
/// </summary>
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public GMaps Manager
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return GMaps.Instance;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region IGControl event Members
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs when current position is changed
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event PositionChanged OnPositionChanged
|
|
|
|
|
{
|
|
|
|
|
add
|
|
|
|
|
{
|
|
|
|
|
Core.OnCurrentPositionChanged += value;
|
|
|
|
|
}
|
|
|
|
|
remove
|
|
|
|
|
{
|
|
|
|
|
Core.OnCurrentPositionChanged -= value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs when tile set load is complete
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event TileLoadComplete OnTileLoadComplete
|
|
|
|
|
{
|
|
|
|
|
add
|
|
|
|
|
{
|
|
|
|
|
Core.OnTileLoadComplete += value;
|
|
|
|
|
}
|
|
|
|
|
remove
|
|
|
|
|
{
|
|
|
|
|
Core.OnTileLoadComplete -= value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs when tile set is starting to load
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event TileLoadStart OnTileLoadStart
|
|
|
|
|
{
|
|
|
|
|
add
|
|
|
|
|
{
|
|
|
|
|
Core.OnTileLoadStart += value;
|
|
|
|
|
}
|
|
|
|
|
remove
|
|
|
|
|
{
|
|
|
|
|
Core.OnTileLoadStart -= value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs on map drag
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event MapDrag OnMapDrag
|
|
|
|
|
{
|
|
|
|
|
add
|
|
|
|
|
{
|
|
|
|
|
Core.OnMapDrag += value;
|
|
|
|
|
}
|
|
|
|
|
remove
|
|
|
|
|
{
|
|
|
|
|
Core.OnMapDrag -= value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs on map zoom changed
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event MapZoomChanged OnMapZoomChanged
|
|
|
|
|
{
|
|
|
|
|
add
|
|
|
|
|
{
|
|
|
|
|
Core.OnMapZoomChanged += value;
|
|
|
|
|
}
|
|
|
|
|
remove
|
|
|
|
|
{
|
|
|
|
|
Core.OnMapZoomChanged -= value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occures on map type changed
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event MapTypeChanged OnMapTypeChanged
|
|
|
|
|
{
|
|
|
|
|
add
|
|
|
|
|
{
|
|
|
|
|
Core.OnMapTypeChanged += value;
|
|
|
|
|
}
|
|
|
|
|
remove
|
|
|
|
|
{
|
|
|
|
|
Core.OnMapTypeChanged -= value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// occurs on empty tile displayed
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EmptyTileError OnEmptyTileError
|
|
|
|
|
{
|
|
|
|
|
add
|
|
|
|
|
{
|
|
|
|
|
Core.OnEmptyTileError += value;
|
|
|
|
|
}
|
|
|
|
|
remove
|
|
|
|
|
{
|
|
|
|
|
Core.OnEmptyTileError -= value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
#region Serialization
|
|
|
|
|
|
|
|
|
|
static readonly BinaryFormatter BinaryFormatter = new BinaryFormatter();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Serializes the overlays.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="stream">The stream.</param>
|
|
|
|
|
public void SerializeOverlays(Stream stream)
|
|
|
|
|
{
|
|
|
|
|
if(stream == null)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentNullException("stream");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create an array from the overlays
|
|
|
|
|
GMapOverlay[] overlayArray = new GMapOverlay[this.Overlays.Count];
|
|
|
|
|
this.Overlays.CopyTo(overlayArray, 0);
|
|
|
|
|
|
|
|
|
|
// Serialize the overlays
|
|
|
|
|
BinaryFormatter.Serialize(stream, overlayArray);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// De-serializes the overlays.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="stream">The stream.</param>
|
|
|
|
|
public void DeserializeOverlays(Stream stream)
|
|
|
|
|
{
|
|
|
|
|
if(stream == null)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentNullException("stream");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// De-serialize the overlays
|
|
|
|
|
GMapOverlay[] overlayArray = BinaryFormatter.Deserialize(stream) as GMapOverlay[];
|
|
|
|
|
|
|
|
|
|
// Populate the collection of overlays.
|
|
|
|
|
foreach(GMapOverlay overlay in overlayArray)
|
|
|
|
|
{
|
|
|
|
|
overlay.Control = this;
|
|
|
|
|
this.Overlays.Add(overlay);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.ForceUpdateOverlays();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !PocketPC
|
|
|
|
|
public enum HelperLineOptions
|
|
|
|
|
{
|
|
|
|
|
DontShow = 0,
|
|
|
|
|
ShowAlways = 1,
|
|
|
|
|
ShowOnModifierKey = 2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public delegate void SelectionChange(RectLatLng Selection, bool ZoomToFit);
|
|
|
|
|
#endif
|
|
|
|
|
}
|