Google Maps API v3 - javascript

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

JS Geocoder cannot assign Global Variable for Google Maps Variable

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>

Google Reverse Geocoding for multiple addresses: problems to implement a callback function in a loop

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);
}
}

Google maps API v3 markers

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);
});

how to get center latitude and longitude in route between two location

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));
};

Need to prevent a dropdown list being added over and over

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');
}
});
}

Categories

Resources