Google Maps API Geocoding - handling multiple requests - google-maps

I want to be able to reverse geocode multiple points on map. My code looks like this:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Simple Polylines</title>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas, #map_canvas {
height: 100%;
}
#media print {
html, body {
height: auto;
}
#map_canvas {
height: 650px;
}
}
#panel {
position: absolute;
top: 5px;
left: 50%;
margin-left: -180px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script type="text/javascript" src="src/polyline.edit.packed.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
var flightPath;
var map;
var geocoder;
function initialize() {
geocoder = new google.maps.Geocoder();
var myLatLng = new google.maps.LatLng(0, -180);
var mapOptions = {
zoom: 3,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var flightPlanCoordinates = [
/*new google.maps.LatLng(37.772323, -122.214897),
new google.maps.LatLng(21.291982, -157.821856),
new google.maps.LatLng(-18.142599, 178.431),
new google.maps.LatLng(-27.46758, 153.027892)*/
];
flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
// Add a listener for the click event
google.maps.event.addListener(map, 'click', addLatLng);
// Add listener for end of editing event
google.maps.event.addListener(flightPath, 'edit_end', function(path){
var coords = [];
//THIS PART IS INTERESTING FOR THIS POST
//I'm requesting geocoding for every point on map
path.forEach(function(position){
coords.push(position.toUrlValue(5));
var latlng = new google.maps.LatLng(position.lat(), position.lng());
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
console.log(results[1].formatted_address);
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
window.setTimeout(console.log('tic tac'), 500);
});
console.log("[edit_end] path: " + coords.join(" | "));
});
//flightPath.setMap(map);
flightPath.edit();
}
//function when user clicked on map
function addLatLng(event) {
var path = flightPath.getPath();
// Because path is an MVCArray, we can simply append a new coordinate
// and it will automatically appear
path.push(event.latLng);
flightPath.edit();
}
// stop edit mode
function save(){
flightPath.edit(false);
}
google.maps.event.addDomListener(window, 'load', initialize);
$(window).load(function(){
});
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
And in return I get some of the points reverse geocoded bot for some i get "Geocoder failed due to: OVER_QUERY_LIMIT", and it's not the same amount of points that pass reverse geocoding, sometimes I get 4 points processed sometimes, sometimes 5, 7 etc. Why do I get that OVER_QUERY_LIMIT error? I made maybe 100 geocoder requests today so I'm far away from 2500 day limit. If there's a better way to handle multiple requests please show it to me.

Related

Google Maps Geocoding API returns undesired result after being passed zip code

I use the Google Maps Geocoding API. When I pass in the zip 75116, I get Paris, France. Specifically: 48.8585799, lon = 2.284701700000028. I should get Duncanville, Texas.
This is the URL I'm using:
https://maps.googleapis.com/maps/api/js?sensor=true&client=CLIENT-NAME&v=3.21
I tried appending this to the URL but it didn't work:
&components=country:US
In the maps-Javascript-API the componentRestrictions must be passed along with the geocoderRequest
function init() {
var map = new google.maps.Map(document.getElementById("map-canvas"), {
center: new google.maps.LatLng(0.0),
zoom: 13
}),
geocoder = new google.maps.Geocoder();
geocoder.geocode({
address: '75116',
componentRestrictions: {
country: 'us'
}
},
function(r, s) {
if (s == google.maps.GeocoderStatus.OK) {
map.setCenter(r[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: r[0].geometry.location
});
} else {
window.alert('Geocode was not successful for the following reason: ' + s);
}
}
);
}
html,
body,
#map-canvas {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map-canvas"></div>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3&callback=init">
</script>
I can see two locations in the response for the "75116" geocoding request: Paris and Duncanville. Apparently, "75116" is not a unique location identifier.
Requesting "US 75116" results in the single expectable location.
You have to use geocoder for getting address using zipcode:
Here sample code is provided:
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAtRkkKYEMY8CX1IbWbsAYLqzh-_pecegg&callback=initMap"
async defer></script>
<script>
var map;
function initMap() {
var geocoder = new google.maps.Geocoder();
var myLatlng = new google.maps.LatLng(48.8585799, 2.284701700000028);
var mapOptions = {
center : myLatlng,
zoom : 17
};
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
geocoder.geocode({
address : '75116',
componentRestrictions: {
country: 'us'
}
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
} else {
// alert("no asdsd");
}
});
}
</script>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
</body>
</html>

Uncaught TypeError: Cannot read property 'length' of null

I used google map javascript V3 API for this module.
This code working fine untill we don't drag the map, but when i drag the map i'll get "Uncaught TypeError: Cannot read property 'length' of null "(from google chrome inspect element)
Code:
<html>
<head>
<title>
Google Search
</title>
<style type="text/css">
html, body { height: 100%; margin: 0; padding: 0;}
#map-canvas { height: 80%; width:80%; margin: auto; padding: 0;}
</style>
<script src="js/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script>
<script>
var map;
var service;
$(document).ready(function(){
navigator.geolocation.getCurrentPosition(initialize);
});
function initialize(location) {
console.log(location);
var currentlocation = new google.maps.LatLng(location.coords.latitude, location.coords.longitude);
var mapOptions = {
center: currentlocation ,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true,
draggable: true
};
map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
var marker = new google.maps.Marker({
position: currentlocation,
map: map,
title:"Hello World!"
});
service = new google.maps.places.PlacesService(map);
google.maps.event.addListener(map, 'bounds_changed', performSearch);
var circleOptions = {
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.25,
map: map,
center: currentlocation,
radius: 10000
};
var circle = new google.maps.Circle(circleOptions);
}
function performSearch() {
var request = {
bounds: map.getBounds(),
name: "McDonald's"
};
service.nearbySearch(request, handleSearchResult);
}
function handleSearchResult(results, status){
console.log(results);
for (var i = 0; i < results.length; i++) {
var marker = new google.maps.Marker({
position: results[i].geometry.location,
map: map,
icon: "images//restaurant-71.png"
});
}
}
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
You aren't checking the return status of the places search. If it encounters an error (or doesn't return any results), it will fail.
function handleSearchResult(results, status){
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
var marker = new google.maps.Marker({
position: results[i].geometry.location,
map: map,
icon: "images//restaurant-71.png"
});
}
else { alert("no results"); }
}

How can I merge these two HTML codes?

I have one code that shows elevation and another which displays weather information. Is there a way to merge the two codes together so I have one map that has both features? I am using notepad to work on this.
Code 1:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Elevation service</title>
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script>
var weatherLayer = new google.maps.weather.WeatherLayer({
temperatureUnits: google.maps.weather.TemperatureUnit.CELSIUS
});
weatherLayer.setMap(map);
var cloudLayer = new google.maps.weather.CloudLayer();
cloudLayer.setMap(map);
}
var elevator;
var map;
var infowindow = new google.maps.InfoWindow();
var denali = new google.maps.LatLng(60.750000, -139.500000);
function initialize() {
var mapOptions = {
zoom: 8,
center: denali,
mapTypeId: 'terrain'
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
// Create an ElevationService
elevator = new google.maps.ElevationService();
// Add a listener for the click event and call getElevation on that location
google.maps.event.addListener(map, 'click', getElevation);
}
function getElevation(event) {
var locations = [];
// Retrieve the clicked location and push it on the array
var clickedLocation = event.latLng;
locations.push(clickedLocation);
// Create a LocationElevationRequest object using the array's one value
var positionalRequest = {
'locations': locations
}
// Initiate the location request
elevator.getElevationForLocations(positionalRequest, function(results, status) {
if (status == google.maps.ElevationStatus.OK) {
// Retrieve the first result
if (results[0]) {
// Open an info window indicating the elevation at the clicked position
infowindow.setContent('The elevation at this point <br>is ' + results[0].elevation + ' meters.');
infowindow.setPosition(clickedLocation);
infowindow.open(map);
} else {
alert('No results found');
}
} else {
alert('Elevation service failed due to: ' + status);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
AND Code 2:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Weather layer</title>
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=weather"></script>
<script>
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(60.750000, -139.500000),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var weatherLayer = new google.maps.weather.WeatherLayer({
temperatureUnits: google.maps.weather.TemperatureUnit.CELSIUS
});
weatherLayer.setMap(map);
var cloudLayer = new google.maps.weather.CloudLayer();
cloudLayer.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
You would probably want to put the code into a seperate .js file, and link it in. That way, the code would be right next to each other, and hence you could get both effects, which other wise would not work. You are already linking a script file from google - all you would need is to put the code of yours into a .js file, and link it in the same way

How to get the state of a marker?

I am using the the Google Maps JavaScript API v3. I have a map that has markers on each state. When I click the state marker, I need access to the state abbreviation in the callback function. Is there any way native to google maps that I can access the state of a marker?
google.maps.event.addListener(mark,'click',function(event){
// how can I access the state abbreviation (e.g. 'MO') from in here?
}
I know that I can probably accomplish this via reverse geocoding, but is there any simpler (and less error-prone) way?
If this can only be accomplished using reverse geocoding, what is the simplest code to access the state? I assume my code would look something like this:
google.maps.event.addListener(mark,'click',function(event){
geocoder.geocode({'latLng': event.latLng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
... get state from results ...
}
}
}
What would be the simplest code to get the state from the results? Based on the documentation of the address component types, I assume I would be looking for the "short_name" of the "administrative_area_level_1". Is this correct? Is there an easier way to access it than looping over the results until I find the "administrative_area_level_1"? (I have jquery included on the page and so can code with it if it makes anything simpler)
Here's a working example:
<!DOCTYPE html>
<html>
<head>
<title>http://stackoverflow.com/questions/17144375/how-to-get-the-state-of-a-marker?noredirect=1#comment24816710_17144375</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100%; width:100% }
</style>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var map;
var markers = [
{lat:54.60039, lng:-3.13632, state:"AA"},
{lat:54.36897, lng:-3.07561, state:"ZZ"},
];
function initialize() {
var myOptions = {
zoom: 10,
center: new google.maps.LatLng(54.42838,-2.9623),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var marker;
var infowindow = new google.maps.InfoWindow({
content: ''
});
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
for (var i = 0; i < markers.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(markers[i].lat,markers[i].lng),
map: map,
title:"marker " + i,
state: markers[i].state // a custom property of our own
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(this.state);
infowindow.open(map, this);
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map_canvas"></div>
</body>
</html>

Google geocode is late (still one step behind)

I put there my whole code. Trying to determine location address. My script should create still one marker with geocoded address (in console - variable kktina).
But, unfortunately, there isn't everything OK. Because by script still resolves previous location (or it takes previous coordinates, dunno). Maybe there is an error in code, but I'm not able to do this anymore..
So asking for help, thank you!
<!DOCTYPE html>
<html>
<head>
<title>Google Maps JavaScript API v3 Example: Map Simple</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map_canvas {
margin: 0;
padding: 0;
height: 100%;
}
</style>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places,geometry"></script>
<script src="http://code.jquery.com/jquery-1.7.min.js" type="text/javascript"></script>
<script>
var map,marker;
var geocoder = new google.maps.Geocoder();
var markers = [];
var img,icon,type;
var prenos,pos,address = "5",point;
function clearMarkersFromArray() {
if (markers.length>0){
markers[0].setMap(null);
markers.shift(markers[0]);
}
}
function geocodePosition(pos) {
geocoder.geocode({
latLng: pos
}, function(responses) {
if (responses && responses.length > 0) {
address = responses[0].formatted_address;
} else {
address = 'Cannot determine address at this location.';
}
});
return address;
}
function initialize() {
var mapOptions = {
zoom: 7,
center: new google.maps.LatLng(49,19),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions),
google.maps.event.addListener(map, 'click', function(response) {
clearMarkersFromArray();
point = new google.maps.LatLng(response.latLng.$a,response.latLng.ab);
var kktina = geocodePosition(point);
console.log(kktina);
var marker = new google.maps.Marker({
position: point,
draggable: true
});
markers.push(marker)
marker.setMap(map);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map_canvas" style="height:400px;width:700px;"></div>
</body>
</html>
You can't do this:
function geocodePosition(pos) {
geocoder.geocode({
latLng: pos
}, function(responses) {
if (responses && responses.length > 0) {
address = responses[0].formatted_address;
} else {
address = 'Cannot determine address at this location.';
}
});
return address;
}
the Geocoder is asynchronous, the value of address is undefined when it is returned.
Use the returned data inside the callback function instead, something like this (not tested):
var kktina = null;
function geocodePosition(pos) {
geocoder.geocode({
latLng: pos
}, function(responses) {
if (responses && responses.length > 0) {
kktina = responses[0].formatted_address;
} else {
kktina = 'Cannot determine address at this location.';
}
console.log(kktina);
var marker = new google.maps.Marker({
position: point,
draggable: true
});
markers.push(marker)
marker.setMap(map);
});
}