using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Drawing.Imaging;
using System.Data;
using System.Windows.Forms;
/// <summary>
/// Mapview control namespace
/// </summary>
namespace GIS.Geometry
{
public class Mapview : System.Windows.Forms.UserControl, ICloneable, IPersist
{
#region Private members of the Mapview Control
/// <summary>
/// Required designer variable.
/// </summary>
///
private System.ComponentModel.Container components = null;
Image _image; // The current image to be drawn
Rectangle _rectDst ; // Rendering Rectangle in DC coordinates
Rectangle _rectSrc ; // ROI of image in image coordinates (0,0, MaxX, MaxY);
Matrix _cm ; // Current matrix
private Point[] _fPoint; // To Draw an 'F' character
private Point _cPoint;
Point m_StartingPoint, m_EndingPoint;
//--------------------------------------------
//
// For Flicker free painting
//
private Rectangle DrawingRect; // used for tracking of rubberband handle
private Image tmpView;
private Image realView;
private RectangleF tmpRect;
private RectangleF realRect;
//--------------------------------------------
private System.Windows.Forms.ToolTip tp;
private System.Drawing.Drawing2D.Matrix m_trans;
private RectangleF viewsize=new RectangleF(0.0F,0.0F,0.0F,0.0F);
private object m_units;
private float m_scale = 1;
private float zoomfactor=1.25F;
private System.Windows.Forms.HScrollBar h_scroll;
private System.Windows.Forms.VScrollBar v_scroll;
private bool showdirection=false;
private bool showscale=false;
private Pen rubberlines=new Pen(Color.Red,1);
private Color backcolor=Color.White;
private int locationtolarnce=2;
private int displayscale=1;
private string text;
private Font f=new Font("Tahoma",16, FontStyle.Regular, GraphicsUnit.Pixel);
private System.Windows.Forms.ContextMenu cmenu;
private System.Windows.Forms.MenuItem mitem;
private GraphicType m_draw_mode = GraphicType.None;
private SubGraphicMode m_sub_draw=SubGraphicMode.None;
private OperationMode m_operation_mode=OperationMode.None;
private SubOperationMode m_sub_operation=SubOperationMode.All;
private ZoomType m_zoomtype=ZoomType.Fit;
private float m_start_x = 0;
private float m_start_y = 0;
private float m_end_x = 0;
private float m_end_y = 0;
private GraphicsCollection m_geom_model=null;
private int m_curr_selection = -1;
private ArrayList m_current_polygon = new ArrayList();
private ArrayList m_selected_list = new ArrayList();
private ArrayList m_copy_list=new ArrayList();
public delegate void CoordChangeEventHandler(object sender, CoordEventArgs e);
public delegate void ItemEventHandler(object sender, ItemEventArgs e);
public delegate void GraphicTypeChangedEventHandler(object sender, GraphicArgs e);
public delegate void OperationChangedEventHandler(object sender, OperationArgs e);
public delegate void GraphicSelectedHandler();
public event CoordChangeEventHandler CoordChangeEvent;
public event ItemEventHandler ItemNewEvent;
public event ItemEventHandler ItemEnterEvent;
public event ItemEventHandler ItemLeaveEvent;
public event GraphicSelectedHandler GraphicSelected;
public event GraphicTypeChangedEventHandler GraphicTypeChanged;
public event OperationChangedEventHandler OperationChanged;
private string xml="";
private int m_drag_handle=-1;
private int m_current_index=-1;
private int handlesize=6;
#endregion
#region Properties of the Mapview Control
public object Units
{
get{return m_units;}
set{m_units=value;}
}
public System.Drawing.Drawing2D.DashStyle RubberLines
{
get {return rubberlines.DashStyle;}
set{rubberlines.DashStyle=value;}
}
public bool ShowScale
{
get{return showscale;}
set{showscale=value;}
}
public int DisplayScale
{
get{return displayscale;}
set{displayscale=value;}
}
public Color BackgroundColor
{
get{return backcolor;}
set
{
backcolor=value;
this.BackColor=backcolor;
}
}
public bool ShowDirection
{
get{return showdirection;}
set{showdirection=value;}
}
public int LocationTolerance
{
get{return locationtolarnce;}
set{locationtolarnce=value;}
}
public float ZoomFactor
{
get{return zoomfactor;}
set{zoomfactor=value;}
}
public void Model(GraphicsCollection objIn)
{
if (objIn!=null)
{
m_geom_model=objIn;
m_geom_model.ItemChangedEvent+=new GIS.Geometry.GraphicsCollection.ItemChangedEventHandler(OnModelChanged);
m_geom_model.ModelChangedEvent+=new GIS.Geometry.GraphicsCollection.ModelChangedEventHandler(OnModelChanged);
}
}
public GraphicsCollection Model()
{
return m_geom_model;
}
/// <summary>
/// initilize graphic object drawing mode.
/// new graphic object is drawn while mouse moving with left key pressed.
/// New graphic object is added to map on mouse release.
/// </summary>
///
public GraphicType CurrentGraphicType
{
get{return m_draw_mode;}
set
{
m_draw_mode=value;
m_current_polygon.Clear();
// Generate Graphic Type Changed event
if(GraphicTypeChanged != null) GraphicTypeChanged(this,new GraphicArgs(m_draw_mode));
}
}
/// <summary>
/// initilize graphic object operation mode.
/// new graphic object operation is drawn while mouse moving with left key pressed.
/// New graphic object operation is added to map on mouse release.
/// </summary>
///
public OperationMode CurrentOperation
{
get{return m_operation_mode;}
set
{
m_operation_mode=value;
// Generate Graphic Type Changed event
if(OperationChanged != null) OperationChanged(this,new OperationArgs(m_operation_mode));
Invalidate();
}
}
/// <summary>
/// initilize graphic object operation mode.
/// new graphic object operation is drawn while mouse moving with left key pressed.
/// New graphic object operation is added to map on mouse release.
/// </summary>
///
public ZoomType CurrentZoomType
{
get{return m_zoomtype;}
set
{
m_zoomtype=value;
// Generate Graphic Type Changed event
if(OperationChanged != null) OperationChanged(this,new OperationArgs(m_operation_mode));
Invalidate();
}
}
#endregion
#region Constructor of Mapview Controls
/// <summary>
/// constructor
/// </summary>
public Mapview()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// TODO: Add any initialization after the InitForm call
//viewsize = new RectangleF();
m_trans = new System.Drawing.Drawing2D.Matrix();
m_scale = 1;
realRect= new Rectangle();
tmpRect= new Rectangle();
}
public Mapview(Mapview mv)
{
}
#endregion
#region Methods of ICloneable
public object Clone()
{
return new Mapview( this );
}
#endregion
#region Methods of Mapview Control
#region Transformation operations
public void SaveSettings()
{
}
public IMapviewObject GetItem(int indx)
{
return m_geom_model.GetItem(indx);
}
public object GetitemObject(int i)
{
return m_geom_model.GetItemObject(i);
}
public int [] GetSelected()
{
return m_geom_model.GetSelected();
}
public int Add(IMapviewObject item)
{
return m_geom_model.Add(item);
}
public PointF ClientToReal(PointF pnt)
{
System.Drawing.Drawing2D.Matrix inv_trans = m_trans.Clone();
inv_trans.Invert();
PointF[] points = {new PointF(pnt.X,pnt.Y)};
inv_trans.TransformPoints(points);
return points[0];
}
public Rectangle RealToClient(RectangleF rect)
{
return RealToClient(new PointF(rect.X,rect.Y),
rect.Width, rect.Height);
}
public Rectangle RealToClient(PointF pnt,float w,float h)
{
System.Drawing.Drawing2D.Matrix inv_trans = m_trans.Clone();
PointF[] points = {new PointF(pnt.X,pnt.Y),new PointF(pnt.X+w,pnt.Y+h)};
inv_trans.TransformPoints(points);
Rectangle rect = new Rectangle((int)points[0].X,(int)points[0].Y,
(int)(points[1].X-points[0].X)+1,
(int)(points[1].Y-points[0].Y)+1);
return rect;
}
#endregion
#region Mouse Events
private void MapClick(object sender,EventArgs e)
{
if (m_operation_mode==GIS.Geometry.OperationMode.None)
{
Select(0);
}
}
protected override void OnMouseEnter(EventArgs e)
{
this.Focus();
}
private void MapMouseMove(object sender, MouseEventArgs e)
{
PointF ep = ClientToReal(new PointF(e.X,e.Y));
// Generate Coordinates Changed event
if(CoordChangeEvent != null) CoordChangeEvent(this,new CoordEventArgs(ep.X,ep.Y,0,0,0));
Graphics graph = this.CreateGraphics();
int x = Math.Min((int)m_start_x,(int)e.X);
int y = Math.Min((int)m_start_y,(int)e.Y);
int w = (int)(e.X-m_start_x<0.0?(int)m_start_x-e.X:(int)e.X-m_start_x);
int h = (int)(e.Y-m_start_y<0.0?(int)m_start_y-e.Y:(int)e.Y-m_start_y);
Rectangle c1 = new Rectangle(x-6,y-6,w+12,h+12);
#region Graphic objects with more than 2 points
if (m_draw_mode==GIS.Geometry.GraphicType.Polyline ||
m_draw_mode==GIS.Geometry.GraphicType.Polygon ||
m_draw_mode==GIS.Geometry.GraphicType.Curve ||
m_draw_mode==GIS.Geometry.GraphicType.Boundary ||
m_draw_mode==GIS.Geometry.GraphicType.Spline ||
m_draw_mode==GIS.Geometry.GraphicType.Freeform)
{
Draw(e);
return;
}
#endregion
if(e.Button != MouseButtons.Left)return;
if( Math.Abs(e.X-m_end_x) < 2 && Math.Abs(e.Y-m_end_y) < 2)
return;
#region Operations on the objects
switch(m_operation_mode)
{
#region For Move Operation
case GIS.Geometry.OperationMode.Move:
if (e.Button == MouseButtons.Left)
{
// calculate Move delta
PointF p_start = new PointF(m_start_x,m_start_y);
PointF p_end = new PointF(m_end_x,m_end_y);
PointF p_start_real = ClientToReal(p_start);
PointF p_end_real = ClientToReal(p_end);
float dx = p_start_real.X-p_end_real.X;
float dy = p_start_real.Y-p_end_real.Y;
// Move the selected objects
m_geom_model.MoveBy(dx,dy);
Invalidate();
m_end_x = e.X;
m_end_y = e.Y;
return;
}
break;
#endregion
#region For Selection Operation
case GIS.Geometry.OperationMode.Selection:
case GIS.Geometry.OperationMode.Edit:
case GIS.Geometry.OperationMode.Zoom:
Invalidate(c1);
Update();
graph.DrawRectangle(rubberlines,x,y,w,h);
break;
#endregion
// #region For Zoom Operation
// case GIS.Geometry.OperationMode.Zoom:
// goto case GIS.Geometry.OperationMode.Selection;
// #endregion
case GIS.Geometry.OperationMode.Pan:
Matrix ScreenToImg = GeoUtil.Swap(_rectDst, _rectSrc);
m_EndingPoint.X = e.X;
m_EndingPoint.Y = e.Y;
Point[] Vector = new Point[2];
Vector[0] = m_EndingPoint;
Vector[1] = m_StartingPoint;
ScreenToImg.TransformPoints(Vector);
Point PtDelta = new Point(Vector[1].X-Vector[0].X+_rectSrc.X,
Vector[1].Y-Vector[0].Y+_rectSrc.Y);
if((PtDelta.X <0) || (PtDelta.X + _rectSrc.Width > _image.Width))
PtDelta.X=0;
else
PtDelta.X-=_rectSrc.X;
if((PtDelta.Y <0) || (PtDelta.Y + _rectSrc.Height > _image.Height))
PtDelta.Y=0;
else
PtDelta.Y-=_rectSrc.Y;
_rectSrc.Offset(PtDelta);
m_StartingPoint = m_EndingPoint;
Refresh();
break;
case GIS.Geometry.OperationMode.Arrange:
break;
case GIS.Geometry.OperationMode.Copy:
goto case GIS.Geometry.OperationMode.Selection;
case GIS.Geometry.OperationMode.Rotate:
default:
break;
}
#endregion
#region Graphic Obejects with 2 points
switch(m_draw_mode)
{
case GIS.Geometry.GraphicType.Line:
{
Invalidate(c1);
Update();
graph.DrawLine(rubberlines,(int)m_start_x,
(int)m_start_y,
(int)e.X,
(int)e.Y);
}
break;
case GIS.Geometry.GraphicType.Rectangle:
{
Invalidate(c1);
Update();
graph.DrawRectangle(rubberlines,x,y,w,h);
}
break;
case GIS.Geometry.GraphicType.Elipse:
{
Invalidate(c1);
Update();
graph.DrawEllipse(rubberlines,x,y,w,h);
}
break;
case GIS.Geometry.GraphicType.Circle:
{
Invalidate(c1);
Update();
graph.DrawEllipse(rubberlines,x,y,w,w);
}
break;
case GIS.Geometry.GraphicType.Polyline:
#region Polyline
if(m_current_polygon.Count>1)
{
//Invalidate();
Update();
m_current_polygon[m_current_polygon.Count-1] = new PointF(e.X,e.Y);
Point[] points = new Point[m_current_polygon.Count];
for(int i=0; i<m_current_polygon.Count; i++)
{
int x1 = (int)((PointF)m_current_polygon[i]).X;
int y1 = (int)((PointF)m_current_polygon[i]).Y;
points[i] = new Point(x1,y1);
}
graph.DrawLines(rubberlines,points);
}
break;
#endregion
case GIS.Geometry.GraphicType.Polygon:
#region polygon
if(m_current_polygon.Count>1)
{
Invalidate(c1);
Update();
m_current_polygon[m_current_polygon.Count-1] = new PointF(e.X,e.Y);
Point[] points = new Point[m_current_polygon.Count];
for(int i=0; i<m_current_polygon.Count; i++)
{
int x1 = (int)((PointF)m_current_polygon[i]).X;
int y1 = (int)((PointF)m_current_polygon[i]).Y;
points[i] = new Point(x1,y1);
}
graph.DrawPolygon(rubberlines,points);
}
break;
#endregion
case GIS.Geometry.GraphicType.Spline:
#region Spline
if(m_current_polygon.Count>1)
{
Invalidate(c1);
Update();
m_current_polygon[m_current_polygon.Count-1] = new PointF(e.X,e.Y);
Point[] points = new Point[m_current_polygon.Count];
for(int i=0; i<m_current_polygon.Count; i++)
{
int x1 = (int)((PointF)m_current_polygon[i]).X;
int y1 = (int)((PointF)m_current_polygon[i]).Y;
points[i] = new Point(x1,y1);
}
graph.DrawBeziers(rubberlines,points);
}
break;
#endregion
case GIS.Geometry.GraphicType.Curve:
#region Curve
if(m_current_polygon.Count>3)
{
Invalidate(c1);
Update();
m_current_polygon[m_current_polygon.Count-1] = new PointF(e.X,e.Y);
Point[] points = new Point[m_current_polygon.Count];
for(int i=0; i<m_current_polygon.Count; i++)
{
int x1 = (int)((PointF)m_current_polygon[i]).X;
int y1 = (int)((PointF)m_current_polygon[i]).Y;
points[i] = new Point(x1,y1);
}
graph.DrawCurve(rubberlines,points);
}
break;
#endregion
case GIS.Geometry.GraphicType.Freeform:
break;
case GIS.Geometry.GraphicType.UserDefined:
///TODO: Yet to be planned
break;
case GIS.Geometry.GraphicType.Text:
graph.DrawString(text,f,new SolidBrush(Color.Red),c1,System.Drawing.StringFormat.GenericDefault);
break;
default:
break;
}
#endregion
m_end_x = e.X;
m_end_y = e.Y;
}
private void MapMouseDown(object sender, MouseEventArgs e)
{
m_start_x = e.X;
m_start_y = e.Y;
#region For Context menus
if (e.Button==MouseButtons.Right)
{
switch(m_draw_mode)
{
case GIS.Geometry.GraphicType.Line:
cmenu.MenuItems.Add("Cut");
cmenu.MenuItems.Add("Copy");
cmenu.MenuItems.Add("Paste");
cmenu.MenuItems.Add("-");
cmenu.MenuItems.Add("Edit Points");
break;
case GIS.Geometry.GraphicType.Circle:
break;
case GIS.Geometry.GraphicType.Arc:
break;
case GIS.Geometry.GraphicType.None:
for(int i=0; i<cmenu.MenuItems.Count-1; i++)
{
cmenu.MenuItems.RemoveAt(i);
}
break;
}
}
#endregion
#region For Resize handles
if (m_operation_mode==GIS.Geometry.OperationMode.Edit)
{
if (m_drag_handle!=-1)
{
IMapviewObject item=m_geom_model.GetByIndex(m_current_index);
for (int i=0; i<item.Vertices.Length-1; i++)
{
if (Math.Abs(item.Vertices[i].X - e.X) < handlesize/2 &&
Math.Abs(item.Vertices[i].Y - e.Y) < handlesize/2)
{
m_drag_handle = i;
this.Cursor= Cursors.Cross;
break;
}
}
}
}
#endregion
if(m_draw_mode == GIS.Geometry.GraphicType.None)
return;
if(m_draw_mode == GIS.Geometry.GraphicType.Polygon ||
m_draw_mode==GIS.Geometry.GraphicType.Polyline ||
m_draw_mode == GIS.Geometry.GraphicType.Curve ||
m_draw_mode == GIS.Geometry.GraphicType.Spline ||
m_draw_mode == GIS.Geometry.GraphicType.Freeform )
{
if (m_operation_mode==GIS.Geometry.OperationMode.Edit)
{
// m_current_polygon.Insert(new PointF(e.X,e.Y));
}
else
{
m_current_polygon.Add(new PointF(e.X,e.Y));
}
}
}
private void MapMouseUp(object sender, MouseEventArgs e)
{
#region Operations
switch(m_operation_mode)
{
case GIS.Geometry.OperationMode.Selection:
Select(-1);
Invalidate();
break;
case GIS.Geometry.OperationMode.Edit:
Edit();
Invalidate();
break;
case GIS.Geometry.OperationMode.Arrange:
Invalidate();
break;
case GIS.Geometry.OperationMode.Copy:
goto case GIS.Geometry.OperationMode.Selection;
case GIS.Geometry.OperationMode.Rotate:
Invalidate();
break;
case GIS.Geometry.OperationMode.Zoom:
Zoom();
Invalidate();
break;
default:
break;
}
#endregion
#region For Graphics
if(m_draw_mode == GIS.Geometry.GraphicType.None)
return;
System.Drawing.Drawing2D.Matrix inv_trans = m_trans.Clone();
inv_trans.Invert();
PointF [] points = {new PointF(m_start_x,m_start_y),
new PointF(m_end_x,m_end_y)};
inv_trans.TransformPoints(points);
int curr_item_id = -1,w,h;
switch(m_draw_mode)
{
case GIS.Geometry.GraphicType.Point:
curr_item_id = m_geom_model.Add(new PointObject(points[0].X,points[0].Y));
break;
case GIS.Geometry.GraphicType.Line:
curr_item_id = m_geom_model.Add(new LineObject(points[0].X,points[0].Y, points[1].X,points[1].Y));
break;
case GIS.Geometry.GraphicType.Rectangle:
GeoUtil.Swap(ref points);
w = (int)(points[1].X - points[0].X);
h = (int)(points[1].Y - points[0].Y);
curr_item_id = m_geom_model.Add(new RectangleObject(points[0].X,points[0].Y,w,h));
break;
case GIS.Geometry.GraphicType.Elipse:
GeoUtil.Swap(ref points);
w = (int)(points[1].X - points[0].X);
h = (int)(points[1].Y - points[0].Y);
curr_item_id = m_geom_model.Add(new EllipseObject(points[0].X,points[0].Y,w,h));
break;
case GIS.Geometry.GraphicType.Circle:
GeoUtil.Swap(ref points);
w = (int)(points[1].X - points[0].X);
curr_item_id = m_geom_model.Add(new CircleObject(points[0].X,points[0].Y,w,w));
break;
case GIS.Geometry.GraphicType.Text:
curr_item_id=m_geom_model.Add(new TextObject(points[0].X, points[0].Y,text,f));
return;
}
if(m_draw_mode != GIS.Geometry.GraphicType.Polygon ||
m_draw_mode != GIS.Geometry.GraphicType.Polyline ||
m_draw_mode != GIS.Geometry.GraphicType.Curve ||
m_draw_mode != GIS.Geometry.GraphicType.Spline ||
m_draw_mode != GIS.Geometry.GraphicType.Freeform ||
m_operation_mode != GIS.Geometry.OperationMode.Move)
{
m_start_x = 0;
m_start_y = 0;
}
#endregion
#region Context Menu
if (e.Button==MouseButtons.Right)
{
this.ContextMenu=cmenu;
}
#endregion
#region Notify the others by raising the event
if(ItemNewEvent != null && (
m_draw_mode == GIS.Geometry.GraphicType.Line ||
m_draw_mode == GIS.Geometry.GraphicType.Rectangle ||
m_draw_mode == GIS.Geometry.GraphicType.Elipse ||
m_draw_mode == GIS.Geometry.GraphicType.Circle ||
m_draw_mode == GIS.Geometry.GraphicType.Point ||
m_draw_mode == GIS.Geometry.GraphicType.Text
))
ItemNewEvent(this,new ItemEventArgs(curr_item_id));
#endregion
}
protected override void OnDoubleClick(EventArgs e)
{
Close();
}
#endregion
#region Key Events
protected override void OnKeyDown(KeyEventArgs e)
{
// if (e.Modifiers==Keys.ControlKey && System.Windows.Forms.Keys.A)
// BeginSelection(false);
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
}
protected override void OnKeyUp(KeyEventArgs e)
{
if (m_draw_mode==GIS.Geometry.GraphicType.Text)
{
text+=e.KeyCode;
}
switch(e.KeyData)
{
case System.Windows.Forms.Keys.Escape:
Reset();
break;
case System.Windows.Forms.Keys.Delete:
Delete();
break;
}
Invalidate();
}
#endregion
#region Paint Events
private void MapPaint(object sender,PaintEventArgs e)
{
RefreshView();
}
public void OnModelChanged(object sender, ItemEventArgs e)
{
RefreshView();
}
private void OnPaintBackground(PaintEventArgs e)
{
//
}
#endregion
#region Zoom, Pan Events
private PointF GetCenter()
{
// Draw image center marker
System.Drawing.Drawing2D.Matrix inv_trans = m_trans.Clone();
inv_trans.Invert();
// create 0,0 and width,height points
PointF[] points = {new PointF(0,0),new PointF(this.Width,this.Height)};
inv_trans.TransformPoints(points);
int x0 = (int)(points[0].X+points[1].X)/2;
int y0 = (int)(points[0].Y+points[1].Y)/2;
return new PointF(x0,y0);
}
public void Zoom()
{
float shift_x = this.Width/2;
float shift_y = this.Height/2;
//tmpRect= viewsize;
realRect=m_geom_model.BoundingBox();
Matrix ScreenToImg = GeoUtil.Swap(tmpRect, realRect);
Point[] Pts = new Point[2];
Pts[0] = new Point((int)m_end_x,(int)m_end_y);
Pts[1] = new Point((int)m_start_x,(int)m_start_y);
ScreenToImg.TransformPoints(Pts);
switch(m_zoomtype)
{
case GIS.Geometry.ZoomType.In:
m_scale += zoomfactor;
m_trans.Scale(zoomfactor, zoomfactor, System.Drawing.Drawing2D.MatrixOrder.Append);
m_trans.Translate(-shift_x, -shift_y, System.Drawing.Drawing2D.MatrixOrder.Append);
break;
case GIS.Geometry.ZoomType.Out:
m_scale -= zoomfactor;
m_trans.Scale(zoomfactor, zoomfactor, System.Drawing.Drawing2D.MatrixOrder.Append);
m_trans.Translate(zoomfactor, zoomfactor, System.Drawing.Drawing2D.MatrixOrder.Append);
break;
case GIS.Geometry.ZoomType.Extents:
break;
case GIS.Geometry.ZoomType.Center:
break;
case GIS.Geometry.ZoomType.Pan:
Point PtDelta = new Point(Pts[1].X-Pts[0].X+realRect.X,
Pts[1].Y-Pts[0].Y+realRect.Y);
if((PtDelta.X <0) || (PtDelta.X + realRect.Width > realView.Width))
PtDelta.X=0;
else
PtDelta.X-=realRect.X;
if((PtDelta.Y <0) || (PtDelta.Y + realRect.Height > realView.Height))
PtDelta.Y=0;
else
PtDelta.Y-=realRect.Y;
realRect.Offset(PtDelta);
m_StartingPoint = m_EndingPoint;
Refresh();
break;
case GIS.Geometry.ZoomType.Window:
// Limits Maximum Zoom
if(pts[1].X - Pts[0].X>10)
if(Pts[1].Y - Pts[0].Y>10)
{
realRect.Location = Pts[0];
realRect.Width = Pts[1].X - Pts[0].X;
realRect.Height = Pts[1].Y - Pts[0].Y;
Refresh();
}
break;
case GIS.Geometry.ZoomType.Fit:
Fit();
break;
}
UpdateScroll();
RefreshView();
}
public void Fit()
{
viewsize = m_geom_model.BoundingBox();
if(viewsize.Width == 0 || viewsize.Height == 0)
return;
m_trans.Reset();
m_trans.Translate(viewsize.X,viewsize.Y);
m_trans.Scale(this.Width/viewsize.Width,this.Height/viewsize.Height);
//Invalidate();
RefreshView();
}
public void Pan(Point p0, Point p1)
{
Matrix matPan = m_trans.Clone();
// m_EndingPoint.X = (int)p1.X;
// m_EndingPoint.Y = (int)p1.Y;
// m_StartingPoint.X=(int)p0.X;
// m_StartingPoint.Y=(int)p0.Y;
Point[] Vector = new Point[2];
Vector[0] = (Point)p0; //m_EndingPoint;
Vector[1] = (Point)p1; //m_StartingPoint;
matPan.TransformPoints(Vector);
PointF PtDelta = new PointF(Vector[1].X-Vector[0].X+viewsize.X,
Vector[1].Y-Vector[0].Y+viewsize.Y);
if((PtDelta.X <0) || (PtDelta.X + viewsize.Width > viewsize.Width))
PtDelta.X=0;
else
PtDelta.X-=viewsize.X;
if((PtDelta.Y <0) || (PtDelta.Y + viewsize.Height > viewsize.Height))
PtDelta.Y=0;
else
PtDelta.Y-=viewsize.Y;
viewsize.Offset(PtDelta);
Refresh();
}
private void UpdateScroll()
{
// calculate and update H and V scroll values:
if(h_scroll != null)
{
int val = (int)(-m_trans.OffsetX/m_scale/viewsize.Width*100);
if(val < 0)
val = 0;
if(val > 99)
val = 99;
h_scroll.Value = val+1;
}
if(v_scroll != null)
{
int val = (int)(-m_trans.OffsetY/m_scale/viewsize.Height*100);
if(val < 1)
val = 1;
if(val > 100)
val = 100;
v_scroll.Value = val-1;
}
}
public void LoadImage(string fname)
{
m_geom_model.LoadImage(fname);
viewsize = m_geom_model.BoundingBox();
RefreshView();
}
public void HorizontalScroll(object sender, System.Windows.Forms.ScrollEventArgs e)
{
viewsize = m_geom_model.BoundingBox();
float off_x = m_trans.OffsetX;
float shift = viewsize.Width*e.NewValue/100*m_scale+off_x;
m_trans.Translate(-shift, 0, System.Drawing.Drawing2D.MatrixOrder.Append);
RefreshView();
}
public void VerticalScroll(object sender, System.Windows.Forms.ScrollEventArgs e)
{
viewsize = m_geom_model.BoundingBox();
float off_y = m_trans.OffsetY;
float shift = viewsize.Height*e.NewValue/100*m_scale+off_y;
m_trans.Translate(0, -shift, System.Drawing.Drawing2D.MatrixOrder.Append);
RefreshView();
}
public void UpdateView(Image i)
{ // draws image of the Frame.
Graphics g = this.CreateGraphics();
g.DrawImage(i, this.ClientRectangle);
g.Dispose();
}
private void RefreshView()
{ // erase the main image and redraw all the rectangles from the list.
realView.Dispose();
realView = new Bitmap(this.ClientRectangle.Width,
this.ClientRectangle.Height);
Graphics g = Graphics.FromImage(realView);
Brush BrushTemp = new SolidBrush(this.BackColor);
g.FillRectangle(BrushTemp, this.ClientRectangle);
if (m_geom_model!=null)
{
m_geom_model.Draw(g,m_trans);
}
BrushTemp.Dispose();
g.Dispose();
UpdateView(realView);
}
#endregion
#region Operations like Select, Move, Delete, Rotate, Scale...
private void Select(int intType)
{
PointF [] points = {new PointF(m_start_x,m_start_y),
new PointF(m_end_x,m_end_y)};
int i=GeoUtil.Swap(ref points);
PointF c_pnt = new PointF(m_start_x,m_start_y);
PointF c_pnt1 = new PointF(m_end_x,m_end_y);
PointF r_pnt = ClientToReal(c_pnt);
PointF r_pnt1 = ClientToReal(c_pnt1);
float dist = r_pnt1.X-r_pnt.X;
Rectangle rect = new Rectangle((int)points[0].X,(int)points[0].Y,
(int)(points[1].X-points[0].X)+1,
(int)(points[1].Y-points[0].Y)+1);
for (int indx=0; indx<m_geom_model.Count; indx++)
{
IMapviewObject item = m_geom_model.GetByIndex(indx);
if (intType==1)
{
item.Select(true);
}
else if(intType==0)
{
item.Select(false);
}
else
{
switch(i)
{
case 1: // Crossing the window :: Intersection,
if(rect.IntersectsWith(item.BoundingBox()))
item.Select(true);
break;
case 2://Except this
if(rect.IntersectsWith(item.BoundingBox()))
item.Select(false);
break;
case 3://All :: Union
item.Select(true);
break;
case 4: // Inside the window :: In,
if (rect.Contains(item.BoundingBox()))
item.Select(true);
break;
}
}
}
// Generate Object selected event
if(GraphicSelected != null) GraphicSelected();
}
private void Move(MouseEventArgs e)
{
m_curr_selection = -1;
PointF c_pnt = new PointF(e.X,e.Y);
PointF c_pnt1 = new PointF(e.X+5,e.Y);
PointF r_pnt = ClientToReal(c_pnt);
PointF r_pnt1 = ClientToReal(c_pnt1);
float dist = r_pnt1.X-r_pnt.X;
for(int indx=0; indx < m_geom_model.Count; indx++)
{
IMapviewObject item = m_geom_model.GetByIndex(indx);
if(item.IsSelected())
{
if(!item.IsObjectAt(r_pnt,dist))
{
if(m_selected_list.IndexOf(indx,0,m_selected_list.Count) == -1)
{
item.Select(false);
Invalidate(RealToClient(item.BoundingBox()));
if(ItemLeaveEvent != null)
ItemLeaveEvent(this,new ItemEventArgs(indx));
}
}
else
{
m_curr_selection = m_geom_model.GetKey(indx);
}
}
else
{
if(item.IsObjectAt(r_pnt,dist))
{
m_curr_selection = m_geom_model.GetKey(indx);
item.Select(true);
Invalidate(RealToClient(item.BoundingBox()));
// To notify the index of the current selected graphic index
if(ItemEnterEvent != null) ItemEnterEvent(this,new ItemEventArgs(indx));
}
}
}
m_end_x = e.X;
m_end_y = e.Y;
}
private void Draw(MouseEventArgs e)
{
RefreshView();
Graphics graph = this.CreateGraphics();
int x = Math.Min((int)m_start_x,(int)e.X);
int y = Math.Min((int)m_start_y,(int)e.Y);
int w = (int)(e.X-m_start_x<0.0?(int)m_start_x-e.X:(int)e.X-m_start_x);
int h = (int)(e.Y-m_start_y<0.0?(int)m_start_y-e.Y:(int)e.Y-m_start_y);
Rectangle c1 = new Rectangle(x-6,y-6,w+12,h+12);
switch(m_draw_mode)
{
case GIS.Geometry.GraphicType.Polyline:
#region Polyline
if(m_current_polygon.Count>1)
{
m_current_polygon[m_current_polygon.Count-1] = new PointF(e.X,e.Y);
Point[] points = new Point[m_current_polygon.Count];
for(int i=0; i<m_current_polygon.Count; i++)
{
int x1 = (int)((PointF)m_current_polygon[i]).X;
int y1 = (int)((PointF)m_current_polygon[i]).Y;
points[i] = new Point(x1,y1);
}
graph.DrawLines(rubberlines,points);
}
break;
#endregion
case GIS.Geometry.GraphicType.Polygon:
#region polygon
if(m_current_polygon.Count>1)
{
m_current_polygon[m_current_polygon.Count-1] = new PointF(e.X,e.Y);
Point[] points = new Point[m_current_polygon.Count];
for(int i=0; i<m_current_polygon.Count; i++)
{
int x1 = (int)((PointF)m_current_polygon[i]).X;
int y1 = (int)((PointF)m_current_polygon[i]).Y;
points[i] = new Point(x1,y1);
}
graph.DrawPolygon(rubberlines,points);
}
break;
#endregion
case GIS.Geometry.GraphicType.Spline:
#region Spline
if(m_current_polygon.Count>1)
{
m_current_polygon[m_current_polygon.Count-1] = new PointF(e.X,e.Y);
Point[] points = new Point[m_current_polygon.Count];
for(int i=0; i<m_current_polygon.Count; i++)
{
int x1 = (int)((PointF)m_current_polygon[i]).X;
int y1 = (int)((PointF)m_current_polygon[i]).Y;
points[i] = new Point(x1,y1);
}
graph.DrawBeziers(rubberlines,points);
}
break;
#endregion
case GIS.Geometry.GraphicType.Curve:
#region Curve
if(m_current_polygon.Count>3)
{
m_current_polygon[m_current_polygon.Count-1] = new PointF(e.X,e.Y);
Point[] points = new Point[m_current_polygon.Count];
for(int i=0; i<m_current_polygon.Count; i++)
{
int x1 = (int)((PointF)m_current_polygon[i]).X;
int y1 = (int)((PointF)m_current_polygon[i]).Y;
points[i] = new Point(x1,y1);
}
graph.DrawCurve(rubberlines,points);
}
break;
#endregion
case GIS.Geometry.GraphicType.Freeform:
break;
case GIS.Geometry.GraphicType.UserDefined:
///TODO: Yet to be planned
break;
case GIS.Geometry.GraphicType.Text:
graph.DrawString(text,f,new SolidBrush(Color.Red),c1,System.Drawing.StringFormat.GenericDefault);
break;
default:
break;
}
}
private void Close()
{
m_start_x = 0;
m_start_y = 0;
if (m_draw_mode==GIS.Geometry.GraphicType.Polyline ||
m_draw_mode==GIS.Geometry.GraphicType.Polygon ||
m_draw_mode== GIS.Geometry.GraphicType.Curve ||
m_draw_mode== GIS.Geometry.GraphicType.Spline ||
m_draw_mode== GIS.Geometry.GraphicType.Freeform )
{
System.Drawing.Drawing2D.Matrix inv_trans = m_trans.Clone();
inv_trans.Invert();
PointF [] points = new PointF[m_current_polygon.Count];
m_current_polygon.CopyTo(0,points,0,m_current_polygon.Count);
inv_trans.TransformPoints(points);
for(int i=0; i<m_current_polygon.Count; i++)
m_current_polygon[i] = points[i];
int item_id =0;
switch (m_draw_mode)
{
case GIS.Geometry.GraphicType.Polyline:
item_id = m_geom_model.Add(new PolylineObject(m_current_polygon));
break;
case GIS.Geometry.GraphicType.Polygon:
item_id = m_geom_model.Add(new PolygonObject(m_current_polygon));
break;
case GIS.Geometry.GraphicType.Curve:
item_id = m_geom_model.Add(new CurveObject(m_current_polygon));
break;
case GIS.Geometry.GraphicType.Spline:
item_id = m_geom_model.Add(new SplineObject(m_current_polygon));
break;
case GIS.Geometry.GraphicType.Freeform:
item_id = m_geom_model.Add(new FreeFormObject(m_current_polygon));
break;
}
if(ItemNewEvent != null)
ItemNewEvent(this,new ItemEventArgs(item_id));
}
Invalidate();
m_current_polygon.Clear();
}
public void Edit()
{
PointF [] points = {new PointF(m_start_x,m_start_y),
new PointF(m_end_x,m_end_y)};
int i=GeoUtil.Swap(ref points);
PointF c_pnt = new PointF(m_start_x,m_start_y);
PointF c_pnt1 = new PointF(m_end_x,m_end_y);
PointF r_pnt = ClientToReal(c_pnt);
PointF r_pnt1 = ClientToReal(c_pnt1);
float dist = r_pnt1.X-r_pnt.X;
Rectangle rect = new Rectangle((int)points[0].X,(int)points[0].Y,
(int)(points[1].X-points[0].X)+1,
(int)(points[1].Y-points[0].Y)+1);
for (int indx=0; indx<m_geom_model.Count; indx++)
{
IMapviewObject item = m_geom_model.GetByIndex(indx);
switch(i)
{
case 1: // Crossing the window :: Intersection,
if(rect.IntersectsWith(item.BoundingBox()))
item.IsEdit=true;
m_current_index=i;
return;
case 2://Except this
if(rect.IntersectsWith(item.BoundingBox()))
item.IsEdit=true;
m_current_index=i;
return;
//case 3://All :: Union
//item.IsEdit=true;
// return;
case 4: // Inside the window :: In,
if (rect.Contains(item.BoundingBox()))
item.IsEdit=true;
m_current_index=i;
return;
}
}
}
public void Delete()
{
m_geom_model.Delete();
RefreshView();
}
public void Scale()
{
m_geom_model.Scale();
RefreshView();
}
public void Rotate()
{
m_geom_model.Rotate();
RefreshView();
}
public void RotateAt()
{
m_geom_model.RotateAt();
RefreshView();
}
public virtual void Reset()
{
m_draw_mode=GIS.Geometry.GraphicType.None;
m_current_polygon.Clear();
m_operation_mode=GIS.Geometry.OperationMode.None;
m_current_index=-1;
}
#endregion
#endregion
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Mapview));
realView = new Bitmap(this.ClientRectangle.Width,
this.ClientRectangle.Height);
Graphics GraphicsTemp = Graphics.FromImage(realView);
Brush BrushTemp = new SolidBrush(this.BackColor);
GraphicsTemp.FillRectangle(BrushTemp, this.ClientRectangle);
// Disposing
BrushTemp.Dispose();
GraphicsTemp.Dispose();
this.h_scroll = new System.Windows.Forms.HScrollBar();
this.v_scroll = new System.Windows.Forms.VScrollBar();
this.cmenu = new System.Windows.Forms.ContextMenu();
this.mitem = new System.Windows.Forms.MenuItem();
this.SuspendLayout();
//
// h_scroll
//
this.h_scroll.Anchor = ((System.Windows.Forms.AnchorStyles)(resources.GetObject("h_scroll.Anchor")));
this.h_scroll.Dock = ((System.Windows.Forms.DockStyle)(resources.GetObject("h_scroll.Dock")));
this.h_scroll.Name = "h_scroll";
this.h_scroll.Minimum=0;
this.h_scroll.Maximum=100;
this.h_scroll.Value=50;
this.h_scroll.Scroll += new System.Windows.Forms.ScrollEventHandler(this.HorizontalScroll);
//
// v_scroll
//
this.v_scroll.Anchor = ((System.Windows.Forms.AnchorStyles)(resources.GetObject("v_scroll.Anchor")));
this.v_scroll.Dock = ((System.Windows.Forms.DockStyle)(resources.GetObject("v_scroll.Dock")));
this.v_scroll.Name = "v_scroll";
this.v_scroll.Minimum=0;
this.v_scroll.Maximum=100;
this.v_scroll.Value=50;
this.v_scroll.Scroll += new System.Windows.Forms.ScrollEventHandler(this.VerticalScroll);
//
// cmenu
//
this.cmenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {this.mitem});
this.cmenu.RightToLeft = ((System.Windows.Forms.RightToLeft)(resources.GetObject("cmenu.RightToLeft")));
//
// mitem
//
this.mitem.Enabled = ((bool)(resources.GetObject("mitem.Enabled")));
this.mitem.Index = 0;
this.mitem.Shortcut = ((System.Windows.Forms.Shortcut)(resources.GetObject("mitem.Shortcut")));
this.mitem.ShowShortcut = ((bool)(resources.GetObject("mitem.ShowShortcut")));
this.mitem.Text = resources.GetString("mitem.Text");
this.mitem.Visible = ((bool)(resources.GetObject("mitem.Visible")));
///
///Tooltip
///
//
// Mapview
//
this.ContextMenu = this.cmenu;
this.Controls.Add(this.h_scroll);
this.Controls.Add(this.v_scroll);
this.BackgroundColor=backcolor;
this.BackColor=backcolor;
this.Name = "Mapview";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.MapPaint);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.MapMouseMove);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MapMouseDown);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.MapMouseUp);
this.Click+=new EventHandler(this.MapClick);
this.GraphicSelected+=new GraphicSelectedHandler(this.Edit);
this.ResumeLayout(false);
m_trans = new System.Drawing.Drawing2D.Matrix();
m_scale = 1;
//SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint,true);
//SetStyle(System.Windows.Forms.ControlStyles.UserPaint, true);
//SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer,true);
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#endregion
#region IPersist Members
public string ToXML
{
get{return m_geom_model.ToXML;}
set{xml=value;}
}
public string ToVML
{
get{return m_geom_model.ToVML;}
set{xml=value;}
}
public string ToGML
{
get{return m_geom_model.ToGML;}
set{xml=value;}
}
public string ToSVG
{
get{return m_geom_model.ToSVG;}
set{xml=value;}
}
#endregion
}
}