Fairly new to the Google Maps Api. I've got an array of data that I want to cycle through and plot on a map. Seems fairly simple, but all the multi-marker tutorials I have found are quite complex.
Let's use the data array from Google's site for an example:
var locations = [
['Bondi Beach', -33.890542, 151.274856, 4],
['Coogee Beach', -33.923036, 151.259052, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];
I simply want to plot all of these points and have an infoWindow pop up when clicked to display the name.
This is the simplest I could reduce it to:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Google Maps Multiple Markers</title>
<script src="http://maps.google.com/maps/api/js?key=YOUR_API_KEY"
type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 500px; height: 400px;"></div>
<script type="text/javascript">
var locations = [
['Bondi Beach', -33.890542, 151.274856, 4],
['Coogee Beach', -33.923036, 151.259052, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(-33.92, 151.25),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
</script>
</body>
</html>
👨💻 Edit/fork on a Codepen →
SCREENSHOT
There is some closure magic happening when passing the callback argument to the addListener method. This can be quite a tricky topic if you are not familiar with how closures work. I would suggest checking out the following Mozilla article for a brief introduction if it is the case:
❯ Mozilla Dev Center: Working with Closures
Here is another example of multiple markers loading with a unique title and infoWindow text. Tested with the latest google maps API V3.11.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Multiple Markers Google Maps</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script
src="https://maps.googleapis.com/maps/api/js?v=3.11&sensor=false"
type="text/javascript"
></script>
<script type="text/javascript">
// check DOM Ready
$(document).ready(function () {
// execute
(function () {
// map options
var options = {
zoom: 5,
center: new google.maps.LatLng(39.909736, -98.522109), // centered US
mapTypeId: google.maps.MapTypeId.TERRAIN,
mapTypeControl: false,
};
// init map
var map = new google.maps.Map(
document.getElementById('map_canvas'),
options
);
// NY and CA sample Lat / Lng
var southWest = new google.maps.LatLng(40.744656, -74.005966);
var northEast = new google.maps.LatLng(34.052234, -118.243685);
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
// set multiple marker
for (var i = 0; i < 250; i++) {
// init markers
var marker = new google.maps.Marker({
position: new google.maps.LatLng(
southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random()
),
map: map,
title: 'Click Me ' + i,
});
// process multiple info windows
(function (marker, i) {
// add click event
google.maps.event.addListener(marker, 'click', function () {
infowindow = new google.maps.InfoWindow({
content: 'Hello, World!!',
});
infowindow.open(map, marker);
});
})(marker, i);
}
})();
});
</script>
</head>
<body>
<div id="map_canvas" style="width: 800px; height: 500px"></div>
</body>
</html>
Screenshot of 250 Markers:
It will automatically randomize the Lat/Lng to make it unique. This example will be very helpful if you want to test 500, 1000, xxx markers and performance.
I thought I would put this here as it appears to be a popular landing point for those starting to use Google Maps API's. Multiple markers rendered on the client side is probably the downfall of many mapping applications performance wise. It is difficult to benchmark, fix and in some cases even establish there is an issue (due to browser implementation differences, hardware available to the client, mobile devices, the list goes on).
The simplest way to begin to address this issue is to use a marker clustering solution. The basic idea is to group geographically similar locations into a group with the number of points displayed. As the user zooms into the map these groups expand to reveal individual markers beneath.
Perhaps the simplest to implement is the markerclusterer library. A basic implementation would be as follows (after library imports):
<script type="text/javascript">
function initialize() {
var center = new google.maps.LatLng(37.4419, -122.1419);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var markers = [];
for (var i = 0; i < 100; i++) {
var location = yourData.location[i];
var latLng = new google.maps.LatLng(location.latitude,
location.longitude);
var marker = new google.maps.Marker({
position: latLng
});
markers.push(marker);
}
var markerCluster = new MarkerClusterer({map, markers});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
The markers instead of being added directly to the map are added to an array. This array is then passed to the library which handles complex calculation for you and attached to the map.
Not only do these implementations massively increase client side performance but they also in many cases lead to a simpler and less cluttered UI and easier digestion of data on larger scales.
Other implementations are available from Google.
Hope this aids some of those newer to the nuances of mapping.
Asynchronous version :
<script type="text/javascript">
function initialize() {
var locations = [
['Bondi Beach', -33.890542, 151.274856, 4],
['Coogee Beach', -33.923036, 151.259052, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(-33.92, 151.25),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
function loadScript() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&' +
'callback=initialize';
document.body.appendChild(script);
}
window.onload = loadScript;
</script>
var arr = new Array();
function initialize() {
var i;
var Locations = [
{
lat:48.856614,
lon:2.3522219000000177,
address:'Paris',
gval:'25.5',
aType:'Non-Commodity',
title:'Paris',
descr:'Paris'
},
{
lat: 55.7512419,
lon: 37.6184217,
address:'Moscow',
gval:'11.5',
aType:'Non-Commodity',
title:'Moscow',
descr:'Moscow Airport'
},
{
lat:-9.481553000000002,
lon:147.190242,
address:'Port Moresby',
gval:'1',
aType:'Oil',
title:'Papua New Guinea',
descr:'Papua New Guinea 123123123'
},
{
lat:20.5200,
lon:77.7500,
address:'Indore',
gval:'1',
aType:'Oil',
title:'Indore, India',
descr:'Airport India'
}
];
var myOptions = {
zoom: 2,
center: new google.maps.LatLng(51.9000,8.4731),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
var infowindow = new google.maps.InfoWindow({
content: ''
});
for (i = 0; i < Locations.length; i++) {
size=15;
var img=new google.maps.MarkerImage('marker.png',
new google.maps.Size(size, size),
new google.maps.Point(0,0),
new google.maps.Point(size/2, size/2)
);
var marker = new google.maps.Marker({
map: map,
title: Locations[i].title,
position: new google.maps.LatLng(Locations[i].lat, Locations[i].lon),
icon: img
});
bindInfoWindow(marker, map, infowindow, "<p>" + Locations[i].descr + "</p>",Locations[i].title);
}
}
function bindInfoWindow(marker, map, infowindow, html, Ltitle) {
google.maps.event.addListener(marker, 'mouseover', function() {
infowindow.setContent(html);
infowindow.open(map, marker);
});
google.maps.event.addListener(marker, 'mouseout', function() {
infowindow.close();
});
}
Full working example. You can just copy, paste and use.
From Google Map API samples:
function initialize() {
var myOptions = {
zoom: 10,
center: new google.maps.LatLng(-33.9, 151.2),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
setMarkers(map, beaches);
}
/**
* Data for the markers consisting of a name, a LatLng and a zIndex for
* the order in which these markers should display on top of each
* other.
*/
var beaches = [
['Bondi Beach', -33.890542, 151.274856, 4],
['Coogee Beach', -33.923036, 151.259052, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];
function setMarkers(map, locations) {
// Add markers to the map
// Marker sizes are expressed as a Size of X,Y
// where the origin of the image (0,0) is located
// in the top left of the image.
// Origins, anchor positions and coordinates of the marker
// increase in the X direction to the right and in
// the Y direction down.
var image = new google.maps.MarkerImage('images/beachflag.png',
// This marker is 20 pixels wide by 32 pixels tall.
new google.maps.Size(20, 32),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at 0,32.
new google.maps.Point(0, 32));
var shadow = new google.maps.MarkerImage('images/beachflag_shadow.png',
// The shadow image is larger in the horizontal dimension
// while the position and offset are the same as for the main image.
new google.maps.Size(37, 32),
new google.maps.Point(0,0),
new google.maps.Point(0, 32));
// Shapes define the clickable region of the icon.
// The type defines an HTML <area> element 'poly' which
// traces out a polygon as a series of X,Y points. The final
// coordinate closes the poly by connecting to the first
// coordinate.
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18 , 1],
type: 'poly'
};
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
shadow: shadow,
icon: image,
shape: shape,
title: beach[0],
zIndex: beach[3]
});
}
}
Here is another version I wrote to save map real estate, that places the infowindow pointer on the actual lat and long of the marker, while temporarily hiding the marker while the infowindow is being displayed.
It also does away with the standard 'marker' assignment and speeds up
processing by directly assigning the new marker to the markers array on the markers creation. Note however, that additional properties have been added to both the marker and the infowindow, so this approach is a tad unconventional... but that's me!
It is never mentioned in these infowindow questions, that the standard infowindow IS NOT placed at the lat and lng of the marker point, but rather at the top of the marker image. The marker visibility must be hidden for this to work, otherwise the Maps API will shove the infowindow anchor back to the top of the marker image again.
Reference to the markers in the 'markers' array are created immediately upon marker declaration for any additional processing tasks that may be desired later(hiding/showing, grabbing the coords,etc...). This saves the additional step of assigning the marker object to 'marker', and then pushing the 'marker' to the markers array... a lot of unnecessary processing in my book.
Anyway, a different take on infowindows, and hope it helps to inform and inspire you.
var locations = [
['Bondi Beach', -33.890542, 151.274856, 4],
['Coogee Beach', -33.923036, 151.259052, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];
var map;
var markers = [];
function init(){
map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 10,
center: new google.maps.LatLng(-33.92, 151.25),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var num_markers = locations.length;
for (var i = 0; i < num_markers; i++) {
markers[i] = new google.maps.Marker({
position: {lat:locations[i][1], lng:locations[i][2]},
map: map,
html: locations[i][0],
id: i,
});
google.maps.event.addListener(markers[i], 'click', function(){
var infowindow = new google.maps.InfoWindow({
id: this.id,
content:this.html,
position:this.getPosition()
});
google.maps.event.addListenerOnce(infowindow, 'closeclick', function(){
markers[this.id].setVisible(true);
});
this.setVisible(false);
infowindow.open(map);
});
}
}
google.maps.event.addDomListener(window, 'load', init);
Here is a working JSFiddle
Additional Note
You will notice in this given Google example data a fourth place in the 'locations' array with a number. Given this in the example, you could also use this value for the marker id in place of the current loop value, such that...
var num_markers = locations.length;
for (var i = 0; i < num_markers; i++) {
markers[i] = new google.maps.Marker({
position: {lat:locations[i][1], lng:locations[i][2]},
map: map,
html: locations[i][0],
id: locations[i][3],
});
};
Accepted answer, rewritten in ES6:
$(document).ready(() => {
const mapEl = $('#our_map').get(0); // OR document.getElementById('our_map');
// Display a map on the page
const map = new google.maps.Map(mapEl, { mapTypeId: 'roadmap' });
const buildings = [
{
title: 'London Eye, London',
coordinates: [51.503454, -0.119562],
info: 'carousel'
},
{
title: 'Palace of Westminster, London',
coordinates: [51.499633, -0.124755],
info: 'palace'
}
];
placeBuildingsOnMap(buildings, map);
});
const placeBuildingsOnMap = (buildings, map) => {
// Loop through our array of buildings & place each one on the map
const bounds = new google.maps.LatLngBounds();
buildings.forEach((building) => {
const position = { lat: building.coordinates[0], lng: building.coordinates[1] }
// Stretch our bounds to the newly found marker position
bounds.extend(position);
const marker = new google.maps.Marker({
position: position,
map: map,
title: building.title
});
const infoWindow = new google.maps.InfoWindow();
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', () => {
infoWindow.setContent(building.info);
infoWindow.open(map, marker);
})
// Automatically center the map fitting all markers on the screen
map.fitBounds(bounds);
})
})
Add a marker in your program is very easy. You just may add this code:
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
The following fields are particularly important and commonly set when you construct a marker:
position (required) specifies a LatLng identifying the initial location of the marker. One way of retrieving a LatLng is by using the Geocoding service.
map (optional) specifies the Map on which to place the marker. If you do not specify a map on construction of the marker, the marker is created but is not attached to (or displayed on) the map. You may add the marker later by calling the marker's setMap() method.
Note, in the example, the title field set the marker's title who will appear as a tooltip.
You may consult the Google api documenation here.
This is a complete example to set one marker in a map. Be care full, you have to replace YOUR_API_KEY by your google API key:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Simple markers</title>
<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>
function initMap() {
var myLatLng = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
Now, if you want to plot markers of an array in a map, you should do like this:
var locations = [
['Bondi Beach', -33.890542, 151.274856, 4],
['Coogee Beach', -33.923036, 151.259052, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];
function initMap() {
var myLatLng = {lat: -33.90, lng: 151.16};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: myLatLng
});
var count;
for (count = 0; count < locations.length; count++) {
new google.maps.Marker({
position: new google.maps.LatLng(locations[count][1], locations[count][2]),
map: map,
title: locations[count][0]
});
}
}
This example give me the following result:
You can, also, add an infoWindow in your pin. You just need this code:
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[count][1], locations[count][2]),
map: map
});
marker.info = new google.maps.InfoWindow({
content: 'Hello World!'
});
You can have the Google's documentation about infoWindows here.
Now, we can open the infoWindow when the marker is "clik" like this:
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[count][1], locations[count][2]),
map: map
});
marker.info = new google.maps.InfoWindow({
content: locations [count][0]
});
google.maps.event.addListener(marker, 'click', function() {
// this = marker
var marker_map = this.getMap();
this.info.open(marker_map, this);
// Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
});
Note, you can have some documentation about Listener here in google developer.
And, finally, we can plot an infoWindow in a marker if the user click on it. This is my complete code:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Info windows</title>
<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 locations = [
['Bondi Beach', -33.890542, 151.274856, 4],
['Coogee Beach', -33.923036, 151.259052, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];
// When the user clicks the marker, an info window opens.
function initMap() {
var myLatLng = {lat: -33.90, lng: 151.16};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: myLatLng
});
var count=0;
for (count = 0; count < locations.length; count++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[count][1], locations[count][2]),
map: map
});
marker.info = new google.maps.InfoWindow({
content: locations [count][0]
});
google.maps.event.addListener(marker, 'click', function() {
// this = marker
var marker_map = this.getMap();
this.info.open(marker_map, this);
// Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
});
}
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
</body>
</html>
Normally, you should have this result:
Source Link
Demo Link
Complete HTML code
Show InfoWindow on Click or Hover.
Only one InfoWindow will be shown
<!DOCTYPE html>
<html>
<head>
<style>
/* <span class="metadata-marker" style="display: none;" data-region_tag="css"></span> Set the size of the div element that contains the map */
#map {
height: 400px;
/* The height is 400 pixels */
width: 100%;
/* The width is the width of the web page */
}
</style>
<script>
var map;
var InforObj = [];
var centerCords = {
lat: -25.344,
lng: 131.036
};
var markersOnMap = [{
placeName: "Australia (Uluru)",
LatLng: [{
lat: -25.344,
lng: 131.036
}]
},
{
placeName: "Australia (Melbourne)",
LatLng: [{
lat: -37.852086,
lng: 504.985963
}]
},
{
placeName: "Australia (Canberra)",
LatLng: [{
lat: -35.299085,
lng: 509.109615
}]
},
{
placeName: "Australia (Gold Coast)",
LatLng: [{
lat: -28.013044,
lng: 513.425586
}]
},
{
placeName: "Australia (Perth)",
LatLng: [{
lat: -31.951994,
lng: 475.858081
}]
}
];
window.onload = function () {
initMap();
};
function addMarkerInfo() {
for (var i = 0; i < markersOnMap.length; i++) {
var contentString = '<div id="content"><h1>' + markersOnMap[i].placeName +
'</h1><p>Lorem ipsum dolor sit amet, vix mutat posse suscipit id, vel ea tantas omittam detraxit.</p></div>';
const marker = new google.maps.Marker({
position: markersOnMap[i].LatLng[0],
map: map
});
const infowindow = new google.maps.InfoWindow({
content: contentString,
maxWidth: 200
});
marker.addListener('click', function () {
closeOtherInfo();
infowindow.open(marker.get('map'), marker);
InforObj[0] = infowindow;
});
// marker.addListener('mouseover', function () {
// closeOtherInfo();
// infowindow.open(marker.get('map'), marker);
// InforObj[0] = infowindow;
// });
// marker.addListener('mouseout', function () {
// closeOtherInfo();
// infowindow.close();
// InforObj[0] = infowindow;
// });
}
}
function closeOtherInfo() {
if (InforObj.length > 0) {
/* detach the info-window from the marker ... undocumented in the API docs */
InforObj[0].set("marker", null);
/* and close it */
InforObj[0].close();
/* blank the array */
InforObj.length = 0;
}
}
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: centerCords
});
addMarkerInfo();
}
</script>
</head>
<body>
<h3>My Google Maps Demo</h3>
<!--The div element for the map -->
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
</body>
</html>
Following from Daniel Vassallo's answer, here is a version that deals with the closure issue in a simpler way.
Since since all markers will have an individual InfoWindow and since JavaScript doesn't care if you add extra properties to an object, all you need to do is add an InfoWindow to the Marker's properties and then call the .open() on the InfoWindow from itself!
Edit: With enough data, the pageload could take a lot of time, so rather than construction the InfoWindow with the marker, the construction should happen only when needed. Note that any data used to construct the InfoWindow must be appended to the Marker as a property (data). Also note that after the first click event, infoWindow will persist as a property of it's marker so the browser doesn't need to constantly reconstruct.
var locations = [
['Bondi Beach', -33.890542, 151.274856, 4],
['Coogee Beach', -33.923036, 151.259052, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(-33.92, 151.25)
});
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
data: {
name: locations[i][0]
}
});
marker.addListener('click', function() {
if(!this.infoWindow) {
this.infoWindow = new google.maps.InfoWindow({
content: this.data.name;
});
}
this.infoWindow.open(map,this);
})
}
I know this answer is very much late. But I wish this will help other developers also. :-)
The Following code will add multiple markers on the google map with the information window.
And this code can be used to plot any number of markers on the map.
Please put your Google Map API key to the correct position of this code. (I have marked that as "Your API Key")
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Google Map</title>
<style>
#map{
height: 600px;
width: 100%;
}
</style>
</head>
<body>
<h1>My Google Map`</h1>
<div id="map"></div>
<script>
function initMap(){
//Map options
var options = {
zoom:9,
center:{lat:42.3601, lng:-71.0589}
}
// new map
var map = new google.maps.Map(document.getElementById('map'), options);
// customer marker
var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/parking_lot_maps.png';
//array of Marrkeers
var markers = [
{
coords:{lat: 42.4668, lng: -70.9495},img:iconBase,con:'<h3> This Is your Content <h3>'
},
{
coords:{lat: 42.8584, lng: -70.9300},img:iconBase,con:'<h3> This Is your Content <h3>'
},
{
coords:{lat: 42.7762, lng: -71.0773},img:iconBase,con:'<h3> This Is your Content <h3>'
}
];
//loopthrough markers
for(var i = 0; i <markers.length; i++){
//add markeers
addMarker(markers[i]);
}
//function for the plotting markers on the map
function addMarker (props){
var marker = new google.maps.Marker({
position: props.coords,
map:map,
icon:props.img
});
var infoWindow = new google.maps.InfoWindow({
content:props.con,
});
marker.addListener("click", () => {
infoWindow.open(map, marker);
});
}
}
</script>
<script
src="https://maps.googleapis.com/maps/api/js?key=**YourAPIKey**&callback=initMap"
defer
></script>
</body>
</html>
Here is a nearly complete example javascript function that will allow multiple markers defined in a JSONObject.
It will only display the markers that are with in the bounds of the map.
This is important so you are not doing extra work.
You can also set a limit to the markers so you are not showing an extreme amount of markers (if there is a possibility of a thing in your usage);
it will also not display markers if the center of the map has not changed more than 500 meters.
This is important because if a user clicks on the marker and accidentally drags the map while doing so you don't want the map to reload the markers.
I attached this function to the idle event listener for the map so markers will show only when the map is idle and will redisplay the markers after a different event.
In action screen shot
there is a little change in the screen shot showing more content in the infowindow.
pasted from pastbin.com
<script src="//pastebin.com/embed_js/uWAbRxfg"></script>
The recent simplest after modification in current map markers and clusterer algorithm:
Modification on: https://developers.google.com/maps/documentation/javascript/marker-clustering
<!DOCTYPE Html>
<html>
<head>
<meta Content-Security-Policy="default-src 'self'; script-src 'self' 'unsafe-eval' https://*/;">
<link type="text/css" href="http://www.mapsmarker.com/wp-content/uploads/leaflet-maps-marker-icons/bar_coktail.png">
<link rel="icon" href="data:,">
<title>App</title>
</head>
<style type="text/css">
#map {
height: 500
}
</style>
<body>
<div id='map' style="width:100%; height:400px"></div>
<script type='text/javascript'>
function initMap() {
maps = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(12.9824855, 77.637094),
zoom: 5,
disableDefaultUI: false,
mapTypeId: google.maps.MapTypeId.HYBRID
});
var labels='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var markerImage = 'http://www.mapsmarker.com/wp-content/uploads/leaflet-maps-marker-icons/bar_coktail.png';
marker = locations.map(function (location, i) {
return new google.maps.Marker({
position: new google.maps.LatLng(location.lat, location.lng),
map: maps,
title: "Map",
label: labels[i % labels.length],
icon: markerImage
});
});
var markerCluster = new MarkerClusterer(maps, marker, {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
}
var locations = [
{ lat: 12.9824855, lng: 77.637094},
{ lat: 11.9824855, lng: 77.154312 },
{ lat: 12.8824855, lng: 77.637094},
{ lat: 10.8824855, lng: 77.054312 },
{ lat: 12.9824855, lng: 77.637094},
{ lat: 11.9824855, lng: 77.154312 },
{ lat: 12.8824855, lng: 77.637094},
{ lat: 13.8824855, lng: 77.054312 },
{ lat: 14.9824855, lng: 54.637094},
{ lat: 15.9824855, lng: 54.154312 },
{ lat: 16.8824855, lng: 53.637094},
{ lat: 17.8824855, lng: 52.054312 },
{ lat: 18.9824855, lng: 51.637094},
{ lat: 19.9824855, lng: 69.154312 },
{ lat: 20.8824855, lng: 68.637094},
{ lat: 21.8824855, lng: 67.054312 },
{ lat: 12.9824855, lng: 76.637094},
{ lat: 11.9824855, lng: 75.154312 },
{ lat: 12.8824855, lng: 74.637094},
{ lat: 10.8824855, lng: 74.054312 },
{ lat: 12.9824855, lng: 73.637094},
{ lat: 3.9824855, lng: 72.154312 },
{ lat: 2.8824855, lng: 71.637094},
{ lat: 1.8824855, lng: 70.054312 }
];
</script>
<script src="https://unpkg.com/#google/markerclustererplus#4.0.1/dist/markerclustererplus.min.js">
</script>
<script src="https:maps.googleapis.com/maps/api/js?key=AIzaSyDWu6_Io9xA1oerfOxE77YAv31etN4u3Dw&callback=initMap">
</script>
<script type='text/javascript'></script>
Here is an example of multiple markers in Reactjs.
Below is the map component
import React from 'react';
import PropTypes from 'prop-types';
import { Map, InfoWindow, Marker, GoogleApiWrapper } from 'google-maps-react';
const MapContainer = (props) => {
const [mapConfigurations, setMapConfigurations] = useState({
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {}
});
var points = [
{ lat: 42.02, lng: -77.01 },
{ lat: 42.03, lng: -77.02 },
{ lat: 41.03, lng: -77.04 },
{ lat: 42.05, lng: -77.02 }
]
const onMarkerClick = (newProps, marker) => {};
if (!props.google) {
return <div>Loading...</div>;
}
return (
<div className="custom-map-container">
<Map
style={{
minWidth: '200px',
minHeight: '140px',
width: '100%',
height: '100%',
position: 'relative'
}}
initialCenter={{
lat: 42.39,
lng: -72.52
}}
google={props.google}
zoom={16}
>
{points.map(coordinates => (
<Marker
position={{ lat: coordinates.lat, lng: coordinates.lng }}
onClick={onMarkerClick}
icon={{
url: 'https://res.cloudinary.com/mybukka/image/upload/c_scale,r_50,w_30,h_30/v1580550858/yaiwq492u1lwuy2lb9ua.png',
anchor: new google.maps.Point(32, 32), // eslint-disable-line
scaledSize: new google.maps.Size(30, 30) // eslint-disable-line
}}
name={name}
/>))}
<InfoWindow
marker={mapConfigurations.activeMarker}
visible={mapConfigurations.showingInfoWindow}
>
<div>
<h1>{mapConfigurations.selectedPlace.name}</h1>
</div>
</InfoWindow>
</Map>
</div>
);
};
export default GoogleApiWrapper({
apiKey: process.env.GOOGLE_API_KEY,
v: '3'
})(MapContainer);
MapContainer.propTypes = {
google: PropTypes.shape({}).isRequired,
};
I want to display a map with multiple markers and it should display numbers in the marker and also an infowindow with info from the array.
It shows all the markers but with the number 5 in all of them and it is displaying the "Maroubra Beach" in the info window on all.
The info window itself, works as it should, that is that it opens on every marker as it should, but is displaying the wrong text!
Im not sure what Im doing wrong with the counter!? Since it is displaying 5 in all markers.
var geocoder;
var map;
function initializemulti() {
//this is the geolocationmarker-compiled.js file
(function() {var c=null,e;
function f(b,a,d){var i={clickable:!1,cursor:"pointer",draggable:!1,flat:!0,icon:new google.maps.MarkerImage("https://google-maps-utility-library-v3.googlecode.com/svn/trunk/GeolocationMarker/images/gpsloc.png",new google.maps.Size(15,15),new google.maps.Point(0,0),new google.maps.Point(7,7)),optimized:!1,position:new google.maps.LatLng(0,0),title:"Current location",zIndex:2};a&&(i=g(i,a));a={clickable:!1,radius:0,strokeColor:"1bb6ff",strokeOpacity:0.4,fillColor:"61a0bf",fillOpacity:0.4,strokeWeight:1,
zIndex:1};d&&(a=g(a,d));this.a=new google.maps.Marker(i);this.b=new google.maps.Circle(a);this.b.bindTo("center",this.a,"position");this.b.bindTo("map",this.a);b&&this.e(b)}e=f.prototype;e.c=c;e.a=c;e.b=c;e.g=function(){return this.c};e.h=function(){return this.c?this.a.getPosition():c};e.f=function(){return this.c?this.b.getBounds():c};e.i=function(){return this.c?this.b.getRadius():c};e.d=-1;
e.e=function(b){if(this.c=b){var a=this,b={enableHighAccuracy:!0,maximumAge:1E3};navigator.geolocation&&(this.d=navigator.geolocation.watchPosition(function(d){var b=new google.maps.LatLng(d.coords.latitude,d.coords.longitude);a.b.setRadius(d.coords.accuracy);if(!a.a.getMap()||!b.equals(a.a.getPosition()))a.a.setPosition(new google.maps.LatLng(d.coords.latitude,d.coords.longitude)),a.a.setPosition(b),a.a.getMap()||a.a.setMap(a.c),google.maps.event.trigger(a,"position_changed",new h(b,a.b.getBounds(),
d.coords.accuracy))},function(b){google.maps.event.trigger(a,"geolocation_error",b)},b))}else navigator.geolocation.clearWatch(this.d),this.d=-1,this.a.setMap(b)};e.k=function(b){this.a.setOptions(g({},b))};e.j=function(b){this.b.setOptions(g({},b))};function g(b,a){for(var d in a)j[d]||(b[d]=a[d]);return b}var j={map:!0,position:!0,radius:!0};function h(b,a,d){b&&(this.position=b);a&&(this.bounds=a);d&&(this.accuracy=d)}h.prototype.position=c;h.prototype.bounds=c;h.prototype.accuracy=c;f.prototype.getAccuracy=f.prototype.i;f.prototype.getBounds=f.prototype.f;f.prototype.getMap=f.prototype.g;f.prototype.getPosition=f.prototype.h;f.prototype.setCircleOptions=f.prototype.j;f.prototype.setMap=f.prototype.e;f.prototype.setMarkerOptions=f.prototype.k;window.GeolocationMarker=f;})()
//alert("init");
var locations = [
['Big Boys Grill & Bar', '<br />Kungsgatan 28, Varberg'],
['Black Pearl Varberg', '<br />Kungsgatan 13, Varberg'],
['Bruket', '<br />Birger Svenssons väg 16 E, Varberg'],
['Comwell Varbergs Kurort', '<br />Nils Kreugers väg 5, Varberg']
];
var mapen = new google.maps.Map(document.getElementById('map_canvasmulti'), {
zoom: 12,
center: new google.maps.LatLng(57.111488,12.246623),
//center: undefined,
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var geocoder = new google.maps.Geocoder();
//for displaying the current users location
var GeoMarker = new GeolocationMarker();
GeoMarker.setCircleOptions({fillColor: '#808080'});
google.maps.event.addListenerOnce(GeoMarker, 'position_changed', function() {
// mapen.setCenter(this.getPosition());
// mapen.fitBounds(this.getBounds());
});
google.maps.event.addListener(GeoMarker, 'geolocation_error', function(e) {
alert('There was an error obtaining your position. Message: ' + e.message);
});
GeoMarker.setMap(mapen);
var marker,i;
var markers = [];
var marker, i;
for (i = 0; i < locations.length; i++) {
var p = locations[i];
geocoder.geocode({
'address': locations[i][1]
}, (function(i,p) {
return function(results, status) {
//alert(status);
if (status == google.maps.GeocoderStatus.OK) {
//alert(results[0].geometry.location);
mapen.setCenter(results[0].geometry.location);
marker = new google.maps.Marker({
position: results[0].geometry.location,
icon: 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=' + ([i+1]) + '|FF776B|000000',
map: mapen,
title: p[2]
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(p[0] + p[1]);
infowindow.open(mapen, this);
});
// google.maps.event.addListener(marker, 'mouseover', function() { infowindow.open(mapen, this);});
google.maps.event.addListener(marker, 'mouseout', function() {
infowindow.close();
});
} else {
alert("some problem in geocode" + status);
}
};
})(i,p));
}
}
Any input really appreciated, thanks!
Ok so this works, except for that the blue dots is not showing? The circle around the users location i showing, but not the blue dot?
Use anonymous function closure (doesn't have to be anonymous, named functions work as well) to keep the information associated with the geocode request (for use in the callback) and in the infowindow click event handler (for use when the marker is clicked).
var locations = [
['Bondi Beach', '850 Bay st 04 Toronto, Ont'],
['Coogee Beach', '932 Bay Street, Toronto, ON M5S 1B1'],
['Cronulla Beach', '61 Town Centre Court, Toronto, ON M1P'],
['Manly Beach', '832 Bay Street, Toronto, ON M5S 1B1'],
['Maroubra Beach', '606 New Toronto Street, Toronto, ON M8V 2E8']
];
var mapen = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 10,
center: new google.maps.LatLng(43.253205, -80.480347),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var geocoder = new google.maps.Geocoder();
var marker, i;
for (i = 0; i < locations.length; i++) {
var p = locations[i];
geocoder.geocode({
'address': locations[i][1]
}, (function(i,p) {
return function(results, status) {
//alert(status);
if (status == google.maps.GeocoderStatus.OK) {
//alert(results[0].geometry.location);
mapen.setCenter(results[0].geometry.location);
marker = new google.maps.Marker({
position: results[0].geometry.location,
icon: 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=' + ([i]) + '|FF776B|000000',
map: mapen,
title: p[2]
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(p[0]);
infowindow.open(mapen, this);
});
// google.maps.event.addListener(marker, 'mouseover', function() { infowindow.open(mapen, this);});
google.maps.event.addListener(marker, 'mouseout', function() {
infowindow.close();
});
} else {
alert("some problem in geocode" + status);
}
};
})(i,p));
}
html,
body,
#map_canvas {
height: 100%;
margin: 0px;
padding: 0px;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas" style="width: 100%; height: 100%;"></div>
Problem is you're loosing marker reference and only keeping the last one (note your array has 5 elements), to keep them, just create a markers[] array to store them:
var markers = [];
Then when marker is created add it to array
markers.push(marker);
Your code will be like this:
var locations = [
['Bondi Beach', '850 Bay st 04 Toronto, Ont'],
['Coogee Beach', '932 Bay Street, Toronto, ON M5S 1B1'],
['Cronulla Beach', '61 Town Centre Court, Toronto, ON M1P'],
['Manly Beach', '832 Bay Street, Toronto, ON M5S 1B1'],
['Maroubra Beach', '606 New Toronto Street, Toronto, ON M8V 2E8']
];
var mapen = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 10,
center: new google.maps.LatLng(43.253205,-80.480347),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var geocoder = new google.maps.Geocoder();
var marker,i;
var markers = [];
for (i = 0; i < locations.length; i++) {
var p = locations[i];
geocoder.geocode( { 'address': locations[i][1]}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
mapen.setCenter(results[0].geometry.location);
marker = new google.maps.Marker({
position: results[0].geometry.location,
icon:'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld='+ ([i]) +'|FF776B|000000',
map: mapen,
title: p[2]
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(p[0]);
infowindow.open(mapen, this);
});
google.maps.event.addListener(marker, 'mouseout', function() { infowindow.close();});
// insert created marker in the array
markers.push(marker);
}
else
{
alert("some problem in geocode" + status);
}
});
}
I've been stuck on this issue for a while now and could really use some help. In a Google Map, I have a list of markers which are being treated as a markerArray, with their own custom icons. But along with displaying those markers, I would like for it to create a marker which is placed at the users geotagged location. I have tried merging the suggestions I've come across here on stack overflow, and have successfully gotten the users browser to center the map based off of geolocation, but whenever I try to add a marker outside of the standard var=locations, all of the markers disappear. I am providing my working code, which simply lacks the feature to add the "current location" marker. If anyone has any input, I'd be thrilled.
var map = null;
var markerArray = [];
function initialize() {
var myOptions = {
zoom: 13,
center: new google.maps.LatLng(40.746613, -73.990109),
mapTypeControl: false,
navigationControl: false,
streetViewControl: false,
zoomControl: false,
styles: [{featureType:"landscape",stylers:[{saturation:-100},{lightness:65},{visibility:"on"}]},{featureType:"poi",stylers:[{saturation:-100},{lightness:51},{visibility:"simplified"}]},{featureType:"road.highway",stylers:[{saturation:-100},{visibility:"simplified"}]},{featureType:"road.arterial",stylers:[{saturation:-100},{lightness:30},{visibility:"on"}]},{featureType:"road.local",stylers:[{saturation:-100},{lightness:40},{visibility:"on"}]},{featureType:"transit",stylers:[{saturation:-100},{visibility:"simplified"}]},{featureType:"administrative.province",stylers:[{visibility:"off"}]/**/},{featureType:"administrative.locality",stylers:[{visibility:"off"}]},{featureType:"administrative.neighborhood",stylers:[{visibility:"on"}]/**/},{featureType:"water",elementType:"labels",stylers:[{visibility:"on"},{lightness:-25},{saturation:-100}]},{featureType:"water",elementType:"geometry",stylers:[{hue:"#ffff00"},{lightness:-25},{saturation:-97}]}]
};
map = new google.maps.Map(document.getElementById('map'), myOptions);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(initialLocation);
});
}
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
var locations = [
['90 West Apartment', 40.709943, -74.014430, 7, 'images/pin2.png'],
['Caffe Vita', 40.719652, -73.988411, 6, 'images/pin1.png'],
['Croxleys Ale House', 40.722480, -73.983386, 5, 'images/pin1.png'],
['Grays Papaya', 40.778291, -73.981829, 4, 'images/pin2.png'],
['The Back Room', 40.718723, -73.986913, 3, 'images/pin1.png'],
['MUD Coffee', 40.729912, -73.990678, 2, 'images/pin1.png'],
['Nurse Bettie', 40.718820, -73.986863, 1, 'pin2.png']];
for (var i = 0; i < locations.length; i++) {
createMarker(new google.maps.LatLng(locations[i][1], locations[i][2]),locations[i][0], locations[i][3], locations[i][4]);
}
mc.addMarkers(markerArray, true);
}
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150, 50)
});
function createMarker(latlng, myTitle, myNum, myIcon) {
var contentString = myTitle;
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: myIcon,
zIndex: Math.round(latlng.lat() * -100000) << 5,
title: myTitle
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
markerArray.push(marker);
}
window.onload = initialize;
Let's try this.
Put this in your initialize(): navigator.geolocation.getCurrentPosition(showPosition);
Then define showPosition:
var showPosition = function (position) {
var userLatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
// Do whatever you want with userLatLng.
var marker = new google.maps.Marker({
position: userLatLng,
title: 'Your Location',
map: map
});
}