kopia lustrzana https://github.com/dl2alf/AirScout
303 wiersze
8.0 KiB
C#
303 wiersze
8.0 KiB
C#
|
|
namespace GMap.NET.WindowsForms
|
|
{
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Runtime.Serialization;
|
|
using GMap.NET;
|
|
using System.Windows.Forms;
|
|
using System;
|
|
|
|
/// <summary>
|
|
/// GMap.NET polygon
|
|
/// </summary>
|
|
[System.Serializable]
|
|
#if !PocketPC
|
|
public class GMapPolygon : MapRoute, ISerializable, IDeserializationCallback, IDisposable
|
|
#else
|
|
public class GMapPolygon : MapRoute, IDisposable
|
|
#endif
|
|
{
|
|
private bool visible = true;
|
|
|
|
/// <summary>
|
|
/// is polygon visible
|
|
/// </summary>
|
|
public bool IsVisible
|
|
{
|
|
get
|
|
{
|
|
return visible;
|
|
}
|
|
set
|
|
{
|
|
if(value != visible)
|
|
{
|
|
visible = value;
|
|
|
|
if(Overlay != null && Overlay.Control != null)
|
|
{
|
|
if(visible)
|
|
{
|
|
Overlay.Control.UpdatePolygonLocalPosition(this);
|
|
}
|
|
|
|
{
|
|
if(!Overlay.Control.HoldInvalidation)
|
|
{
|
|
Overlay.Control.Core.Refresh.Set();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// can receive input
|
|
/// </summary>
|
|
public bool IsHitTestVisible = false;
|
|
|
|
private bool isMouseOver = false;
|
|
|
|
/// <summary>
|
|
/// is mouse over
|
|
/// </summary>
|
|
public bool IsMouseOver
|
|
{
|
|
get
|
|
{
|
|
return isMouseOver;
|
|
}
|
|
internal set
|
|
{
|
|
isMouseOver = value;
|
|
}
|
|
}
|
|
|
|
GMapOverlay overlay;
|
|
public GMapOverlay Overlay
|
|
{
|
|
get
|
|
{
|
|
return overlay;
|
|
}
|
|
internal set
|
|
{
|
|
overlay = value;
|
|
}
|
|
}
|
|
|
|
public virtual void OnRender(Graphics g)
|
|
{
|
|
#if !PocketPC
|
|
if(IsVisible)
|
|
{
|
|
using(GraphicsPath rp = new GraphicsPath())
|
|
{
|
|
for(int i = 0; i < LocalPoints.Count; i++)
|
|
{
|
|
GPoint p2 = LocalPoints[i];
|
|
|
|
if(i == 0)
|
|
{
|
|
rp.AddLine(p2.X, p2.Y, p2.X, p2.Y);
|
|
}
|
|
else
|
|
{
|
|
System.Drawing.PointF p = rp.GetLastPoint();
|
|
rp.AddLine(p.X, p.Y, p2.X, p2.Y);
|
|
}
|
|
}
|
|
|
|
if(rp.PointCount > 0)
|
|
{
|
|
rp.CloseFigure();
|
|
|
|
g.FillPath(Fill, rp);
|
|
|
|
g.DrawPath(Stroke, rp);
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
{
|
|
if(IsVisible)
|
|
{
|
|
Point[] pnts = new Point[LocalPoints.Count];
|
|
for(int i = 0; i < LocalPoints.Count; i++)
|
|
{
|
|
Point p2 = new Point((int)LocalPoints[i].X, (int)LocalPoints[i].Y);
|
|
pnts[pnts.Length - 1 - i] = p2;
|
|
}
|
|
|
|
if(pnts.Length > 0)
|
|
{
|
|
g.FillPolygon(Fill, pnts);
|
|
g.DrawPolygon(Stroke, pnts);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
//public double Area
|
|
//{
|
|
// get
|
|
// {
|
|
// return 0;
|
|
// }
|
|
//}
|
|
|
|
/// <summary>
|
|
/// specifies how the outline is painted
|
|
/// </summary>
|
|
[NonSerialized]
|
|
#if !PocketPC
|
|
public Pen Stroke = new Pen(Color.FromArgb(155, Color.MidnightBlue));
|
|
#else
|
|
public Pen Stroke = new Pen(Color.MidnightBlue);
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// background color
|
|
/// </summary>
|
|
[NonSerialized]
|
|
#if !PocketPC
|
|
public Brush Fill = new SolidBrush(Color.FromArgb(155, Color.AliceBlue));
|
|
#else
|
|
public Brush Fill = new System.Drawing.SolidBrush(Color.AliceBlue);
|
|
#endif
|
|
|
|
public readonly List<GPoint> LocalPoints = new List<GPoint>();
|
|
|
|
public GMapPolygon(List<PointLatLng> points, string name)
|
|
: base(points, name)
|
|
{
|
|
LocalPoints.Capacity = Points.Count;
|
|
|
|
#if !PocketPC
|
|
Stroke.LineJoin = LineJoin.Round;
|
|
#endif
|
|
Stroke.Width = 5;
|
|
}
|
|
|
|
/// <summary>
|
|
/// checks if point is inside the polygon,
|
|
/// info.: http://greatmaps.codeplex.com/discussions/279437#post700449
|
|
/// </summary>
|
|
/// <param name="p"></param>
|
|
/// <returns></returns>
|
|
public bool IsInside(PointLatLng p)
|
|
{
|
|
int count = Points.Count;
|
|
|
|
if(count < 3)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool result = false;
|
|
|
|
for(int i = 0, j = count - 1; i < count; i++)
|
|
{
|
|
var p1 = Points[i];
|
|
var p2 = Points[j];
|
|
|
|
if(p1.Lat < p.Lat && p2.Lat >= p.Lat || p2.Lat < p.Lat && p1.Lat >= p.Lat)
|
|
{
|
|
if(p1.Lng + (p.Lat - p1.Lat) / (p2.Lat - p1.Lat) * (p2.Lng - p1.Lng) < p.Lng)
|
|
{
|
|
result = !result;
|
|
}
|
|
}
|
|
j = i;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#if !PocketPC
|
|
#region ISerializable Members
|
|
|
|
/// <summary>
|
|
/// Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo"/> with the data needed to serialize the target object.
|
|
/// </summary>
|
|
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to populate with data.</param>
|
|
/// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext"/>) for this serialization.</param>
|
|
/// <exception cref="T:System.Security.SecurityException">
|
|
/// The caller does not have the required permission.
|
|
/// </exception>
|
|
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
|
{
|
|
base.GetObjectData(info, context);
|
|
//info.AddValue("Stroke", this.Stroke);
|
|
//info.AddValue("Fill", this.Fill);
|
|
info.AddValue("LocalPoints", this.LocalPoints.ToArray());
|
|
info.AddValue("Visible", this.IsVisible);
|
|
}
|
|
|
|
// Temp store for de-serialization.
|
|
private GPoint[] deserializedLocalPoints;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="MapRoute"/> class.
|
|
/// </summary>
|
|
/// <param name="info">The info.</param>
|
|
/// <param name="context">The context.</param>
|
|
protected GMapPolygon(SerializationInfo info, StreamingContext context)
|
|
: base(info, context)
|
|
{
|
|
//this.Stroke = Extensions.GetValue<Pen>(info, "Stroke", new Pen(Color.FromArgb(155, Color.MidnightBlue)));
|
|
//this.Fill = Extensions.GetValue<Brush>(info, "Fill", new SolidBrush(Color.FromArgb(155, Color.AliceBlue)));
|
|
this.deserializedLocalPoints = Extensions.GetValue<GPoint[]>(info, "LocalPoints");
|
|
this.IsVisible = Extensions.GetStruct<bool>(info, "Visible", true);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IDeserializationCallback Members
|
|
|
|
/// <summary>
|
|
/// Runs when the entire object graph has been de-serialized.
|
|
/// </summary>
|
|
/// <param name="sender">The object that initiated the callback. The functionality for this parameter is not currently implemented.</param>
|
|
public override void OnDeserialization(object sender)
|
|
{
|
|
base.OnDeserialization(sender);
|
|
|
|
// Accounts for the de-serialization being breadth first rather than depth first.
|
|
LocalPoints.AddRange(deserializedLocalPoints);
|
|
LocalPoints.Capacity = Points.Count;
|
|
}
|
|
|
|
#endregion
|
|
#endif
|
|
|
|
#region IDisposable Members
|
|
|
|
bool disposed = false;
|
|
|
|
public virtual void Dispose()
|
|
{
|
|
if(!disposed)
|
|
{
|
|
disposed = true;
|
|
|
|
Fill.Dispose();
|
|
Stroke.Dispose();
|
|
LocalPoints.Clear();
|
|
|
|
base.Clear();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public delegate void PolygonClick(GMapPolygon item, MouseEventArgs e);
|
|
public delegate void PolygonEnter(GMapPolygon item);
|
|
public delegate void PolygonLeave(GMapPolygon item);
|
|
}
|