GetMapView() TopLeftLatLong/BottomRightLatLong oddity

Im using GetMapView () with TopLeftLatLong and BottomRightLatLong to display a set of pushpins in the visible area of the map and i am seeing some weirdness with the values being returned for BottomRightLatLong.

On page load i obtain the values i need using

var v = map.GetMapView();
alert("Vis cTOP LEFT" + v.TopLeftLatLong);
alert("Vis cBOTTOM RIGHT" + v.BottomRightLatLong);

The values returned by BottomRightLatLong show as:
42.488966
-83.102903

I also have an event attached to a mouse click which uses the same exact code:

var v = map.GetMapView();
alert("Click cTOP LEFT" + v.TopLeftLatLong);
alert("Click cBOTTOM RIGHT" + v.BottomRightLatLong);

The values returned by BottomRightLatLong for the click function show as:
42.4662
-83.0615

The map is not respositioned at all between the page load values and the mouse click values yet they are not the same.  The values coming back from the mouse click function are the ones i believe to be correct since once i click the mouse i get the correct display of pushpins on the map.

TopLeftLatLong returns the same values on page load and on the mouse click.

Is this a bug or am I not doing something correctly on the page load which causes incorrect values to come back from BottomRightLatLong

Thanks for any insight/help

Robert




Answer this question

GetMapView() TopLeftLatLong/BottomRightLatLong oddity

  • kfsoft

    We are seeing the same sort of behavior on our end - though intermittently (is the problem intermittent with you as well )

    GetMapView seems to always work when the map first loads, but then after some panning and zooming, and then only some of time, the bottom right corner is reported incorrectly. And the error is always a larger bounds (LR is further away from UL) - almost as if GetMapView was snagging the bounds of all rendered (and offscreen) tiles instead of what is in view.

    We are reporting the bounding region on an envelope change:

    map.AttachEvent('onchangeview', EnvelopeChange);

    function EnvelopeChange() { var ul = map.GetMapView().TopLeftLatLong; var lr = map.GetMapView().BottomRightLatLong;...\

    --Brian



  • oipreS

    Thanks for the reply :)

    I was getting the same behavior when i had the map full screened and nothing writing above it as well...

    Did the movie kinda show the oddness that i am getting at all

    Im considering starting to use GetTop, Get Left, Get Center and then just calc the bottom right lat/long by hand.



  • John McMillion

    I've been having problems caused by my display DPI being set to large fonts (I've just posted a new thread about it). Your issue sounds similar to mine in that the expected LatLong positions are slightly different from what you expect. In my case it's with plotting polygons.

    Is your display set to Large fonts If so, try changing it to normal and see if you then get the expected output.

    Stu


  • IlCapo

    No large fonts on my end here. Generally just clicking the map or sliding it very slightly will cause the correct points to appear on the map.

    Very frustrating as im but pretty sure its not something im doing in the page but I cant be 100% sure.



  • Glenn Burnside

    Hm, well... I just tried it with really basic page, and I'm not able to repro. Try the following and let me know if you see the problem:

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <script src="http://dev.virtualearth.net/mapcontrol/v3/mapcontrol.js">

    <html>

    <head>

    <script>

    var map = null;

    function GetMap() {

    map = new VEMap('myMap');

    map.LoadMap(new VELatLong(42.75108, -84.56652), 8, 'r', false);

    map.AttachEvent('onclick',BRLLTest);

    BRLLTest();

    }

    function BRLLTest() {

    var gmv = map.GetMapView();

    alert(gmv.BottomRightLatLong);

    }

    </script>

    </head>

    <body>

    <div id="myMap" style="position:relative; width:705px; height:505px;"></div>

    </body>

    </html>


  • CollegeSeniorProjectNeedsHelp

    Jeremy,

    The current project I’m on the map is actually fixed but the rest of the page resizes.

    I found I has to make a call to the map.Resize(mWidth, mHeight);. And attach it to the onresize event like this.

    //set window events for map to run.

    if (window.attachEvent) {

    window.attachEvent("onresize", MapResize);

    } else {

    window.addEventListener("resize", MapResize, false);

    }

    What this means is you would have to know the actual width of your map – 90% isn’t going to work.

    You should be able to calculate it based on what it is 90% of. Eg if it is 90% of the whole window then it is possible to get the whole width by using:

    if( typeof( window.innerWidth ) == 'number' )

    {

    //Non-IE

    mHeight = window.innerHeight;

    mWidth = window.innerWidth

    }

    else

    {

    //IE

    mHeight = document.body.clientHeight;

    mWidth = document.body.clientWidth;

    }

    if (mWidth < 240) //min width

    {

    mWidth = 240;

    }

    if (mHeight < 240) //min height

    {

    mHeight = 240;

    }

    And then use 90% of that. (The VE map actually throws errors if too small)

    If that doesn’t work I have actually changed to using the map.PixelToLatLong(mWidth,mHeight) function where you call it twice, once with 0,0 and the other with your newfoundwidth,350

    This should work. The benefit of this approach is you can play with over-sizing the bounds if required or what I am current doing is over-sizing to standard bounds, for example over-sizing to the nearest full lat/long eg 23,-78 to 18,-68. The idea is this way we will get lots of the same requests and our caching algorithms will be more effective.

    I hope this helps.

    John.



  • darkwarrior0404

    Appreciate it, if you need any additional info on my end just let me know.

    Robert



  • roni102

    I am having the same problem and I am almost 100% sure I know the cause of the problem.

    If you set the div tag to have absolute size (ex: width=400px, height=300px) the GetMapView() returns the correct results.

    For me, the problem starts when I change the width or height to a value that uses percentages (ex: width=90%, height=350px). It is then that the calculations go screwy.

    This seems like a bug, anyone concur or have a solution


  • Canalside Studios

    Well, I ended up solving the problem by manually calc'ing the bottom right lat/long using the topleft lat/long and the center lat/long.

    In case anyone else runs into this here's some code to manually get the bottom right lat/long:

    var v = map.GetMapView();

    //GET TOP LEFT LAT/LONG OF VIEWABLE AREA
    var TopLeftLatLong = v.TopLeftLatLong.toString();
    //GET TOP LEFT LATITUDE
    var TopLeftLatSplit = TopLeftLatLong.split(",")[0];
    //GET TOP RIGHT LONGITUDE
    var TopLeftLongSplit = TopLeftLatLong.split(",")[1];

    //CENTER
    var CenterLatLong = map.GetCenter().toString();
    //GET BOTTOM RIGHT LAT
    var CenterLatSplit = CenterLatLong.split(",")[0];
    //GET BOTTOM RIGHT LONG
    var CenterLongSplit = CenterLatLong.split(",")[1];

    //CALC BOTTOM RIGHT LAT/LONG
    var BottomRightLatSplit = CenterLatSplit - (TopLeftLatSplit - CenterLatSplit);
    //alert ("Bot Right Lat " + RightLat);
    var BottomRightLongSplit = CenterLongSplit - (TopLeftLongSplit - CenterLongSplit);
    //alert ("Bot Right Long " + RightLong);



  • bes7252

    This is a new one for me...I'll investigate and pass on to the team. I'll post a followup when (if ) I know more.


  • billb59

    I took your code and started a new test project and the numbers returned correctly. Im still having a problem with my app tho.

    I made a short AVI that may help show what is happening if you would like to check it out (its about 2.5meg)

    I've attached PixelToLatLong to a click event using:

    mapXPixel =
    event.clientX - map.GetLeft();

    mapYPixel = event.clientY - map.GetTop();

    latLong = map.PixelToLatLong(mapXPixel,mapYPixel);

    var x = document.getElementById("Click");

    x.innerHTML = ("Click PixelToLatLong Latitude=" + latLong.Latitude + " Longitude=" + latLong.Longitude);

    In the AVI i load the map control and display the TopLeftLatLong and BottomRightLatLong returned from GetMapView()

    I then click the map in the bottom right corner of the map and use PixelToLatLong to display the the returned values from that below. The visible companies text shows how many pins should be returned from my query.

    I would expect when i click the map and use PixelToLatLong to get the same(or very close to) GetMapView() BottomRightLatLong.

    The avi aint pretty but i think it shows the issue i am having. http://www.virtualgrp.com/clip0001.avi. Pause the vid after i click the lower right corner to compare the numbers.

    Here's the complete page code. If you would like to see the Handlers i can post those as well:

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml">

    <head runat="server">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    <script src="http://dev.virtualearth.net/mapcontrol/v3/mapcontrol.js">

    </script>

    <title>Locations</title>

    <script language="javascript" src="sarissa.js"></script>

    <script type="text/javascript">

    var map = null;

    var pinID = 1;

    var doc;

    function GetMap()

    {

    //alert("GETMAP()");

    map = new VEMap('myMap');

    map.LoadMap(new VELatLong(42.479231, -83.084826), 15);

    map.AttachEvent('onchangeview', VisibleCompanies);

    map.AttachEvent('onclick', BRLLTest);

    VisibleCompanies();

    //VisibleLabels();

    //BRLLTest();

    }

    function BRLLTest()

    {

    mapXPixel = event.clientX - map.GetLeft();

    mapYPixel = event.clientY - map.GetTop();

    latLong = map.PixelToLatLong(mapXPixel,mapYPixel);

    var x = document.getElementById("Click");

    x.innerHTML = ("Click PixelToLatLong Latitude=" + latLong.Latitude + " Longitude=" + latLong.Longitude);

    // var gmv = map.GetMapView();

    //alert("BRLL TEST" + gmv.BottomRightLatLong);

    }

    function VisibleCompanies()

    {

    //alert("VisibleCompanies()")

    //map.DeleteAllPushpins();

    map.Clear();

    //ADD IMAGE AND PIN FOR MH OFFICE TODO UPDATE IMAGE

    var pin = new VEPushpin (pinID, new VELatLong(42.479231, -83.084826), 'VirtualServices2.jpg', 'VSI Technical', '25307 Dequindre Road');

    //TEST DATA

    //var pin = new VEPushpin (pinID, new VELatLong(43.63855, -79.473945), 'VirtualServices2.jpg', 'VSI Technical', '25307 Dequindre Road');

    map.AddPushpin(pin);

    var v = map.GetMapView();

    //alert("Vis cTOP LEFT" + v.TopLeftLatLong);

    //alert("Vis cBOTTOM RIGHT" + v.BottomRightLatLong);

    //GET TOP LEFT LAT/LONG OF VIEWABLE AREA

    var TopLeftLatLong = v.TopLeftLatLong.toString();

    //GET TOP LEFT LATITUDE

    var TopLeftLatSplit = TopLeftLatLong.split(",")[0];

    //GET TOP RIGHT LONGITUDE

    var TopLeftLongSplit = TopLeftLatLong.split(",")[1];

    //GET BOTTOM RIGHT LAT/LONG OF VIEWABLE AREA

    var BottomRightLatLong = v.BottomRightLatLong.toString();

    //GET BOTTOM RIGHT LAT

    var BottomRightLatSplit = BottomRightLatLong.split(",")[0];

    //GET BOTTOM RIGHT LONG

    var BottomRightLongSplit = BottomRightLatLong.split(",")[1];

    //alert("Comp " + BottomRightLongSplit);

    var l = document.getElementById("pLat")

    l.innerHTML = "GetMapView() TopLeftLatLong " + TopLeftLatLong + "<br>GetMapView() BottomRight " + BottomRightLatLong;

    //CALL HANDLER TO GET THE COMPANIES WHICH SHOULD BE IN THE VISIBLE AREA

    doc = Sarissa.getDomDocument();

    doc.async = false;

    //alert(getCurrentRoot() + "VisibleCompanies.ashx");

    doc.load(getCurrentRoot () + "VisibleCompanies.ashx TLat="+ TopLeftLatSplit

    + "&TLong=" + TopLeftLongSplit

    + "&BLat=" + BottomRightLatSplit

    + "&BLong=" + BottomRightLongSplit);

    var comp = doc.selectNodes("companies/company");

    var companyPinID = 1;

    // alert ("Visisble Comps: " + comp.length);

    var t = document.getElementById("Comps");

    t.innerHTML = "Visible Pins Query Return" + comp.length;

    for (var i = 0 ; i < comp.length; i++)

    {

    //DEBUG

    //alert("IN FOR LOOP RecTest()");

    //alert(comp.length);

    //PIN ID Increment

    pinID++

    //GET DETAILS FOR FIRST LAVEL

    var cLat = compIdea.getAttribute('lat');

    var cLong = compIdea.getAttribute('lng');

    var cName = compIdea.getAttribute('name');

    var cAddressCityStateZip = compIdea.getAttribute('address') + "<br>" + compIdea.getAttribute('city') + ", " + compIdea.getAttribute('state') + " " + compIdea.getAttribute('zip');

    //alert ("cLat " + cLat);

    //alert (pinID)

    var companyPin = new VEPushpin (pinID, new VELatLong(cLat, cLong), 'bluebal.gif', cName, cAddressCityStateZip);

    try

    {

    map.AddPushpin(companyPin);

    }

    catch (e)

    {

    alert (e.message);

    }

    }

    }

    // function importXML()

    // {

    // //DEBUG

    // //alert("in import");

    // //xmlDoc = Sarissa.getDomDocument();

    // //xmlDoc.async = false;

    // //xmlDoc.load("temp.xml");

    // refreshMap();

    // }

    function getCurrentRoot()

    {

    var pos = window.location.pathname.lastIndexOf("/");

    return window.location.protocol + "//" + window.location.host + window.location.pathname.substr(0, pos) + "/";

    }

    function VisibleLabels()

    {

    //DEBUG

    // alert("VisibleLabels()");

    //var markers = xmlDoc.selectNodes('markers/marker');

    var LabelView = map.GetMapView();

    // alert("lTOP LEFT" + LabelView.TopLeftLatLong);

    // alert("lBOTTOM RIGHT" + LabelView.BottomRightLatLong);

    //GET TOP LEFT LAT/LONG OF VIEWABLE AREA

    var lTopLeftLatLong = LabelView.TopLeftLatLong.toString();

    //GET TOP LEFT LATITUDE

    var lTopLeftLatSplit = lTopLeftLatLong.split(",")[0];

    //GET TOP RIGHT LONGITUDE

    var lTopLeftLongSplit = lTopLeftLatLong.split(",")[1];

    //GET BOTTOM RIGHT LAT/LONG OF VIEWABLE AREA

    var lBottomRightLatLong = LabelView.BottomRightLatLong.toString();

    //GET BOTTOM RIGHT LAT

    var lBottomRightLatSplit = lBottomRightLatLong.split(",")[0];

    //GET BOTTOM RIGHT LONG

    var lBottomRightLongSplit = lBottomRightLatLong.split(",")[1];

    //alert("Label " + BottomRightLongSplit);

    //CALL HANDLER TO GET THE LABELS WHICH SHOULD BE IN THE VISIBLE AREA

    doc = Sarissa.getDomDocument();

    doc.async = false;

    doc.load(getCurrentRoot() + "VisibleLabels.ashx TLat=" + lTopLeftLatSplit

    + "&TLong=" + lTopLeftLongSplit

    + "&BLat=" + lBottomRightLatSplit

    + "&BLong=" + lBottomRightLongSplit);

    var labels = doc.selectNodes("labels/label");

    // alert ("Labels Visible " + labels.length);

    LabelID = 0;

    for (var i = 0 ; i < labels.length; i++)

    {

    //DEBUG

    // alert("IN FOR LOOP");

    //GET DETAILS FOR FIRST LAVEL

    var Lat = labelsIdea.getAttribute('lat');

    var Long = labelsIdea.getAttribute('lng');

    var name = labelsIdea.getAttribute('name');

    var point = map.LatLongToPixel(new VELatLong(Lat, Long));

    var el = document.createElement("div");

    el.setAttribute('id',"VELabel" + LabelID);

    //alert("ADD LABEL ID VELabel " + LabelID);

    el.style.top = (point.y + 1) + "px";

    el.style.left = (point.x + 1) + "px";

    el.style.border = "1px solid gray";

    el.style.font = "9px arial";

    el.style.background = "Blue";

    el.style.color = "White";

    el.style.padding = "0px 2px 0px 2px";

    el.innerHTML = name;

    //alert("adding control");

    map.AddControl(el);

    LabelID++;

    }

    //alert("LabelID COunt" + LabelID);

    }

    function LastKnown()

    {

    alert("In LastKnown");

    //CALL HANDLER TO GET THE LAST KNOWN POSITION FOR SELECTED LINK

    doc = Sarissa.getDomDocument();

    doc.async = false;

    doc.load(getCurrentRoot () + "LastKnownPosition.ashx");

    var position = doc.selectNodes("position/lastloc");

    var Lat = position[0].getAttribute('lat');

    var Long = position[0].getAttribute('lng');

    alert("about to pan!");

    //CENTER MAP OVER LOCATION

    map.SetCenter(new VELatLong(Lat, Long));

    }

    function RemoveLabels()

    {

    //DEBUG

    // alert("In ZoomXml");

    // alert('The current zoom level of the map is: '+map.GetZoomLevel());

    for (var i = 0 ; i < LabelID; i++)

    {

    //alert("IN REMOVE FOR LOOP");

    var elRemove = document.getElementById("VELabel" + i);

    //alert("REMOVE VELabel" + i);

    elRemove.parentNode.removeChild(elRemove);

    }

    VisibleCompanies();

    VisibleLabels();

    }

    </script>

    </head>

    <body onload="GetMap();">

    <form id="form1" runat="server">

    <div><p id="pLat"></p>

    <p id="Comps"></p>

    <p id="Click"></p>

    </div>

    <div id='myMap' style="position: relative; :80%; height:80%;"></div>

    </form>

    </body>

    </html>



  • Nially

    I used to think it was intermintent but I cant say for sure. Once i determined something was wrong and really started looking for the causes (ie my code or the map control) i could tell it was happening everytime, even on initial page load with no forced panning. Now maybe the map control was panning underneath to get to my 'center point) but i didnt have time to debug it that far down.

    The solution i came up with above (manually calcing the bottom right) still seems to be working well enough for my purposes currently and i have not revisted using GetMapView() to get the bottom right lat/longs.



  • HSBF Lewe

    You have to be a little careful with this as the world is not flat and is distorted to appear on VE.

    Basically you'll find assuming the earth is flat ok for around 100km or it your case if your centred on the equator.

    May cause no problems unless you do lots of work in Greenland, just something to be aware of.

    Here is a nice graphic example showing lat and lon over the VE map:

    http://soulsolutions.com.au/MegaClusterEx1.htm

    (Zoom out a bit to get the grid to appear)

    John.



  • Umberto

    Nice to see a movie on the forums

    I noticed you have stuff appearing above the map. I would check that your map.gettop() is returning the correct value.

    try this instead:

    function SetMapOffsets(obj) {

    if (obj.offsetParent) {

    mapleft = obj.offsetLeft

    maptop = obj.offsetTop

    while (obj = obj.offsetParent) {

    mapleft += obj.offsetLeft

    maptop += obj.offsetTop

    }

    }

    }



  • GetMapView() TopLeftLatLong/BottomRightLatLong oddity