I cannot figure out how to implement the search box in my google maps. I have it where the user can pick some stuff from a form and it loads the markers on the map. Now I want to add where they can type in the city and state using the google search box, like on maps.google.com. Can this be done with API v. 3?
There is no complete "widget" in Google maps for this task. But it is easy to accomplish it. In HTML you can have a text field and a button "Search". (Instead you can handle the Enter key in the text field).
<input type="text" id="search_address" value=""/>
<button onclick="search();">Search</button>
In Javascript you instantiate and use a Geocoder:
var addressField = document.getElementById('search_address');
var geocoder = new google.maps.Geocoder();
function search() {
geocoder.geocode(
{'address': addressField.value},
function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var loc = results[0].geometry.location;
// use loc.lat(), loc.lng()
}
else {
alert("Not found: " + status);
}
}
);
};
Related
I've been doing mobile part of my project after "completing" the web part. I'm using google map api. I have coded following:
function codeAddress() {
var image = 'images/tickmark1.png';
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 markerZad = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: "NEW TASK",
icon: image
});
document.getElementById('latitude').value =results[0].geometry.location.nb.toPrecision(9);
document.getElementById('longitude').value=results[0].geometry.location.ob.toPrecision(9);
document.getElementById('adrs').value=document.getElementById('address').value;
document.getElementById('latit').value =results[0].geometry.location.nb.toPrecision(9);
document.getElementById('longit').value=results[0].geometry.location.ob.toPrecision(9);
alert("Ustalono wspolrzedne nowego zadania. Wybierz pracownika \n (PPM usuwa znacznik)");
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
google.maps.event.addListener(markerZad, 'click', function() {
alert("Nowe zadanie: \n"+ address + "\n"+"Wybierz pracownika \n (PPM usuwa znacznik)");
map.setZoom(14);
map.setCenter(this.getPosition());
});
google.maps.event.addListener(markerZad, 'rightclick', function() {
markerZad.setMap(null);
document.getElementById('latitude').value =0;
document.getElementById('longitude').value=0;
document.getElementById('adrs').value=0;
document.getElementById('latit').value =0;
document.getElementById('longit').value=0;
document.getElementById('ajdideva').value="X";
document.getElementById('iddev').value=0;
document.getElementById('baton').disabled=true;
alert("Usunieto znacznik. Wpisz inny adres.");
});
});
}
Let's leave behind the level of this code. I'm sure it's a bad one. But the thing is...it used to work for me like few days ago. Now it doesn't. And yes, I haven't touched it since then... I figured out myself, that the problem causes "results". I get status==OK, then it places a marker in a correct spot, and then...nothing happens. I mean my inputs in html file don't get their values changed and +listeners aren't working. When I changed "results[0]." etc to simple string, it worked, that's why I think that there's a problem with results[0]. Any suggestions please?
Don't access undocumented properties like e.g. results[0].geometry.location.nb . The names of these properties may(and will) change. To access the values of these properties use the documented methods, e.g. lat() to access the latitude of a LatLng-instance:
document.getElementById('latitude').value
= results[0].geometry.location.lat().toPrecision(9);
My requirement is to get google places autocomplete suggestion only for Bangalore places, but I am not getting places only for Bangalore or within mention latitude longitude.
I want to retireve only below image places in autocomplete textfield.
can someone plz suggest how to achieve the same and where I am going wrong.
Javascript:
<script type="text/javascript">
function initialize1() {
var southWest = new google.maps.LatLng( 12.97232, 77.59480 );
var northEast = new google.maps.LatLng( 12.89201, 77.58905 );
var bangaloreBounds = new google.maps.LatLngBounds( southWest, northEast );
var options = {
bounds: bangaloreBounds,
types: ['(cities)'],
componentRestrictions: {country: 'in'}
};
var input = document.getElementById('searchTextFieldTo');
var autocomplete = new google.maps.places.Autocomplete(input, options);
}
google.maps.event.addDomListener(window, 'load', initialize1);
</script>
TextField:
<input type="text" id="searchTextFieldTo" class="ui-timepicker-hour" style="width:350px;text-align:left;font-style:italic;" placeholder="Enter To location" autocomplete="on" />
Google Provides two ways to achieve this. If you are not satisfied because in countries like India it do not work well, because states and provisions here do not have rectangular or structure boundaries.
1.LatLngBounds (LatLng southwest, LatLng northeast): Where you can give latitude and longitude to form an rectangle.
2. Location (Lat,Lng) & Radius: Where you can give latitude and longitude to form a circle.
But the problem with these approaches they do not provide expected results if you are from countries like India, where states and provisions are not in structured shapes (Rectangular) as in USA.
If you are facing same issue than there is an hack.
With jQuery/Jacascript, you can attach functions which will consistently maintain city name in text input which is bounded with Autocomplete object of Places API.
Here it is:
<script>
$(document).ready(function(){
$("#locality").val(your-city-name) //your-city-name will have city name and some space to seperate it from actual user-input for example: “Bengaluru | ”
});
$("#locality").keydown(function(event) { //locality is text-input box whixh i supplied while creating Autocomplete object
var localeKeyword = “your-city-name”
var localeKeywordLen = localeKeyword.length;
var keyword = $("#locality").val();
var keywordLen = keyword.length;
if(keywordLen == localeKeywordLen) {
var e = event || window.event;
var key = e.keyCode || e.which;
if(key == Number(46) || key == Number(8) || key == Number(37)){
e.preventDefault();
}//Here I am restricting user to delete city name (Restricting use of delete/backspace/left arrow) if length == city-name provided
if(keyword != localeKeyword) {
$("#locality").val(localeKeyword);
}//If input-text does not contain city-name put it there
}
if(!(keyword.includes(localeKeyword))) {
$("#locality").val(localeKeyword);
}//If keyworf not includes city name put it there
});
</script>
(Image:) Before This Hack
(Image:) After This hack
As mentioned in my answer here:
It is currently not possible to restrict results to a specific locality. You can use bounds as you have done so above to bias results towards, but not restricted to places contained within the specified bounds.
If you believe restriction by locality would be a useful feature please file a Places API - Feature Request.
EDIT:
As per 2018-07 it's possible to define the types of places to be retrieved, like cities (which are locality or administrative_area3 according to the API). Check out full answer here.
I think you can try this.
var bangaloreBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(12.864162, 77.438610),
new google.maps.LatLng(13.139807, 77.711895));
var autocomplete = new google.maps.places.Autocomplete(this, {
bounds: bangaloreBounds,
strictBounds: true,
});
autocomplete.addListener('place_changed', function () {
});
Note form xomena:
strictBounds option was added in version 3.27 of Maps JavaScript API which is currently (January 2017) the experimental version.
function initialize() {
var bangaloreBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(12.864162, 77.438610),
new google.maps.LatLng(13.139807, 77.711895));
var options = {
bounds: bangaloreBounds,
componentRestrictions: {country: 'in'},
strictBounds: true,
};
var input = document.getElementById('autocomplete');
var autocomplete = new google.maps.places.Autocomplete(input, options);
}
google.maps.event.addDomListener(window, 'load', initialize);
As in the current documentation for Google javascript Places API here, you can define an array of types of places to be retrieved. In the example below, I set it to retrieve only cities (which are, according to the API, locality or administrative_area3). You can set it retrieve regions, addresses, establishments and geocodes as well.
function initMap() {
var input = document.getElementById('my-input');
var options = {
types: ['(cities)']
};
var autocomplete = new google.maps.places.Autocomplete(input, options);
// the rest of the code ...
}
I'm building an web app that uses this code to search for addresses:
http://code.google.com/intl/en/apis/maps/documentation/javascript/examples/places-autocomplete.html
Type there, New York, NY.
So, when the map is loaded in the DOM after the user using the autocomplete option, the user can save the Location Address in the database, and it will be available as it is "ex. New York, NY". But, for the application I need to save also the Latitude and Longitude.
But I have no ideia how to grab them from the Google API.
As a test app, I'm still using the google code.
I guess I should create some HIDDEN fields and assign the latitude and longitude to them as the user chooses the Address.
Any implementation for my problem is welcome!!
Thanks in advance
P.S:
As I'm new in StackOverflow I could't answer myself.
So I'm editing the post, as suggested by stackoverflow, and here is the solution based in Daniel's answer and some researches in the Google Api:
function getLatLng( address )
{
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address' : address }, function( results, status ) {
if ( status == google.maps.GeocoderStatus.OK ) {
var mapLatLng = document.getElementById( 'mapLatLng' ); // mapLatLng is my hidden field, use your own
mapLatLng.value = results[0].geometry.location.lat() + ', ' + results[0].geometry.location.lng();
} else {
alert( "Geocode was not successful for the following reason: " + status );
}
});
}
Daniel is right for the most part, where he is incorrect is his access of the property here:
$('#latitude').val(results[0].geometry.location.Pa)
$('#longitude').val(results[0].geometry.location.Qa)
You should instead use the lat() and lng() functions provided:
$('#latitude').val(results[0].geometry.location.lat())
$('#longitude').val(results[0].geometry.location.lng())
You can use the Google API to get the Longitude and Latitude from your address.
As you already said, you should implement a hidden field where the result should be inserted.
Then you can save the location together with the coordinates.
I recently implemented this function in one of my projects:
function getLatLngFromAddress(city, country){
var address = city +", "+ country;
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
$('#latitude').val(results[0].geometry.location.lat());
$('#longitude').val(results[0].geometry.location.lng());
} else {
console.log("Geocode was not successful for the following reason: " + status);
}
});
}
Hitting a page with the follow script displays:
lat: undefined
lon: 51.5001524
Why is it that while lat is undefined, lon is not?
A working example can be found here.
Pull up your web console and see for yourself!
$(document).ready(function(){
var geocoder;
function codeAddress()
{
geocoder = new google.maps.Geocoder();
var address = 'London, England';
geocoder.geocode({'address': address}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
lat = results[0].geometry.location.Ia;
lon = results[0].geometry.location.Ja;
console.log("lat: " + lat);
console.log("lon: " + lon);
}
});
}
codeAddress();
});
</script>
</head>
<body>
</body>
</html>
While we're at it - what is the historical significance of Ia and Ja? I presume it relates to the Cartesian unit vectors i and j (predominately used in Engineering) though I'm not sure.
I found other examples online who use .lat for .Ia and .lng for .Ja
These, however, are returning in the console:
function () {
return this[a];
}
Just need a kick in the right direction.
Thank you.
I would use lat() and lng():
var lat = results[0].geometry.location.lat();
var lng = results[0].geometry.location.lng();
This is a designed behaviour of the geocoder: google shifts the identifiers in
geometry.location.Ia;
geometry.location.Ja;
on a weekly basis, i.e. from above to
geometry.location.Ja;
geometry.location.Ka;
and so on, so it is not possible to refer by id to the geocoder result object.
Chances are Google are using a javascript minifier (e.g. http://jscompress.com/) which renames all variables - hence they're subject to change on every build.
I was wondering if its possible to geocode something using googlemaps api synchronously so instead of waiting for a callback function to be called, it would wait for a value to be returned. Has anyone found a way to do something like this.
P.S.: I'm using version 3 of the api
Yes, what you are trying to achieve is possible, although a synchronous request is not needed.
Look at this code
function StoreGeo()
{
var address = $('input[name=zipcode]').val() + ', ' + $('input[name=city]').val();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var ll = results[0].geometry.location.toString();
llarr = ll.replace(/[\(\) ]/g, '').split(',');
for(i = 0; i < llarr.length;i++)
{
$('#form').append($('<input type="hidden" name="'+(i == 0 ? 'lat' : 'long')+'">').val(llarr[i]));
}
$('#form').submit();
}
else
{
alert(status);
}
});
$('#form').unbind('submit');
return false;
}
$(document).ready(function () {
//init maps
geocoder = new google.maps.Geocoder();
$('#form').bind('submit',function() {
StoreGeo();
});
});
So, attach submit handler to the form, when it is submitted do the geo request based on the address info from your form. But at the same time postpone submitting by returning false in the handler.
The response handler will make 2 hidden textfields 'lat' and 'long' and store the response. finally the form is submitted by client script, including the two new fields. At the server side you can store them in the DB.
!! Note that this is possible, but is probably against the google terms, like noted above.
The Geocoder calls your callback function with the value. That's the only way to do it. If it were synchronous, your script would freeze while it waited for the Geocode to process. There really isn't any reason to do it like that.
What exactly are you trying to accomplish?
I simply use a flag during form submit to know when submit should pass or when it should wait for geocoding. When geocoding is done it will then re-submit the form again.
var hasGeocoded = false;
searchFrom.on('submit', function(){
//If not geocoded yet
if (!hasGeocoded) {
var geocoder = new google.maps.Geocoder();
var location = locationEl.val();
geocoder.geocode({'address': location}, function (results, status) {
hasGeocoded = true;
if (status == google.maps.GeocoderStatus.OK) {
$('#coords').val(
results[0].geometry.location.lat() + ',' + results[0].geometry.location.lng()
);
}
searchFrom.submit();
});
return false; //wait for geocoder to finish and re-submit the form
}
return true;
});