I'm creating a store locator with a list of stores and their details, plus each store has a View on Map button which allows you to move to the correspondent marker and displays an infowindow, like on this website http://www.poundland.co.uk/store-finder/searchResults/
I've got this code to create markers:
function createMarker(point, name, address, urladdress, locationNumber,id) {
var image = {
url: "/i/markers/MapIcon.png",
size: new google.maps.Size(48, 55),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(24, 0)
};
var marker = new google.maps.Marker({
position: point,
map: map,
/*shadow: shadow,*/
icon: image,
title: address,
// id:id
});
var infowindow = new google.maps.InfoWindow({
content: name + '<br>' + address + '<br>' + '<a target="_blank" href="http://maps.google.co.uk/maps?f=q&hl=en&q=from:' + homeSpatialInfo.fromAddress + '+to:' + urladdress + '">Directions</a>'
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
map.setZoom(16);
});
return marker;
}
I'm giving each button the ID of the store it is associated with it
<div style="text-align: right; margin-top: 5px;">
<asp:Button ID="viewStoreBtn-133"class="btn btn-default btn-sm viewStoreBtn" runat="server" Text="view on map" style="border-radius: 10px;"/>view on map
</div>
After that I guess I will have to add an onclick event listener but I'm not sure what to write in the onclick function (as I'm very new to this).
You can use google.maps.event.addListener for click. This is my example and i think it will be usefull for you.
In initMap add these codes:
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event);
});
function placeMarker(event) {
var geocoder = new google.maps.Geocoder;
console.log(event.latLng);
var infowindow = new google.maps.InfoWindow();
geocoder.geocode({'location': event.latLng}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
if (results[1]) {
map.setZoom(11);
var marker = new google.maps.Marker({
position: event.latLng,
map: map
});
google.maps.event.addListener(marker, 'click', function() {
if (infowindow) {
infowindow.close();
}
infowindow.setContent('<div><strong>' + results[0].name + '</strong><br>' +
'<br>' +
results[0].formatted_address + '</div>');
console.log(results[0].geometry.location);
console.log(results[0].geometry.location.lat());
console.log(results[0].name + results[0].formatted_address + results[0].geometry.location.lat() + results[0].geometry.location.lng());
infowindow.open(map, this);
});
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
EDIT:
if you have marker you can just use pan function to move view area.
google.maps.event.addListener(marker, 'click', function() {
map.panTo(this.getPosition());
}
Related
I am using Google place API to retrieve place reviews from the API, Here is the code that i am using to retrive data from Google place API its working fine but it is working on place name, i want it to search on place id. I have attachted the js code and screen shot that its working fine.
Screen shot
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 41.9030632,
lng: 12.466275999999993
},
zoom: 13
});
var input = document.getElementById('pac-input');
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var infowindow = new google.maps.InfoWindow();
var marker = new google.maps.Marker({
map: map
});
marker.addListener('click', function() {
infowindow.open(map, marker);
});
autocomplete.addListener('place_changed', function() {
infowindow.close();
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17);
}
// Set the position of the marker using the place ID and location.
marker.setPlace({
placeId: place.place_id,
location: place.geometry.location
});
marker.setVisible(true);
infowindow.setContent('<div><strong>' + place.name + '</strong><br>' +
'Place ID: ' + place.place_id + '<br>' +
place.formatted_address);
infowindow.open(map, marker);
var service = new google.maps.places.PlacesService(map);
var details_container = document.getElementById('details');
service.getDetails({
placeId: place.place_id
}, function(place, status) {
details_container.innerHTML ='<p><strong>Place ID:</strong> <code>' + place.place_id + '</code></p>' +
'<p><strong>Address:</strong> <code>' + place.formatted_address + '</code></p><h1>Reviews</h1>';
for(var a=0;a<5;a++){
details_container.innerHTML +='<h2 style="font-weight:300;color:red;">'+place.reviews[a].author_name+'</h2>';
details_container.innerHTML +='<p>'+place.reviews[a].rating+' Stars</p>';
details_container.innerHTML +='<p> Comment > '+place.reviews[a].text+'</p>';
}
console.log(place.place_id);
});
}); // end autocomplete addListener
}
So I'm trying to build a simple web app that takes the address from the user and places a marker on that address. After that, the user can drag the marker to another location and the address field should update accordingly. The problem is I cannot get the address field to update automatically on dragend. The best I have done so far is to update when you click the marker but this is a horrible user experience.
tl;dr change the code so that the "address" field gets updated on dragend and not on click.
var geocoder = new google.maps.Geocoder();
var map;
var marker;
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150, 50)
});
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(37.9839, 23.7294);
var mapOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
}
function geocodePosition(pos) {
geocoder.geocode({
latLng: pos
}, function(responses) {
if (responses && responses.length > 0) {
marker.formatted_address = responses[0].formatted_address;
} else {
marker.formatted_address = 'Cannot determine address at this location.';
}
infowindow.setContent("<b>" + marker.formatted_address + "</b>" + "<br> Drag the marker and click on it to update the address field!");
infowindow.open(map, marker);
});
}
function codeAddress() {
var address = document.getElementById('address').value;
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
if (marker) {
marker.setMap(null);
if (infowindow) infowindow.close();
}
marker = new google.maps.Marker({
map: map,
draggable: true,
position: results[0].geometry.location
});
google.maps.event.addListener(marker, 'dragend', function() {
geocodePosition(marker.getPosition());
});
google.maps.event.addListener(marker, 'click', function() {
newAddress = marker.formatted_address;
document.getElementById("address").value = newAddress;
if (marker.formatted_address) {
infowindow.setContent("<b>" + marker.formatted_address + "</b>" + "<br> Drag the marker and click on it to update the address field!");
} else {
infowindow.setContent("<b>" + address + "</b>" + "<br> Drag the marker and click on it to update the address field!");
}
infowindow.open(map, marker);
});
google.maps.event.trigger(marker, 'click');
}
else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
google.maps.event.addDomListener(window, "load", initialize);
geocoding runs asynchronously, you must update the input when the response arrives, not immediately.
Possible approach to achieve it:
change
google.maps.event.addListener(marker, 'dragend', function() {
geocodePosition(marker.getPosition());
});
...to
google.maps.event.addListener(marker, 'dragend', function() {
var that=this;
geocodePosition(that.getPosition(),
function(){
google.maps.event.trigger(that, 'click');
});
});
now you have a callback-function which may be executed when the response arrives.
To call it change
function geocodePosition(pos) {
geocoder.geocode({
latLng: pos
}, function(responses) {
if (responses && responses.length > 0) {
marker.formatted_address = responses[0].formatted_address;
} else {
marker.formatted_address = 'Cannot determine address at this location.';
}
infowindow.setContent("<b>" + marker.formatted_address + "</b>" + "<br> Drag the marker and click on it to update the address field!");
infowindow.open(map, marker);
});
}
...to
function geocodePosition(pos,callback) {
geocoder.geocode({
latLng: pos
}, function(responses) {
if (responses && responses.length > 0) {
marker.formatted_address = responses[0].formatted_address;
} else {
marker.formatted_address = 'Cannot determine address at this location.';
}
infowindow.setContent("<b>" + marker.formatted_address + "</b>" + "<br> Drag the marker to update the address field!");
callback();//<--this will trigger the marker-click
infowindow.open(map, marker);
});
}
I'm trying to show 2 locations on a map that when clicked display all the place details in their respective infowindows. I can only get a return of very limited place details to show, namely the address and that's about it. You can see here: http://www.intermountainvet.com/contact-0. I am console logging the place objects.
I know that there is a robust google place for this business, you can see here: https://www.google.com/maps/place/Intermountain+Pet+Hospital+%26+Lodge/#43.5906437,-116.4033528,15z/data=!4m6!1m3!3m2!1s0x0:0x2a5e055f442189ea!2sIntermountain+Pet+Hospital+%26+Lodge!3m1!1s0x0:0x2a5e055f442189ea
Why can't I access all of those place details to display in my infowindow?
Here is my code. (I have my api key and the libraries=places src in a script tag that I'm not showing here):
<script type="text/javascript">
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 43.618928, lng: -116.274319},
zoom: 11
});
var infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
var locA = service.getDetails({
placeId: 'ChIJa_maRXxRrlQRSimVL1yUG8Q'
}, function(place, status) {
console.log(place);
console.log(status);
if (status === google.maps.places.PlacesServiceStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('<img src="' + place.icon + '" /><font style="color:#000;">' + place.name +
'<br />Rating: ' + place.rating + '<br />Vicinity: ' + place.vicinity + '</font>');
infowindow.open(map, this);
});
}
});
var locB = service.getDetails({
placeId: 'ChIJow1xfMRUrlQR6ewuO4NvrF0'
}, function(place, status) {
console.log(place);
console.log(status);
if (status === google.maps.places.PlacesServiceStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('<img src="' + place.icon + '" />font style="color:#000;">' + place.name +
'<br />Rating: ' + place.rating + '<br />Vicinity: ' + place.vicinity + '</font>');
infowindow.open(map, this);
});
}
});
}
Thanks for looking. I feel like this should be simple and I must be missing something minor.
You need to use the place id for the business (ChIJa_maRXxRrlQR6okhRF8FXio) not the address (ChIJa_maRXxRrlQRSimVL1yUG8Q)
I am trying to make a website that need a google map on it with some markers
I have a problem with reading a javascript 2D array multiple time it gives me error
Cannot read property '0' of undefined
and here its my code
function initialize() {
var locations = [
//'City',LatLng,LatLng,Zoom
['Egypt', 26.820553, 30.802498, 6], //Center of whole map
['Alexandria', 'Egypt'], //pointer
['Mansoura', 'Egypt'], //pointer
['Assiut', 'Egypt'] //pointer
];
var mapOptions = {
zoom: locations[0][3],
center: new google.maps.LatLng(locations[0][1], locations[0][2]),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);
var infowindow = new google.maps.InfoWindow();
var marker, i;
var geocoder = new google.maps.Geocoder();
var image = 'flag.png';
for (i = 1; i < locations.length; i++) {
geocoder.geocode({ 'address': locations[i][0] + ' ' + locations[i][1] }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
marker = new google.maps.Marker({
animation: google.maps.Animation.DROP,
map: map,
icon: image,
position: results[0].geometry.location,
title: locations[i][0]
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent('<b style="font-size:30px;">' + locations[i][0] + '</b>'
+ '<br><b>Starting Date:</b> 11/5/2012'
+ '<br><b>Ending Date:</b> 30/5/2012'
+ '<br>Event Website');
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?key=AIzaSyA6yYH66F1L3NgHAobufuUF6l-jjVCLwfE&sensor=false&' +
'callback=initialize';
document.body.appendChild(script);
}
window.onload = loadScript;
I got the error in this section
when I am trying to read locations[i][0] many times.
for (i = 1; i < locations.length; i++) {
geocoder.geocode({ 'address': locations[i][0] + ' ' + locations[i][1] }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
marker = new google.maps.Marker({
animation: google.maps.Animation.DROP,
map: map,
icon: image,
position: results[0].geometry.location,
title: locations[i][0]
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent('<b style="font-size:30px;">' + locations[i][0] + '</b>'
+ '<br><b>Starting Date:</b> 11/5/2012'
+ '<br><b>Ending Date:</b> 30/5/2012'
+ '<br>Event Website');
infowindow.open(map, marker);
}
})(marker, i));
}
});
}
and if there is anyway that I can handle this code in c# code behind it will be nice
[ignore previous comment about results]
The problem is that you're referencing i in the geocode() callback. The geocode() method is asynchronous - i.e. your callback is called after the for-loop has already finished. And at that time, i = 4, meaning locations[i] is undefined.
You should read up on how closures work if that doesn't make sense, but basically the solution is to put the code inside your for-loop into a separate function and pass it the location entry you want to work with, like so:
function geocodeLocation(location) {
geocoder.geocode({ 'address': location[0] + ' ' + location[1] },
function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
marker = new google.maps.Marker({
animation: google.maps.Animation.DROP,
map: map,
icon: image,
position: results[0].geometry.location,
title: location[0]
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent('<b style="font-size:30px;">' + location[0] + '</b>'
+ '<br><b>Starting Date:</b> 11/5/2012'
+ '<br><b>Ending Date:</b> 30/5/2012'
+ '<br>Event Website');
infowindow.open(map, marker);
}
})(marker, i));
}
}
);
}
for (var i = 1; i < locations.length; i++) {
geocodeLocation(locations[i]);
}
I am using geolocation to get the address of places on my google maps API by looking up the longitude and latitude and returning the results to my page for use in my database.
I have been unable to display these results in my infowindow in my map.
How can I using the code below include the address in my infowindow. It currently displays the long and lat with the following code:
infowindow.setContent('<div><strong>' + marker.getPosition()+ '</strong><br>');
infowindow.open(map, marker);
The function geocodePosition looks up the address of the coordinates and appends it to the html input in my form.
How can I adapt it to update the infowindow too. I have tried many methods now and no success. Any ideas??
<script type="text/javascript">
var geocoder = new google.maps.Geocoder();
function geocodePosition(pos) {
geocoder.geocode({
latLng: pos
}, function(responses) {
if (responses && responses.length > 0) {
updateMarkerAddress(responses[0].formatted_address);
} else {
updateMarkerAddress('Cannot determine address at this location.');
}
});
}
function updateMarkerStatus(str) {
document.getElementById('markerStatus').value = str;
}
function updateMarkerPosition(latLng) {
document.getElementById('info').value = [
latLng.lat(),
latLng.lng()
].join(', ');
}
function updateMarkerAddress(str) {
document.getElementById('address').value = str;
}
function initialize() {
var latLng = new google.maps.LatLng(-34.397, 150.644);
var map = new google.maps.Map(document.getElementById('mapCanvas'), {
zoom: 8,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var marker = new google.maps.Marker({
position: latLng,
title: 'Property location marker',
map: map,
draggable: true
});
var input = document.getElementById('searchTextField');
var autocomplete = new google.maps.places.Autocomplete(input);
var infowindow = new google.maps.InfoWindow();
autocomplete.bindTo('bounds', map);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
var place = autocomplete.getPlace();
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17);
}
var image = new google.maps.MarkerImage(
place.icon, new google.maps.Size(71, 71),
new google.maps.Point(0, 0), new google.maps.Point(17, 34),
new google.maps.Size(35, 35));
marker.setIcon(image);
marker.setPosition(place.geometry.location);
infowindow.setContent('<div><strong>' + marker.getPosition()+ '</strong><br>');
infowindow.open(map, marker);
});
// Update current position info.
updateMarkerPosition(latLng);
geocodePosition(latLng);
infowindow.setContent('<div><strong>' + marker.getPosition()+ '</strong><br>');
infowindow.open(map, marker);
// Add dragging event listeners.
google.maps.event.addListener(marker, 'dragstart', function() {
updateMarkerAddress('Dragging...');
});
google.maps.event.addListener(marker, 'drag', function() {
updateMarkerStatus('Dragging...');
updateMarkerPosition(marker.getPosition());
});
google.maps.event.addListener(marker, 'dragend', function() {
updateMarkerStatus('Drag ended');
geocodePosition(marker.getPosition());
//Show property address in window
infowindow.setContent('<div><strong>' + marker.getPosition()+ '</strong><br>');
infowindow.open(map, marker);
});
}
// Onload handler to fire off the app.
google.maps.event.addDomListener(window, 'load', initialize);
</script>
marker.getPosition() is not going to provide the street address. Given your current code, your best bet is to move:
infowindow.setContent('<div><strong>' + marker.getPosition()+ '</strong><br>');
to your geocodePosition() function, and then to pass the infowindow object as a second argument to that function.
So in your initialize() function you would modify calls to geocodePosition by including a second argument:
function initialize() {
...
geocodePosition(marker.getPosition(), infowindow);
}
Then in your geocodePosition() function, you would accept the second argument, and update it with the responses[0].formatted_address value. I added variables to make it easier to pass on the values for address and the message.
function geocodePosition(pos, infowindow) {
geocoder.geocode({
latLng: pos
}, function(responses) {
if (responses && responses.length > 0) {
var address = responses[0].formatted_address;
updateMarkerAddress(address);
infowindow.setContent('<div><strong>' + address + '</strong><br>');
} else {
var msg = 'Cannot determine address at this location.';
updateMarkerAddress(msg);
infowindow.setContent('<div><strong>' + msg + '</strong><br>');
}
});
}
You might want to use Google map api - http://code.google.com/apis/maps/documentation/geocoding/#GeocodingRequests
There are others APIs that will give you the same - but most of them will cost money and with Google you get a lot of 'miles' for free.