Geocoder is automatically panning google map to the left - javascript

I am creating a page with a marker that stays fixed at the center of a map, even if the user pans/zoom the map. When the user clicks on the marker it shows the full address of the marker.
The problem is that the infoWindow.setContent() shows a string when I supply one, but pans the map to the left (and doesnt show the infoWindow) when I supply results[0].formatted_address.
The code below is the reverse geocoding I have. The alert function (which I have uncommented) shows the address correctly.
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': input}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
//alert(results[0].formatted_address);
infoWindow.setContent(results[0].formatted_address);
infoWindow.open(map,marker);
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
And my complete Javascript Code is:
var map;
var marker;
var infoWindow = new google.maps.InfoWindow();
function initialize() {
function setUpMap(){
var mapOptions = {
zoom: 14,
center: new google.maps.LatLng(22.519422, 88.35741400000006),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),mapOptions);
google.maps.event.addListener(map, 'center_changed', function() {
removeMarker();
});
google.maps.event.addListener(map, 'idle', function() {
setMarker();
});
}
function removeMarker(){
marker.setMap(null);
}
function setMarker(){
marker = new google.maps.Marker({
position: map.getCenter(),
map: map,
title:"Hello World!"
});
google.maps.event.addListener(marker, 'click', function() {
var input = marker.getPosition();
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': input}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
//alert(results[0].formatted_address);
infoWindow.setContent(results[0].formatted_address);
infoWindow.open(map,marker);
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
});
}
setUpMap();
}
google.maps.event.addDomListener(window, 'load', initialize);
I think the problem is that, when the user clicks on the marker, somehow setMarker() gets called. I can't really find out where the problem is coming from. Can anyone help me find it?

It's forced by a interaction between the center_changed-handler and the autoPan of the infoWindow.
When you open a infoWindow the API by default tries to pan the map to be able to show the infoWindow at the best position. But when this happens the center of the map changes, the marker will be removed(that's why you don't see the infowindow). You must set the disableAutoPan-option of the infoWindow to true.
Modified code:
function initialize() {
function setUpMap() {
var mapOptions = {
zoom: 14,
center: new google.maps.LatLng(22.519422, 88.35741400000006),
mapTypeId: google.maps.MapTypeId.ROADMAP
},
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions),
infoWindow = new google.maps.InfoWindow({
disableAutoPan: true
}),
marker = setMarker(map, infoWindow);
google.maps.event.addListener(map, 'center_changed', function() {
infoWindow.close();
marker.setPosition(this.getCenter());
});
}
function setMarker(map, infoWindow) {
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map,
title: "Hello World!"
});
google.maps.event.addListener(marker, 'click', function() {
var input = marker.getPosition();
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'latLng': input
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log(results)
if (results[0]) {
console.log(results[0].formatted_address)
//alert(results[0].formatted_address);
infoWindow.setOptions({
content: '<div style="xwidth:200px">' + results[0].formatted_address + '</div>'
});
infoWindow.open(map, marker);
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
});
return marker;
}
setUpMap();
}
google.maps.event.addDomListener(window, 'load', initialize);
html {
height: 100%
}
body {
height: 100%;
margin: 0;
padding: 0
}
#map_canvas {
height: 100%
}
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<div id="map_canvas"></div>

Related

After maximize google map window, autocomplete doesn't work

I'm trying to use google map with mvc in my project.
I can find the location by typing in textbox while map is minimized.
The location is showed automatically.
However the location isn't showed automatically in the maximize state.
Here is my code :
function initialize() {
var latlng = new google.maps.LatLng(Lat, Long);
var map = new google.maps.Map(document.getElementById('map'), {
center: latlng,
zoom: 13
});
var marker = new google.maps.Marker({
map: map,
position: latlng,
draggable: true,
anchorPoint: new google.maps.Point(0, -29)
});
var input = document.getElementById('searchInput');
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var geocoder = new google.maps.Geocoder();
var autocomplete = new google.maps.places.Autocomplete(input);
//Set initial restrict countries.
autocomplete.setComponentRestrictions(
{ 'country': ['mm'] });
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
autocomplete.addListener('place_changed', function () {
infowindow.close();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
window.alert("Autocomplete's returned place contains no geometry");
return;
}
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17);
}
marker.setPosition(place.geometry.location);
marker.setVisible(true);
infowindow.setContent(place.formatted_address);
infowindow.open(map, marker);
});
// this function will work on marker move event into map
google.maps.event.addListener(marker, 'dragend', function () {
geocoder.geocode({ 'latLng': marker.getPosition() }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
infowindow.setContent(results[0].formatted_address);
infowindow.open(map, marker);
}
}
});
});
}
google.maps.event.addDomListener(window, 'load', initialize);
Screenshot :
Screenshot 1
Screenshot 2
Set a z-index for .pac-container that is above the map (warning undocumented behavior, may change with future releases of the API)
.pac-container {
z-index: 2147483648;
}
proof of concept fiddle
code snippet:
function initialize() {
var latlng = new google.maps.LatLng(21.958828, 96.089103);
var map = new google.maps.Map(document.getElementById('map'), {
center: latlng,
zoom: 13
});
var marker = new google.maps.Marker({
map: map,
position: latlng,
draggable: true,
anchorPoint: new google.maps.Point(0, -29)
});
var input = document.getElementById('searchInput');
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var geocoder = new google.maps.Geocoder();
var autocomplete = new google.maps.places.Autocomplete(input);
//Set initial restrict countries.
autocomplete.setComponentRestrictions({
'country': ['mm']
});
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
autocomplete.addListener('place_changed', function() {
infowindow.close();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
window.alert("Autocomplete's returned place contains no geometry");
return;
}
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17);
}
marker.setPosition(place.geometry.location);
marker.setVisible(true);
infowindow.setContent(place.formatted_address);
infowindow.open(map, marker);
});
// this function will work on marker move event into map
google.maps.event.addListener(marker, 'dragend', function() {
geocoder.geocode({
'latLng': marker.getPosition()
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
infowindow.setContent(results[0].formatted_address);
infowindow.open(map, marker);
}
}
});
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
z-index: 0;
}
#searchInput {
top: 15px;
left: 120px;
}
.pac-container {
z-index: 2147483648;
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
<input id="searchInput" />
<div id="map"></div>

How to display certain names in google maps infowindow marker

I'm kind of stuck and was wondering if someone could help, here is a snippet of my code:
function test(person,address)
{
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(43.761539, -79.411079),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow()
var marker, i;
var clatlng, clat, clng;
for (i = 0; i < address.length; i++) {
geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address[i]}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
clat = results[0].geometry.location.lat();
clng = results[0].geometry.location.lng();
clatlng = new google.maps.LatLng(clat, clng);
marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
google.maps.event.addListener(marker, 'click', (function(marker) {
//cant add information here dont know why...
return function() {
infowindow.setContent(person[0].cName + "<br>" + results[0].formatted_address);
infowindow.open(map, marker);
}
})(marker));
}
});
}//for
}//function
I'm passing an array of addresses and names. I've been trying to get each marker to display the person's name and address upon clicking on the infowindow of the marker on the map. This is where I'm having issues, I solved the address issue by just using the results[0].formatted_address but am unsure on how to display the specific user to that marker. Any tips would be appreciated.
You need function closure on the name as well as the marker in the click listener for the marker. As the name of the person needs to be available in the callback for the geocoder as well, you need function closure on the geocoder callback function as well.
Related questions
Google Maps V3 - I cannot reconcile closure
JS Geocoder cannot assign Global Variable for Google Maps Variable
proof of concept fiddle
code snippet:
function test(person, address) {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: new google.maps.LatLng(43.761539, -79.411079),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow()
var marker, i;
var clatlng, clat, clng;
for (i = 0; i < address.length; i++) {
geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address[i]
}, (function(name) {
return function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
clat = results[0].geometry.location.lat();
clng = results[0].geometry.location.lng();
clatlng = new google.maps.LatLng(clat, clng);
marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
google.maps.event.addListener(marker, 'click', (function(marker, name) {
//cant add information here dont know why...
return function() {
infowindow.setContent(name + "<br>" + results[0].formatted_address);
infowindow.open(map, marker);
}
})(marker, name));
}
}
})(person[i]));
} //for
} //function
function initialize() {
test(["fred", "george", "frank"], ["New York, NY", "Newark, NJ", "Toronto, CA"]);
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>

How to populate a string array by clicking on the map in JavaScript?

I want to gather information as I click on the map in JavaScript. I'm using Google Maps API. As I right click on the map a reverse Geocode tool works and gets the information of the point clicked.
What I want to do is as I clicked on the map I want to see these Geocoded points names and some attributes in a list.
Is it even possible ?
here I'm sharing some of my code ;
This is clicking and getting coordinates ;
google.maps.event.addListener(map, "rightclick", function (event) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
alert(markersinfo);
document.getElementById("latlng").value = lat.toFixed(5) + ', ' + lng.toFixed(5);
geocodeLatLng(geocoder, map, infowindow);
});
Here is geocoding ;
function geocodeLatLng(geocoder, map, infowindow) {
var input = document.getElementById('latlng').value;
var latlngStr = input.split(',', 2);
var latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])};
geocoder.geocode({'location': latlng}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
if (results[1]) {
//map.setZoom(11);
var marker = new google.maps.Marker({
position: latlng,
map: map
});
markersinfo.push(marker);
infowindow.setContent(results[1].formatted_address);
infowindow.open(map, marker);
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
I've tried to create an array called markersinfo[] and tried to push markers in to this array but I've realized that I'm just sending objects to array but not the informations. I need Geocode string , latitude and longitude of each clicked point in this markersinfo[] array.
So, instead of google.maps.Marker objects you would like to save lat, lng and address properties in markersinfo array, right? If so, the below example shows how to accomplish it:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: {
lat: -28.643387,
lng: 153.612224
},
mapTypeControl: true
});
var infowindow = new google.maps.InfoWindow({
content: ''
});
var geocoder = new google.maps.Geocoder();
var markersinfo = [];
google.maps.event.addListener(map, "rightclick", function(event) {
geocodeLatLng(geocoder, event.latLng,
function(results) {
if (results[0]) {
var marker = new google.maps.Marker({
position: event.latLng,
map: map
});
infowindow.setContent(results[1].formatted_address);
infowindow.open(map, marker);
markersinfo.push({
'address': results[0].formatted_address,
'lat': event.latLng.lat(),
'lng': event.latLng.lng()
}); //save info
document.getElementById('output').innerHTML = JSON.stringify(markersinfo);
} else {
window.alert('No results found');
}
},
function(status) {
window.alert('Geocoder failed due to: ' + status);
});
});
}
function geocodeLatLng(geocoder, latLng, success, error) {
var location = {
lat: latLng.lat(),
lng: latLng.lng()
};
geocoder.geocode({
'location': location
}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
success(results);
} else {
error(status);
}
});
}
html,
body {
height: 220px;
margin: 0;
padding: 0;
}
#map {
height: 220px;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?signed_in=false&callback=initMap" async defer>
</script>
<div id='output' />
You can gather your info in the same area where you're putting info in your infowindow. Just save your lat / long, etc to a string or array. You haven't been very clear about what content should be shown (other than lat / long), or what is clicked to trigger the display. So this code will need to be adjusted to suit your specific needs.
Example:
var contentString = "";
if (results[1]) {
//...
var contentString += "Location: " + latlng + "<br />";
}
//perhaps add trigger this on an event, depending on what you want.
$('#myDiv').append(contentString);
And then your div to hold the content:
<div id="myDiv"></div>

Simple Geocoding Map in JQuery

How do I make a simple map in Jquery that plots only one location. Here is the code I have now. this plots an array of locations, but I just need a simple map that will plot one point in Lng,Lat format. I am using the google geocoder for this.
var geocoder;
var map;
var markersArray = [];
var bounds;
var infowindow = new google.maps.InfoWindow({
content: ''
});
function initialize() {
geocoder = new google.maps.Geocoder();
bounds = new google.maps.LatLngBounds();
var myOptions = {
zoom: 2,
mapTypeId: google.maps.MapTypeId.ROADMAP,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
}
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
geocoder.geocode({
'address': '5th Avenus New Yort'
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
bounds.extend(results[0].geometry.location);
markersArray.push(marker);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
plotMarkers();
}
var locationsArray = [
['Google Official', '1600 Amphitheatre Parkway, Mountain View, USA'],
['Google 1', '112 S. Main St., Ann Arbor, USA'],
['Google 2', '10 10th Street NE, Suite 600 USA']
];
function plotMarkers() {
var i;
for (i = 0; i < locationsArray.length; i++) {
codeAddresses(locationsArray[i]);
}
}
function codeAddresses(address) {
geocoder.geocode({
'address': address[1]
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(address[0]);
infowindow.open(map, this);
});
bounds.extend(results[0].geometry.location);
markersArray.push(marker);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
map.fitBounds(bounds);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
I then call this in my file with:
<body>
<div id="map_canvas" style="width: 100%; height: 700px;"></div>
</body>
</html>
I need the new map to plot one lat and lng point along with posting the listing the location in the textbook as above. I can not figure out how to do this without an array.
It seems like you're using an example that shows multiple markers.
I haven't tested it, but I think this JavaScript is close:
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions = {
zoom: 8,
center: latlng
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
geocoder.geocode( { 'address': '5th Avenue New York' }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
Review this for more information: https://developers.google.com/maps/documentation/javascript/geocoding

Center Google Maps InfoWindow On Load

I'm having a problem centering my InfoWindow on page load. On load, the map is centering on the marker, which puts the InfoWindow off screen (I'm working with a short height for my map container).
Now clicking the marker does re-center the map on the InfoWindow so that it looks exactly like I want. That being the case, I've even tried firing the marker.click trigger to achieve a solution on load, but had no luck. What am I missing?
JSFIDDLE: http://jsfiddle.net/q9NTS/7/
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script type="text/javascript">
var geocoder = new google.maps.Geocoder();
var marker;
var infoWindow;
var map;
function initialize() {
var mapOptions = {
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
setLocation();
}
function setLocation() {
var address = '#(Model.Event.Address)' + ', ' + '#(Model.Event.City)' + ', ' + '#(Model.Event.State)' + ' ' + '#(Model.Event.Zip)';
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var position = results[0].geometry.location;
marker = new google.maps.Marker({
map: map,
position: position,
title: '#(Model.Event.Venue)'
});
map.setCenter(marker.getPosition());
var content = 'blah';
infoWindow = new google.maps.InfoWindow({
content: content
});
google.maps.event.addListener(marker, 'click', function () {
infoWindow.open(map, marker);
});
//infoWindow.open(map, marker); doesn't work
google.maps.event.trigger(marker, 'click'); //still doesn't work
}
else {
//
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
You apparently just need to wait longer before triggering the click event.
// wait until the map is idle.
google.maps.event.addListenerOnce(map, 'idle', function() {
setTimeout(function() {
// wait some more (...)
google.maps.event.trigger(marker, 'click'); //still doesn't work
},2000);
});
fiddle

Categories

Resources