I am trying to place multiple markers on a Google Map (API v3). I looked at the Google docs and also this thread. The map draws and centers to the init point but no markers are showing on the map.
Firebug is not reporting any errors.
Here is the JS
<script type="text/javascript">
var map;
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(41.056466,-85.3312009),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
//Add 1st marker
var Latlng_0 = new google.maps.LatLng(41.057814980291,-85.329851919709);
var marker_0 = new google.maps.Marker({
position: Latlng_0,
title:"0"});
marker_0.setMap(map);
//Add 2nd marker
var Latlng_1 = new google.maps.LatLng(41.065294480291,-85.330151019708);
var marker_1 = new google.maps.Marker({
position: Latlng_1,
title:"1"});
marker_1.setMap(map);
google.maps.event.addDomListener(window, 'load', initialize);
</script>
Thanks for looking!
The reason the markers are not showing up is because that part of the code is getting executed before the load event gets fired and the initialize method gets invoked - at that point your map variable is already created but is still null.
try adding the code to add the markers inside the initialize method
var map;
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(41.056466,-85.3312009),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
// Add 1st marker
var Latlng_0 = new google.maps.LatLng(41.057814980291,-85.329851919709);
var marker_0 = new google.maps.Marker(
{
position: Latlng_0,
title:"0"
}
);
marker_0.setMap(map);
//Add 2nd marker
var Latlng_1 = new google.maps.LatLng(41.065294480291,-85.330151019708);
var marker_1 = new google.maps.Marker(
{
position: Latlng_1,
title:"1"
}
);
marker_1.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
see this jsfiddle here where the markers are showing up http://jsfiddle.net/KvugB/
I use this code. I hope it helps you:
(function() {
window.onload = function() {
// Creating a new map
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(41.056466, -85.3312009),
disableDefaultUI: false,
zoom: 16,
mapTypeId: google.maps.MapTypeId.SATELLITE
});
// Creating the JSON data
var json = [
{
"title": "Title 1",
"lat": 41.057814980291,
"lng": -85.329851919709,
"description": ""
},
{
"title": "Title 2",
"lat": 41.057814981000,
"lng": -85.8048,
"description": ""
},
]
var styles = [
{
"featureType": "water",
"elementType": "geometry.fill",
"stylers": [
{ "visibility": "on" },
{ "color": "#0077bb" },
{ "lightness": 70 }
]
},{
"featureType": "landscape.natural",
"elementType": "geometry.fill",
"stylers": [
{ "visibility": "on" },
{ "saturation": -100 },
{ "color": "#699e6b" },
{ "lightness": 76 }
]
},{
"featureType": "poi.park",
"elementType": "geometry.fill",
"stylers": [
{ "visibility": "off" }
]
},{
"featureType": "road.local",
"elementType": "geometry.fill",
"stylers": [
{ "visibility": "on" },
{ "color": "#ffffff" }
]
}
];
map.setOptions({styles: styles});
// Creating a global infoWindow object that will be reused by all markers
var infoWindow = new google.maps.InfoWindow();
// Looping through the JSON data
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i],
latLng = new google.maps.LatLng(data.lat, data.lng);
// Creating a marker and putting it on the map
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: data.title
});
// Creating a closure to retain the correct data, notice how I pass the current data in the loop into the closure (marker, data)
(function(marker, data) {
// Attaching a click event to the current marker
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
})(marker, data);
}
}
})();
This is a reply to #JoanManuelHernández's answer, but I can't post formatted code in a comment.
Joan, your solution is excellent; it's very similar to how I would do it myself. Creating an array of marker locations is way better than using individual variables for each one.
I'd like to suggest a couple of minor improvements. One is where you have the array named json. That isn't a very descriptive name; json could mean any kind of data. How about calling it something like places or locations or the like?
Next, where you have the loop that creates the closure to handle the asynchronous callback, I think it's a bit easier to understand how it works if you move the entire loop body into its own function. Then you don't need the inline anonymous function. So this code:
// Looping through the JSON data
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i],
latLng = new google.maps.LatLng(data.lat, data.lng);
// Creating a marker and putting it on the map
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: data.title
});
// Creating a closure to retain the correct data, notice how I pass the current data in the loop into the closure (marker, data)
(function(marker, data) {
// Attaching a click event to the current marker
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
})(marker, data);
}
would become:
// Looping through the places list
for( var i = 0, length = places.length; i < length; i++ ) {
addPlace( places[i] );
}
// Add one place marker
function addPlace( place ) {
var latLng = new google.maps.LatLng( place.lat, place.lng );
// Creating a marker and putting it on the map
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: place.title
});
// Attaching a click event to the current marker
google.maps.event.addListener( marker, "click", function(e) {
infoWindow.setContent( place.description );
infoWindow.open( map, marker );
});
}
It does the same thing, just a little simpler this way.
One other thought: The styled map stuff is very cool—I'm a big fan of styled maps myself—but I wonder if it should be left out here for the sake of simplicity, since it isn't related to the OP's question?
Feel free to incorporate any of these ideas into your own answer if you like them, and if anyone else finds this variation useful, please upvote Joan's answer since that's where the original code came from.
Related
I'm trying to add a marker to my google map within my HTML project. The map centres on the exact coordinates I like and is perfect except the marker I've added doesn't show up at all. I've followed the documentation but to no success.
var google;
function init() {
var myLatlng = new google.maps.LatLng(40.69847032728747, -73.9514422416687);
var mapOptions = {
// How zoomed in you want the map to start at (always required)
zoom: 7,
// The latitude and longitude to center the map (always required)
center: myLatlng,
// How you would like to style the map.
scrollwheel: false,
styles: [
{
"featureType": "administrative.country",
"elementType": "geometry",
"stylers": [
{
"visibility": "simplified"
},
{
"hue": "#ff0000"
}
]
}
]
};
I'm using a div with id="map" seen below
var mapElement = document.getElementById('map');
var map = new google.maps.Map(mapElement, mapOptions);
var addresses = ['New York'];
for (var x = 0; x < addresses.length; x++) {
$.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address='+addresses[x]+'&sensor=false', null, function (data) {
var p = data.results[0].geometry.location
var latlng = new google.maps.LatLng(p.lat, p.lng);
new google.maps.Marker({
position: latlng,
map: map,
title: 'NY'
});
});
}
}
google.maps.event.addDomListener(window, 'load', init);
You have to add your API key.
$.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address='+addresses[x]+'&sensor=false&key=ADD_YOUR_API_KEY', null, function (data) {
Check this out!
https://developers.google.com/maps/documentation/geocoding/intro#GeocodingResponses
I am trying to learn from a simple google developers tutorial in import GeoJSON data from either a local or remote source, and display it on my map. I have code and this code for USGS earth quake data JSON:
<!DOCTYPE html>
<html>
<head>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: new google.maps.LatLng(2.8,-187.3),
mapTypeId: 'terrain'
});
// Create a <script> tag and set the USGS URL as the source.
var script = document.createElement('script');
// This example uses a local copy of the GeoJSON stored at
// http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp
script.src = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp';
document.getElementsByTagName('head')[0].appendChild(script);
}
// Loop through the results array and place a marker for each
// set of coordinates.
window.eqfeed_callback = function(results) {
for (var i = 0; i < results.features.length; i++) {
var coords = results.features[i].geometry.coordinates;
var text = ''+results.features[i].properties.place+'';
var latLng = new google.maps.LatLng(coords[1],coords[0]);
var marker = new google.maps.Marker({
position: latLng,
map: map
});
}
var infowindow = new google.maps.InfoWindow({
content: text
});
marker.addListener('click', function() {
infowindow.open(map, marker);
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=xxxx&callback=initMap">
</script>
</body>
</html>
The code working fine without problem. But I am having some problems with InfoWindows when clicked on marker's should open and hold some information. I try to configure it but it doesn't work. When clicked no opening on the marker's click event that I attached example like place name for that earth quake.
JSON response for earth quake:
{
"type": "FeatureCollection",
"metadata": {
"generated": 1545674780000,
"url": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp",
"title": "USGS Magnitude 2.5+ Earthquakes, Past Week",
"status": 200,
"api": "1.7.0",
"count": 326
},
"features": [
{
"type": "Feature",
"properties": {
"mag": 2.6,
"place": "14km WNW of Big Lake, Alaska",
"time": 1545672051177,
"updated": 1545672768461,
"tz": -540,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/ak20539699",
"detail": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/ak20539699.geojsonp",
"felt": null,
"cdi": null,
"mmi": null,
"alert": null,
"status": "automatic",
"tsunami": 0,
"sig": 104,
"net": "ak",
"code": "20539699",
"ids": ",ak20539699,",
"sources": ",ak,",
"types": ",geoserve,origin,",
"nst": null,
"dmin": null,
"rms": 0.82,
"gap": null,
"magType": "ml",
"type": "earthquake",
"title": "M 2.6 - 14km WNW of Big Lake, Alaska"
},
"geometry": {
"type": "Point",
"coordinates": [
-150.2,
61.5832,
17.5
]
},
"id": "ak20539699"
}
]
}
Related question: Google Maps JS API v3 - Simple Multiple Marker Example
Your "click" event listener needs to be inside the loop so it can be associated with each marker, and the content needs to be associated with the marker (the option used for that in the related question is function closure):
infowindow = new google.maps.InfoWindow();
for (var i = 0; i < results.features.length; i++) {
var coords = results.features[i].geometry.coordinates;
var text = '' + results.features[i].properties.place + '';
var latLng = new google.maps.LatLng(coords[1], coords[0]);
var marker = new google.maps.Marker({
position: latLng,
map: map
});
marker.addListener('click', (function(marker, text) {
return function(e) {
infowindow.setContent(text);
infowindow.open(map, marker);
}
})(marker, text));
}
proof of concept fiddle
code snippet:
var map, infowindow;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: new google.maps.LatLng(2.8, -187.3),
mapTypeId: 'terrain'
});
infowindow = new google.maps.InfoWindow();
// Create a <script> tag and set the USGS URL as the source.
var script = document.createElement('script');
// This example uses a local copy of the GeoJSON stored at
// http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp
script.src = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp';
document.getElementsByTagName('head')[0].appendChild(script);
}
// Loop through the results array and place a marker for each
// set of coordinates.
window.eqfeed_callback = function(results) {
for (var i = 0; i < results.features.length; i++) {
var coords = results.features[i].geometry.coordinates;
var text = '' + results.features[i].properties.place + '';
var latLng = new google.maps.LatLng(coords[1], coords[0]);
var marker = new google.maps.Marker({
position: latLng,
map: map
});
marker.addListener('click', (function(marker, text) {
return function(e) {
infowindow.setContent(text);
infowindow.open(map, marker);
}
})(marker, text));
}
}
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap"></script>
var x1 = 0;
var startPoint = new google.maps.LatLng(0, 0);
var endPoint = new google.maps.LatLng(0, 0);
var marker;
var latlngs = new Array();
var infowindow;
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var locations = [
{
"name": "Frankie Johnnie & Luigo Too",
"address": "939 W El Camino Real, Mountain View, CA",
"lat": 37.386339,
"lng": -122.085823
}, {
"name": "Amici's East Coast Pizzeria",
"address": "790 Castro St, Mountain View, CA",
"lat": 37.38714,
"lng": -122.083235
}, {
"name": "Kapp's Pizza Bar & Grill",
"address": "191 Castro St, Mountain View, CA",
"lat": 37.393885,
"lng": -122.078916
}, {
"name": "Round Table Pizza: Mountain View",
"address": "570 N Shoreline Blvd, Mountain View, CA",
"lat": 37.402653,
"lng": -122.079354
}];
Edit: these are the global variables just to clarify ^
I want create a "click on markers to get directions" functionality. So far I have created a list in JSON that creates all the markers from the "lat" and "long" in the list without a problem:
for (var k in locations) {
latlngs[k] = new google.maps.LatLng(locations[k].lat, locations[k].lng);
marker = new google.maps.Marker({
position: latlngs[k],
animation: google.maps.Animation.DROP,
title: locations[k].name,
map: map
});
};
The JSON list ( locations[k] ) is 132 locations in total. I want to be able to click on a marker, save it as a start point for directions then wait for the secnond marker to be clicked on, which will be saved as an end point. Clicking the second marker will calculate and show directions as Iv'e tried below:
google.maps.event.addListener(marker, 'click', function () {
if (x1 === 0) {
startPoint = this.marker.position;
var infowindow = new google.maps.InfoWindow({
content: "Start",
position: startPoint
});
infowindow.open(map, this.marker);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('panel'));
x1++;
} else {
endPoint = this.marker.position;
x1 = 0;
calculateDirections(startPoint, endPoint);
}
});
At this point no infowindow gets displayed and I get the error saying "cannot read 'position' of undefined". I can get the directions to show when I hardcode the start and end points.
The following threads touches on the same idea but don't answer the listener for all markers problem, which I think is the main issue.
Google Maps API V3 - add event listener to all markers?
and
how do I add same event listener to many markers and then differentiate between the markers in the listeners in google maps api v3?
If you get the LatLang on click then saving it wont be a big deal. I have tried to achieve this on click and get the latlang. I am not sure how much this will solve your problem but definitely will give you some idea to move ahead.
Here is the working example, and I hope this will help you.
var map;
var geocoder;
var mapOptions = { center: new google.maps.LatLng(37.09024, -95.712891),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP };
function initialize() {
var myOptions = {
center: new google.maps.LatLng(37.09024, -95.712891),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
geocoder = new google.maps.Geocoder();
var map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
var marker;
function placeMarker(location) {
if(marker){ //on vérifie si le marqueur existe
marker.setPosition(location); //on change sa position
}else{
marker = new google.maps.Marker({ //on créé le marqueur
position: location,
map: map
});
}
document.getElementById('lat').value=location.lat();
document.getElementById('lng').value=location.lng();
getAddress(location);
}
function getAddress(latLng) {
geocoder.geocode( {'latLng': latLng},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
if(results[0]) {
document.getElementById("address").value = results[0].formatted_address;
}
else {
document.getElementById("address").value = "No results";
}
}
else {
document.getElementById("address").value = status;
}
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
html, body, #map_canvas { margin: 0; padding: 0; height: 100% }
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script><input type="text" id="address" size="30"><br><input type="text" id="lat" size="10"><input type="text" id="lng" size="10">
<div id="map_canvas"></div>
I end up with this code to show google map:
<script>
function init_map() {
// Create an array of styles.
var styles = [
{
"featureType": "water",
"elementType": "geometry",
"stylers": [
{
"color": "red"
},
{
"lightness": 25
}
]
}
];
var myOptions = {
mapTypeControlOptions: {
mapTypeIds: ['Map']
},
center: new google.maps.LatLng(40.514459, 0.13461),
zoom:3,
disableDefaultUI: false,
mapTypeId: 'Map',
scrollwheel: false,
navigationControl: true,
scaleControl: true,
};
var div = document.getElementById('gmap_canvas');
var map = new google.maps.Map(div, myOptions);
var styledMapType = new google.maps.StyledMapType(styles, { name: 'Map' });
map.mapTypes.set('Map', styledMapType);
var bounds = new google.maps.LatLngBounds();
marker = new google.maps.Marker({
map: map,
//position: new google.maps.LatLng(56.6789471,-0.34535),
icon: "images/marker.png"
});
var markers = [
['One', 11.232214,122.155547],
['Two', 39.555535,-87.5462367],
['Three', 48.3563671,-1.34554825],
];
for( i = 0; i < markers.length; i++ ) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
icon: "images/ico.png",
title: markers[i][0]
});
}
}
if (document.getElementById("gmap_canvas")) {
google.maps.event.addDomListener(window, 'load', init_map);
}
This code above creates google map with mulitple points (one, two, three).
And what i want to do, is to have a list of this contact points like:
<div class="point">Contact ONE</div>
<div class="point">Contact TWO</div>
<div class="point">Contact THREE</div>
And when i click this contact map should zoom to this point.
I found this, but example shows only one point, and also event is fired on marker click, not custom Html element.
https://developers.google.com/maps/documentation/javascript/examples/event-simple
You should set the map variable to global and define a global variable to a marker array (in the sample : markerArr).(Outside the init_map() function):
<script>
var map;
var markerArr = [];
function init_map() {...
...
Then in the for loop add each marker to this array:
for( i = 0; i < markers.length; i++ ) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
icon: "images/ico.png",
title: markers[i][0]
});
markerArr.push(marker); // Add the marker to the array
}
Then create a simple function with an integer param, let's call it jumpToMarker, where we can zoom and jump to the selected marker.:
function jumpToMarker(cnt){
map.panTo(markerArr[cnt].getPosition());
map.setZoom(4);
}
Finally set the divs and their onclick event in the DOM, after the map's div:
<div class="point">Contact ONE</div>
<div class="point">Contact TWO</div>
<div class="point">Contact THREE</div>
Hope this helps!
I need to allow users to create polylines on a google map and also allow them to delete a node between the polylines they created. The result of this removal should be a new polyline connecting the two new neighboring nodes. At the moment I'm struggling with allowing a user to delete a node. I've researched a bit and found a google reference and this SO question. Unfortunately, both of them assume that I have a reference to the polyline somewhere, which I don't, since the polyline is being created dynamically by the user.
This is the code that I currently use :
function initialize() {
var mapOptions = {
center: { lat: 45.797436, lng: 24.152044 },
zoom: 12
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.MARKER,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.MARKER,
google.maps.drawing.OverlayType.POLYLINE
]
},
markerOptions: {
icon: '/Mvc/Content/Styles/dropDownArrow.png'
},
polylineOptions: {
editable: true,
}
});
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'markercomplete', markerCompleted);
google.maps.event.addListener(drawingManager, 'polylinecomplete', polylineCompleted);
function markerCompleted(marker) {
var coordinates = { lng: marker.getPosition().lng(), lat: marker.getPosition().lat() };
alert('The coordinates for the new marker are: lat:' + coordinates.lat + ', long: ' + coordinates.lng);
}
function polylineCompleted(polyline) {
}
}
google.maps.event.addDomListener(window, 'load', initialize);
What I've tried is to map the polyline parameter inside the polylineCompleted event handler to a global variable, and then use the solution found in the SO link to somehow update the polyline, after which, using the getMap() and setMap() functions of the DrawingManager class, to update the map, but I got stuck. Is there any way of allowing a user to delete a polyline node, without having a reference to the polyline object?
Not sure this is what you are trying to achieve, but here is an example on how to let a user add and remove nodes from a polyline without using the drawingManager.
var map, polyline, markers = new Array();
function initialize() {
var mapOptions = {
zoom: 6,
center: new google.maps.LatLng(20.291, 153.027),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
polyline = new google.maps.Polyline({
strokeColor: 'red',
strokeWeight: 1,
map: map
});
google.maps.event.addListener(map, 'click', function (event) {
addPoint(event.latLng);
});
}
function removePoint(marker) {
for (var i = 0; i < markers.length; i++) {
if (markers[i] === marker) {
markers[i].setMap(null);
markers.splice(i, 1);
polyline.getPath().removeAt(i);
}
}
}
function addPoint(latlng) {
var marker = new google.maps.Marker({
position: latlng,
map: map
});
markers.push(marker);
polyline.getPath().setAt(markers.length - 1, latlng);
google.maps.event.addListener(marker, 'click', function (event) {
removePoint(marker);
});
}
initialize();
JSFiddle demo
Click on the map to add a point and click on a marker to remove a point.