0

apologies if this has been answered already - I've looked for a few hours on StackOverflow and elsewhere, and can't figure it out.

I'm trying the Google Maps V3 geolocation function (Google Maps Javascript API V3 - Detecting the User's Location), and wanted to add a simple centre marker (amongst other things) after the map has been centered.

If I add the following at the end of the "initialize" function, it doesn't seem to have access to the "initialLocation" variable:

          var marker = new google.maps.Marker({
            position: initialLocation, 
            map: map
          });

However, if I alert the initialLocation just before that, it works.

Here is the full code, almost identical to Google's example:

    var initialLocation;
    var siberia = new google.maps.LatLng(60, 105);
    var newyork = new google.maps.LatLng(40.69847032728747, -73.9514422416687);
    var browserSupportFlag =  new Boolean();
    var map;
    var infowindow = new google.maps.InfoWindow();

    function initialize() {
      var myOptions = {
        zoom: 6,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      };
      map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

      // Try W3C Geolocation method (Preferred)
      if(navigator.geolocation) {
        browserSupportFlag = true;
        navigator.geolocation.getCurrentPosition(function(position) {
          initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
          contentString = "Location found using W3C standard";
          map.setCenter(initialLocation);
          infowindow.setContent(contentString);
          infowindow.setPosition(initialLocation);
          infowindow.open(map);
        }, function() {
          handleNoGeolocation(browserSupportFlag);
        });
      } else if (google.gears) {
        // Try Google Gears Geolocation
        browserSupportFlag = true;
        var geo = google.gears.factory.create('beta.geolocation');
        geo.getCurrentPosition(function(position) {
          initialLocation = new google.maps.LatLng(position.latitude,position.longitude);
          contentString = "Location found using Google Gears";
          map.setCenter(initialLocation);
          infowindow.setContent(contentString);
          infowindow.setPosition(initialLocation);
          infowindow.open(map);
        }, function() {
          handleNoGeolocation(browserSupportFlag);
        });
      } else {
        // Browser doesn't support Geolocation
        browserSupportFlag = false;
        handleNoGeolocation(browserSupportFlag);
      }

      //alert(initialLocation);

      var marker = new google.maps.Marker({
            position: initialLocation, 
            map: map
      });
    }

    function handleNoGeolocation(errorFlag) {
      if (errorFlag == true) {
        initialLocation = newyork;
        contentString = "Error: The Geolocation service failed.";
      } else {
        initialLocation = siberia;
        contentString = "Error: Your browser doesn't support geolocation. Are you in Siberia?";
      }
      map.setCenter(initialLocation);
      infowindow.setContent(contentString);
      infowindow.setPosition(initialLocation);
      infowindow.open(map);
    }

The above will not add a marker, but if you uncomment the line "alert(initialLocation);", it will then work.

Why is this? I suspect it's a question of scope, but I'm not sure.

(It's important to my app that the initialLocation variable is accessible outside of the "if(navigator.geolocation) {" block)

Thanks!

Galen
  • 29,976
  • 9
  • 71
  • 89
pinksy
  • 301
  • 4
  • 14

2 Answers2

1

The call, getCurrentPosition(), is asynchronous meaning that the function() you provide as a parameter in the call will run once the location is determined. So initialLocation will not be set immediately, it will be set once those callback functions are called.

What you need to do is move the

var marker = new google.maps.Marker({
            position: initialLocation, 
            map: map
      });

inside that function like this.

navigator.geolocation.getCurrentPosition(function(position) {
          initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
          contentString = "Location found using W3C standard";
          map.setCenter(initialLocation);
          infowindow.setContent(contentString);
          infowindow.setPosition(initialLocation);
          infowindow.open(map);
          var marker = new google.maps.Marker({
            position: initialLocation, 
            map: map
          });
        }, function() {
          handleNoGeolocation(browserSupportFlag);
        });

As you can see in the example, they don't do anything with initialLocation outside of those callback functions.

Robby Pond
  • 73,164
  • 16
  • 126
  • 119
  • Thanks Robby, I should have spotted that at https://developer.mozilla.org/en/using_geolocation#Getting_the_current_position It's so accurate compared to geolocation by IP address, but I'm finding it so flakey, and it looks like others do too: http://stackoverflow.com/questions/3397585/navigator-geolocation-getcurrentposition-sometimes-works-sometimes-doesnt – pinksy Mar 19 '11 at 19:31
1

The issue is that the code isn't waiting until it has the location when it tries to add your marker.

add the marker code right after initialLocation is set and it will work.

Galen
  • 29,976
  • 9
  • 71
  • 89
  • Thanks Galen... As a side issue, if you've had any success in getting geolocation to behave reliably, I'd love to know how! It seems quite erratic - Chrome is reasonably reliable, FF3.6 sometimes works and sometimes doesn't, IE8 barely ever works. I'm getting the same experience as most of the people posting on [this thread](http://stackoverflow.com/questions/3397585/navigator-geolocation-getcurrentposition-sometimes-works-sometimes-doesnt). Shame! – pinksy Mar 19 '11 at 19:38
  • ive had the same issues, chrome/safari work well, ff sometimes. – Galen Mar 19 '11 at 20:37
  • Have you found a way around it? – pinksy Mar 20 '11 at 20:39
  • no, we just have to wait until the browsers support geolocation better – Galen Mar 20 '11 at 21:46