ConstrainExtentBehavior Constraint

554
4
Jump to solution
04-11-2013 06:42 PM
StanleyHo
New Contributor III
Hi,

I have 2 questions regarding ConstrainExtentBehavior.

1) Is there a way to just constraint the height (Y axis) not the width (X axis)?
2) I notice that when the map is scrolled to the limit, it will have a "bouncing" effect and the map actually got push back a bit. Is a way to prevent this bonucing effect and make the scroll/move stop just at the edge?

Thanks
0 Kudos
1 Solution

Accepted Solutions
DavidMartin
Occasional Contributor II
You could write your own to do what you want. The Map has 2 events - ExtentChanged and ExtentChanging which you could handle in order to re-set the extent however you want.

The bouncing effect you notice seems likely to be intentional (as an indicator that a limit has been reached?) or it might be down to constraints on implementation. The ExtentChanging event doesn't offer the ability to Cancel, so it may be that the behaviour is simply to "bounce" back to the old extent if the new extent is outside of bounds??

View solution in original post

0 Kudos
4 Replies
DavidMartin
Occasional Contributor II
You could write your own to do what you want. The Map has 2 events - ExtentChanged and ExtentChanging which you could handle in order to re-set the extent however you want.

The bouncing effect you notice seems likely to be intentional (as an indicator that a limit has been reached?) or it might be down to constraints on implementation. The ExtentChanging event doesn't offer the ability to Cancel, so it may be that the behaviour is simply to "bounce" back to the old extent if the new extent is outside of bounds??
0 Kudos
StanleyHo
New Contributor III
thanks for the reply.

I have implemented what you suggest but I am getting a stackoverflow error if I zoom and scroll to the edge.
Not sure what is causing it.

Note: I am using "http://server.arcgisonline.com/arcgis/rest/services/ESRI_StreetMap_World_2D/MapServer" map which is a WGS84 map and not a mecator map.
Code for Map_ExtentChanged and Map_ExtentChanging is shown below.
private void MyMap_ExtentChanged(object sender, ExtentEventArgs e)
        {
            //new envelope to set if needed
            Envelope newExtent = null;

            if (MyMap.WrapAroundIsActive)
            {
                //Wrap around is set to true
                ESRI.ArcGIS.Client.Geometry.Geometry normalizedExtent = ESRI.ArcGIS.Client.Geometry.Geometry.NormalizeCentralMeridian(e.NewExtent);
                if (normalizedExtent is Polygon)
                {
                    newExtent = new Envelope();

                    foreach (MapPoint p in (normalizedExtent as Polygon).Rings[0])
                    {
                        if (p.X < newExtent.XMin || double.IsNaN(newExtent.XMin))
                            newExtent.XMin = p.X;
                        if (p.Y < newExtent.YMin || double.IsNaN(newExtent.YMin))
                            newExtent.YMin = p.Y;
                    }

                    foreach (MapPoint p in (normalizedExtent as Polygon).Rings[1])
                    {
                        if (p.X > newExtent.XMax || double.IsNaN(newExtent.XMax))
                            newExtent.XMax = p.X;
                        if (p.Y > newExtent.YMax || double.IsNaN(newExtent.YMax))
                            newExtent.YMax = p.Y;
                    }
                }
                else if (normalizedExtent is Envelope)
                {
                    newExtent = normalizedExtent as Envelope;
                }
            }
            else
            {
                newExtent = e.NewExtent;
            }

            //constraint it to -90 to 90 degree latitude (Y-axis)
            newExtent.YMin = Math.Max(-90, newExtent.YMin);
            newExtent.YMax = Math.Min(90, newExtent.YMax);

            //No constraint on longitude (X-axis)
            newExtent.XMin = MyMap.Extent.XMin;
            newExtent.XMax = MyMap.Extent.XMax;

            if ((MyMap != null) && ((MyMap.Extent.YMin != newExtent.YMin) || (MyMap.Extent.YMax != newExtent.YMax)))
            {
                //set map new envelope if Y-axis min and max is exceeded
                MyMap.Extent = newExtent;
            }
        }


It seems like "MyMap.Extent = newExtent;" is always executed after after certain zooming operations after the edge.
For example:
1) zoom in twice (zoom factor=2) and scroll to the top edge.
2) zoom in once (zoom factor=2) and scroll to the bottom edge and zoom out.
0 Kudos
StanleyHo
New Contributor III
I think I managed to solve the problem.

I found out that it was likely to be caused by Map.Extent doesn't updated immediately but rather over time.
Hence I added a small threshold in my check before setting the Map.Extent.
0 Kudos
DavidMartin
Occasional Contributor II
Stack overflow? Beware infinite loops (caused by changing the map extent within the extentchanged handler, which will re-trigger the handler).
Glad you've got something working though!
0 Kudos