Map Zooms Itself In/Out After Manual Zoom Change

Last post 3/4/2010 8:09:05 PM by drichard. 2 replies. << Back to Web.Maps.VE v3.0 General
10/15/2009 4:30:31 PM
drichard

Map Zooms Itself In/Out After Manual Zoom Change

Hello,

I am having a problem where, if the user attempts to zoom into/out of the map, it occasionally will subsequently "undo" the zoom, and return to the previous zoom level. It happen equally if you zoom with the dashboard buttons or use the mouse scroll-wheel.

It doesn't seem to be consistent in when it happens either, just often enough to effect usability.

Is this a known problem? I am very curious because nothing happens if I move around the map, just if I zoom in/out.

Thanks,
Daniel
11/20/2009 2:24:07 PM
Chris Pietschmann

Re:Map Zooms Itself In/Out After Manual Zoom Change

Could you post some code that demonstrates this issue?
3/4/2010 8:09:05 PM
drichard

Re:Map Zooms Itself In/Out After Manual Zoom Change

I have been able to verify that this does happen in a very slightly modified version of one of the examples on this site, the same way it does with my own code.

Using the PopupWindowDemo with the following modifications to default.aspx and default.aspx.cs

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default"
Title="Web.Maps.VE with Popup Window Demo" %>

<%@ Register Assembly="Simplovation.Web.Maps.VE" Namespace="Simplovation.Web.Maps.VE" TagPrefix="Simplovation" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
   
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
    <link href="StyleSheet.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h3>Web.Maps.VE with Popup Window Demo</h3>
        <p>This is a demonstration of how to dynamically edit the Shapes/Pushpins on the Map utilizing the AjaxControlToolkit. This also demonstrates how to easily add new Shapes/Pushpins to the Map by allowing the user to click the location, then enter in the desired values via an AjaxControlToolkit ModalPopup control.</p>
        <p>Click on an existing Pushpin to Edit.<br />
        Click anywhere else to Add a New Pushpin.<br />
        Hold Control (Ctrl) Key and Left Click to Delete a Pushpin.</p>
   
        <asp:ScriptManager runat="server" ID="sm1"></asp:ScriptManager>
   
        <Simplovation:Map runat="server" ID="Map1" Width="800" Height="500"
            AsyncPostbackPassShapes="False" DashboardSize="Small"
            TileBuffer="2">
        </Simplovation:Map>
   
        <asp:Panel ID="Panel1" runat="server" Style="display: none" CssClass="modalPopup">
            <asp:Panel ID="Panel3" runat="server" CssClass="modalPopupHandle">
                <div>
                    <p>Edit Pushpin Values</p>
                </div>
            </asp:Panel>
                <div>
                    <asp:UpdatePanel runat="server" ID="upPopup">
                        <ContentTemplate>
                            <asp:HiddenField runat="server" ID="hfTag" />
                            <p>
                                Title:<br />
                                <asp:TextBox runat="server" ID="txtTitle"></asp:TextBox>
                            </p>
                            <p>
                                Description<br />
                                <asp:TextBox runat="server" ID="txtDescription"></asp:TextBox>
                            </p>
                        </ContentTemplate>
                        <Triggers>
                            <asp:AsyncPostBackTrigger ControlID="OkButton" EventName="Click" />
                        </Triggers>
                    </asp:UpdatePanel>
                    <p style="text-align: center;">
                        <asp:Button ID="OkButton" runat="server" Text="OK" OnClick="OkButton_Click" />
                        <asp:Button ID="CancelButton" runat="server" Text="Cancel" />
                    </p>
                </div>
        </asp:Panel>
        <asp:Button runat="server" ID="hiddenTargetControlForModalPopup" style="display:none"/>
        <ajaxToolkit:ModalPopupExtender ID="ModalPopupExtender1" runat="server"
            BehaviorID="programmaticModalPopupBehavior"
            TargetControlID="hiddenTargetControlForModalPopup"
            PopupControlID="Panel1"
            BackgroundCssClass="modalBackground"
            CancelControlID="CancelButton"
            DropShadow="true"
            PopupDragHandleControlID="Panel3" />   
           
        <h4>&copy; 2009 <a href="http://simplovation.com">Simplovation LLC</a></h4>
        <h4>Use this Example Code at your own risk. No warranties or rights to use Simplovation's Web.Maps.VE control are expressed or implied by this example. If you are interested in purchasing a license to Simplovation's Web.Maps.VE control, please go here: <a href="http://simplovation.com">http://simplovation.com</a></h4>
    </div>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
            <asp:Timer ID="Timer1" runat="server" Interval="100"
    ontick="Timer1_Tick">
            </asp:Timer>
        </ContentTemplate>
    </asp:UpdatePanel>
    </form>
</body>
</html>

and Default.aspx.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Simplovation.Web.Maps.VE;

    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                shapes = new ShapeLayer();
                // Instead of the below code, this is where you would load your Pushpins, Shapes or Data
                // to be displayed on the Map when the page first loads.

                // Only add a Pushpin at the center of the Map on the initial Page load
                // Never on Postbacks or Async Postbacks
                var s = new Shape(Map1.LatLong);
                s.Tag = Guid.NewGuid().ToString(); // Set the Pushpins Tag to a unique value so we can reference it later
                s.Title = "Initial Center Point";
                s.Description = "This Pushpin is located at the initial center location of the Map when it first loaded.";

                Map1.Layers.Add(shapes);
                shapes.Shapes.Add(s);

                //Map1.AddShape(s);
            }
        }

        protected void Map1_Click(object sender, AsyncMapEventArgs e)
        {
            if (e.Shape != null) // If user clicked on a Shape
            {
                if (e.leftMouseButton && e.ctrlKey)
                {
                    // Check if the Left Mouse Button and Control Key was pressed

                    // Remove Pushpin
                    Map1.DeleteShape(e.Shape);
                }
                else
                {
                    // Populate the Popup fields
                    hfTag.Value = e.Shape.Tag;
                    txtTitle.Text = e.Shape.Title;
                    txtDescription.Text = e.Shape.Description;

                    // Show Popup
                    this.ModalPopupExtender1.Show();
                }
            }
            else // if an existing Shape was not clicked
            {
                if (e.leftMouseButton) // Check if the Left Mouse button was clicked
                {
                    // Set Tag field to signify a New Pushpin
                    // In this case we're saving the JSON serialization of the location to create the new Pushpin
                    hfTag.Value = JSONHelper.Serialize<LatLong>(e.latlong);

                    // Clear the other fields
                    txtTitle.Text = "";
                    txtDescription.Text = "";

                    // Show Popup
                    this.ModalPopupExtender1.Show();
                }
            }
        }

        protected void OkButton_Click(object sender, EventArgs e)
        {
            Shape shape = null;

            // Check if this is a New Shape to be created
            bool isNewShape = (hfTag.Value.StartsWith("{") && hfTag.Value.EndsWith("}"));

            if (isNewShape)
            {
                // Create New Shape to be created
                // In this case the Tag value is the JSON serialization of the LatLong object
                // that represents the location of the new Shape.
                var latlong = JSONHelper.Deserialize<LatLong>(hfTag.Value);
                shape = new Shape(latlong);
                // Set the New Shapes Tag to a unique value (in this case a Guid)
                shape.Tag = Guid.NewGuid().ToString();
            }
            else
            {
                // Get the Shape that we'll save values to
                shape = getShapeByTag(hfTag.Value);
            }

            if (shape != null) // Check that Shape was found
            {
                // Save the new Values to the Pushpin
                shape.Title = txtTitle.Text;
                shape.Description = txtDescription.Text;

                if (isNewShape)
                {
                    // If the Shape is New, then Add it to the Map
                    Map1.Layers[0].Shapes.Add(shape);
                    shapes.Shapes.Add(shape);
                }


                // Perform logic here to save value to database or other data store.


                // Hide the Popup
                this.ModalPopupExtender1.Hide();
            }
        }


        /// <summary>
        /// This is a helpe method that allows you to easily get a reference to
        /// a particular Shape by the value of its Tag property.
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        private Shape getShapeByTag(string tag)
        {
            foreach (var l in Map1.Layers)
            {
                foreach (var s in l.Shapes)
                {
                    if (s.Tag == tag)
                    {
                        return s;
                    }
                }
            }
            return null;
        }
        protected void Timer1_Tick(object sender, EventArgs e)
        {
            foreach (ShapeLayer sl in Map1.Layers)
            {
                sl.Shapes.Clear();
            }
            //Map1.Layers.Remove(shapes);
            Map1.Layers.Clear();

            var s = new Shape(Map1.LatLong);
            s.Tag = Guid.NewGuid().ToString(); // Set the Pushpins Tag to a unique value so we can reference it later
            s.Title = "Initial Center Point";
            s.Description = "This Pushpin is located at the initial center location of the Map when it first loaded.";

            shapes = new ShapeLayer();
            shapes.Shapes.Add(s);
            Map1.Layers.Add(shapes);
        }

        protected ShapeLayer shapes;
    }

Basically, I disabled the onclick and added a timer. On the timer's event I clear all of the shapelayers on the map, and remake the default pushpin at the new center location.

If you zoom in/out fast enough/often enough it will occasionally "undo" the last zoom, returning the map to the zoom level immediately prior to the zoom operation. So if for example I zoom from level 1 to level 5 quickly, it will occasionally get to level 5 then zoom back to level 4. While not present in this example, it seems to happen more often if more shapes/shapelayers have to be cleaned/re-added during the update. With roughly 75 shapes on the map, it happens on nearly 1/5-1/3 of the times I try to zoom.

This happens both if I change the zoom using a mouse scroll wheel or the map's own +/- zoom buttons.