I am facing an issue with my google maps code. I am trying to place markers on my map from an array. But I am stuck in between when I am trying to do the same.My firebug console gives me an error that results is not defined in function createMarkers. Here is my code:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script>
var addresses = new Array();
abc = document.getElementsByTagName('td');
//loc = mydiv.getAttribute("data-addr");
var l = abc.length;
for (var i=0; i < l; i++){
if (abc[i].hasAttribute('name'))
{
addresses.push("'"+abc[i].innerHTML+"'");
}
}
var len = addresses.length;
var geocoder;
var map;
var add = document.getElementById("addr").value;
window.onload = function init() {
geocoder = new google.maps.Geocoder();
var add = document.getElementById("address").value;
var latlng = codeAddress(add);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
}
//for (var i = 0; i < addresses.length; i++)
//{
function codeAddress(add)
{
//var addr = addresses[i];
geocoder.geocode( { 'address':add }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function createMarkers()
{
for(var i = 0; i < len; i++){
(function(addresses){
geocoder.geocode( { 'address': addresses }, function(results) {
var marker = new google.maps.Marker ({
map: map,
position: results[0].geometry.location,//error:results[0] is undefined
title: address
});
google.maps.event.addListener(marker, 'click', function() {
alert(addresses);
});
});
})(addresses[i]);
}
}
window.onload = createMarkers;
</script>
Well after a long battle with the code,I found the solution. The error I was facing because I was pushing the addresses into array in a wrong format i.e. I pushed the addresses into the array with a '(single quote) surrounding it,which the geocoder did not accept.So then finally edited the loc where I was pushing the address.The modified code is as :
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script>
var addresses = new Array();
abc = document.getElementsByTagName('td');
//loc = mydiv.getAttribute("data-addr");
var l = abc.length;
for (var i=0; i < l; i++){
if (abc[i].hasAttribute('name'))
{
addresses.push(""+abc[i].innerHTML+""); //removed single quotes here. see previous code
}
}
var len = addresses.length;
var geocoder;
var map;
var add = document.getElementById("addr").value;
window.onload = function init() {
geocoder = new google.maps.Geocoder();
var add = document.getElementById("address").value;
var latlng = codeAddress(add);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
}
//for (var i = 0; i < addresses.length; i++)
//{
function codeAddress(add)
{
//var addr = addresses[i];
geocoder.geocode( { 'address':add }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function createMarkers()
{
for(var i = 0; i < len; i++){
(function(addresses){
geocoder.geocode( { 'address': addresses }, function(results) {
var marker = new google.maps.Marker ({
map: map,
position: results[0].geometry.location,//error:results[0] is undefined
title: address
});
google.maps.event.addListener(marker, 'click', function() {
alert(addresses);
});
});
})(addresses[i]);
}
}
window.onload = createMarkers;
</script>
Related
i have variable array 2 dimentional:
var locations = new Array(3);
for (var i = 0; i < 3; i++) {
locations[i] = ['1', '2', '3'];
}
and i have array with name Place inside
data = ["Terogong, Indonesia", "Blok M, Indonesia", "Cipinang, Indonesia"]
when i use Geocoder to search Lat and Lang, then its fill Locations[] with name place, Lat and Lang:
for (var i = 0; i < data.length-1; i++) {
var c = data[i];
geocoder.geocode( { 'address': data[i] + ", indonesia"}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
//alert("location : " + results[0].geometry.location.lat() + " " +results[0].geometry.location.lng());
locations[i] = [c , results[0].geometry.location.lat(), results[0].geometry.location.lng()];
alert(locations[i]);
} else {
alert("Something got wrong " + status);
}
});
}
and then, when i alert(locations[0]) its apear 1.
why this is happen??
The geocoder is asynchronous. One option is to use function closure to associate the variables in the request with the callback function:
for (var i = 0; i < data.length; i++) {
geocoder.geocode({
'address': data[i] + ", indonesia"
}, (function(data, i) { return function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
locations[i] = [data, results[0].geometry.location.lat(), results[0].geometry.location.lng()];
var mark = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
title: data
});
// alert(locations[i]);
} else {
alert("Something got wrong " + status);
}
}}(data[i], i))); // has function closure on data[i] as data, i (as i)
}
working fiddle
code snippet:
var geocoder = new google.maps.Geocoder();
var map;
var data = ["Terogong, Indonesia", "Blok M, Indonesia", "Cipinang, Indonesia"];
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var bounds = new google.maps.LatLngBounds();
var locations = new Array(3);
for (var i = 0; i < 3; i++) {
locations[i] = ['1', '2', '3'];
}
for (var i = 0; i < data.length; i++) {
geocoder.geocode({
'address': data[i] + ", indonesia"
}, (function(data, i) {
return function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
bounds.extend(results[0].geometry.location);
map.fitBounds(bounds);
locations[i] = [data, results[0].geometry.location.lat(), results[0].geometry.location.lng()];
var mark = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
title: data
});
} else {
alert("Something got wrong " + status);
}
}
}(data[i], i)));
}
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>
I want to get zip codes from latitude and longitude coordinates, which are stored in an excel sheet called Test.xlsx
It looks like this:
Column 1 Column 2 Column 3
Row 1 Latitude Longitude Result
Row 2 40.730885 -73.997383 New York City, New York 10012, USA
Row 3 ... ... ...
Since I added a loop to iterate over the rows in the excel sheet I have got problems because of the asynchronous Google Geocoder.
I think I need a callbackfunction but don't know how to integrate it into the existing code.
I already did some research on stackoverflow and the best result, which might be very useful was that one: Google geocoding mutliple addresses in a loop with javascript, how do I know when everything is done?
Here is my code:
<html>
<head>
<link href="https://google-developers.appspot.com/maps/documentation/javascript/examples/default.css" rel="stylesheet">
<script src="https://maps.googleapis.com/maps/api/js?sensor=true"></script>
<script>
var geocoder;
var map;
var infowindow = new google.maps.InfoWindow();
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(40.730885,-73.997383);
var mapOptions = {
zoom: 8,
center: latlng,
mapTypeId: 'roadmap'
}
map = new google.maps.Map(document.getElementById('map_canvas'),mapOptions);
}
function codeLatLng(){
var input = document.getElementById('latlng').value;
var latlngStr = input.split(',',2);
var excel = new ActiveXObject("Excel.Application");
var excel_sheet = new ActiveXObject("Excel.Sheet");
var excel_file = excel.Workbooks.Open("d:\\Test.xlsx");
excel_sheet = excel.Worksheets("Tabelle1");
var i = 2;
for(var i=2;i<=10;i++){
var lat = excel_sheet.Range("A"+i);
var lng = excel_sheet.Range("B"+i);
var latlng = new google.maps.LatLng(lat,lng);
geocoder.geocode({'latLng':latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]){
excel_sheet.Range("C"+i) = results[1].formatted_address;
excel_sheet.Application.Visible = true;
excel_sheet.SaveAs("d:\\Test.xlsx");
excel_sheet.Application.Quit();
} else {
excel_sheet.Range("C"+i)="No results found";
}
}else {
alert('Geocoder failed due to: ' + status);
}
});
}
}
</script>
</head>
<body onload="initialize()">
<div>
<input id="latlng" type="textbox" value = "40.730885,-73.997383">
</div>
<div>
<input type="button" value="Reverse Geocode" onclick="codeLatLng()">
</div>
<div id="map_canvas" style="height: 90%; top:60px, border: 1px solid black;"></div>
</body>
</html>
You have a callback function in your code. What you need is function closure on the reverse geocode operation to associate the response with the request.
var geocoder = new google.maps.Geocoder();
var map;
function initialize() {
var latlng = new google.maps.LatLng(40.730885,-73.997383);
var mapOptions = {
zoom: 8,
center: latlng,
mapTypeId: 'roadmap'
}
map = new google.maps.Map(document.getElementById('map_canvas'),mapOptions);
}
function codeLatLng(latlng, excel_sheet, i){
geocoder.geocode({'latLng':latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results && (results.length > 0 )){
// return the result with the type = "postal_code" (won't always be results[1]
for (var j=0; j<results.length; j++) {
for (var k=0; k<results[j].types.length; k++) {
if (results[j].types[k] == "postal_code") {
excel_sheet.Range("C"+i) = results[j].formatted_address;
excel_sheet.Application.Visible = true;
excel_sheet.SaveAs("");
excel_sheet.Application.Quit();
}
}
}
} else {
excel_sheet.Range("C"+i)="No results found";
}
}else {
alert('Geocoder failed due to: ' + status);
}
});
}
function codeLatLngs(){
var input = document.getElementById('latlng').value;
var latlngStr = input.split(',',2);
var excel = new ActiveXObject("Excel.Application");
var excel_sheet = new ActiveXObject("Excel.Sheet");
var excel_file = excel.Workbooks.Open("");
excel_sheet = excel.Worksheets("Tabelle1");
var i = 2;
for(var i=2;i<=10;i++){
var lat = excel_sheet.Range("A"+i);
var lng = excel_sheet.Range("B"+i);
var latlng = new google.maps.LatLng(lat,lng);
codeLatLng(latlng, excel_sheet, i);
}
}
Can any one give me an idea on how to zoom your map according to the markers. Actually I have geocoded the addresses and the markers are shown on the map. But they are not centered i.e. I have to drag the map to see the other marker.I want my map to fit bounds using the addresses that I have in my addresses array. How this can be done.? My current code for geocoding is:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script>
var addresses = new Array();
abc = document.getElementsByTagName('td');
//loc = mydiv.getAttribute("data-addr");
var l = abc.length;
for (var i=0; i < l; i++){
if (abc[i].hasAttribute('name'))
{
addresses.push(""+abc[i].innerHTML+""); //removed single quotes here. see previous code
}
}
var len = addresses.length;
var geocoder;
var map;
var add = document.getElementById("addr").value;
window.onload = function init() {
geocoder = new google.maps.Geocoder();
var add = document.getElementById("address").value;
var latlng = codeAddress(add);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
}
//for (var i = 0; i < addresses.length; i++)
//{
function codeAddress(add)
{
//var addr = addresses[i];
geocoder.geocode( { 'address':add }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function createMarkers()
{
for(var i = 0; i < len; i++){
(function(addresses){
geocoder.geocode( { 'address': addresses }, function(results) {
var marker = new google.maps.Marker ({
map: map,
position: results[0].geometry.location,//error:results[0] is undefined
title: address
});
google.maps.event.addListener(marker, 'click', function() {
alert(addresses);
});
});
})(addresses[i]);
}
}
window.onload = createMarkers;
</script>
In your function where you are creating the markers you can also extend the bounds (with
function createMarkers()
{
//create the bounds for the map
var bounds = new google.maps.LatLngBounds();
for(var i = 0; i < len; i++){
(function(addresses){
geocoder.geocode( { 'address': addresses }, function(results) {
var marker = new google.maps.Marker ({
map: map,
position: results[0].geometry.location,//error:results[0] is undefined
title: address
});
google.maps.event.addListener(marker, 'click', function() {
alert(addresses);
});
});
})(addresses[i]);
//extend the bounds with each address
bounds.extend (addresses[i]);
}
//fit to the full list of bounds
map.fitBounds(bounds);
}
If you want to set a maximum zoom level no matter what the actual bounds are you can add this after the map.fitBounds (you can change the level of zoom):
var listener = google.maps.event.addListener(map, "idle", function() {
if (map.getZoom() > 10) map.setZoom(10);
google.maps.event.removeListener(listener);
});
I am using google map to find route between two location.i want to get center latitude and longitude of the route. can u please tell me how to get center of the route.i am using the below code for getting routes,Thanks in advance
var map;
var directionsDisplay;
var directionsService;
var stepDisplay;
var markerArray = [];
var infoWindow;
var service;
var lat1 = 0;
var lng1;
function pre_initialize() {
var mapOptions = {
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
var pos = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
var infowindow = new google.maps.InfoWindow({
map: map,
position: pos,
content: 'Current Location.'
});
map.setCenter(pos);
}, function () {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
}
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
var infowindow = new google.maps.InfoWindow(options);
map.setCenter(options.position);
}
function initialize() {
var mapOptions = {
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var addressfrom = document.getElementById("from").value;
var addressto = document.getElementById("to").value;
var geocoder = new google.maps.Geocoder();
var coords = new google.maps.LatLng(0, 0);
alert(lat1);
coords = geocoder.geocode({ 'address': addressfrom }, function (results, status) {
results[0].geometry.location.lat();
results[0].geometry.location.lng();
});
directionsService = new google.maps.DirectionsService();
// Create a renderer for directions and bind it to the map.
var rendererOptions = {
map: map
}
directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions)
// Instantiate an info window to hold step text.
infoWindow = new google.maps.InfoWindow();
stepDisplay = new google.maps.InfoWindow();
calcRoute();
google.maps.event.addListenerOnce(map, 'bounds_changed', performSearch);
}
function performSearch() {
var request = {
bounds: map.getBounds(),
radius: 100,
types: ['hospital', 'cafe', 'restaurant', 'food', 'bar'],
keyword: 'best view'
};
service = new google.maps.places.PlacesService(map);
//service.nearbySearch(request, callback);
service.radarSearch(request, callback);
//service.textSearch(request, callback);
}
function callback(results, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
for (var i = 0, result; result = results[i]; i++) {
createMarker(result);
}
}
function createMarker(place) {
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location,
icon:
{
// Star
path: 'M 0,-24 6,-7 24,-7 10,4 15,21 0,11 -15,21 -10,4 -24,-7 -6,-7 z',
fillColor: '#ff0000',
fillOpacity: 1,
scale: 1 / 4,
strokeColor: '#bd8d2c',
strokeWeight: 1
}
});
google.maps.event.addListener(marker, 'click', function () {
service.getDetails(place, function (result, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
infoWindow.setContent(result.name);
infoWindow.open(map, marker);
});
});
}
function calcRoute() {
// First, remove any existing markers from the map.
for (var i = 0; i < markerArray.length; i++) {
markerArray[i].setMap(null);
}
// Now, clear the array itself.
markerArray = [];
var start = document.getElementById('from').value;
var end = document.getElementById('to').value;
var request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode.WALKING
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
var warnings = document.getElementById('warnings_panel');
warnings.innerHTML = '<b>' + response.routes[0].warnings + '</b>';
directionsDisplay.setDirections(response);
showSteps(response);
}
});
}
function showSteps(directionResult) {
var myRoute = directionResult.routes[0].legs[0];
for (var i = 0; i < myRoute.steps.length; i++) {
var marker = new google.maps.Marker({
position: myRoute.steps[i].start_point,
map: map
});
attachInstructionText(marker, myRoute.steps[i].instructions);
markerArray[i] = marker;
}
}
function attachInstructionText(marker, text) {
google.maps.event.addListener(marker, 'click', function () {
stepDisplay.setContent(text);
stepDisplay.open(map, marker);
});
}
</script>
Refer to the code below:
self.adjustPosition = function () {
var lat = 0, lng = 0;
if (self.nearbyPlaces().length == 0) {
return false;
}
for (var i = 0; i < self.nearbyPlaces().length; i++) {
lat += self.nearbyPlaces()[i].latitude;
lng += self.nearbyPlaces()[i].longitude;
}
lat = lat / self.nearbyPlaces().length;
lng = lng / self.nearbyPlaces().length;
self.map.setCenter(new window.google.maps.LatLng(lat, lng));
};
I'm using the Google Maps code with PHP MySql, and as per the code from their developers site I've got the map working. However, as part of their code they add a menu (which contains all of the returned options) under the map. The problem is that when i carry out another search I get another added rather than the one that is already there being updated with the new information. I think that the problem is something to dow with the locationSelect object, I would appreciate some help with it:
//Variables that we need later
var map;
var markers = [];
var infoWindow;
var locationSelect;
var myLatLng = new google.maps.LatLng(40,-100);
var addmap = ('<div id="map" style="visibility:visible;"></div>');
var addLocationSelect = '</br><div id="locationSelectDiv"><select id="locationSelect"></select></div>';
var subject_text = "";
var subject_id = "";
function load(myLatlng) {
map = new google.maps.Map(document.getElementById("map"), {
center: myLatLng,
zoom: 3,
mapTypeId: 'roadmap',
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
});
google.maps.event.trigger(map, 'resize');
infoWindow = new google.maps.InfoWindow();
locationSelect = document.getElementById("locationSelect");
locationSelect.onchange = function() {
var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
if (markerNum != "none"){
google.maps.event.trigger(markers[markerNum], 'click');
}
};
}
function searchLocations() {
var address = document.getElementById("addressInput").value;
var subject_text = $('#search_subject>option:selected').text();
var subject_id = $('#search_subject>option:selected').val();
console.log(address);
console.log(subject_text);
console.log(subject_id);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({address: address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
$('#container').replaceWith(addmap);
$("#map").slideDown("4000", function(){
$('#map').after(addLocationSelect);
load();
searchLocationsNear(results[0].geometry.location);
});
} else {
alert(address + ' not found');
}
});
}
function clearLocations() {
infoWindow.close();
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers.length = 0;
locationSelect.innerHTML = "";
var option = document.createElement("option");
option.value = "none";
option.innerHTML = "See all results:";
locationSelect.appendChild(option);
}
function searchLocationsNear(center) {
clearLocations();
var searchUrl = 'findlocations.php?lat=' + center.lat() + '&lng=' + center.lng() + '&radius=20';
downloadUrl(searchUrl, function(data) {
var xml = parseXml(data);
var markerNodes = xml.documentElement.getElementsByTagName("marker");
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markerNodes.length; i++) {
var name = markerNodes[i].getAttribute("name");
var address = markerNodes[i].getAttribute("address");
var distance = parseFloat(markerNodes[i].getAttribute("distance"));
var latlng = new google.maps.LatLng(
parseFloat(markerNodes[i].getAttribute("lat")),
parseFloat(markerNodes[i].getAttribute("lng")));
createOption(name, distance, i);
createMarker(latlng, name, address);
bounds.extend(latlng);
}
map.fitBounds(bounds);
locationSelect.style.visibility = "visible";
locationSelect.onchange = function() {
var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
google.maps.event.trigger(markers[markerNum], 'click');
};
});
}
function createMarker(latlng, name, address) {
var html = "<h3>" + name + "</h3><p>The biography will go here</p>";
var marker = new google.maps.Marker({
map: map,
position: latlng
});
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
markers.push(marker);
}
function createOption(name, distance, num) {
var option = document.createElement("option");
option.value = num;
option.innerHTML = name + " is " + distance.toFixed(1) + "miles away";
locationSelect.appendChild(option);
}
createOption() does exactly as it says it creates a new option. If you want to add the results of a new search (including markers) you will need to add these to the existing locations.
pseudo code NOT tested
GLOBAL var flag = 0;\\Set to 0 for 1st Search
IN searchLocationsNear() add following
searchLocationsNear(center) {
if(flag ==0){//1st Search
clearLocations();
}else{//Sugsequent Searches
flag =1;
}
The problem is that the locationSelect select dropdown is added every time searchLocations function returns. I just moved it to the top of the function and it's added fresh every time the submit button is entered, which will only provide a single dropdown with the results for the map.
function searchLocations() {
$('#container').replaceWith(addmap);
var address = document.getElementById("addressInput").value;
alert(address);
var subject_text = $('#search_subject>option:selected').text();
var subject_id = $('#search_subject>option:selected').val();
console.log(address);
console.log(subject_text);
console.log(subject_id);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({address: address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
$("#map").slideDown("4000", function(){
load();
searchLocationsNear(results[0].geometry.location);
});
} else {
alert(address + ' not found');
}
});
}