SharpMap.UI plugin to draw polygon

Topics: SharpMap v0.9 / v1.x, WinForms Controls
Dec 11, 2008 at 1:56 PM
Hi all,

what would be a good approach to create a plugin which uses the SharpMap.UI's MapImage.cs to draw a polygon or place a point?

I'd like to have the code in a seperate class to keep stuff clear. A plugin which overrides the MouseDown, MouseMove and MouseUp is my goal.

Does anyone have some tips or code on how to do this?

Thanks,

Jan

Coordinator
Dec 11, 2008 at 6:17 PM
You could just subclass the MapImage control and add your tools to the Tools enum and override the necessary methods.
Alternatively you could refactor the control to have  a tool 'handler' base class which you would subclass to contain the logic for each type of action / pan / zoom etc then create a new 'handler' for your tools.
Then create a property on the control which sets the currently active handler.

hth jd
Dec 11, 2008 at 7:45 PM
Hi Jd,

thanks for the info.

The first one i tried but i'd like to use the current zoom/pan functions from MapImage.cs and as you stat,e based upon the Tools enum, have different classes deal with eacht new 'Tool'. Like a DrawPoint class and a DrawPolygon class.
When overriding, i should check if the tool is from the subclass(new) or the baseclass (MapImage). So like:

        public override void MapImage_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (new_tool)
            {
                // this subclass
                Console.WriteLine("It works");
            }
            else
            {
                // baseclass
                base.MapImage_MouseMove(sender, e);
            }
        }


The 'refactor the control' approach i do not quite understand. Do i 'remove' the current Mouse events totally in the MapImage.cs and write them in each 'Plugin'?
Ehm,... can you explain a ltittle bit more about refactoring in relation to the MapImage.cs class?

Thanks!





Coordinator
Dec 11, 2008 at 8:32 PM
Edited Dec 11, 2008 at 8:32 PM
Hi Jan, for the first case it may be easier to re-implement all the base functionality but using your new enum for the switches.
For the second one you would remove the current mouse events and re-implement and it might look something like this :

public interface ITool //interface which all your tools implement
{
    Map TargetMap {get;set;}
    void MouseDown(object sender, MouseEventArgs e);
    void MouseUp(object sender, MouseEventArgs e);
    void MouseMove(object sender, MouseEventArgs e);
}


public class MapImageVNext
{
    private ITool _tool;
    public ITool ActiveTool{get;set;} //The currently active tool 

    ........


    private void MapImage_MouseDown(object sender, MouseEventArgs e)
    {
        if(ActiveTool!=null)
            ActiveTool.MouseDown(sender, e); //relay the call to the real tool 
    }

    private void MapImage_MouseMove(object sender, MouseEventArgs e)
    {
        if(ActiveTool!=null)
            ActiveTool.MouseMove(sender, e); //relay the call to the real tool 
    }

    private void MapImage_MouseUp(object sender, MouseEventArgs e)
    {
            if(ActiveTool!=null)
                ActiveTool.MouseUp(sender, e); //relay the call to the real tool 
    }


}
Dec 12, 2008 at 12:01 AM
Hi John,

thanks for the reply. Excellent info!

At first i thought i was in it over my head, but after some trial and error (Designer.cs messing stuff up) it looks to be ok now.

In the MapImage.cs at creation i have:


        private ITool _currenttool = new ToolNothing(); // default (CurrentTool is replacing ActiveTool)


        public MapImage()
        {
           ....
            _currenttool = new ToolNothing(); // does what it says
            base.MouseMove += new System.Windows.Forms.MouseEventHandler(CurrentTool.MouseMove);
            base.MouseUp += new System.Windows.Forms.MouseEventHandler(CurrentTool.MouseUp);
            base.MouseDown += new System.Windows.Forms.MouseEventHandler(CurrentTool.MouseDown);

            base.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.MapImage_Wheel);// default
            .....
        }


        public ITool CurrentTool
        {
            get { return _currenttool; }
            
            //set { _currenttool = value; }

            set
            {
                // for the old controller, remove references to the view
                if (_currenttool != null)
                {
                    MouseDown -= new System.Windows.Forms.MouseEventHandler(_currenttool.MouseDown);
                    MouseMove -= new System.Windows.Forms.MouseEventHandler(_currenttool.MouseMove);
                    MouseUp -= new System.Windows.Forms.MouseEventHandler(_currenttool.MouseUp);
                }
                _currenttool = value;
                // initialize the controller to listen to mouse events
                if (_currenttool != null)
                {
                    MouseDown += new System.Windows.Forms.MouseEventHandler(_currenttool.MouseDown);
                    MouseMove += new System.Windows.Forms.MouseEventHandler(_currenttool.MouseMove);
                    MouseUp += new System.Windows.Forms.MouseEventHandler(_currenttool.MouseUp);
                }
            }
        }


    public interface ITool // the interface which all tools implement
    {
        Map TargetMap { get; set;}

        void MouseDown(object sender, System.Windows.Forms.MouseEventArgs e);
        void MouseUp(object sender, System.Windows.Forms.MouseEventArgs e);
        void MouseMove(object sender, System.Windows.Forms.MouseEventArgs e);
    }


And in the 'Tools' (public class ToolA : ITool) i use like:

        public void MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            Console.WriteLine("Tool A MouseDown");
        }






Coordinator
Dec 12, 2008 at 9:17 AM
Glad it's working for you - and your solution is very similar to the presenters from v2 so understanding these concepts will help you migrate later. Good luck jd
Dec 12, 2008 at 9:48 AM
That's good to hear. You should go for a job as a teacher :)

Glad to hear that's the good approach. Regarding v2: i just can't set myself to learn the <T> logics.
Maybe if i get really really boared :)

Coordinator
Dec 12, 2008 at 10:06 AM
lol I wasn't a very good student and I dont think I would be any better as a teacher!
Generics is a very powerful tool - it may take a bit of head scratching to start with but once you 'get it' it will open up loads of possibilities - I cant recommend understanding it highly enough..
Dec 12, 2008 at 10:12 AM
hh :)

Generics like List<> is understandable but the <T> is ehm, not. Will do some reading then. Can now safely say i plan that foor next year. Lol.