I'm hitting an issue that is WELL discussed in these forums, but none of the recommendations seem to be working for me so I'm looking for some full javascript that works when saved as an html file.
The issue is I keep hitting the OVER_QUERY_LIMIT error when trying to geocode > 11 locations on a Google Map using the V3 APIs called by Javascript. I understand that there is a limit to the rate at which you can call the geocoder (as well as the daily limit on total volume), so I need to introduce a pause in between each result in the array.
Any help very much appreciated.
Here is my code:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var geocoder;
var map;
var wait = false;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(51.32, 0.5);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
codeAddress('KT16 8LA' + ', UK');
codeAddress('LS8 2LQ' + ', UK');
codeAddress('NE13 8AF' + ', UK');
codeAddress('KT12 2BE' + ', UK');
codeAddress('W1W 8AN' + ', UK');
codeAddress('EC3N 2LS' + ', UK');
codeAddress('BS9 3BH' + ', UK');
codeAddress('KA10 6LZ' + ', UK');
codeAddress('EC1V 9BW' + ', UK');
codeAddress('WD18 8YN' + ', UK');
codeAddress('HA3 6DQ' + ', UK');
codeAddress('W1U 3PL' + ', UK');
codeAddress('W1T 7QL' + ', UK');
codeAddress('W1S 1TD' + ', UK');
codeAddress('SW1X 8NX' + ', UK');
codeAddress('LE2 8ET' + ', UK');
codeAddress('BA3 4BH' + ', UK');
codeAddress('AL3 8JP' + ', UK');
codeAddress('DE55 4QJ' + ', UK');
codeAddress('W6 0QT' + ', UK');
codeAddress('LA1 1PP' + ', UK');
codeAddress('SW16 4DH' + ', UK');
codeAddress('WC2N 6DF' + ', UK');
codeAddress('RM6 6LS' + ', UK');
codeAddress('S25 3QZ' + ', UK');
codeAddress('WC2H 7LR' + ', UK');
codeAddress('BH24 1DW' + ', UK');
codeAddress('EC2N 6AR' + ', UK');
codeAddress('W1U 2FA' + ', UK');
codeAddress('B60 3DX' + ', UK');
}
function codeAddress(vPostCode) {
if (geocoder) {
geocoder.geocode( { 'address': "'" + vPostCode + "'"}, 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);
}
});
}
}
</script>
<body style="margin:0px; padding:0px;" onload="initialize()">
<div id="map_canvas" style="width:100%; height:90%"></div>
</body>
EDIT: This is what I've tried to do to get it to pause/wait in the relevant section, but it doesn't do anything:
function codeAddress(vPostCode) {
if (geocoder) {
while (wait) { /* Just wait. */ };
geocoder.geocode( { 'address': "'" + vPostCode + "'"}, 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
});
/* When geocoding "fails", see if it was because of over quota error: */
} else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
wait = true;
setTimeout("wait = true", 2000);
//alert("OQL: " + status);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
}
Nothing like these two lines appears in Mike Williams' tutorial:
wait = true;
setTimeout("wait = true", 2000);
Here's a Version 3 port:
http://acleach.me.uk/gmaps/v3/plotaddresses.htm
The relevant bit of code is
// ====== Geocoding ======
function getAddress(search, next) {
geo.geocode({address:search}, function (results,status)
{
// If that was successful
if (status == google.maps.GeocoderStatus.OK) {
// Lets assume that the first marker is the one we want
var p = results[0].geometry.location;
var lat=p.lat();
var lng=p.lng();
// Output the data
var msg = 'address="' + search + '" lat=' +lat+ ' lng=' +lng+ '(delay='+delay+'ms)<br>';
document.getElementById("messages").innerHTML += msg;
// Create a marker
createMarker(search,lat,lng);
}
// ====== Decode the error status ======
else {
// === if we were sending the requests to fast, try this one again and increase the delay
if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
nextAddress--;
delay++;
} else {
var reason="Code "+status;
var msg = 'address="' + search + '" error=' +reason+ '(delay='+delay+'ms)<br>';
document.getElementById("messages").innerHTML += msg;
}
}
next();
}
);
}
The general answer to this question is:
Don't geocode known locations every time you load your page. Geocode them off-line and use the resulting coordinates to display the markers on your page.
The limits exist for a reason.
If you can't geocode the locations off-line, see this page (Part 17 Geocoding multiple addresses) from Mike Williams' v2 tutorial which describes an approach, port that to the v3 API.
Here I have loaded 2200 markers. It takes around 1 min to add 2200 locations.
https://jsfiddle.net/suchg/qm1pqunz/11/
//function to get random element from an array
(function($) {
$.rand = function(arg) {
if ($.isArray(arg)) {
return arg[$.rand(arg.length)];
} else if (typeof arg === "number") {
return Math.floor(Math.random() * arg);
} else {
return 4; // chosen by fair dice roll
}
};
})(jQuery);
//start code on document ready
$(document).ready(function () {
var map;
var elevator;
var myOptions = {
zoom: 0,
center: new google.maps.LatLng(35.392738, -100.019531),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map($('#map_canvas')[0], myOptions);
//get place from inputfile.js
var placesObject = place;
errorArray = [];
//will fire 20 ajax request at a time and other will keep in queue
var queuCounter = 0, setLimit = 20;
//keep count of added markers and update at top
totalAddedMarkers = 0;
//make an array of geocode keys to avoid the overlimit error
var geoCodKeys = [
'AIzaSyCF82XXUtT0vzMTcEPpTXvKQPr1keMNr_4',
'AIzaSyAYPw6oFHktAMhQqp34PptnkDEdmXwC3s0',
'AIzaSyAwd0OLvubYtKkEWwMe4Fe0DQpauX0pzlk',
'AIzaSyDF3F09RkYcibDuTFaINrWFBOG7ilCsVL0',
'AIzaSyC1dyD2kzPmZPmM4-oGYnIH_0x--0hVSY8'
];
//funciton to add marker
var addMarkers = function(address, queKey){
var key = jQuery.rand(geoCodKeys);
var url = 'https://maps.googleapis.com/maps/api/geocode/json?key='+key+'&address='+address+'&sensor=false';
var qyName = '';
if( queKey ) {
qyName = queKey;
} else {
qyName = 'MyQueue'+queuCounter;
}
$.ajaxq (qyName, {
url: url,
dataType: 'json'
}).done(function( data ) {
var address = getParameterByName('address', this.url);
var index = errorArray.indexOf(address);
try{
var p = data.results[0].geometry.location;
var latlng = new google.maps.LatLng(p.lat, p.lng);
new google.maps.Marker({
position: latlng,
map: map
});
totalAddedMarkers ++;
//update adde marker count
$("#totalAddedMarker").text(totalAddedMarkers);
if (index > -1) {
errorArray.splice(index, 1);
}
}catch(e){
if(data.status = 'ZERO_RESULTS')
return false;
//on error call add marker function for same address
//and keep in Error ajax queue
addMarkers( address, 'Errror' );
if (index == -1) {
errorArray.push( address );
}
}
});
//mentain ajax queue set
queuCounter++;
if( queuCounter == setLimit ){
queuCounter = 0;
}
}
//function get url parameter from url string
getParameterByName = function ( name,href )
{
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( href );
if( results == null )
return "";
else
return decodeURIComponent(results[1].replace(/\+/g, " "));
}
//call add marker function for each address mention in inputfile.js
for (var x = 0; x < placesObject.length; x++) {
var address = placesObject[x]['City'] + ', ' + placesObject[x]['State'];
addMarkers(address);
}
});
Using "setInterval" & "clearInterval" fixes the problem:
function drawMarkers(map, markers) {
var _this = this,
geocoder = new google.maps.Geocoder(),
geocode_filetrs;
_this.key = 0;
_this.interval = setInterval(function() {
_this.markerData = markers[_this.key];
geocoder.geocode({ address: _this.markerData.address }, yourCallback(_this.markerData));
_this.key++;
if ( ! markers[_this.key]) {
clearInterval(_this.interval);
}
}, 300);
}
this post was made a while ago, but it provides an answer that did not solve the problem regarding reaching the limit of requests in an iteration for me, so I publish this, to help who else has not served.
My environment happened in Ionic 3.
Instead of making a "pause" in the iteration, I ocurred the idea of iterating with a timer, this timer has the particularity of executing the code that would go in the iteration, but will run every so often until it is reached the maximum count of the "Array" in which we want to iterate.
In other words, we will consult the Google API in a certain time so that it does not exceed the limit allowed in milliseconds.
// Code to start the timer
this.count= 0;
let loading = this.loadingCtrl.create({
content: 'Buscando los mejores servicios...'
});
loading.present();
this.interval = setInterval(() => this.getDistancias(loading), 40);
// Function that runs the timer, that is, query Google API
getDistancias(loading){
if(this.count>= this.datos.length){
clearInterval(this.interval);
} else {
var sucursal = this.datos[this.count];
this.calcularDistancia(this.posicion, new LatLng(parseFloat(sucursal.position.latitude),parseFloat(sucursal.position.longitude)),sucursal.codigo).then(distancia => {
}).catch(error => {
console.log('error');
console.log(error);
});
}
this.count += 1;
}
calcularDistancia(miPosicion, markerPosicion, codigo){
return new Promise(async (resolve,reject) => {
var service = new google.maps.DistanceMatrixService;
var distance;
var duration;
service.getDistanceMatrix({
origins: [miPosicion, 'salida'],
destinations: [markerPosicion, 'llegada'],
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, function(response, status){
if (status == 'OK') {
var originList = response.originAddresses;
var destinationList = response.destinationAddresses;
try{
if(response != null && response != undefined){
distance = response.rows[0].elements[0].distance.value;
duration = response.rows[0].elements[0].duration.text;
resolve(distance);
}
}catch(error){
console.log("ERROR GOOGLE");
console.log(status);
}
}
});
});
}
I hope this helps!
I'm sorry for my English, I hope it's not an inconvenience, I had to use the Google translator.
Regards, Leandro.
You are using setTimeout wrong way. The (one of) function signature is setTimeout(callback, delay). So you can easily specify what code should be run after what delay.
var codeAddress = (function() {
var index = 0;
var delay = 100;
function GeocodeCallback(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
new google.maps.Marker({ map: map, position: results[0].geometry.location, animation: google.maps.Animation.DROP });
console.log(results);
}
else alert("Geocode was not successful for the following reason: " + status);
};
return function(vPostCode) {
if (geocoder) setTimeout(geocoder.geocode.bind(geocoder, { 'address': "'" + vPostCode + "'"}, GeocodeCallback), index*delay);
index++;
};
})();
This way, every codeAddress() call will result in geocoder.geocode() being called 100ms later after previous call.
I also added animation to marker so you will have a nice animation effect with markers being added to map one after another. I'm not sure what is the current google limit, so you may need to increase the value of delay variable.
Also, if you are each time geocoding the same addresses, you should instead save the results of geocode to your db and next time just use those (so you will save some traffic and your application will be a little bit quicker)
Related
Reading that title it's probably confusing as to what's going on....I agree.
So I have an address that I want to show on a Google Map. I don't have the lat/long so I need to call the Geocoder service provided by the Google Maps API.
When I request the lat/long for an address, the service is returning a legitimate value, but when stepping through the javascript on the last line in the geocode function, the code goes off into the geocoder.js minified code and never returns (no successful result, no exception).
I've done lots of research on using the Google Maps API, and as far as I can tell, I've implemented exactly how the examples show. Where am I going wrong here?
Here's the javascript code that calls the lat/long service:
function getLatLong(street, city, state, zip) {
var geocoder = new google.maps.Geocoder();
var address = street && street.length > 0 ? street + ' ' : '';
address += city && city.length > 0 ? city + ', ' : '';
address += state && state.length > 0 ? state + ' ' : '';
address += zip && zip.length > 0 ? zip : '';
var latLong = {
lat: 0.0,
long: 0.0
};
try {
geocoder.geocode({ 'address' : address }, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
return {
lat: results[0].geometry.location.lat(),
long: results[0].geometry.location.lng()
};
} else {
return latLong;
}
});
} catch (exception) {
alert(e.message);
}
}
(If you don't want to step through, it's "getting lost" on the line above the catch in the code above)
And if you want to see it in action and step through for yourself, here's the URL: http://golfproxy.com/course/list
Edit: If it helps, here's the function that adds the map and markers, which calls the getLatLong function above:
function plotMapHardCodePos(position) {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 9,
center: position
});
$.each(tournaments.Result, function (i, item) {
var latLong = {};
if (!item.Latitude || !item.Longitude) {
latLong = getLatLong(item.Street, item.City, item.State, item.ZipCode);
if (latLong) {
item.Latitude = latLong.lat;
item.Longitude = latLong.long;
}
}
if (!(item.Latitude === 0.0 && item.Longitude === 0.0)) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(item.Latitude, item.Longitude),
map: map
});
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/blue-dot.png');
var infoWindow = new google.maps.InfoWindow({
content: "<div class=''><h4>" + item.Name + "</h4></div><br/><span>" +
item.Body1 + "</span>" + "<br/><span>" + item.Body2 + "</span>"
});
google.maps.event.addListener(marker, 'click', function () {
infoWindow.open(map, marker);
});
}
});
}
You can't return anything from an asynchronous callback function, you need to use the data in the callback function when/where it is available
May I know how to get more than 10 data results from Google Map when using the radarSearch method that can retrieved 200 results and getDetails method? I want all the marker information is listed down in the white space below the map. However, I only get 10 of it. May I know the problem? The 10 result stay the same and may only change 1 of them when the browser is refresh for a few times.
Here is the code that I used to retrieve the information from Google Map and create the marker. I used the radar Search method to perform the search.
function callback(results, status) {
if (status !== google.maps.places.PlacesServiceStatus.OK) {
console.error(status);
return;
}
for (var i = 0, result; result = results[i]; i++) {
addMarker(result);
}
}
function addMarker(place) {
var placesList = document.getElementById('test');
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location,
icon: {
url: 'http://maps.gstatic.com/mapfiles/circle.png',
anchor: new google.maps.Point(10, 10),
scaledSize: new google.maps.Size(10, 17)
}
});
service.getDetails(place, function(result, status) {
if (status !== google.maps.places.PlacesServiceStatus.OK) {
console.error(status);
return;
}
iname = result.name;
iLatitude = [result.geometry.location.lat()];
iLongitude = [result.geometry.location.lng()];
iAddress = [result.formatted_address];
placesList.innerHTML += '<li>' + iname +' '+ iAddress + '</li>';
});
}
ScreenShot of the result.
The marker result is nearly 200, while the listed down data only consists of 10
Actually the problem is due to the OVER_QUERY_LIMIT issue, it can be bypass when the time sent request is delayed, setTimeout method can be implemented to avoid OVER_QUERY_LIMIT problem.
Replace with the code below. Can retrieve all the marker data on the map,(currently I have 148 restaurants marker on the Google Map)
service.getDetails(place, function(result, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
iname = result.name;
iLatitude = [result.geometry.location.lat()];
iLongitude = [result.geometry.location.lng()];
iAddress = [result.formatted_address];
placesList.innerHTML += '<li>' + iname + ''+ iAddress + '</li>';
}
else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
setTimeout(function() {
addMarker(place);
}, 200);
}
});
I am using google maps and i have working code to display markers on a map. I now want to put this code inside of a function view_maps() and activate this function on click. So far i get the errors Maximum call stack size exceeded and getAddress is not a function. This works but when the code inside of view_maps() function i get these errors.
function view_maps() {
function marker_map() {
var url = "http://example.co.uk/deliveries/map/get_region_orders";
var region = $("ul#regions").children("li[data-active='1']").attr("class");
var data = {
region: region
};
var obj = {};
var locations = [];
var details_array = [];
$.ajax({
type: "POST",
url: "http://example.co.uk/deliveries/map/get_region_orders",
data: data,
async: false,
success: function(response) {
var result = $.parseJSON(response);
jQuery.each(result, function(i) {
var order_id = result[i].order_id;
var customer_name = result[i].customer_name;
var address_1 = result[i].address_1;
var address_2 = result[i].address_2;
var post_code = result[i].post_code;
var address = post_code;
var details = "<b>Order Number: " + order_id + "</b><br>" + address_1 + "<br>" + address_2 + "<br>" + post_code;
details_array.push(details);
locations.push(address);
});
}
});
obj['address'] = locations;
obj['details'] = details_array;
return (obj);
}
// delay between geocode requests - at the time of writing, 100 miliseconds seems to work well
var delay = 70;
// ====== Create map objects ======
var infowindow = new google.maps.InfoWindow();
var latlng = new google.maps.LatLng(53.381021, -2.608138);
var mapOptions = {
zoom: 9,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var geo = new google.maps.Geocoder();
var map = new google.maps.Map(document.getElementById("marker-map"), mapOptions);
var bounds = new google.maps.LatLngBounds();
// ====== Geocoding ======
function getAddress(search, count, next) {
geo.geocode({
address: search
}, function(results, status) {
// If that was successful
if (status == google.maps.GeocoderStatus.OK) {
// Lets assume that the first marker is the one we want
var p = results[0].geometry.location;
var lat = p.lat();
var lng = p.lng();
// Output the data
var msg = 'address="' + search + '" lat=' + lat + ' lng=' + lng + '(delay=' + delay + 'ms)<br>';
document.getElementById("messages").innerHTML += msg;
// Create a marker
createMarker(search, count, lat, lng);
}
// ====== Decode the error status ======
else {
// === if we were sending the requests to fast, try this one again and increase the delay
if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
nextAddress--;
delay++;
} else {
var reason = "Code " + status;
var msg = 'address="' + search + '" error=' + reason + '(delay=' + delay + 'ms)<br>';
//document.getElementById("messages").innerHTML += msg;
}
}
next();
});
}
// ======= Function to create a marker
function createMarker(add, count, lat, lng) {
var contentString = add;
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
map: map,
zIndex: Math.round(latlng.lat() * -100000) << 5
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(details_array[count]);
//infowindow.setContent(contentString);
infowindow.open(map, marker);
});
bounds.extend(marker.position);
}
// ======= An array of locations that we want to Geocode ========
//console.log(marker_map());
var locations = marker_map();
var addresses = locations.address;
var details_array = locations.details;
// ======= Global variable to remind us what to do next
var nextAddress = 0;
// ======= Function to call the next Geocode operation when the reply comes back
function theNext() {
if (nextAddress < addresses.length) {
setTimeout('getAddress("' + addresses[nextAddress] + '","' + nextAddress + '",theNext)', delay);
nextAddress++;
} else {
// We're done. Show map bounds
map.fitBounds(bounds);
}
}
// ======= Call that function for the first time =======
theNext();
}
How do i solve? I think this is to do with scope of functions because getAddress is clearly a function.
you have to change your theNext function with this one.
function theNext() {
if (nextAddress < addresses.length) {
setTimeout(getAddress(addresses[nextAddress],nextAddress,theNext), delay);
nextAddress++;
} else {
// We're done. Show map bounds
map.fitBounds(bounds);
}
}
see change in setTimeout, I am Calling function not passing string (which will evaluate later and search in global scope)
I also create a demo for proof of concept. Enjoy :)
Issue I'm having is that I am performing a Google Places radar search that returns at least 20 results. In my code, I am limiting the number of the search results to 20. So there should be a max of 20 markers on my embedded google map (this part works) and the associated list of 20 places on my results panel (this doesn't work). However, I am constantly getting only 10 results on my results panel. Here is my code performing the radar search and the addResult function in the callback (since its asynchronous):
function getPlaces(placeQuery, locInput){
var location = new google.maps.LatLng(locInput.geometry.location.lat(), locInput.geometry.location.lng());
var queryValue = placeQuery.value;
var resultsLength;
var request = {
location: location,
radius: 3200,
keyword: queryValue
};
service = new google.maps.places.PlacesService(map);
service.radarSearch(request, function callback(results, status) {
if(status == google.maps.places.PlacesServiceStatus.OK) {
clearMarkers();
if(results.length < 20){
resultsLength = results.length;
}
else{
resultsLength = 20;
}
for (var i = 0; i < resultsLength; i++){
var markerLetter = String.fromCharCode('A'.charCodeAt(0)+ i);
var markerIcon = MARKER_PATH + markerLetter + '.png';
markers[i] = new google.maps.Marker({
position: results[i].geometry.location,
animation: google.maps.Animation.DROP,
icon: markerIcon
});
markers[i].placeResult = results[i];
google.maps.event.addListener(markers[i], 'click', showInfoWindow);
setTimeout(dropMarker(i), i * 100);
addResult(results[i], i);
}
}
});
}
Here is my addResult function:
function addResult(place, i) {
var name;
var address;
var results = document.getElementById("results");
service.getDetails({placeId: place.place_id}, function(result, status) {
if (status !== google.maps.places.PlacesServiceStatus.OK) {
return;
}
results.innerHTML += '<li>' + result.name + '</li>';
});
}
I did some debug testing and the for-loop is executing completely. However in the service.getDetails in the addResult function, only 10 place IDs are going through. Not sure why... Note: Can't use jQuery or promise libraries etc.
There is a quota/rate limit on calls to the .getDetails request. You are silently failing if the result is not "OK", add error handling and you will see the issue.
function addResult(place, i) {
var name;
var address;
var results = document.getElementById("results");
service.getDetails({placeId: place.place_id}, function(result, status) {
if (status !== google.maps.places.PlacesServiceStatus.OK) {
results.innerHTML += '<li>'+ status + '</li>';
} else {
results.innerHTML += '<li>' + result.name + '</li>';
}
});
}
(or add an alert if you don't mind clicking on all the popup dialog boxes)
I must say this is the weirdest error that I've ever caught during my programming adventures. I really have no idea why this is happening.
Basically, my application must receive some data from a Mysql Database and when the user clicks in a country, a infowindow must appear with some information (from the DB). The DB communication is working fine, the problem is: when I pass the mouse over a country, sometimes, the mouseover event isn't called, same thing with mouseout.
But sometimes? With what frequency? Here is the weirdest part: During specific times of the day. I'm brazilian, I work with UTC -3 here, if I acces my application at 18:00, it doesn't work, however if I access it during the morning, like 7 am, IT DOES WORK.
I really have no idea why this is happening, tryed to search online but found nothing...
Can someone help me? This is the code I'm using (no erros appears in the js console, the error happens in chrome, firefox, IE...):
<script type="text/javascript" >
var colors = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00'];
var map
var infowindow;
function initialize() {
var myOptions = {
zoom: 2,
center: new google.maps.LatLng(10, 0),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
myOptions);
geocoder = new google.maps.Geocoder();
// Initialize JSONP request
var script = document.createElement('script');
var url = ['https://www.googleapis.com/fusiontables/v1/query?'];
url.push('sql=');
var query = 'SELECT name, kml_4326 FROM ' +
'1foc3xO9DyfSIF6ofvN0kp2bxSfSeKog5FbdWdQ';
var encodedQuery = encodeURIComponent(query);
url.push(encodedQuery);
url.push('&callback=drawMap');
url.push('&key=AIzaSyAm9yWCV7JPCTHCJut8whOjARd7pwROFDQ');
script.src = url.join('');
var body = document.getElementsByTagName('body')[0];
body.appendChild(script);
}
function drawMap(data) {
var rows = data['rows'];
for (var i in rows) {
if (rows[i][0] != 'Antarctica') {
var newCoordinates = [];
var geometries = rows[i][1]['geometries'];
if (geometries) {
for (var j in geometries) {
newCoordinates.push(constructNewCoordinates(geometries[j]));
}
} else {
newCoordinates = constructNewCoordinates(rows[i][1]['geometry']);
}
//var randomnumber = Math.floor(Math.random() * 4);
var country = new google.maps.Polygon({
paths: newCoordinates,
//strokeColor: colors[randomnumber],
strokeOpacity: 0,
strokeWeight: 1,
//fillColor: colors[randomnumber],
fillOpacity: 0
});
infowindow = new google.maps.InfoWindow({
content: ''
});
google.maps.event.addListener(country, 'mouseover', function() {
alert("HIIIIII JOW");
this.setOptions({fillOpacity: 0.3});
});
google.maps.event.addListener(country, 'mouseout', function() {
this.setOptions({fillOpacity: 0});
});
google.maps.event.addListener(country, 'click', function(event) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
initialize2(lat,lng);
});
country.setMap(map);
}
}
}
function constructNewCoordinates(polygon) {
var newCoordinates = [];
var coordinates = polygon['coordinates'][0];
for (var i in coordinates) {
newCoordinates.push(
new google.maps.LatLng(coordinates[i][1], coordinates[i][0]));
}
return newCoordinates;
}
function initialize2(lat,lng){
var url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=" + lat + "," + lng+ "&sensor=true&language=en";
jQuery.getJSON(url, function (data) {
for (var i = 0; i < data.results[0].address_components.length; i++){
//var formatted = results[0].formatted_address;//.short_name
var countryName
var shortname = data.results[0].address_components[i].short_name;
var longname = data.results[0].address_components[i].long_name;
var type = data.results[0].address_components[i].types;
if (type.indexOf("country") != -1){
if (isNullOrWhitespace(shortname)){
countryName = shortname;
}
else{
countryName = longname;
}
}
}
var lat2;
var lng2
geocoder.geocode( {'address' : countryName}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
lat2 = results[0].geometry.location.lat();
lng2 = results[0].geometry.location.lng();
//alert(results[0].geometry.location);//map.setCenter(results[0].geometry.location);
//alert(lat2+','+lng2);
var array = <?php echo json_encode($arr); ?>;
var str = 'Nenhuma exchange cadastrada neste país!';
for(var i = 0;i<array.length;i++){
if(countryName==array[i][0]){
var string = 'country_volume.php?country=' + countryName;
str = '<center><strong>'+array[i][0]+'</strong></center>' +
'<strong>Número de Exchanges: </strong>' + array[i][1] + '</br>' +
'<strong>Volume: </strong>' + array[i][2] + '</br>' +
'<strong>Ranking Mundial: </strong> ' + array[i][3] + 'º' + '</br>' +
'<strong>Porcentagem Mundial (%): </strong> ' + array[i][4] + '%' + '</br>' +
'<a href='+string+'>' + 'Mais Informações' + '</a>';
}
}
if (infowindow) infowindow.close();
infowindow = new google.maps.InfoWindow({
content: str,
map: map,
position: new google.maps.LatLng(lat2,lng2)
});
}
});
});
}
function isNullOrWhitespace(text) {
if (text == null) {
return true;
}
return text.replace(/\s/gi, '').length < 1;
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
You may exceeded the daily quota of Fusion Tables API:
The default request quota limits are the following:
25,000 requests per day per API project, where reads count as one request and writes count as five requests.
30 write requests per minute per table
You may request more quota at the Google APIs Console under the "Quotas" tab.
The storage quota limits are:
100 MB per table
250 MB total among all your tables
For more details, please refer to here.