How to add Markers on Google maps v3 API asynchronously? - javascript

I've been following the official documentation on how to add markers on the map so far
Nevertheless, I can see only one marker at a time max. If I try to add another one, then it doesn't work (I can't even see the first one).
My process is the following:
I initialize gmaps api:
jQuery(window).ready(function(){
//If we click on Find me Lakes
jQuery("#btnInit").click(initiate_geolocation);
});
function initiate_geolocation() {
if (navigator.geolocation)
{
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyBbfJJVh0jL1X9b7XFDcPuV7nHD1HlfsKs&sensor=true&callback=initialize";
document.body.appendChild(script);
navigator.geolocation.getCurrentPosition(handle_geolocation_query, handle_errors);
}
else
{
yqlgeo.get('visitor', normalize_yql_response);
}
}
Then, I display it on the appropriate div. But when it comes to make the AJAX call, in order to get my locations of the different markers I'd like to display, It just doesn't work properly. Here is the code with a simple map displayed (since that's the only thing working for me so far).
function handle_geolocation_query(position){
var mapOptions = {
zoom: 14,
center: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
mapTypeId: google.maps.MapTypeId.SATELLITE
}
alert('Lat: ' + position.coords.latitude + ' ' +
'Lon: ' + position.coords.longitude);
$('#map-canvas').slideToggle('slow', function(){
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
});
$.when( getLakes(position.coords.latitude, position.coords.longitude)).done(function(results) {
// InitializeGoogleMaps(results);
if(results)
var data = results.map(function (lake) {
//Check if the lake has any open swims, if not, the button will not be clickable and an alert will pop up
if (lake.available>0)
clickable=true;
else
clickable=false;
return {
name: lake.name,
fishs: lake.fisheryType,
swims: lake.swims,
dist: lake.distance,
lat: lake.latitude,
long: lake.longitude,
id: lake.id,
avail: lake.available,
clickable: clickable,
route: Routing.generate('lake_display', { id: lake.id, lat: position.coords.latitude, lng: position.coords.longitude})
}
});
var template = Handlebars.compile( $('#template').html() );
$('#list').append( template(data) );
} );
};
So I'd like to add markers after the AJAX call. I've set up a function that I should call in the when()
function InitializeGoogleMaps(results) {
};
to display the markers in a foreach loop but nope, can't make it work. It looks like this :
CentralPark = new google.maps.LatLng(37.7699298, -122.4469157);
marker = new google.maps.Marker({
position: location,
map: map
});
Any help would be great !
Thanks

The main issue is that the map variable is declared only in the scope of the anonymous callback on slideToggle. First of all declare at the top-level function scope.
function handle_geolocation_query(position){
var map,
mapOptions = {
zoom: 14,
center: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
mapTypeId: google.maps.MapTypeId.SATELLITE
}
...
Then change the slideToggle callback to initialise the variable instead of redeclaring:
$('#map-canvas').slideToggle('slow', function(){
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
});
Then you should pass map as a second parameter to your InitializeGoogleMaps function and call it using InitializeGoogleMaps(results, map). See where this gets you and hit me back with any questions.

Related

google map api, link to URL

Sorry for asking a simple question I surely can find easily by reading the API docs, but a client just asked me this in general, and I would like to answer him asap.
Situation:
I have a custom map created, with public (or restricted to user) access, where are different markers.
Q1)Is it possible to create markers via the API using e.g. custom data from our database?
Q2)Ist it possible to add a URL to a marker, so that a user clicks on it and gets to a specific site, where he can e.g. vote for this location? (just as an example)
Thanks in advance to everyone, and once more sorry not to look closer by myself
Cheers,
Phil
Following Function Will Create Marker
<script type="text/javascript">
// Standard google maps function
function initialize() {
var myLatlng = new google.maps.LatLng(40.779502, -73.967857);
var myOptions = {
zoom: 12,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
TestMarker();
}
// Function for adding a marker to the page.
function addMarker(location) {
marker = new google.maps.Marker({
position: location,
map: map
});
}
// Testing the addMarker function
function TestMarker() {
CentralPark = new google.maps.LatLng(37.7699298, -122.4469157);
addMarker(CentralPark);
}
For Clicking and URL Use Following Technique
var points = [
['name1', 59.9362384705039, 30.19232525792222, 12, 'www.google.com'],
['name2', 59.941412822085645, 30.263564729357767, 11, 'www.amazon.com'],
['name3', 59.939177197629455, 30.273554411974955, 10, 'www.stackoverflow.com']
];
var marker = new google.maps.Marker({
...
zIndex: place[3],
url: place[4]
});
google.maps.event.addListener(marker, 'click', function() {
window.location.href = this.url;
});

Set marker on Google Map when changing a checkbox

I need some help regarding the Google Maps API. I was able to initialize the map. Now I want to add some markers to it.
I have a set of checkboxes (they are called "networks"). Each checkbox has a hidden longitude and latitude field. If the checkbox is checked, a marker should be displayed on the map
I managed to do this with the detour, of clicking on the map. But I want to trigger the creation of new markers on change of the checkbox.
Here is how it works, when I click on the map the markers appear:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: {lat: 48.7791, lng: 9.0367}
});
google.maps.event.addListener(map, "click", function(event) {
//Get all checked Networks
var checked_network = $( ".checkbox-network:checked" );
checked_network.each(function(){
network_id = $( this ).data("network-id");
//Get the hidden location longitudes and latitudes for each checked network element
network_locations_latitude = $(".location_latitude_network_"+network_id).val();
network_locations_longitude = $(".location_longitude_network_"+network_id).val();
var marker = new google.maps.Marker({
position: new google.maps.LatLng(network_locations_latitude,network_locations_longitude),
map: map
});
});
});
}
Here is how I try to get it to work, with clicking on the checkboxes. Unfortunately nothing happens. The marker object shows up in the JavaScript console, but on the map no markers appear.
$(document).on('change','.checkbox-network', function() {
var checked_network = $( ".checkbox-network:checked" );
checked_network.each(function(){
network_id = $( this ).data("network-id");
//Get the hidden location longitudes and latitudes for each checked network element
network_locations_latitude = $(".location_latitude_network_"+network_id).val();
network_locations_longitude = $(".location_longitude_network_"+network_id).val();
console.log(network_id + " - " + network_locations_latitude);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(network_locations_latitude,network_locations_longitude),
map: map,
title: "test"
});
console.log(marker);
});
});
What am I missing? How can I show the markers in the google-map with the onchangeevent of the checkboxes?
You have to initialize map variable globally. Currently scope of map variable only available inside initMap() function.
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: {lat: 48.7791, lng: 9.0367}
});
$(document).on('change','.checkbox-network', function() {
var checked_network = $( ".checkbox-network:checked" );
checked_network.each(function(){
network_id = $( this ).data("network-id");
//Get the hidden location longitudes and latitudes for each checked network element
network_locations_latitude = $(".location_latitude_network_"+network_id).val();
network_locations_longitude = $(".location_longitude_network_"+network_id).val();
console.log(network_id + " - " + network_locations_latitude);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(network_locations_latitude,network_locations_longitude),
map: map,
title: "test"
});
console.log(marker);
});
});
In the second snippet of your code, the map isn't defined because it's been defined in the scope of initMap(). I wonder why Google doesn't throw any errors.
change your initMap like below; move the map object to the global scope to be accessible from all scope (I always use this for my own projects)
initMap() {
window.map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: {lat: 48.7791, lng: 9.0367}
});
}
Here you should be more logical with the name map, so replace it with another name to avoid further conflicts.

Doing a Google Maps reverse geocode and displaying the result as part as HTML content inside an infowindow

I have put together this script (note: I'm using jQuery 1.11.2) that gets lat long coordinates from a PHP operation (used for something else) and displays a map with a customized marker and infowindow that includes HTML for formatting the information that is displayed.
<script src="https://maps.googleapis.com/maps/api/js?v=3.20&sensor=false"></script>
<script type="text/javascript">
var maplat = 41.36058;
var maplong = 2.19234;
function initialize() {
// Create a Google coordinate object for where to center the map
var latlng = new google.maps.LatLng( maplat, maplong ); // Coordinates
var mapOptions = {
center: latlng,
zoom: 3,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false,
streetViewControl: false,
zoomControl: false,
mapTypeControl: false,
disableDoubleClickZoom: true
};
map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions);
// CREATE AN INFOWINDOW FOR THE MARKER
var content = 'This will show up inside the infowindow and it is here where I would like to show the converted lat/long coordinates into the actual, human-readable City/State/Country'
; // HTML text to display in the InfoWindow
var infowindow = new google.maps.InfoWindow({
content: content,maxWidth: 250
});
var marker = new google.maps.Marker( {
position: latlng,
map: map,
title: "A SHORT BUT BORING TITLE",
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
infowindow.open(map,marker);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
What I'm trying to achieve is to do a reverse geocode on the coordinates stored in the latlng variable and get back the results of that in a "City, State, Country" format and insert that into the HTML for the informarker stored in the "content" variable.
Have tried multiple approaches without success. Please note that I've deliberately left out the reverse geocoding script I tried to use for clarity purposes.
Edit: I've adjusted the script presented here to comply with the rules about it being clear, readable and that it actually should work. I also include a link to a CodePen so that you can see it in action: Script on CodePen
Regarding including the script for reverse geocoding, what I did was a disaster, only breaking the page and producing "undefined value" errors. I'd like to learn the correct way of doing this by example, and that's where the wonderful StackOverflow community comes in. Thanks again for your interest in helping me out.
Use a node instead of a string as content , then you may place the geocoding-result inside the content, no matter if the infoWindow is already visible or not or when the result is available(it doesn't even matter if the InfoWindow has already been initialized, a node is always "live").
Simple Demo:
function initialize() {
var geocoder = new google.maps.Geocoder(),
latlng = new google.maps.LatLng(52.5498783, 13.42520);
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 18,
center: latlng
}),
marker = new google.maps.Marker({
map: map,
position: latlng
}),
content = document.createElement('div'),
infoWin = new google.maps.InfoWindow({
content: content
});
content.innerHTML = '<address>the address should appear here</address>';
google.maps.event.addListener(marker, 'click', function() {
infoWin.open(map, this);
});
geocoder.geocode({
location: latlng
}, function(r, s) {
if (s === google.maps.GeocoderStatus.OK) {
content.getElementsByTagName('address')[0].textContent = r[0].formatted_address;
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<div id="map-canvas"></div>
Here's how I would do it:
function reverseGeocoder(lat, lng, callback) {
var geocoder = new google.maps.Geocoder();
var point = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
geocoder.geocode({"latLng" : point }, function(data, status) {
if (status == google.maps.GeocoderStatus.OK && data[0]) {
callback(null, data[0].formatted_address);
} else {
console.log("Error: " + status);
callback(status, null);
}
});
};
And basically you would call the function like:
reverseGeocoder(lat, lng, function(err, result){
// Do whatever has to be done with result!
// EDIT: For example you can pass the result to your initialize() function like so:
initialize(result); // And then inside your initialize function process the result!
});

Update markers with current position on Google Map API

I am learning to use javascript right now with Rails and I'm having some issues with updating my markers according to my current position using AJAX. I believe the ready page:load is not running the updated coords that have been attached as a data-attribute, coords since the page is not technically reloading. How can I use my current position data and update it with events with longitude/latitude values?
var map;
$(document).on('ready page:load', function() {
if ("geolocation" in navigator) {
myMap.init();
var coords = $('#map-canvas').data('coords');
if (coords){
myMap.addMarkers(coords);
}
}
});
myMap.init = function() {
if(navigator.geolocation){
var mapOptions = {
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
navigator.geolocation.getCurrentPosition(function(position){
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var infoWindow = new google.maps.InfoWindow({
map: map,
position: pos
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
map: map
});
map.setCenter(pos);
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
$.ajax({
url:"/all_events",
method: "GET",
data: {
latitude: latitude,
longitude: longitude
},
dataType: 'script'
});
});
} else {
document.getElementById('map-canvas').innerHTML = 'No Geolocation Support.';
}
};
myMap.addMarkers = function(coords){
var image = "http://maps.google.com/mapfiles/ms/icons/yellow-dot.png"
coords.forEach(function(coord){
var myMarker = new google.maps.Marker({
position: new google.maps.LatLng(coord.latitude, coord.longitude),
map: map,
icon: image
});
});
}
In order to make your script work in the way you want please try out the following steps:
Put your foreach loop in a function and call it at the end of your successive AJAX callbacks.
Load the AJAX once the Google Maps have finished loading completely. If Google Maps library has not finished loading than you wont be able to create a Google LatLng object, this is what is probably happening over here.
Hope this would help

Google Maps don't fully load

I have a somewhat strange problem. I have two maps on my site, a big one and a small one. I want to use the big one to show a route to a certain address. I'm now trying to implement the two maps but get a weird problem. The small map is working fine, but on the big map only a small area of the div is filled with the map, the rest is empty. (See the image.)
I use the following code to display the two maps:
function initialize() {
var latlng = new google.maps.LatLng(51.92475, 4.38206);
var myOptions = {zoom: 10, center: latlng,mapTypeId: google.maps.MapTypeId.ROADMAP};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var marker = new google.maps.Marker({position: latlng, map:map, title:"Home"});
var image = '/Core/Images/Icons/citysquare.png';
var myLatLng = new google.maps.LatLng(51.92308, 4.47058);
var cityCentre = new google.maps.Marker({position:myLatLng, map:map, icon:image, title:"Centre"});
marker.setMap(map);
var largeLatlng = new google.maps.LatLng(51.92475, 4.38206);
var largeOptions = {zoom: 10, center: largeLatlng,mapTypeId: google.maps.MapTypeId.ROADMAP};
var largeMap = new google.maps.Map(document.getElementById("largeMap"), largeOptions);
var largeMarker = new google.maps.Marker({position: largeLatlng, map:largeMap, title:"Cherrytrees"});
largeMarker.setMap(largeMap);
}
[..]
jQuery(document).ready(function () {
[..]
initialize();
});
What's going wrong here?
EDIT:
Unfortunately the suggestions below doesn't seem to work. The closes i came is to remove the display:none from the elements and set the elements to hide with jquery
[..]
jQuery(document).ready(function () {
[..]
$("#shadow").add($("#shadowContent"),$("#closebar"),$("#content")).hide();
});
With the following result
Yes, #Argiropoulos-Stavros but, Add it as a listener
google.maps.event.addListenerOnce(map, 'idle', function(){
google.maps.event.trigger(map, 'resize');
map.setCenter(location);
});
It will begin re-sizing after, map rendered.
I think you are using v3.
So google.maps.event.trigger(map, "resize");
Also take a look at here
I fixed it!
I made an own function for the largemap and placed it in the callback when the elements are opened
function largeMap(){
var largeLatlng = new google.maps.LatLng(51.92475, 4.38206);
var largeOptions = {zoom: 10, center: largeLatlng,mapTypeId: google.maps.MapTypeId.ROADMAP};
var largeMap = new google.maps.Map(document.getElementById("largeMap"), largeOptions);
var largeMarker = new google.maps.Marker({position: largeLatlng, map:largeMap, title:"Cherrytrees"});
largeMarker.setMap(largeMap);
}
[..]
$("#showRoute").click(function(e){
e.preventDefault();
$("#shadow").add($("#shadowContent"),$("#closebar"),$("#content")).fadeIn(500);
$("#shadowContent").show().css({'width':'750px','top':'25px','left':'50%','margin-left':'-400px'});
$("#closeBarLink").click(function(l){
l.preventDefault();
$("#shadow").add($("#shadowContent"),$("#closebar"),$("#content")).fadeOut(500);
});
largeMap();
});
Thanks anyway!!
call initialize(); function after you box active.
$(document).ready(function () {
$("#shadow").show(function () {
initialize();
})
});
When you're loading in the large map, try adding this at the end of your map code.
map.checkResize();
When Google Maps first renders on your page, it has the dimensions recorded so that it displays the map images in that size. If you're resizing the map dynamically, you need to tell the API to check the new size.
<script type='text/javascript' >
var geocoder, map;
function codeAddress() {
var address= '<?php echo $this->subject()->address; ?>';
geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var myOptions = {
zoom: 13,
center: results[0].geometry.location,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon:'http://rvillage.com/application/themes/rvillage/images/map-marker.png'
});
var infowindow = new google.maps.InfoWindow({ content: 'coming soon' });
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, this);
});
}
});
}
jQuery(document).ready(function () {
codeAddress();
});
</script>
You are using pop up window with jQuery, and I guest you call initialize() function when document is ready ( $(document).ready(function() {initialize(); }) ).
Try call initialize() function after pop up windown showed.
Johnny

Categories

Resources