Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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! :)

like image 988
Joseph Duffy Avatar asked Jan 16 '23 18:01

Joseph Duffy


2 Answers

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.

like image 50
benastan Avatar answered Jan 22 '23 15:01

benastan


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.

like image 36
Sean Mickey Avatar answered Jan 22 '23 15:01

Sean Mickey