wiki:CodeSamples/JavaScript/ZoomRectangleTweak

Recently was asked by a user that the Zoom to Rectangle tool in Mapguide doesn't work. In investigating their statement, it turns out that when they were using the 'Zoom to Rectangle' tool they were drawing a rectangle that went precisely over top of the object of interest, and therefore was being cut off on the outer bounds.

In looking at the code base for the 'Zoom to Rectangle' function calculates the new mapscale based on the largest side of the rectangle, AND assumes the first x/y position of the rectangle is the top left (90% of the time it would be but some people will draw a rectangle from lower right to top left).

The following code adjusts the 'Zoom to Rectangle' function slightly so that no matter what order the rectangle is captured in (lower right to top left/top right to lower left/top left to lower right/etc), it resets the x1/y1 values to be the top left, and recalculates the shape of the zoom rectangle to roughly fit the shape of the mapframe. It does this by getting the larger edge of the zoom rectangle, and adjust the other edge by applying the ratio of width to height of the mapframe. In addition to the recalculate of the zoom rectangle shape, it puts a expands it by 5px, to ensure that the object being zoomed to fits in the mapframe and is not cut off.

To use this code replace the ExecuteRectangleTool?() function in ajaxmappane.templ, with the one below.

<script type="text/javascript">
function ExecuteRectangleTool()
{
    var x1, x2;
    var y1, y2;

    if(rcx1 <= rcx2)
    {
        x1 = rcx1;
        x2 = rcx2;
    }
    else
    {
        x1 = rcx2;
        x2 = rcx1;
    }

    if(rcy1 <= rcy2)
    {
        y1 = rcy1;
        y2 = rcy2;
    }
    else
    {
        y1 = rcy2;
        y2 = rcy1;
    }

    if(tool == 3)
    {
        if((x2 - x1 <= 2) && (y2 - y1 <= 2))
            return;

//ensure we have the box extents as true upper left/lower right
        var minx = Math.min(x1, x2);
        var miny = Math.min(y1, y2);
        var maxx = Math.max(x1, x2);
        var maxy = Math.max(y1, y2);
        

//get the width and height of the zoom box/window        
        var width = maxx - minx;
        var height = maxy - miny;

//get the ratio of width to height from the mapframe, this is to ensure the dimensions of the zoom box best fit the mapframe.
        var ratio = mapDevW / mapDevH;

//deterimine whether the width or height is to be reset.
        if (width < height)
          {
            width = ratio * height;
          }
         else
          {
            height = width / ratio; 
          }

        x2 = minx + width;
        y2 = miny + height;


// add a 5 px margin to the zoom box to ensure coverage of area of interest.
        x1 = minx - 5;
        y1 = miny - 5;
        x2 = x2 + 5;
        y2 = y2 + 5;


        pt1 = ScreenToMapUnits(x1, y1);
        pt2 = ScreenToMapUnits(x2, y2);

        mcsW = pt2.X - pt1.X;
        mcsH = pt2.Y - pt1.Y;
        scale = CalculateScale1(mcsW, mcsH, mapDevW, mapDevH);
        scale = finscale? GetNearestFiniteScale(scale): NormalizeScale(scale);
        HideMapImage();
        GotoView(pt1.X + mcsW/2, pt1.Y + mcsH/2, scale, true, false);
    }
    else if(tool == 0)
    {
        if((x2 - x1 <= 2) && (y2 - y1 <= 2))
        {
            pt1 = ScreenToMapUnits(x1-2, y1-2);
            pt2 = ScreenToMapUnits(x1+2, y1+2);
            RequestPointSelection(pt1.X, pt1.Y, pt2.X, pt2.Y, appending);
        }
        else
        {
            pt1 = ScreenToMapUnits(x1, y1);
            pt2 = ScreenToMapUnits(x2, y2);
            RequestRectSelection(pt1.X, pt1.Y, pt2.X, pt2.Y, appending);
        }
    }
}
</script>

Comments are appreciated. Jamie

Last modified 5 years ago Last modified on Feb 6, 2013 1:14:31 PM