Background become white due to using Map.Refresh()?

Topics: SharpMap Project, SharpMap v0.9 / v1.x
Dec 10, 2013 at 11:49 AM
Edited Dec 10, 2013 at 5:45 PM
Dear all,


I intended to use SharpMap control to draw infrastructure networks, in which require me to construct points (nodes) and polylines (connected links) separately to form networks. Because the toolbox provided (Draw point and Draw polyline) in SharpMap cannot perform link connection function (i.e. polyline cannot connect each others based on start nodes or end nodes), therefore I decided to construct a toolbox by myself.

I decided to use Mouse events to deal with drawings and everything right now is fine for me. But I have a problem is that when I drawing the links (I click to establish the first point, and snap to direct the line and mouse up to generate the second point of line), particularly at Mouse Move process, the background of the map become white (disappeared), once Mouse Up, the background will appear and recover again. I think it might be I refer the Map.Refresh() method so it updates all the layers in the Mapbox?

I am wondering if I understand this right, and for this issue, is there any available method to break this problem? In addition, I really want to know what is the differences between Map Invalidate() and Map.Refresh() method, I found that Map invalidate() sometimes does not work well as Map.Refresh().

I have posted my codes as follows:
        public void OnMouseDown(Coordinate coordinate, MouseEventArgs e)
        {
            _mapbox.Cursor = Cursors.Cross;
            rectangle = new Rectangle(e.Location.X, e.Location.Y, 3, 3);

                _isDrawingLink = true;

                if (States.Network.InfraNodes.Count > 0)
                {
                    foreach (var node in States.Network.InfraNodes)
                    {
                        if (node.EnvelopeContains(coordinate))
                        {
                            _pointArray.Add(node.Coordinate);
                            _pointArray.Add(node.Coordinate);
                        }
                    }
                }
                else
                {
                    _pointArray.Add(coordinate);
                    _pointArray.Add(coordinate);
                }
        }

        public void OnMouseMove(Coordinate coordinate, MouseEventArgs e)
        {
            if (_isDrawingLink)
            {
                if (_pointArray.Count == 2)
                {
                    _pointArray[_pointArray.Count - 1] = _mapbox.Map.ImageToWorld(e.Location);
                    _mapbox.Refresh();
                }
            }
        }

        public void OnMouseUp(Coordinate coordinate, MouseEventArgs e)
        {
            rectangle = new Rectangle(e.Location.X, e.Location.Y, 3, 3);

            if (_pointArray.Count == 2)
            {
                _pointArray[_pointArray.Count - 1] = coordinate;
                InfraLink link = new InfraLink(_pointArray[0], _pointArray[1]);
                States.Network.AddLink(link);
                _mapbox.Refresh();
            }
            _isDrawingLink = false;
            _pointArray.Clear();
        }

        public void OnPaint(object sender, PaintEventArgs e)
        {
            if (_isDrawingLink&&_pointArray != null)
            {
                    var p1 = _mapbox.Map.WorldToImage(_pointArray[0]);
                    var p2 = _mapbox.Map.WorldToImage(_pointArray[1]);
                    e.Graphics.DrawRectangle(new Pen(Color.Blue, 3F), rectangle);
                    e.Graphics.DrawLine(new Pen(Color.Green, 2F), p1, p2);
            }

            if (States.Network.InfraNodes.Count >0 || States.Network.InfraLinks.Count >0)
            {
                NetworkVisualiser.DrawNetwork(_mapbox, States.Network);
            }

        }
The DrawNetwork is a static method and it is:
        public static void DrawNetwork(MapBox mapbox, InfraNetwork network)
        {
                mapbox.Map.Layers.Clear();

                if (network.NodeGeometry.Count > 0)
                {
                    GeometryFeatureProvider gf2 = new GeometryFeatureProvider(network.NodeGeometry);
                    VectorLayer vectorLayer2 = new VectorLayer("NetworkNodes", gf2);
                    vectorLayer2.IsQueryEnabled = true;
                    mapbox.Map.Layers.Add(vectorLayer2);
                }

                if (network.LineGeometry.Count >0)
                {
                    GeometryFeatureProvider gf3 = new GeometryFeatureProvider(network.LineGeometry);
                    VectorLayer vectorLayer3 = new VectorLayer("NetworkLink", gf3);
                    vectorLayer3.IsQueryEnabled = true;
                    mapbox.Map.Layers.Add(vectorLayer3);
                }
        }
Dec 10, 2013 at 5:27 PM
Could anyone do me a favour please? I am really stuck here to use the map events.
Coordinator
Dec 11, 2013 at 6:57 AM
It might be better to not disturb the rendering within MapBox by subscribing to the Paint event.
Instead create a custom NetworkLayer : Layer class that has the network drawing functionality in its Render method.
Dec 11, 2013 at 11:10 AM
Many thanks for the information. I will have a try what happens!
Dec 11, 2013 at 5:32 PM
Edited Dec 11, 2013 at 5:35 PM
Hi FObermaier,

Thanks for your guidance. Could you please provide more information about what I need to write into the derived NetworkLayer? I have checked the VectorLayer class and I found it has provided the Render method to visualise the Feature data. Even I write a NetworkLayer I think that is what I can write in and it is same as Vectorlayer. I cannot understand the differences that I need to make into the NetworkLayer class, so I would not need to subscribing Paint event for drawing things?
Dec 11, 2013 at 5:34 PM
Hi FObermaier,

Thanks for your guidance. Could you please provide more information about what I need to write into the derived NetworkLayer? I have checked the VectorLayer class and I found it has provided the Render method to visualise the Feature data. Even I write a NetworkLayer I think that is what I can write in and it is same as Vectorlayer. I cannot understand the differences that I need to make into the NetworkLayer class, so I would not need to subscribing Paint event for drawing things?