I want to add multiple markers and infowindows that activated with a click.
I am having trouble to present the relevant infowindow of the marker, after a click the same infowindow open for all markers.
The information comes from a for loop
this is the code
function GetMarkerSuccess(results) {
results = $.parseJSON(results.d);
markers = [];
infowindows = [];
for (var i = 0; i < results.length; i++) {
var myLatLng = { lat: results[i].Latitude, lng: results[i].Longitude };
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon:'images/car.png'
});
var infowindow = new google.maps.InfoWindow({
content: "<div style='text-align:right'><h3>" + results[i].Date.substring(0, 10) + "</h3><p> התחלה: " + results[i].Starttime + " סיום: " + results[i].Endtime + "</p><p> ₪ מחיר:" + results[i].Price + "</p></div>"
});
markers.push(marker);
infowindows.push(infowindow);
listenMarker(marker);
function listenMarker(marker) {
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
}
}
function GetMarkerSuccess(results) {
results = $.parseJSON(results.d);
markers = [];
infowindows = [];
for (var i = 0; i < results.length; i++) {
var myLatLng = { lat: results[i].Latitude, lng: results[i].Longitude };
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon:'images/car.png'
});
var infowindow = new google.maps.InfoWindow({
content: "<div style='text-align:right'><h3>" + results[i].Date.substring(0, 10) + "</h3><p> התחלה: " + results[i].Starttime + " סיום: " + results[i].Endtime + "</p><p> ₪ מחיר:" + results[i].Price + "</p></div>"
});
markers.push(marker);
infowindows.push(infowindow);
listenMarker(marker);
function listenMarker(marker) {
google.maps.event.addListener(marker,'click', (function(marker,content,infowindow){
return function() {
infowindow.setContent(content);
infowindow.open(map,marker);
};
})(marker,content,infowindow));
}
}
}
Related
I've created some code to create a google map and it pulls in some marker data. How would I structure this code to only have a single Infowindow open at once? The more direct answer the better.
function initializeLocations(locations) {
$.each(locations, function (i, location) {
var marker = new google.maps.Marker({
position: location.geo,
map: map,
title: location.name
});
var contentName = '<br><b>' + location.name + '</b><br>';
var contentLink = 'More Info';
var contentAddress = location.address;
var content = contentName + contentAddress + contentLink
var infoWindow = new google.maps.InfoWindow({
content: content
});
marker.addListener('click', function() {
infoWindow.open(map, this);
});
});
}
I found the solution. Heres what i did.
function initializeLocations(locations) {
var infoWindow = new google.maps.InfoWindow({});
$.each(locations, function (i, location) {
var marker = new google.maps.Marker({
position: location.geo,
map: map,
title: location.name
});
var contentName = '<br><b>' + location.name + '</b><br>';
var contentLink = 'More Info';
var contentAddress = location.address;
var content = contentName + contentAddress + contentLink
google.maps.event.addListener(marker, 'click', (function(marker) {
return function(){
infoWindow.setContent(content);
infoWindow.open(map, marker);
}
})(marker));
});
}
I am using Google Maps API in Rails. Getting my all locations from ajax call and displaying it in for loop. I followed this link When I copy paste this
code in my file it seems to work perfectly. But when I am trying to do the same thing for my code. It keeps showing the last marker info.
jQuery(function($) {
var myCenter = new google.maps.LatLng(51.508742,-0.120850);
var mapCanvas = document.getElementById("map");
var mapOptions = {center: myCenter, zoom: 5};
var map = new google.maps.Map(mapCanvas, mapOptions);
$.ajax({
url: "/list_proposals",
type: "GET",
dataType: "json",
success:function(data) {
placeMarker(map, data);
}
});
function placeMarker(map, data){
for (var i = 0; i < data.length; i++) {
var location_data = data[i];
var lat = location_data["lat"];
var long = location_data["long"];
var planting_proposal = location_data["planting_proposal"];
var proposal_id = planting_proposal["id"];
var title = planting_proposal["title"];
var photo_url = planting_proposal["main_photo"]["attachment_thumb_url"];
latlngset = new google.maps.LatLng(lat, long);
var image = {
url: window.location.origin + "/" + photo_url,
size: new google.maps.Size(50, 50),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(0, 32)
};
var marker = new google.maps.Marker({
map: map, title: title , position: latlngset, icon: image
});
map.setCenter(marker.getPosition());
var show_proposal_link = '' + title + '';
var contentString = '<div class="card text-center" style="width: 20rem;">' +
'<div class="card-block">' +
'<h4 class="card-title">'+ show_proposal_link + '</h4>' +
'<p class="card-text">' + '<img src="'+ window.location.origin + "/" + photo_url + '" width="100%;"/>' + '</p>' +
'</div>' +
'</div>';
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker,'click', (function(marker,content,infowindow){
return function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
};
})(marker,content,infowindow));
}
}
});
I am new in Google Maps API. Please me help me out with it what am I doing wrong?
You should correctly implement an IIFE in your code. Please replace the google.maps.event.addListener(marker,... part of the code with the following IIFE:
(function(marker,content,infowindow) {
google.maps.event.addListener(marker,'click', function() {
infowindow.setContent(content);
infowindow.open(map, marker);
});
})(marker,contentString,infowindow);
Proof of concept
var map;
var locations = [
{
planting_proposal: {
id: 1,
title: "Proposal 1"
},
lat: 41.386043,
long: 2.14561
},
{
planting_proposal: {
id: 2,
title: "Proposal 2"
},
lat: 41.417371,
long: 2.172115
},
{
planting_proposal: {
id: 3,
title: "Proposal 3"
},
lat: 41.399475,
long: 2.184048
}
]
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 41.385064, lng: 2.173403},
zoom: 12
});
placeMarker(map, locations);
}
function placeMarker(map, data){
for (var i = 0; i < data.length; i++) {
var location_data = data[i];
var lat = location_data["lat"];
var long = location_data["long"];
var planting_proposal = location_data["planting_proposal"];
var proposal_id = planting_proposal["id"];
var title = planting_proposal["title"];
latlngset = new google.maps.LatLng(lat, long);
var marker = new google.maps.Marker({
map: map,
title: title ,
position: latlngset
});
var show_proposal_link = '' + title + '';
var contentString = '<div class="card text-center" style="width: 20rem;">' +
'<div class="card-block">' +
'<h4 class="card-title">'+ show_proposal_link + '</h4>' +
'</div>' +
'</div>';
var infowindow = new google.maps.InfoWindow();
(function(marker,content,infowindow) {
google.maps.event.addListener(marker,'click', function() {
infowindow.setContent(content);
infowindow.open(map, marker);
});
})(marker,contentString,infowindow);
}
}
#map {
height: 100%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&callback=initMap"
async defer></script>
I hope this helps!
I want to calculate driving distance between given latitudes and longitudes. On my project I'm displaying markers on road. And what I want is to calculate distance between those markers not all of the routes. Can some one explain to me how can I calculate that distance?
I know I should work on DistanceMatrixService but I couldn't figure out how to work on it.
Where I put Markers:
var pointsArray = response.routes[0].overview_path;
for (var i = 0; i < pointsArray.length; i++) {
var marker = new google.maps.Marker ({
position:pointsArray[i],
draggable:false,
map:map,
flat:true
});
}
If the pointsArray comes from the directions service, you can do something like this:
var pointsArray = response.routes[0].overview_path;
for (var i = 0; i < pointsArray.length; i++) {
var marker = new google.maps.Marker({
position: pointsArray[i],
draggable: false,
map: map,
flat: true
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function (evt) {
var html = "marker #" + i + "<br />";
if (i != (markers.length - 1)) {
html += "<a href='javascript: google.maps.event.trigger(markers[" + (i + 1) + "],\"click\");'>next</a> dist:" + google.maps.geometry.spherical.computeDistanceBetween(markers[i].getPosition(), markers[i + 1].getPosition()).toFixed(2) + " meters<br />";
}
if (i !== 0) {
html += "<a href='javascript: google.maps.event.trigger(markers[" + (i - 1) + "],\"click\");'>prev</a> dist:" + google.maps.geometry.spherical.computeDistanceBetween(markers[i].getPosition(), markers[i - 1].getPosition()).toFixed(2) + " meters";
}
infowindow.setContent(html);
infowindow.open(map, marker);
}
})(marker, i))
}
Another option would be to get the distances out of the directions response.
code snippet:
var infowindow = new google.maps.InfoWindow();
var markers = [];
function initMap() {
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 7,
center: {
lat: 37.4419,
lng: -122.1419
}
});
directionsDisplay.setMap(map);
calculateAndDisplayRoute(new google.maps.LatLng(37.4419, -122.1419), new google.maps.LatLng(37.447597, -122.159582),
directionsService, directionsDisplay, map);
}
function calculateAndDisplayRoute(start, end, directionsService, directionsDisplay, map) {
directionsService.route({
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
var pointsArray = response.routes[0].overview_path;
for (var i = 0; i < pointsArray.length; i++) {
var marker = new google.maps.Marker({
position: pointsArray[i],
draggable: false,
map: map,
flat: true
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function(evt) {
var html = "marker #" + i + "<br />";
if (i != (markers.length - 1)) {
html += "<a href='javascript: google.maps.event.trigger(markers[" + (i + 1) + "],\"click\");'>next</a> dist:" + google.maps.geometry.spherical.computeDistanceBetween(markers[i].getPosition(), markers[i + 1].getPosition()).toFixed(2) + " meters<br />";
}
if (i !== 0) {
html += "<a href='javascript: google.maps.event.trigger(markers[" + (i - 1) + "],\"click\");'>prev</a> dist:" + google.maps.geometry.spherical.computeDistanceBetween(markers[i].getPosition(), markers[i - 1].getPosition()).toFixed(2) + " meters";
}
infowindow.setContent(html);
infowindow.open(map, marker);
}
})(marker, i))
}
} else {
alert('Directions request failed due to ' + status);
}
});
}
google.maps.event.addDomListener(window, "load", initMap);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map"></div>
Here in this small code snippet,I am facing a little problem.THe problem is if I close all the marker after page completely loaded.And again when I click on markers same detail display on all markers..Here is my code:
var map, infoBubble;
function onload() {
var mapCenter = new google.maps.LatLng(13.0162476, 77.5073893);
map = new google.maps.Map(document.getElementById('dvMap'), {
zoom: 8,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
for (i = 0; i < markers.length; i++) {
//icons[i];
//alert("undefined icons" + icons[i]);
var data = markers[i]
//var myLatlng = new google.maps.LatLng(13.4162691, 77.5064153);
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Par Id ' + data.ParId,
icon: 'Google Marker/In/' + data.title + '.png'
});
if (data.RANK == "1") {
data.RANK = "Primary";
} else {
data.RANK = "Secondary";
}
// alert(data.IMAGEPATH);
var contentString = '<div id="content" align="left" >' +
'<h1>Parcel Details</h1>' +
'<h3>Parcel Id:' + data.ParId + '</h3>' +
'<h3>Rank:' + data.RANK + '</h3>' +
'<h3>Captured by:' + data.Capturedby + '</h3>' +
'<h3>Captured Date:' + data.Capturedate + '</h3>' +
'</div>';
infoBubble = new InfoBubble({
maxWidth: 300,
maxHeight: 200,
backgroundColor: 'rgb(236,255,255)'
});
infoBubble.open(map, marker);
var div = document.createElement('DIV');
div.align = "left";
div.innerHTML = '<IMG BORDER="0" ALIGN="Left" width=97% height=200px alt="Pulpit rock1" SRC="' + data.IMAGEPATH + '"/>';
infoBubble.addTab('Photo', div);
infoBubble.addTab('Details', contentString);
(function (marker, data) {
google.maps.event.addListener(marker, 'click', function () {
// if (!infoBubble.isOpen()) {
infoBubble.open(map, marker);
alert("Par Id:" + data.ParId);
//alert("2");
//}
//infoWindow.open(map);
});
// alert(data.title);
//google.maps.event.trigger(marker, 'click'); //stil
}(marker, data));
}
}
google.maps.event.addDomListener(window, 'load', onload);
the infoBubble-variable will be overwritten inside the loop.
Solution: pass the infoBubble as argument to the function that adds the click-listener:
(function (marker, data , infoBubble) {
google.maps.event.addListener(marker, 'click', function () {
infoBubble.open(map, marker);
});
}(marker, data, infoBubble));
Hello I cannot figure out why I get this error.
I've got a list with inputs which values contain lat/long/name/address.
Printing the markers on the map works fine, using the infowin workED fine, till I realized that it only openend the same info in all windows. Soo, obviously I needed to attach this (the marker i just clicked) to the eventListner.
But, when doing this I get an error saying view.createMarkerHTML is not a function.
Question: What do I do to attach the right info to be open, on the right marker?
view = {
map: {
init: function init (){
view.map.initMap();
},
initMap: function initMap() {
if(navigator.geolocation) {
function hasPosition(position) {
var point = new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
myOptions = {
zoom: 12,
center: point,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
mapDiv = document.getElementById("map"),
map = new google.maps.Map(mapDiv, myOptions);
view.map.handleMarkers(map);
}
navigator.geolocation.getCurrentPosition(hasPosition);
}
},
handleMarkers: function handleMarkers(map) {
var list = $('#pois input'),
l = list.length,
i = 0, lat = '', long = '', marker = {}, theName = '', address = '', info = {};
for (i = 0; i < l; i += 1) {
info = $(list[i]).val().split('|');
lat = parseFloat(info[0], 10);
long = parseFloat(info[1], 10);
theName = info[2];
address = info[3];
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, long),
map: map,
icon: icon
});
google.maps.event.addListener(marker, 'click', function() {
currentMarker = this;view.map.createMarkerHTML(map, theName, address);
});
}
} ,
createMarkerHTML: function createMarkerHTML(map, theName, address) {
var contentString =
'<div id="gMapInfoWin">' +
'<h1>' + theName + '</h1>' +
'<ul>' +
'<li>' + address + '</li>' +
'</ul>' +
'</div>'
;
currentMarker.infowindow = new google.maps.InfoWindow({
content: contentString
});
currentMarker.infowindow.open(map, currentMarker);
}
}
};
Shouldn't you use a closure to keep the values of your variables set in the loop ?
(function(theName, address) {
google.maps.event.addListener(marker, 'click', function() {
currentMarker = this;view.map.createMarkerHTML(map, theName, address);
});
}(theName, address));
You could even add your marker in parameter instead of using currentMarker
I'll wager that it's a scoping issue. Not having access to your libs I can't be sure that this will work, but try replacing:
google.maps.event.addListener(marker, 'click', function() {
currentMarker = this;view.map.createMarkerHTML(map, theName, address);
});
with this:
google.maps.event.addListener(marker,
'click',
createClickListener( this,
map,
theName,
address ) );
and then add this function somewhere else in the program:
function createClickListener( cm, map, theName, address )
{
return function() {
currentMarker = cm;
view.map.createMarkerHTML(map, theName, address);
}
}
for (i = 0; i < l; i += 1) {
info = $(list[i]).val().split('|');
lat = parseFloat(info[0], 10);
long = parseFloat(info[1], 10);
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, long),
map: map,
icon: icon
});
marker.theName = info[2];
marker.address = info[3];
google.maps.event.addListener(marker, 'click', function() {
currentMarker = this;
m_name = this.theName;
m_address = this.address
view.map.createMarkerHTML(map, m_name, m_address);
});
}
marker.theName = info[2];
marker.address = info[3];
currentMarker = this;
m_name = this.theName;
m_address = this.address
... is the soulution!