Some contribution to the project

Topics: General Topics, SharpMap v0.9 / v1.x
Sep 19, 2012 at 1:03 PM
Edited Sep 19, 2012 at 2:02 PM

Hi,

Because I missed something (zoom previous & next) in SharpMap 0.9, I wrote it myself:

    /// <summary>
    /// An implementation of zoom previous/zoom next like *** MapControl
    /// </summary>
    public class ZoomExtentStack
    {
        private SharpMap.Forms.MapBox _mapBox;
        private List<BoundingBox> _zoomExtentStack = new List<BoundingBox>();
        private bool _storeExtentsUser = false;
        private bool _storeExtentsInternal = false;
        private int _index = 0;
 
        /// <summary>
        /// Initialisation; no extents will be stored until .StoreExtents = true
        /// </summary>
        /// <param name="mapBox">mapbox control</param>
        public ZoomExtentStack(SharpMap.Forms.MapBox mapBox)
        {
            _mapBox = mapBox;
            _mapBox.Map.MapViewOnChange += new SharpMap.Map.MapViewChangedHandler(_map_MapViewOnChange);
        }
 
        void _map_MapViewOnChange()
        {
            if (_storeExtentsUser && _storeExtentsInternal)
                Add(_mapBox.Map.Envelope);
            else
                _storeExtentsInternal = true;
        }
 
        /// <summary>
        /// If true extents will be stored, starting with the current;
        /// if false no extents will be stored (paused).
        /// </summary>
        public bool StoreExtents
        {
            get { return _storeExtentsUser; }
            set
            {
                if (value) Add(_mapBox.Map.Envelope);
                _storeExtentsUser = value;
            }
        }
 
        /// <summary>
        /// Erases the extents stack
        /// </summary>
        public void Clear()
        {
            _zoomExtentStack.Clear();
            _index = 0;
        }
 
        /// <summary>
        /// true if previous zoom is available
        /// </summary>
        public bool CanZoomPrevious
        { get { return (_index > 0); } }
 
        /// <summary>
        /// true if 'next' zoom is available
        /// </summary>
        public bool CanZoomNext
        { get { return (_index < _zoomExtentStack.Count - 1); } }
 
        /// <summary>
        /// Execute a zoom previous
        /// </summary>
        public void ZoomPrevious()
        {
            if (CanZoomPrevious)
            {
                _storeExtentsInternal = false;
                _index--;
                _mapBox.Map.ZoomToBox(_zoomExtentStack[_index]);
            }
        }
 
        /// <summary>
        /// Execute a zoom next
        /// </summary>
        public void ZoomNext()
        {
            if (CanZoomNext)
            {
                _storeExtentsInternal = false;
                _index++;
                _mapBox.Map.ZoomToBox(_zoomExtentStack[_index]);
            }
        }
 
        /// <summary>
        /// Adds the given extent to the stack
        /// </summary>
        /// <param name="newExtent">the extent to be stored</param>
        private void Add(BoundingBox newExtent)
        {
            // remove all above index
            if (_zoomExtentStack.Count - 1 > _index)
                _zoomExtentStack.RemoveRange(_index + 1, _zoomExtentStack.Count - _index - 1);
            // add given extent
            _zoomExtentStack.Add(newExtent);
            // correct index
            _index = _zoomExtentStack.Count - 1;
        }
    }

How to use it:

declaration

private ZoomExtentStack _zoomExtentStack;

intialization after InitializeComponent() of form (where mapBox is the control's name on the form)

_zoomExtentStack = new ZoomExtentStack(mapBox);
mapBox.Map.MapViewOnChange += new SharpMap.Map.MapViewChangedHandler(Map_MapViewOnChange);

after adding the layers

_zoomExtentStack.StoreExtents = true;

and add

void Map_MapViewOnChange()
{
    zoomPreviousButton.Enabled = _zoomExtentStack.CanZoomPrevious;
    zoomNextButton.Enabled = _zoomExtentStack.CanZoomNext;
}

also two buttons (zoomPreviousButton and zoomNextButton)

private void zoomPreviousButton_Click(object sender, EventArgs e)
{
    _zoomExtentStack.ZoomPrevious();
    mapBox.Refresh();
}
 
private void zoomNextButton_Click(object sender, EventArgs e)
{
    _zoomExtentStack.ZoomNext();
    mapBox.Refresh();
}

Pieter

Coordinator
Sep 19, 2012 at 2:40 PM
Edited Sep 19, 2012 at 2:43 PM

Thank you very much.

Could you provide a patchfile?

Sep 20, 2012 at 6:46 AM
Edited Sep 20, 2012 at 8:58 AM

Hello mr. Obermaier,

I will transfer the class code file, but some additions have to be made to the code of the form containing the MapBox control.

I also experienced a strange behaviour when doing pan: a lot of extents are stored in the stack, so some events code and a new variable needs to be added to the class:

Add a new variable to the class

private bool _blockStoringWhenPanning = false;

Add to the class declaration ( in public ZoomExtentStack(SharpMap.Forms.MapBox mapBox) ):

_mapBox.MouseDown += new SharpMap.Forms.MapBox.MouseEventHandler(_mapBox_MouseDown);
_mapBox.MouseUp += new SharpMap.Forms.MapBox.MouseEventHandler(_mapBox_MouseUp);

Add this two event handlers:

void _mapBox_MouseDown(Point worldPos, System.Windows.Forms.MouseEventArgs imagePos)
{
    if (_mapBox.ActiveTool == SharpMap.Forms.MapBox.Tools.Pan) _blockStoringWhenPanning = true;
}
 
void _mapBox_MouseUp(Point worldPos, System.Windows.Forms.MouseEventArgs imagePos)
{
    if (_mapBox.ActiveTool == SharpMap.Forms.MapBox.Tools.Pan) _blockStoringWhenPanning = false;
}

And modify the existing

void _map_MapViewOnChange()
{
    if (_storeExtentsUser && _storeExtentsInternal && !_blockStoringWhenPanning)
        Add(_mapBox.Map.Envelope);
    else
        _storeExtentsInternal = true;
}

In the patchfile I included some other code, because I found out that BoundingBox.Join didn't work.

Have a nice day,

Pieter

PS (10:55 am) In the two event handlers I changed true and false, now it is correct. In the published patchfile it is not....

Sep 21, 2012 at 7:30 AM

Sorry, I've forgotten one small line of code in the _mapBox_MouseUp event handler, otherwise the extent will not be stored when the map has been panned:

void _mapBox_MouseUp(Point worldPos, System.Windows.Forms.MouseEventArgs imagePos)
{
    if (_mapBox.ActiveTool == SharpMap.Forms.MapBox.Tools.Pan)
    {
        _blockStoringWhenPanning = false;
        Add(_mapBox.Map.Envelope);
    }
}

Do I have to transfer the patchfile again?

Pieter

Coordinator
Sep 24, 2012 at 12:32 PM

No, that is ok, I'll try to incorporate the code into the toolbar

FObermaier