Mark Wiltshire
Mark Wiltshire

Reputation: 61

google maps API v3 - zoom after load How

I am trying to get google maps to load, then zoom into my marker, but I have something wrong with my javascript, as the scope of the map is not visible, despite it being defined globally.

Any ideas what I am doing wrong ?

Many thanks

Mark

<!DOCTYPE html>
<html>
  <head>
    <title>Geolocation</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <script src="js/jquery-1.10.1.min.js"></script>    
    <link href="css/default.css" rel="stylesheet">
    <!--
    Include the maps javascript with sensor=true because this code is using a
    sensor (a GPS locator) to determine the user's location.
    See: https://developers.google.com/apis/maps/documentation/javascript/basics#SpecifyingSensor
    -->
    <script src="https://maps.googleapis.com/maps/api/js?v=3.12&sensor=true"></script>

    <script>

//START Global Variables
var geocoder;
var map;
var marker;
var initialZoomLevel = 7;
var endZoomLevel = 16;
var zoomTimeInterval_ms = 1000;
var mapIcon = {
  url: "images/im_here.png",
   // This marker is 130 pixels wide by 120 pixels tall
  size: new google.maps.Size(130,120),
  //scale image so it works with retina displays
  scaledSize: new google.maps.Size(65,60),
  // The origin for this image is 0,0.
  origin: new google.maps.Point(0,0),  
  // The anchor point is be middle of the base
  anchor: new google.maps.Point(32.5,60)
};
var mapIcon_shadow = {
  url: "images/im_here_shadow.png",
   // This shadow is 191 pixels wide by 120 pixels tall
  size: new google.maps.Size(191,120),
  //scale image so it works with retina displays
  scaledSize: new google.maps.Size(95.5,60),
  // The origin for this image is 0,0.
  origin: new google.maps.Point(0,0),  
  // The anchor point is be middle of the base
  anchor: new google.maps.Point(32.5,60)
};
//Enable the visual refresh
google.maps.visualRefresh = true;
//END Global Variables

/** Initialise function to render the map */
function initialize() {
  geocoder = new google.maps.Geocoder();
  var mapOptions = {
    zoom: initialZoomLevel,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    mapTypeControl: false,
    panControl: false,
    streetViewControl: false,
    zoomControl: false
  };
  map = new google.maps.Map(document.getElementById('map-canvas'),
      mapOptions);

  // Try HTML5 geolocation
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      var pos = new google.maps.LatLng(position.coords.latitude,
                                       position.coords.longitude);

      // set home location
      home = new google.maps.LatLng(position.coords.latitude,
                                    position.coords.longitude);

      // the marker where you are
      marker = new google.maps.Marker({
        map: map,
        position: pos,
        icon: mapIcon,
        shadow: mapIcon_shadow,
        draggable: true
      });

      codeLatLng(pos);
      map.panTo(pos);

      google.maps.event.addListener(marker, 'dragend', function(a) {
        //alert('LatLng is '+a.latLng.lat()+ " "+ a.latLng.lng());
        codeLatLng(a.latLng);
      });

    }, function() {
      handleNoGeolocation(true);
    });
  } else {
    // Browser doesn't support Geolocation
    handleNoGeolocation(false);
  }

  // Create the DIV to hold the control and
  // call the HomeControl() constructor passing
  // in this DIV.
  //var homeControlDiv = document.createElement('div');
  //var homeControl = new HomeControl(homeControlDiv, map);

  //homeControlDiv.index = 1;
  //map.controls[google.maps.ControlPosition.TOP_CENTER].push(homeControlDiv);  

  smoothZoom(map, endZoomLevel, map.getZoom()); // call smoothZoom, parameters map, final zoomLevel, and starting zoom level  
}

function handleNoGeolocation(errorFlag) {
  if (errorFlag) {
    var content = 'Error: The Geolocation service failed.';
  } else {
    var content = 'Error: Your browser doesn\'t support geolocation.';
  }

  var options = {
    map: map,
    position: new google.maps.LatLng(60, 105),
    content: content
  };

  var infowindow = new google.maps.InfoWindow(options);
  map.setCenter(options.position);
}

function codeLatLng(markerLatLang) {
  //var latlng = new google.maps.LatLng(latLng.lat(), latLng.lng());
  geocoder.geocode({'latLng': markerLatLang}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      if (results[0]) {
        name = results[0].formatted_address;
        latlongStr = "LAT = ["+markerLatLang.lat()+"] LNG = ["+markerLatLang.lng()+"]";
        //alert("name = "+name);      
        $('#address').html(name);
        $('#latlong').html(latlongStr);
      } else {
        alert('No results found');
      }
    } else {
      alert('Geocoder failed due to: ' + status);
    }
  });
}

/**
 * The HomeControl adds a control to the map that simply
 * returns the user to home. This constructor takes
 * the control DIV as an argument.
 * @constructor
 */
 /** TODO need to rewite this as normal div, not on map **/
function HomeControl(controlDiv, map) {

  // Set CSS styles for the DIV containing the control
  // Setting padding to 5 px will offset the control
  // from the edge of the map
  controlDiv.style.padding = '5px';

  // Set CSS for the control border
  var controlUI = document.createElement('div');
  controlUI.style.backgroundColor = 'white';
  controlUI.style.borderStyle = 'solid';
  controlUI.style.borderWidth = '2px';
  controlUI.style.cursor = 'pointer';
  controlUI.style.textAlign = 'center';
  controlUI.title = 'Click to set the map to Start Location';
  controlDiv.appendChild(controlUI);

  // Set CSS for the control interior
  var controlText = document.createElement('div');
  controlText.style.fontFamily = 'Helvetica,sans-serif';
  controlText.style.fontSize = '16px';
  controlText.style.paddingLeft = '4px';
  controlText.style.paddingRight = '4px';
  controlText.style.zIndex = "100";
  controlText.innerHTML = '<b>Reset Map</b>';
  controlUI.appendChild(controlText);

  // Setup the click event listeners: simply set the map back to home
  google.maps.event.addDomListener(controlUI, 'click', function() {
    marker.setPosition(home);
    map.setCenter(home);
  });
}

// the smooth zoom function
function smoothZoom (map, max, cnt) {
    if (cnt >= max) {
            return;
        }
    else {
        z = google.maps.event.addListener(map, 'zoom_changed', function(event){
            google.maps.event.removeListener(z);
            self.smoothZoom(map, max, cnt + 1);
        });
        setTimeout(function(){map.setZoom(cnt)}, zoomTimeInterval_ms);
    }
}  

google.maps.event.addDomListener(window, 'load', initialize);

    </script>
  </head>
  <body>
    <div id="panel">        
        <div id="latlong">No latlong Yet</div>
        <div id="address">No Address Yet</div>
    </div>
    <div id="map-canvas"></div>
  </body>
</html>

Upvotes: 1

Views: 3594

Answers (1)

geocodezip
geocodezip

Reputation: 161404

The fact that your map is defined globally isn't relevant if you don't wait until it is initialized before using it. It is initialized by the initialize function which runs on the body onload event. You use it inline before that happens. This works for me:

function initialize() {
  geocoder = new google.maps.Geocoder();
  var mapOptions = {
    zoom: initialZoomLevel,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    mapTypeControl: false,
    panControl: false,
    streetViewControl: false,
    zoomControl: false
  };
  map = new google.maps.Map(document.getElementById('map-canvas'),
      mapOptions);

  google.maps.event.addListenerOnce(map,"zoom_changed", function() {
     smoothZoom(map, endZoomLevel, map.getZoom()); // call smoothZoom, parameters map, final zoomLevel, and starting zoom level
  });   

working example

seems the zoom_changed event doesn't fire when the map initializes, using the "idle" event seems to work: working example with zoom on idle

Upvotes: 1

Related Questions