Problem with "clickable map" example

Topics: General Topics
Mar 27, 2007 at 1:46 PM
Edited Mar 27, 2007 at 2:11 PM
Hi,

I have some difficulties with the "clickable map" example ( http://www.codeplex.com/SharpMap/Wiki/View.aspx?title=Create%20a%20clickable%20map

If I resize the window which contains my pictureBox, the map is not positioned correctly.

My getMap method :


public Image getMap(int width, int height)
		{
			map.Size = new Size(width, height);
           
			if (layer_l == null)
			{
				layer_l = new VectorLayer("layer_l");
				layer_l.DataSource = new ShapeFile(path + fileName + ".shp", true);
                
				map.Layers.Add(layer_l);
 
				map.Center = layer_l.Envelope.GetCentroid(); 
 
				maximumZoom = layer_l.Envelope.Width;
 
				map.ZoomToExtents();
				zoom = map.Zoom;
			}
			else
			{
				map.Zoom = zoom;
				
				map.Center = map.ImageToWorld(center);
			}
			
			return map.GetMap();
		}

The parameters are the dimensions of my pictureBox

This method is called when the shapeFile is opened, on zoom Action or when the window is resized.
The zoom action define the zoom and center properties.
Coordinator
Mar 27, 2007 at 3:24 PM
Since it appears you are using WinForms, have you tried using the MapImage control? I believe it handles most of this for you.
Mar 28, 2007 at 3:02 PM
Seems to work. But I have also found the reason of my problem. My getMap method was called every time the Image was resized. So Map.Center was also recalculate and my map didn't appear correctly.

But I will keep the MapImage Control.
I already tried to use the zoom (mouseWheel) event and I already have problems.
The zoom does not work correctly. I search in the SharpMap source and I found that the zoom value is calculate with these two lines :

double scale = 0.5 * e.Delta;
_Map.Zoom *= 1 / scale;

My maximum and minimum zoom values are 5000 and 500. The zoom value is initially set to 5000.
If I try a zoom I get :

scale = 0.5 * e.Delta = 0.5 * 120 = 60
_Map.Zoom *= 1 / scale = (1 / 60) * 5000 = 83.3

=> I'm always out of zoom bounds.


At this time the only one solution I have found is to modify the sources and use them in my project instead of the DLL.

My modified method :
private void MapImage_Wheel(object sender, System.Windows.Forms.MouseEventArgs e)
{
	if (_Map != null)
	{
		if (e.Delta < 0)
		{
			_Map.Zoom *= 2;
		}
		else
		{
			_Map.Zoom /= 2;
		}
 
		_Map.Center = _Map.ImageToWorld(new PointF(e.X, e.Y));
 
		if (MapZoomChanged != null)
			MapZoomChanged(_Map.Zoom);
		Refresh();
	}
} 

Is there an other solution ?
Coordinator
Mar 28, 2007 at 8:40 PM
It appears to be a bug in SharpMap - I'll tag it as a workitem. If you look at the docs for MouseEventArgs, we're not dividing e.Delta by Window's WHEEL_DELTA constant, which is currently 120. (BTW, handling MouseEventArgs.Delta is messy in .Net, since there is no equivalent constant to WHEEL_DELTA found in WinUser.h to link against in the Framework - we are forced to hard code it. It should be a static readonly property on the MouseEventArgs class. I submitted a MS Connect issue for this oversight: vote for it!)

One current workaround would be to just inherit from MapImage and override the MapImage_Wheel method, using your code as a replacement or replacing the event args with one that precomputes the Delta property by dividing by 120, that way you don't have to recompile the whole library each time.
Coordinator
Mar 28, 2007 at 9:04 PM
This discussion has been copied to Work Item 9210. You may wish to continue further discussion there.
Apr 2, 2007 at 11:50 AM
Thank you very much ! :-)