Joseph Duffy
Joseph Duffy

Reputation: 4836

Google Maps API (v3) adding/updating markers

EDIT: It now works, but does not load if the user does not allow or have location-based services. See accepted answer comment for jsfiddle example.

I've looked through a few tutorials and questions but I can't quiet understand what's happening (or in this case, not happening). I'm loading my map when the user clicks a link. This loads the map with the users current location in the center, and a marker at the users location. However, any markers outside of the if (navigation.location) don't seem to load. Below is my current code:

function initialize() {
        // Check if user support geo-location
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(position) {
                var point = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                var userLat = position.coords.latitude;
                var userLong = position.coords.longitude;
                var mapOptions = {
                    zoom: 8,
                    center: point,
                    mapTypeId: google.maps.MapTypeId.HYBRID
                }

            // Initialize the Google Maps API v3
            var map = new google.maps.Map(document.getElementById("map"), mapOptions);

            // Place a marker
            new google.maps.Marker({
                position: point,
                map: map,
                title: 'Your GPS Location'
            });
        });
    } else {
        var userLat = 53;
        var userLong = 0;
        var mapOptions = {
            zoom: 8,
            center: new google.maps.LatLng(userLat, userLong),
            mapTypeId: google.maps.MapTypeId.HYBRID
        }
        // Place a marker
        new google.maps.Marker({
            position: point,
            map: map,
            title: 'Default Location'
        });
        // Initialize the Google Maps API v3
        var map = new google.maps.Map(document.getElementById("map"), mapOptions);
    }
    <?
    for ($i = 0; $i < sizeof($userLocations); $i++) {
        ?>
        var userLatLong = new google.maps.LatLng(<? echo $userLocations[$i]['lat']; ?>, <? echo $userLocations[$i]['long']; ?>);
        new google.maps.Marker({
            position: userLatLong,
            map: map,
            title:"<? echo $userLocations[$i]['displayName'] . ', ' . $userLocations[$i]['usertype']; ?>"
        });
        <?
    }
    ?>
}

function loadMapScript() {
    if (typeof(loaded) == "undefined") {
        $("#showMap").css("display", "none");
        $("#showMapLink").removeAttr("href");
        $("#map").css("height", "600px");
        $("#map").css("width", "600px");
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = "http://maps.googleapis.com/maps/api/js?key=MY_API_KEY&sensor=true&callback=initialize";
        document.body.appendChild(script);
        loaded = true;
    } else {
        alert("Map already loaded!");
    }
}

loadMapScript() is called when the user clicks a link. The php for loop loops through a pre-created array with all the information.
I'm guessing I don't fully understand it, as when if I put:

var userLatLong = new google.maps.LatLng(53, 0);
            new google.maps.Marker({
                position: userLatLong,
                map: map,
                title:"Title"
            });

into the console (Google Chrome), I get the error:

Error: Invalid value for property <map>: [object HTMLDivElement]

I don't, however, get any errors otherwise. Any help would be much appreciated! :)

Upvotes: 4

Views: 17072

Answers (4)

Sean Mickey
Sean Mickey

Reputation: 7726

Have you tried:

var map = null;
function initialize() { ... }

and then changing the code inside:

map = new google.maps.Map( ... ); //make this the first line
if (navigator.geolocation) {
    // Change the code from:
    var map ...
    // to:
    map ...

You just reference the map directly (without the var) everywhere else, so that should work.

Upvotes: 1

benastan
benastan

Reputation: 2278

navigator.geolocation.getCurrentPosition() is asynchronous.

Reorganize your code like this:

var mapOptions = {
    zoom: 8,
    mapTypeId: google.maps.MapTypeId.HYBRID
}

function initialize() {
    // Check if user support geo-location
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
            makeMap(position.coords.latitude, position.coords.longitude, 'Your GPS Location');
        });
    } else {
        makeMap(53, 0, 'DefaultLocation');
    }
}

function makeMap(lat, lng, text) {
    var point = new google.maps.LatLng(lat, lng);
    mapOptions.center = point;
    map = new google.maps.Map(document.getElementById("map"), mapOptions);
    new google.maps.Marker({
        position: point,
        map: map,
        title: text
    });
    <?php for ($i = 0; $i < sizeof($userLocations); $i++): ?>
    var userLatLong = new google.maps.LatLng(<? echo $userLocations[$i]['lat']; ?>, <? echo $userLocations[$i]['long']; ?>);
    new google.maps.Marker({
        position: userLatLong,
        map: map,
        title:"<? echo $userLocations[$i]['displayName'] . ', ' . $userLocations[$i]['usertype']; ?>"
    });
    <?php endforeach ?>
}

Also, consider bootstraping the $userLocations into a JavaScript variable like this:

var userLocations = <?php print json_encode($userLocations) ?>;

Then execute your for loop in JavaScript, instead of mixing languages.

Upvotes: 8

chris
chris

Reputation: 37480

It looks like you're creating the marker, but not doing anything with it. Try changing your new Marker to look like this:

var marker = new google.maps.Marker({
               position: point,  // this won't actually work - point is out of scope
               title: 'Your GPS Location'
           });

marker.setMap(map);

Edit: Make sure the point is inside the map!

var bounds = new google.maps.LatLngBounds();
bounds.extend(point);
map.fitBounds(bounds);

Upvotes: 0

benastan
benastan

Reputation: 2278

Change:

 var map = new google.maps.Map(document.getElementById("map"), mapOptions);

To:

map = new google.maps.Map(document.getElementById("map"), mapOptions);

Because of var, your map variable is tied the the scope of initialize(). Removing it will set it as the global map variable (or window.map), making it available outside of the initialize() function.

What's happening is you have an HTML element <div id="map">. In many browsers, global variables are created from html element ids, so map equals document.getElementById('map').


Edit: Actually, this only explains your problem in the Chrome console. You need to set map before trying to attach markers to it, as you do within if (navigator.geolocation) {}. This also explains why none of the user location markers are being placed. The code to place them runs before initialize(). Put this code either within initialize or within its own function, and call that function from initialize.

Upvotes: 0

Related Questions