HTML - Javascript - Combine Geocoding and Nearby Search - javascript

I am trying to combine Google Geocoding and Nearby Search in one Searchbox.
The user will type his address and the map should show all Bars near him.
initmap Function:
function initMap() {
var setMap = new google.maps.LatLng(50, 9398252, 6.93936825);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 15,
center: setMap
});
var request = {
location: setMap,
radius: '5000',
types: ['bar']
};
var geocoder = new google.maps.Geocoder();
document.getElementById('submit').addEventListener('click', function() {
geocodeAddress(geocoder, map);
});
}
This is my geocode function:
function geocodeAddress(geocoder, resultsMap) {
var address = document.getElementById('address').value;
geocoder.geocode({ 'address': address }, function(results, status) {
if (status === 'OK') {
resultsMap.setCenter(results[0].geometry.location);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
This is how I would create Marker:
function callback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
And here is what my search box looks like:
<form class="navbar-form navbar-left">
<div class="form-group">
<div id="floating-panel">
<input id="address" type="textbox" value="Cologne, Germany" class="form-control">
<input id="submit" type="button" value="Search" class="form-control">
</div>
</div>
</form>
Until now I can search for a address, so my geocoder should work.
I just don't know how to involve the nearby search process in my code..
Hopefully somebody can help me with my problem.

Once you receive the result of the Geocoding API, you can call the PlacesService API. Knowing that every call to the API will be async, you'll have to wait for the Geocoding callback to launch the PlaceService API.
It will look like:
function geocodeAddress(geocoder, resultsMap) {
var address = document.getElementById('address').value;
var service;
geocoder.geocode({'address': address}, function(results, status) {
if (status === 'OK') {
resultsMap.setCenter(results[0].geometry.location);
service = new google.maps.places.PlacesService(resultsMap);
service.nearbySearch({ location: results[0].geometry.location, radius: 500, type: [ 'bar' ] }, PlaceServiceCallBack); // where PlaceServiceCallBack handles the markers creation
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}

Related

click function for multiple buttons loading marker in one google map javascript

What I want to achieve is one map, with several (in this case three) buttons, when you click a button, the map loads a marker with that buttons location. So you could "jump" from one location to the next.
I get it working with three separate functions and eventlisteners but I would think there is a way to concatenate it all down to just one function? The working solution is commented out in the code example below...
<div id="floating-panel">
<input id="address-1" class="address" value="Paris" type="button">
<input id="address-2" class="address" value="London" type="button">
<input id="address-3" class="address" value="New York" type="button">
var address = null;
function initMap() {
var geocoder = new google.maps.Geocoder();
var map = new google.maps.Map(document.getElementById('map'), {
zoom: #MapZoom,
center: { lat: #MapCenterLat, lng: #MapCenterLng}
});
document.getElementByClassName('address').addEventListener('click', function () {
address = this.value();
geocodeAddress(geocoder, map);
});
//document.getElementById('address-1').addEventListener('click', function () {
// geocodeAddress1(geocoder, map);
//});
//document.getElementById('address-2').addEventListener('click', function () {
// geocodeAddress2(geocoder, map);
//});
//document.getElementById('address-2').addEventListener('click', function () {
// geocodeAddress3(geocoder, map);
//});
}
function geocodeAddress(geocoder, resultsMap) {
geocoder.geocode({ 'address': address }, function (results, status) {
if (status === 'OK') {
resultsMap.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: resultsMap,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
//function geocodeAddress1(geocoder, resultsMap) {
// geocoder.geocode({ 'address': address }, function (results, status) {
// if (status === 'OK') {
// resultsMap.setCenter(results[0].geometry.location);
// var marker = new google.maps.Marker({
// map: resultsMap,
// position: results[0].geometry.location
// });
// } else {
// alert('Geocode was not successful for the following reason: ' + status);
// }
// });
//}
//function geocodeAddress2(geocoder, resultsMap) {
// geocoder.geocode({ 'address': address }, function (results, status) {
// if (status === 'OK') {
// resultsMap.setCenter(results[0].geometry.location);
// var marker = new google.maps.Marker({
// map: resultsMap,
// position: results[0].geometry.location
// });
// } else {
// alert('Geocode was not successful for the following reason: ' + status);
// }
// });
//}
//function geocodeAddress3(geocoder, resultsMap) {
// geocoder.geocode({ 'address': address }, function (results, status) {
// if (status === 'OK') {
// resultsMap.setCenter(results[0].geometry.location);
// var marker = new google.maps.Marker({
// map: resultsMap,
// position: results[0].geometry.location
// });
// } else {
// alert('Geocode was not successful for the following reason: ' + status);
// }
// });
//}
I get a javascript error with your code: Uncaught TypeError: document.getElementByClassName is not a function. document.getElementByClassName doesn't exist. The name of the function is document.getElementsByClassName (plural), and it returns an array of DOM Elements. Process through the array adding click listeners (or use jQuery with an appropriate selector). Also, this.value is not a function (change this.value() to this.value).
var elems = document.getElementsByClassName('address');
for (var i = 0; i < elems.length; i++) {
elems[i].addEventListener('click', function() {
geocodeAddress(this.value, geocoder, map);
});
};
function geocodeAddress(address, geocoder, resultsMap) {
geocoder.geocode({
'address': address
}, function(results, status) {
if (status === 'OK') {
resultsMap.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: resultsMap,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
proof of concept fiddle
code snippet:
var geocoder;
function initMap() {
geocoder = new google.maps.Geocoder();
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 13,
center: {
lat: 37.4419,
lng: -122.1419
}
});
var elems = document.getElementsByClassName('address');
for (var i = 0; i < elems.length; i++) {
elems[i].addEventListener('click', function() {
geocodeAddress(this.value, geocoder, map);
});
};
}
function geocodeAddress(address, geocoder, resultsMap) {
geocoder.geocode({
'address': address
}, function(results, status) {
if (status === 'OK') {
resultsMap.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: resultsMap,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
google.maps.event.addDomListener(window, "load", initMap);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="floating-panel">
<input id="address-1" class="address" value="Paris" type="button" />
<input id="address-2" class="address" value="London" type="button" />
<input id="address-3" class="address" value="New York" type="button" />
</div>
<div id="map"></div>

Google Maps API Directions Service Displaying Text Directions Repeating

I'm using the Google Maps JavaScript API to display routes and text directions:
JS:
var geocoder;
var map;
var search_lat;
var search_lng;
function initMap() {
var myLatLng = {
lat: 38.5803844,
lng: -121.50024189999999
};
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: myLatLng,
});
geocoder = new google.maps.Geocoder();
document.getElementById('search_button').addEventListener('click', function() {
getDirectionsByAddress(geocoder, map);
});
var locations = <?php echo json_encode($locations_array); ?>;
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][5], locations[i][6]),
animation: google.maps.Animation.DROP,
icon: icon_image,
map: map
});
}
}
function getDirectionsByAddress() {
// GET THE SEARCH ADDRESS
var address = document.getElementById('address').value;
console.log('search address: ' + address);
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
search_lat = results[0].geometry.location.lat();
search_lng = results[0].geometry.location.lng();
console.log('search address coordinates: ' + search_lat + ', ' + search_lng);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
// INITIALIZE GOOGLE MAPS DIRECTIONS SERVICE
var directionsDisplay = new google.maps.DirectionsRenderer;
var directionsService = new google.maps.DirectionsService;
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('directions'));
calculateAndDisplayRoute(directionsService, directionsDisplay);
// CHECK THE MODE OF TRAVEL
document.getElementById('mode').addEventListener('change', function() {
calculateAndDisplayRoute(directionsService, directionsDisplay);
});
// CALCULATE THE DIRECTIONS BASED ON ADDRESS ENTERED AND MODE OF TRAVEL
function calculateAndDisplayRoute(directionsService, directionsDisplay) {
console.log('search address coordinates: ' + search_lat + ', ' + search_lng);
var selectedMode = document.getElementById('mode').value;
directionsService.route({
origin: {lat: search_lat, lng: search_lng},
destination: {lat: 38.5803844, lng: -121.50024189999999},
travelMode: google.maps.TravelMode[selectedMode]
}, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
}
I'm having trouble with the getDirectionsByAddress function. When I search a location and click the "search button" the first time, nothing happens. On the second click of the "search button", the route is drawn successfully on the map and the directions are displayed, however the directions are displayed twice (it seems the directions were calculated on the first click, but only on the second click are they being displayed). If I search a third time, the third set of directions are tacked on and this repeats over and over.
It seems I need to reset the lat and lng values during each search. I tried:
delete search_lat;
delete search_lng;
inside and at the end of the calculateAndDisplayRoute function. No luck.
HTML:
<div id="map"></div>
<div id="directions">
<h3>Directions</h3>
</div>
<div class="search_block">
<input type="text" name="address" id="address" class="address" placeholder="Where are you coming from?" />
</div>
<div class="search_block">
<select name="travel_mode" id="mode">
<option>DRIVING</option>
<option>WALKING</option>
<option>BICYCLE</option>
<option>TRANSIT</option>
</select>
</div>
<div class="search_block">
<button id="search_button" onclick="getDirectionsByAddress();">Search</button>
</div>
Question: How can I make it so the directions are refreshed with a single set of coordinates during each search?
search_lat and search_lng are null until the geocoder returns results.
the geocoder is asynchronous, its results don't come back until after you place the first call to the directions service.
a hint is this error in the javascript console: Uncaught TypeError: Cannot read property 'b' of null
Move the call to the directions service into the callback function for the geocoder (where/when the data exists).
Fix that, and create a single instance of the DirectionsRenderer and it works for me.
proof of concept fiddle
code snippet:
google.maps.event.addDomListener(window, "load", initMap);
var geocoder;
var map;
var search_lat;
var search_lng;
var directionsDisplay;
var directionsService;
function initMap() {
var myLatLng = {
lat: 38.5803844,
lng: -121.50024189999999
};
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: myLatLng,
});
directionsDisplay = new google.maps.DirectionsRenderer;
directionsService = new google.maps.DirectionsService;
geocoder = new google.maps.Geocoder();
document.getElementById('search_button').addEventListener('click', function() {
getDirectionsByAddress(geocoder, map);
});
var locations = []; //<?php echo json_encode($locations_array); ?>;
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][5], locations[i][6]),
animation: google.maps.Animation.DROP,
icon: icon_image,
map: map
});
}
}
function getDirectionsByAddress() {
// GET THE SEARCH ADDRESS
var address = document.getElementById('address').value;
console.log('search address: ' + address);
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
search_lat = results[0].geometry.location.lat();
search_lng = results[0].geometry.location.lng();
console.log('search address coordinates: ' + search_lat + ', ' + search_lng);
calculateAndDisplayRoute(directionsService, directionsDisplay);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
// INITIALIZE GOOGLE MAPS DIRECTIONS SERVICE
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('directions'));
// CHECK THE MODE OF TRAVEL
document.getElementById('mode').addEventListener('change', function() {
calculateAndDisplayRoute(directionsService, directionsDisplay);
});
// CALCULATE THE DIRECTIONS BASED ON ADDRESS ENTERED AND MODE OF TRAVEL
function calculateAndDisplayRoute(directionsService, directionsDisplay) {
console.log('search address coordinates: ' + search_lat + ', ' + search_lng);
var selectedMode = document.getElementById('mode').value;
directionsService.route({
origin: {
lat: search_lat,
lng: search_lng
},
destination: {
lat: 38.5803844,
lng: -121.50024189999999
},
travelMode: google.maps.TravelMode[selectedMode]
}, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
}
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="directions">
<h3>Directions</h3>
</div>
<div class="search_block">
<input type="text" name="address" id="address" class="address" placeholder="Where are you coming from?" value="San Franscisco, CA" />
</div>
<div class="search_block">
<select name="travel_mode" id="mode">
<option>DRIVING</option>
<option>WALKING</option>
<option>BICYCLE</option>
<option>TRANSIT</option>
</select>
</div>
<div class="search_block">
<button id="search_button" onclick="getDirectionsByAddress();">Search</button>
</div>
<div id="map"></div>

Google Maps Geocode not working (no markers)

I have a webpage to find latitude, longitude, and get a marker for that position. I use Google Maps.
My webpage get 2 addresses from user input, address 1 and address 2, and calls codeAddress()
<div id="panel">
<input id="address1" type="textbox" value="">
<input id="address2" type="textbox" value="">
<input type="button" value="find!" onclick="codeAddress()">
</div>
This is my JavaScript code:
var map;
var address1 = document.getElementById('address1').value;
var address2 = document.getElementById('address2').value;
function initialize() {
var latlng = new google.maps.LatLng(-7.275920, 112.791871);
var mapOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
function codeAddress() {
var gc = google.maps.Geocoder();
gc.geocode({
'address': address1
}, function (res1, status) {
if (status == google.maps.GeocoderStatus.OK) {
gc.geocode({
'address': address2
}, function (res2, status) {
if (status == google.maps.GeocoderStatus.OK) {
new google.maps.Marker({
position: res1[0].geometry.location,
map: map
});
new google.maps.Marker({
position: res2[0].geometry.location,
map: map
});
}
});
}
});
}
When I click the button find, I didn’t get the markers. Can any body help me?
Modify the codeAddress function like this:
function codeAddress() {
var gc = new google.maps.Geocoder(); // notice new keyword
initialize(); // Calling initialize. If you skip it, maps aren't loading
gc.geocode({
'address': address1
}, function(res1, status) {
if (status == google.maps.GeocoderStatus.OK) {
gc.geocode({
'address': address2
}, function(res2, status) {
if (status == google.maps.GeocoderStatus.OK) {
new google.maps.Marker({
position: res1[0].geometry.location,
map: map
});
new google.maps.Marker({
position: res2[0].geometry.location,
map: map
});
}
});
}
});
Make sure both of the inputs have some value to test it.
Demo: http://jsfiddle.net/lotusgodkk/GCu2D/213/
update the address variables from the form when the function runs
function codeAddress() {
var address1 = document.getElementById('address1').value;
var address2 = document.getElementById('address2').value;
check for status != OK
} else alert("Geocode failed of " + address1 + ", status=" + status);
use "new" before the google maps Geocoder constructor
var gc = new google.maps.Geocoder();
remove existing markers before displaying new ones so the markers don't accumulate on the map
if (marker1 && marker1.setMap) marker1.setMap(null);
complete code:
var map = null;
var marker1 = null;
var marker2 = null;
var gc = new google.maps.Geocoder();
function initialize() {
var latlng = new google.maps.LatLng(-7.275920, 112.791871);
var mapOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
codeAddress();
}
function codeAddress() {
var address1 = document.getElementById('address1').value;
var address2 = document.getElementById('address2').value;
gc.geocode({
'address': address1
}, function (res1, status) {
if (status == google.maps.GeocoderStatus.OK) {
gc.geocode({
'address': address2
}, function (res2, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (marker1 && marker1.setMap) marker1.setMap(null);
marker1 = new google.maps.Marker({
position: res1[0].geometry.location,
map: map
});
if (marker2 && marker2.setMap) marker2.setMap(null);
marker2 = new google.maps.Marker({
position: res2[0].geometry.location,
map: map
});
} else alert("Geocode failed of " + address2 + ", status=" + status);
});
} else alert("Geocode failed of " + address1 + ", status=" + status);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
working fiddle

Google Maps V3 Geocode + Zoom

I was using geocode service of Google Maps Version 2 the Javascript API.
https://developers.google.com/maps/documentation/javascript/v2/reference
However google decided not to support his anymore.
Note: The Google Maps JavaScript API Version 2 has been officially
deprecated as of May 19, 2010. The V2 API will continue to work until
May 19, 2013. We encourage you to migrate your code to version 3 of
the Maps JavaScript API.
So how can I geocode in google maps version 3 javascript api with zoom?
To zoom the map to best show the results of the geocoding operation, you can use the google.maps.Map fitBounds method with the viewport property of the result:
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, 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
});
if (results[0].geometry.viewport)
map.fitBounds(results[0].geometry.viewport);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
code snippet:
var geocoder, map, marker;
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
if (marker && marker.setMap) marker.setMap(null);
marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
if (results[0].geometry.viewport)
map.fitBounds(results[0].geometry.viewport);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function initialize() {
geocoder = new google.maps.Geocoder();
map = new google.maps.Map(
document.getElementById("map_canvas"), {
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addDomListener(document.getElementById('btn'), 'click', codeAddress);
codeAddress();
}
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>
<input id="address" value="Palo Alto, CA" />
<input id="btn" value="Geocode" type="button" />
<div id="map_canvas"></div>
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': zipcode }, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
map.setCenter(results[0].geometry.location);
map.setZoom(12);
}
else
{
alert(zipcode + " not found");
console.log("status : ", status);
}
});

How do I return a longitude and latitude from Google Maps JavaScript geocoder? [duplicate]

This question already has answers here:
How do I return a variable from Google Maps JavaScript geocoder callback?
(5 answers)
Closed 7 years ago.
When I use the code below its alerting a blank value? why is that?
HTML
<body onload="initialize()">
<div id="map_canvas" style="width: 320px; height: 480px;"></div>
<div>
<input id="address" type="textbox" value="Sydney, NSW">
<input type="button" value="Encode" onclick="display()">
</div>
</body>
JavaScript
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function codeAddress() {
var address = document.getElementById("address").value;
var loc=[];
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
loc[0]=results[0].geometry.location.lat();
loc[1]=results[0].geometry.location.lng();
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
return loc;
}
function display(){
var long_lat=codeAddress();
alert(long_lat);
}
because your function codeAddress is executed, assigning empty array to loc, executing asynchronous request to google geocoder and returns loc, which is empty, because its real value is assigned when response from google comes. In other words, allert should be inside response handler:
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function codeAddress() {
var address = document.getElementById("address").value;
var loc=[];
// next line creates asynchronous request
geocoder.geocode( { 'address': address}, function(results, status) {
// and this is function which processes response
if (status == google.maps.GeocoderStatus.OK) {
loc[0]=results[0].geometry.location.lat();
loc[1]=results[0].geometry.location.lng();
alert( loc ); // the place where loc contains geocoded coordinates
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
// pretty meaningless, because it always will be []
// this line is executed right after creating AJAX request, but not after its response comes
return loc;
}
function display(){
codeAddress();
}
this is how AJAX works... process results in callback handlers.
if you want to separate geocoding and 'dispalying' you can execute display function inside handler:
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var loc=[]; // no need to define it in outer function now
loc[0]=results[0].geometry.location.lat();
loc[1]=results[0].geometry.location.lng();
display( loc );
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function display( long_lat ){
alert(long_lat);
}
html:
<input type="button" value="Encode" onclick="codeAddress()">
you can make it even more generic, if you will geocode not only to display. Then you can define callback as parameter to codeAddress function:
function codeAddress( callback ) {
...
geocoder.geocode( { 'address': address}, function(results, status) {
...
callback( loc ); // instead of dispaly( loc );
...
}
...
}
codeAddress( display ); // to execute geocoding

Categories

Resources