Freeze layer

Topics: Algorithms, General Topics, SharpMap Project, SharpMap v0.9 / v1.x, WinForms Controls
Jul 14, 2009 at 1:06 PM

Hi all,

I'm using SharpMap for tracking the movement of people in a building.
In the mapBox the georeferenced map of the city and the georeferenced floor map of the building ( both are raster files) are displayed.
For every person moving in the floor a tracking line is displayed by a separate layer.
Because rendering the layers with spatial data and because the city map is zoomed to show only the building's area it takes app. 2.7 sec
to refresh the mapBox. It would be nice to reduce this duration because I want to refresh the box cyclical to show the peoples movement.

If no zooming or panning has occured it should be sufficient to only render the tracking layers and to display the unchanged layers without a new rendering.
Any help appreciated.

Thanks, Martin

Coordinator
Jul 14, 2009 at 1:15 PM
Edited Jul 14, 2009 at 1:16 PM

Hi Martin, you could render your background map to an image and cache it, then render only the people layers to another image (with a transparent background) and then merge the two(use a copy of the background )  - that way you only need to re-render the background if the extents have changed hth jd

Jul 14, 2009 at 1:39 PM

Hi John,

thank you for the answer,

How to merge the images? It should be done with every map.refresh !?

Regards, Martin

Coordinator
Jul 14, 2009 at 3:13 PM

Hi Martin,

To merge the images you would do something like:

Bitmap backgroundBmp = BackgroundBmp.Clone();/*assumes you have cached the rendered background map to the property BackgroundBmp*/

Graphics g = Graphics.FromImage(backgroundBmp);

g.DrawImageUnscaled(overlayMap.GetMap());

 

You could also try stacking two maps on top of each other - background one below, people one above - then relay any extents changes recieved by the top map to the bottom map hth jd

Jul 15, 2009 at 11:35 AM

Hi John,

I'm trying to use your first proposal:
In MapBox.cs I have assigned m_Image to this.BackgroundImage when my raster images to freeze are added. Then the new overlayMap is assigned to myMapBox.Map.
Now a new vector layer is added to the overlayMap and to render both images I call a new method of MapBox:

public void NewRefresh()
{
    if (m_Map != null)
    {
          Bitmap backgroundBmp = this.BackgroundImage.Clone() as Bitmap;
          Graphics g = Graphics.FromImage(backgroundBmp);
          g.Clear(Color.Transparent);
          g.DrawImageUnscaled(m_Map.GetMap() as Image, m_Map.Size.Width, m_Map.Size.Height);
          base.Refresh();
    }
}

Only the frozen image is displayed, but what is wrong / missing?

Thank's for your help, Martin

Coordinator
Jul 15, 2009 at 12:06 PM

Hi Martin, DrawImageUnscaled takes image, left and top not image, width and height

also the instructions above was a general merging images technique - it needs to be modified to use with the control.. something like

public class SpecialMapBox:MapBox
{

Bitmap BackgroundBmp {get;set;}

override OnPaint(PaintEventArgs e)
{
e.Graphics.DrawImageUnscaled(BackgroundBmp.Clone(),0,0);
base.OnPaint(e);

}

}

 may get you started.. hth jd

Jul 15, 2009 at 1:01 PM

Hi John,

Sorry when I'm a little bit confused. I thought we want to merge the images? In your last posting the overlayMap is not mentioned - only the frozen image will be displayed.

Regards, Martin

Coordinator
Jul 15, 2009 at 1:48 PM

Hi Martin, sorry to confuse you.. The concept is that we need to merge two images into one. The code I originally posted will merge one image onto another, but all you end up with is the merged image which you could save to disk etc. However in the case of a control we need to draw it on the screen... so In the second example I overrode(?) the OnPaint method which is where the control draws itself to screen, e.Graphics is essentially a Graphics object responsible for drawing to the controls' window surface.
So then we use it to draw the background image to this graphics object before passing back down to the parent class to draw the overlay map as normal.. BTW this idea is untested and you may have issues when the screen pans etc so it may need extra work... hth jd

Jul 16, 2009 at 8:40 AM

Hi John,

ok, the mapBox control now uses the 'SpecialMapBox' derived from MapBox as you described in your former mail. When the 'background' image is added as a layer to the map I assign the BackgroundBmp 

this.BackgroundBmp = Image.Clone() as Bitmap;

... and  a new overlayMap:

mapBox.Map = overlayMap;

With 'mapBox.Refresh'  m_Image is assigned by m_Map.GetMap() with only the overlay layer and now it is running. Next I will investigate how to handle zooming and panning.

Thank you, Martin