views:

1072

answers:

3

I'm not used to writing JS, honestly, and to make matters worse I'm working with the Google Maps API which, while well-documented, is a bear. So, I've written a function that allows a users to zoom onto the map from a link. But the interpreter insists my function isn't defined when I call it. The function is "zoomTo" and it appears in the following monster script.

function load() {
    if (GBrowserIsCompatible()) {
     var gmarkers = [];
     var htmls = [];
     var i = 0;
     // Read the data
     //++++++++++++++++
        GDownloadUrl("/assets/data/nolag.xml", function(data) {
       var xml = GXml.parse(data);
       var markers = 

        xml.documentElement.getElementsByTagName("marker");

  // Draw icons
  for (var i = 0; i < markers.length; i++) {
   var locoName = markers[i].getAttribute("locoName");
   var speed = markers[i].getAttribute("speed");
   var ip = markers[i].getAttribute("ip");
   var date = markers[i].getAttribute("captureTime");
   var lat = markers[i].getAttribute("lat");
   var lng = markers[i].getAttribute("lng");
   var location = markers[i].getAttribute("location");
   var heading = markers[i].getAttribute("heading");
   var type = markers[i].getAttribute("type");
   var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                          parseFloat(markers[i].getAttribute("lng")));
   var marker = createMarker(point, locoName, speed, ip, date, lat, lng, location, heading, type);
   map.addOverlay(marker);
   }
  });


  // create the map
  var map = new GMap2(document.getElementById("map"));
  map.addControl(new GLargeMapControl3D());
  map.addControl(new GMapTypeControl());
  map.setCenter(new GLatLng(40.5500, -72.1700), 7);
  map.enableScrollWheelZoom(); 
  NEC = new GPolyline(NECRoute, "#0d004c", 3, 0.7);
  map.addOverlay(NEC);

 // A function to create the marker and set up the event window
 //+++++++++++++++++

 function createMarker(point, locoName, speed, ip, date, lat, lng, location, heading, type) {
   var marker = new GMarker(point, customIcons[type]);
   marker.tooltip = '<div class="tooltip"><h1>' + locoName + '</h1><h2>' + speed + '<br/>' + location + '</h2></div>';
   marker.contextmenu = '<div class="contextmenu">Hello world</div>';
   var satellite = "<img src=\"./images/icons/satellite.gif\">";
   var gps = "<img src=\"./images/icons/gps.gif\">";
   var cmu = "<img src=\"./images/icons/cmu.gif\">";
   var ftp = "<img src=\"./images/icons/ftp.gif\">";
   var me1k = "<img src=\"./images/icons/me1k.gif\">";
   var html = "<div class=\"bubble\">";
    html += "<h3>" + locoName + "<span class=\"small-data\"> Route 2150</span></h3>";;
    html += "<div class=\"toolbar\">" + gps + satellite + cmu + ftp + me1k + "</div>";
    html += "<h4>Heading " + heading + " @ " + speed + " MPH</h4>"
    html += "<h4>Lat: " + lat + "</h4><h4> Lng: " + lng + "</h4>";
    html += "<h4>IP: " + ip + "</h4>";
    html += "<h4><div class=\"sm-button\"><a style='color: #FFFFFF; decoration:none;' href='map_detail.php'>Details</a></div><div class=\"sm-button\">Zoom To</div></h4>";
    html += "</div>";
  GEvent.addListener(marker, "click", function() {
   marker.openInfoWindowHtml(html);
  });
  gmarkers[i] = marker;
  htmls[i] = html;
  i++;

  //  ======  The new marker "mouseover" and "mouseout" listeners  ======
  GEvent.addListener(marker,"mouseover", function() {
   showTooltip(marker);
  });        
  GEvent.addListener(marker,"mouseout", function() {
   tooltip.style.visibility="hidden"
  }); 
  return marker;
  } 

  // ====== This function displays the tooltip ======
  //+++++++++++++++++++++++++++++++++++++++++++++++++++
  function showTooltip(marker) {
        tooltip.innerHTML = marker.tooltip;
   var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.getBounds().getSouthWest(),map.getZoom());
   var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),map.getZoom());
   var anchor=marker.getIcon().iconAnchor;
   var width=marker.getIcon().iconSize.width;
   var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(offset.x - point.x - anchor.x + width,- offset.y + point.y +anchor.y)); 
   pos.apply(tooltip);
   tooltip.style.visibility="visible";
  }


  // ===== This function is invoked when the mouse goes over an entry in the side_bar =====
  function mymouseover(i) {
   showTooltip(gmarkers[i])
  }
  // ===== This function is invoked when the mouse leaves an entry in the side_bar =====
  function mymouseout() {
   tooltip.style.visibility="hidden";
  }

  // This function picks up the side_bar click and opens the corresponding info window
  function myclick(i) {
   gmarkers[i].openInfoWindowHtml(htmls[i]);
  }




  // ====== set up marker mouseover tooltip div ======
  var tooltip = document.createElement("div");
  document.getElementById("map").appendChild(tooltip);
  tooltip.style.visibility="hidden";


  // === create the context menu div ===
  var contextmenu = document.createElement("div");
  contextmenu.style.visibility="hidden";


  // === functions that perform the context menu options ===
  function zoomTo( lat, lng, level) {
   // perform the requested operation
   map.setCenter( new GLatLng(lat,lng), level);
   // hide the context menu now that it has been used
   contextmenu.style.visibility="hidden";
  }


  contextmenu.innerHTML = '<div class="context"><ul>'
  + '<li class="sectionheading"><a href="javascript:map.setCenter(new GLatLng(40.5500, -72.1700), 7)">Zoom Out</a></li>'
  + '<li class="sectionheading"><a href="javascript:zoomTo(42.343193, -71.049442, 14)">Boston Area</a></li>'
  + '<li><a href="javascript:zoomTo(42.351662,-71.054978,17)">South Station, Boston</a></li>'
  + '<li><a href="javascript:zoomTo(42.333161,-71.060096,17)">South Hampton</a></li>'
  + '<li><a href="javascript:zoomTo(41.293422,-72.928587,17)">New Haven</a></li>'
  + '<li class="sectionheading"><a href="javascript:zoomTo(40.745696, -74.019699, 12)">New York Area</a></li>'
  + '<li><a href="javascript:zoomTo(40.749061,-73.930553,17)">Sunny Side</a></li>'
  + '<li><a href="javascript:zoomTo(40.752556,-73.998113,17)">NY, Penn Station</a></li>'
  + '<li><a href="javascript:zoomTo(39.957517,-75.181376,17)">30th Street, Philadelphia</a></li>'
  + '<li><a href="javascript:zoomTo(39.746481,-75.522090,17)">Wilmington Shops</a></li>'
  + '<li><a href="javascript:zoomTo(39.307817,-76.615412,17)">Baltimore, Penn Station</a></li>'
  + '<li class="sectionheading"><a href="javascript:zoomTo(38.912675, -76.992874, 14)">DC Area</a></li>'
  + '<li><a href="javascript:zoomTo(38.916531,-76.987703,17)">DC, Ivy City</a></li>'
  + '<li><a href="javascript:zoomTo(38.900210,-77.005266,17)">DC, Union Station</a></li>'
  + '</ul</div>'; 

  map.getContainer().appendChild(contextmenu);


  // === listen for singlerightclick ===
  GEvent.addListener(map,"singlerightclick",function(pixel,tile) {
   clickedPixel = pixel;
   var x=pixel.x;
   var y=pixel.y;
   if (x > map.getSize().width - 120) { x = map.getSize().width - 120 }
   if (y > map.getSize().height - 100) { y = map.getSize().height - 100 }
   var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(x,y));
   pos.apply(contextmenu);
   contextmenu.style.visibility = "visible";
  });
  // === If the user clicks on the map, close the context menu ===
  GEvent.addListener(map, "click", function() {
   contextmenu.style.visibility="hidden";
  });
 } else {
      alert("Sorry, the Google Maps API is not compatible with this browser");
    }
}
+7  A: 

It appears that zoomTo is an annonymous function inside of the top-level function load() - therefore, it's not available to top-level calls.

Instead of

// === functions that perform the context menu options ===
                function zoomTo( lat, lng, level) {
                        // perform the requested operation
                        map.setCenter( new GLatLng(lat,lng), level);
                        // hide the context menu now that it has been used
                        contextmenu.style.visibility="hidden";
                }

put the function in the top level, and pass in the map and contextmenu variables:

// === functions that perform the context menu options ===
function zoomTo( lat, lng, level) {
// perform the requested operation
                        map.setCenter( new GLatLng(lat,lng), level);
                        // hide the context menu now that it has been used
                        contextmenu.style.visibility="hidden";
                }
Dave Martorana
ie put it like this<html><head><script type="text/javascript">function zoomTo(x,y,z) {....}</script>
Ratnesh Maurya
That was a very good idea. However, I tried and got no love. This time, it isn't that zoomTo is undefined, but that map is undefined. I'm going to bed now, as I cannot look at it any more. More replies are greatly appreciated. Cheers!
littlerobothead
Without completely rewriting your JS ;) Put the map variable at the top level as well. So you havevar map = null;and when you initialize your map variable, just don't put var in front of it since it's, well, i guess a "global" variable already.map = new GMap2(document.getElementById("map"));
Dave Martorana
A: 

As it dont looks well in comment. posting the comment above here again

<html> 
  <head> 
    <script type="text/javascript"> 
      function zoomTo(x,y,z) { 
        .... 
      } 
    </script> 
  .....
  </head>
  ......
 </html>
Ratnesh Maurya
A: 

please, where is it implemented? Thangs

Eksn