This question already has answers here:
Getting the location from an IP address [closed]
(20 answers)
Closed 2 years ago.
I managed to get the user's latitude and longitude using HTML-based geolocation.
//Check if browser supports W3C Geolocation API
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
//Get latitude and longitude;
function successFunction(position) {
var lat = position.coords.latitude;
var long = position.coords.longitude;
}
I want to display the city name, it seems the only way to get it is to use a reverse geolocation API. I read Google's documentation for reverse geolocation but I don't know how to get the output on my site.
I don't know how to go use this: "http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&sensor=true" to display the city name on the page.
How can I achieve this?
You would do something like that using Google API.
Please note you must include the google maps library for this to work. Google geocoder returns a lot of address components so you must make an educated guess as to which one will have the city.
"administrative_area_level_1" is usually what you are looking for but sometimes locality is the city you are after.
Anyhow - more details on google response types can be found here and here.
Below is the code that should do the trick:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Reverse Geocoding</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var geocoder;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
//Get the latitude and the longitude;
function successFunction(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
codeLatLng(lat, lng)
}
function errorFunction(){
alert("Geocoder failed");
}
function initialize() {
geocoder = new google.maps.Geocoder();
}
function codeLatLng(lat, lng) {
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log(results)
if (results[1]) {
//formatted address
alert(results[0].formatted_address)
//find country name
for (var i=0; i<results[0].address_components.length; i++) {
for (var b=0;b<results[0].address_components[i].types.length;b++) {
//there are different types that might hold a city admin_area_lvl_1 usually does in come cases looking for sublocality type will be more appropriate
if (results[0].address_components[i].types[b] == "administrative_area_level_1") {
//this is the object you are looking for
city= results[0].address_components[i];
break;
}
}
}
//city data
alert(city.short_name + " " + city.long_name)
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
</script>
</head>
<body onload="initialize()">
</body>
</html>
$.ajax({
url: "https://geolocation-db.com/jsonp",
jsonpCallback: "callback",
dataType: "jsonp",
success: function(location) {
$('#country').html(location.country_name);
$('#state').html(location.state);
$('#city').html(location.city);
$('#latitude').html(location.latitude);
$('#longitude').html(location.longitude);
$('#ip').html(location.IPv4);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div>Country: <span id="country"></span></div>
<div>State: <span id="state"></span></div>
<div>City: <span id="city"></span></div>
<div>Latitude: <span id="latitude"></span></div>
<div>Longitude: <span id="longitude"></span></div>
<div>IP: <span id="ip"></span></div>
Using html5 geolocation requires user permission. In case you don't want this, go for an external locator like https://geolocation-db.com IPv6 is supported. No restrictions and unlimited requests allowed.
JSON: https://geolocation-db.com/json
JSONP: https://geolocation-db.com/jsonp
Example
For a pure javascript example, without using jQuery, check out this answer.
Another approach to this is to use my service, http://ipinfo.io, which returns the city, region and country name based on the user's current IP address. Here's a simple example:
$.get("http://ipinfo.io", function(response) {
console.log(response.city, response.country);
}, "jsonp");
Here's a more detailed JSFiddle example that also prints out the full response information, so you can see all of the available details: http://jsfiddle.net/zK5FN/2/
You can get the name of the city, country, street name and other geodata using the Google Maps Geocoding API
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>
<script type="text/javascript">
navigator.geolocation.getCurrentPosition(success, error);
function success(position) {
console.log(position.coords.latitude)
console.log(position.coords.longitude)
var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';
$.getJSON(GEOCODING).done(function(location) {
console.log(location)
})
}
function error(err) {
console.log(err)
}
</script>
</body>
</html>
and to display this data on the page using jQuery
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>
<p>Country: <span id="country"></span></p>
<p>State: <span id="state"></span></p>
<p>City: <span id="city"></span></p>
<p>Address: <span id="address"></span></p>
<p>Latitude: <span id="latitude"></span></p>
<p>Longitude: <span id="longitude"></span></p>
<script type="text/javascript">
navigator.geolocation.getCurrentPosition(success, error);
function success(position) {
var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';
$.getJSON(GEOCODING).done(function(location) {
$('#country').html(location.results[0].address_components[5].long_name);
$('#state').html(location.results[0].address_components[4].long_name);
$('#city').html(location.results[0].address_components[2].long_name);
$('#address').html(location.results[0].formatted_address);
$('#latitude').html(position.coords.latitude);
$('#longitude').html(position.coords.longitude);
})
}
function error(err) {
console.log(err)
}
</script>
</body>
</html>
Here is updated working version for me which will get City/Town, It looks like some fields are modified in the json response. Referring previous answers for this questions. ( Thanks to Michal & one more reference : Link
var geocoder;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
// Get the latitude and the longitude;
function successFunction(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
codeLatLng(lat, lng);
}
function errorFunction() {
alert("Geocoder failed");
}
function initialize() {
geocoder = new google.maps.Geocoder();
}
function codeLatLng(lat, lng) {
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({latLng: latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
var arrAddress = results;
console.log(results);
$.each(arrAddress, function(i, address_component) {
if (address_component.types[0] == "locality") {
console.log("City: " + address_component.address_components[0].long_name);
itemLocality = address_component.address_components[0].long_name;
}
});
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
geolocator.js can do that. (I'm the author).
Getting City Name (Limited Address)
geolocator.locateByIP(options, function (err, location) {
console.log(location.address.city);
});
Getting Full Address Information
Example below will first try HTML5 Geolocation API to obtain the exact coordinates. If fails or rejected, it will fallback to Geo-IP look-up. Once it gets the coordinates, it will reverse-geocode the coordinates into an address.
var options = {
enableHighAccuracy: true,
fallbackToIP: true, // fallback to IP if Geolocation fails or rejected
addressLookup: true
};
geolocator.locate(options, function (err, location) {
console.log(location.address.city);
});
This uses Google APIs internally (for address lookup). So before this call, you should configure geolocator with your Google API key.
geolocator.config({
language: "en",
google: {
version: "3",
key: "YOUR-GOOGLE-API-KEY"
}
});
Geolocator supports geo-location (via HTML5 or IP lookups), geocoding, address look-ups (reverse geocoding), distance & durations, timezone information and a lot more features...
After some searching and piecing together a couple of different solutions along with my own stuff, I came up with this function:
function parse_place(place)
{
var location = [];
for (var ac = 0; ac < place.address_components.length; ac++)
{
var component = place.address_components[ac];
switch(component.types[0])
{
case 'locality':
location['city'] = component.long_name;
break;
case 'administrative_area_level_1':
location['state'] = component.long_name;
break;
case 'country':
location['country'] = component.long_name;
break;
}
};
return location;
}
You can use https://ip-api.io/ to get city Name. It supports IPv6.
As a bonus it allows to check whether ip address is a tor node, public proxy or spammer.
Javascript Code:
$(document).ready(function () {
$('#btnGetIpDetail').click(function () {
if ($('#txtIP').val() == '') {
alert('IP address is reqired');
return false;
}
$.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
function (result) {
alert('City Name: ' + result.city)
console.log(result);
});
});
});
HTML Code
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div>
<input type="text" id="txtIP" />
<button id="btnGetIpDetail">Get Location of IP</button>
</div>
JSON Output
{
"ip": "64.30.228.118",
"country_code": "US",
"country_name": "United States",
"region_code": "FL",
"region_name": "Florida",
"city": "Fort Lauderdale",
"zip_code": "33309",
"time_zone": "America/New_York",
"latitude": 26.1882,
"longitude": -80.1711,
"metro_code": 528,
"suspicious_factors": {
"is_proxy": false,
"is_tor_node": false,
"is_spam": false,
"is_suspicious": false
}
}
As #PirateApp mentioned in his comment, it's explicitly against Google's Maps API Licensing to use the Maps API as you intend.
You have a number of alternatives, including downloading a Geoip database and querying it locally or using a third party API service, such as my service ipdata.co.
ipdata gives you the geolocation, organisation, currency, timezone, calling code, flag and Tor Exit Node status data from any IPv4 or IPv6 address.
And is scalable with 10 global endpoints each able to handle >10,000 requests per second!
This answer uses a 'test' API Key that is very limited and only meant for testing a few calls. Signup for your own Free API Key and get up to 1500 requests daily for development.
$.get("https://api.ipdata.co?api-key=test", function(response) {
$("#ip").html("IP: " + response.ip);
$("#city").html(response.city + ", " + response.region);
$("#response").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>ipdata.co - IP geolocation API</h1>
<div id="ip"></div>
<div id="city"></div>
<pre id="response"></pre>
The fiddle; https://jsfiddle.net/ipdata/6wtf0q4g/922/
Here is another go at it .. Adding more to the accepted answer possibly more comprehensive .. of course switch -case will make it look for elegant.
function parseGeoLocationResults(result) {
const parsedResult = {}
const {address_components} = result;
for (var i = 0; i < address_components.length; i++) {
for (var b = 0; b < address_components[i].types.length; b++) {
if (address_components[i].types[b] == "street_number") {
//this is the object you are looking for
parsedResult.street_number = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "route") {
//this is the object you are looking for
parsedResult.street_name = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "sublocality_level_1") {
//this is the object you are looking for
parsedResult.sublocality_level_1 = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "sublocality_level_2") {
//this is the object you are looking for
parsedResult.sublocality_level_2 = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "sublocality_level_3") {
//this is the object you are looking for
parsedResult.sublocality_level_3 = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "neighborhood") {
//this is the object you are looking for
parsedResult.neighborhood = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "locality") {
//this is the object you are looking for
parsedResult.city = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "administrative_area_level_1") {
//this is the object you are looking for
parsedResult.state = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "postal_code") {
//this is the object you are looking for
parsedResult.zip = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "country") {
//this is the object you are looking for
parsedResult.country = address_components[i].long_name;
break;
}
}
}
return parsedResult;
}
Here's an easy function you can use to get it. I used axios to make the API request, but you can use anything else.
async function getCountry(lat, long) {
const { data: { results } } = await axios.get(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${long}&key=${GOOGLE_API_KEY}`);
const { address_components } = results[0];
for (let i = 0; i < address_components.length; i++) {
const { types, long_name } = address_components[i];
if (types.indexOf("country") !== -1) return long_name;
}
}
Alternatively you could use my service, https://astroip.co, it is a new Geolocation API:
$.get("https://api.astroip.co/?api_key=1725e47c-1486-4369-aaff-463cc9764026", function(response) {
console.log(response.geo.city, response.geo.country);
});
AstroIP provides geolocation data together with security datapoints like proxy, TOR nodes and crawlers detection. The API also returns currency, timezones, ASN and company data.
It is a pretty new api with an average response time of 40ms from multiple regions around the world, which positions it in the handful list of super fast Geolocation APIs available.
Big free plan of up to 30,000 requests per month for free is available.
Please provide me proper solution for following code
how can I pass the Google API Key
function load_map_from_address(mapid, address) {
// check if gps has been locally cached.
geocoder = new google.maps.Geocoder();
//alert(geocoder);
var geocoderAPIKey = 'geocoderAPIKey ';
geocoder.geocode({ 'address': address }, function (results, status) {
//alert(status);
if (status == "OK") {
var gps = results[0].geometry.location;
create_map(gps.lat(), gps.lng(), mapid);
}
else {
$('#' + mapid).html('<div class="map_canvas_text "><h4>address not found</h4></div>').show();
}
});
}
You can mention it when you include the Google map js . Something like .
Path-to-google-map js?key=yourApiKey
In you're script tag
I am trying to get formatted address of customer who access my web page.
For that I wrote function to get lat long and then Reverse geocode it to formatted address.
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script>
function coordinates_to_address(lat, lng) {
var latlng = new google.maps.LatLng(lat, lng);
var geocoder= new google.maps.Geocoder();
geocoder.geocode({'latLng': latlng}, function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
if(results[0]) {
$('#address_current').text(results[0].formatted_address);
} else {
alert('No results found');
}
} else {
var error = {
'ZERO_RESULTS': 'No address'
}
// alert('Geocoder failed due to: ' + status);
$('#address_new').html('<span class="color-red">' + error[status] + '</span>');
}
});
}
navigator.geolocation.getCurrentPosition(function(location) {
console.log(location.coords.latitude);
console.log(location.coords.longitude);
console.log(location.coords.accuracy);
var lat= location.coords.latitude;
var long= location.coords.longitude
coordinates_to_address(lat, long);
});
</script>
The log showed the output lat long
10.8888888888888888
76.43923530000001
40
But this function returned an error:
Google Maps API error: MissingKeyMapError https://developers.google.com/maps/documentation/javascript/error-messages#missing-key-map-error
http://maps.google.com/maps/api/js?sensor=false
Line 34
Is there any easier method to get the formatted address of a lat long?
Keys are now required with the Google Maps Javascript API v3 (but the sensor parameter is not).
This question already has answers here:
Address validation using Google Maps API
(10 answers)
Closed 7 years ago.
I have wrote following example:
http://jsfiddle.net/214190tj/1/
html:
<label for="searchTextField">Please Insert an address:</label>
<br>
<input id="searchTextField" type="text" size="50">
<input type="submit" value="is valid">
js:
var input = document.getElementById('searchTextField');
var options = {componentRestrictions: {country: 'us'}};
new google.maps.places.Autocomplete(input, options);
Now it is working good but I need to check that uset didn't type something like "dsgfdsgfjhfg" when button clicks.
Please help to improve my code.
P.S.
this approximately make what I want but it executes in callback. I need a function which returns true or false.
function codeEditAddress(id) {
var address = document.getElementById('address' + id).value;
isValid = undefined;
geocoder.geocode({ 'address': address}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
$("#mapLat" + id).val(results[0].geometry.location.lat());
$("#mapLng" + id).val(results[0].geometry.location.lng());
if (marker) {
marker.setMap(null);
}
marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
marker.setMap(map);
isValid = true;
} else {
isValid = false;
}
});
}
You're going to have to re-design your address checker function so that you pass in a callback function. Returning a value from an asynchronous operation inherently does not make sense. You'll want something like this:
function codeEditAddress(id, callback) {
var address = document.getElementById('address' + id).value;
geocoder.geocode({ 'address': address}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
$("#mapLat" + id).val(results[0].geometry.location.lat());
$("#mapLng" + id).val(results[0].geometry.location.lng());
if (marker) {
marker.setMap(null);
}
marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
marker.setMap(map);
callback(true);
} else {
callback(false);
}
});
}
To call this function:
codeEditAddress(id, function(isValid) {
if (isValid) {
// submit form, do whatever
}
else {
// show error message, etc
}
});
I have some code which, when the search box is clicked, geocodes a location (unless laready done by the autosuggest) in the location box and should the submit the form.
The problem is, the form does not get submitted after the searhc button is clicked and the geocode is successful. Can anyone tell me where I am going wrong?
This is a link to the jsfiddle: http://jsfiddle.net/sR4GR/35/
This is the full code:
$(function () {
var input = $("#loc"),
lat = $("#lat"),
lng = $("#lng"),
lastQuery = null,
autocomplete;
function processLocation(query) {
var query = $.trim(input.val()),
geocoder;
if (!query || query == lastQuery) {
console.log("Empty or same variable");
return;
}
lastQuery = query;
geocoder = new google.maps.Geocoder();
geocoder.geocode({
address: query
}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
lat.val(results[0].geometry.location.lat());
lng.val(results[0].geometry.location.lng());
} else {
alert("We couldn't find this location. Please try an alternative");
}
});
}
autocomplete = new google.maps.places.Autocomplete(input[0], {
types: ["geocode"],
componentRestrictions: {
country: "uk"
}
});
google.maps.event.addListener(autocomplete, 'place_changed', processLocation);
$('#searchform').on('submit', function (event) {
processLocation();
event.preventDefault();
});
});
I don't know what processLocation(query) expects for query, but idea would be this:
1. change function signature
function processLocation(query, doSubmit) { // <--- new parameter
var query = $.trim(input.val()),
geocoder;
if (!query || query == lastQuery) {
console.log("Empty or same variable");
return;
}
lastQuery = query;
geocoder = new google.maps.Geocoder();
geocoder.geocode({
address: query
}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
lat.val(results[0].geometry.location.lat());
lng.val(results[0].geometry.location.lng());
if (doSubmit){
$('#searchform').submit(); //<-- new param usage
}
} else {
alert("We couldn't find this location. Please try an alternative");
}
});
}
2. remove this call
$('#searchform').on('submit', function (event) {
alert('Submitted')
event.preventDefault();
});
3. add this call
$('#search').click(function(){
processLocation(new Date(), true); //<-- don't know what's the first param
});
Tried to play around in your jsfiddle but had no success as I was constantly getting Empty or same variable message into console. I think you know your logic better and you'll figure out
I would just have the submit button disabled until the values are valid?
<input type="submit" value="Search" id="search" disabled="disabled">
search.removeAttr('disabled')
http://jsfiddle.net/sR4GR/38/
?