Limiting MapBox scrolling to map extents

Nov 7, 2012 at 9:21 AM

Hi,

What would be a sensible way to limit the scrollable region within a MapBox such that the user cannot scroll beyond the edges of the map?

At the moment I can scroll to the side until the map goes completely off the screen. This is very easy to do if the map is fully zoomed out. It can be quite easy to lose the map and not be able to find it again.

Thanks.

Coordinator
Nov 7, 2012 at 1:36 PM

You need to take handle 2 events:

  • MapZoomChanged
    Limit the value zoom to a valid range
  • MapCenterChanged
    Test if the new bounding box is within the desired area. Reset the bounding box if not.

Hth FObermaier

Nov 8, 2012 at 8:54 AM

I already handle the MapZoomChanged event to make sure that the map cant be zoomed in too much or too little.

The MapCenterChanged event only seems to fire when the map is zoomed and not when it is panned. Is that a bug?

Also which bounding boxes should be compared? When zoomed in the edges of the map are off the screen by a long way but in that case it is acceptable. When zoomed out or scrolling to the very edge of the map I need to not allow the map to be scrolled any further.

I can imagine a LockToExtents boolean property would be useful on a MapBox.

Nov 9, 2012 at 3:34 PM

It turns out that MapCenterChanged not being called was because I handle the OnMouseUp event as well in my code and change the ActiveTool to DrawPoint in this. The OnMouseUp event is fired by the MapBox before handling the map move and firing the MapCenterChanged event, which only fires if the ActiveTool is Pan.

I changed my code to not use the DrawPoint tool and just keep Pan as the ActiveTool and now I get the MapCenterChanged event.

So the resulting code to stop the MapBox being scrolled beyond the maximum extents of the map is below. I also had to specify the maximum and minimum zoom levels of the map based on the available resolutions from the tile schema.

    
Coordinate m_lastMapCenter = null;
private void mapBox1_MapCenterChanged(Coordinate center)
    {
      Envelope mapExtents = mapBox1.Map.GetExtents();
      Rectangle bounds = mapBox1.Bounds;
      Coordinate tl = mapBox1.Map.ImageToWorld(new PointF(bounds.Left, bounds.Top), true);
      Coordinate br = mapBox1.Map.ImageToWorld(new PointF(bounds.Right, bounds.Bottom), true);

      //
      // If the visible area is off the end of the map then revert to the previous position.
      //
      if (
          tl.X < mapExtents.Left() ||
          br.X > mapExtents.Right() ||
          tl.Y > mapExtents.Top() ||
          br.Y < mapExtents.Bottom()
        )
      {
        if (tl.X < mapExtents.Left() && br.X > mapExtents.Right())
        {
          //
          // Centre the map if we are fully zoomed out.
          //
          mapBox1.Map.Center = mapExtents.Centre;
          center = mapExtents.Centre;
        }
        else if (m_lastMapCenter != null)
        {
          mapBox1.Map.Center = m_lastMapCenter;
          center = m_lastMapCenter;
        }
      }

      m_lastMapCenter = center;
    }
  }
May 27, 2014 at 7:10 AM
Edited Dec 7, 2014 at 10:47 AM
...