Given the lat/long coordinates, how can we find out the city/country?
Asked Answered
S

17

171

For example if we have these set of coordinates

"latitude": 48.858844300000001,
"longitude": 2.2943506,

How can we find out the city/country?

Stinkpot answered 28/5, 2011 at 1:17 Comment(2)
You'll probably need a database of some sort. I'd try playing with the Google Maps API myself... it supports lat/long.Gala
See also Get country from latitude longitudeGenesia
H
112

The free Google Geocoding API provides this service via a HTTP REST API. Note, the API is usage and rate limited, but you can pay for unlimited access.

Try this link to see an example of the output (this is in json, output is also available in XML)

https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true

Histochemistry answered 15/6, 2011 at 8:31 Comment(5)
accepting this because this is the one i end up going for :) Michael's answer is certainly a great option tho!Stinkpot
Google's reverse geocoding is only allowed in conjunction with a Google Map. If you want a solution that has no such restrictions (though it is commercial and only has US cities), check out: askgeo.comThielen
mapquest api is another option here as it has no rate limits in some cases and very high rate limits for various geocoding needs.Muro
free is debatable, it is only free under certain limits.Footstep
@JamesD: the API policies states that if you display the data on a map, then it must be a Google Map, but you don't have to display it on a map (or at all).Detector
L
196

Another option:

  • Download the cities database from http://download.geonames.org/export/dump/
  • Add each city as a lat/long -> City mapping to a spatial index such as an R-Tree (some DBs also have the functionality)
  • Use nearest-neighbour search to find the closest city for any given point

Advantages:

  • Does not depend on an external server to be available
  • Very fast (easily does thousands of lookups per second)

Disadvantages:

  • Not automatically up to date
  • Requires extra code if you want to distinguish the case where the nearest city is dozens of miles away
  • May give weird results near the poles and the international date line (though there aren't any cities in those places anyway
Lancewood answered 15/6, 2011 at 8:48 Comment(10)
Will also give weird results for cities within cities, for example certain locations in Rome may return "Vatican City" - depending on the lat/lon specified in the database for each.Bytom
They also have a REST api and looks pretty decent: api.geonames.org/…Existential
An example would've been invaluableColtin
GeoNames also offers a free web service which is simply awesome!Kitts
In 2020, GeoNames.org looks pretty much inactive, does anyone know if it's even current ? Problem is nowhere do they mention dates of last update on the site.Smallman
@joedotnot: how does it possibly look "inactive" to you? The forum has discussions with comments from yesterday, there is a blog entry from March, and there is a link "recent modifications" right there on the homepage which is full of updates from today.Lancewood
@michael-borgwardt I landed on the home page, no dates anywhere to be seen. Look in the blog the history of posts is June 26, 2013, APRIL 3, 2018, MARCH 8, 2020 (3 articles within 7 years), The forums for discussion can be 'alive' forever, without the actual thing being discussed being active. But if you are telling me it's active, I accept - just wanted to be re-assured by someone who is more familiar.Smallman
How about a small example on how to do this searchCelka
Nearest city is also inaccurate if you query a point halfway between the centroids of a big city and a small city.Cronk
just an FYI, the geonames api does not give admin 2,3,4 etc informationPointdevice
H
112

The free Google Geocoding API provides this service via a HTTP REST API. Note, the API is usage and rate limited, but you can pay for unlimited access.

Try this link to see an example of the output (this is in json, output is also available in XML)

https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true

Histochemistry answered 15/6, 2011 at 8:31 Comment(5)
accepting this because this is the one i end up going for :) Michael's answer is certainly a great option tho!Stinkpot
Google's reverse geocoding is only allowed in conjunction with a Google Map. If you want a solution that has no such restrictions (though it is commercial and only has US cities), check out: askgeo.comThielen
mapquest api is another option here as it has no rate limits in some cases and very high rate limits for various geocoding needs.Muro
free is debatable, it is only free under certain limits.Footstep
@JamesD: the API policies states that if you display the data on a map, then it must be a Google Map, but you don't have to display it on a map (or at all).Detector
I
66

You need geopy

pip install geopy

and then:

from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="my-app")
location = geolocator.reverse("48.8588443, 2.2943506")

print(location.address)

to get more information:

print (location.raw)

{'place_id': '24066644', 'osm_id': '2387784956', 'lat': '41.442115', 'lon': '-8.2939909', 'boundingbox': ['41.442015', '41.442215', '-8.2940909', '-8.2938909'], 'address': {'country': 'Portugal', 'suburb': 'Oliveira do Castelo', 'house_number': '99', 'city_district': 'Oliveira do Castelo', 'country_code': 'pt', 'city': 'Oliveira, São Paio e São Sebastião', 'state': 'Norte', 'state_district': 'Ave', 'pedestrian': 'Rua Doutor Avelino Germano', 'postcode': '4800-443', 'county': 'Guimarães'}, 'osm_type': 'node', 'display_name': '99, Rua Doutor Avelino Germano, Oliveira do Castelo, Oliveira, São Paio e São Sebastião, Guimarães, Braga, Ave, Norte, 4800-443, Portugal', 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright'}
Invisible answered 13/1, 2016 at 16:3 Comment(3)
Are there any limits to this one? This seems to be the quickest approach. Could there be any reason not to use this over @Michael's approach?Knowland
well it requires a external serviceHerbst
It's a great approach, however I just need the counties, so I need to refine the address. I wish there was a way which gave back the counties.Nightjar
L
29

An Open Source alternative is Nominatim from Open Street Map. All you have to do is set the variables in an URL and it returns the city/country of that location. Please check the following link for official documentation: Nominatim

Lear answered 3/1, 2016 at 1:38 Comment(1)
Note that the Nominatim usage policy operations.osmfoundation.org/policies/nominatim states a maximum rate of one request per second so is only really suitable for ad-hoc queries.Cirrhosis
A
23

I was searching for a similar functionality and I saw the data "http://download.geonames.org/export/dump/" shared on earlier reply (thank you for sharing, it is an excellent source), and implemented a service based on the cities1000.txt data.

You can see it running at http://scatter-otl.rhcloud.com/location?lat=36&long=-78.9 (broken link) Just change the latitude and longitude for your locations.

It is deployed on OpenShift (RedHat Platform). First call after a long idle period may take sometime, but usually performance is satisfactory. Feel free to use this service as you like...

Also, you can find the project source at https://github.com/turgos/Location.

Asha answered 10/6, 2015 at 19:53 Comment(3)
It doesn't work propertly. If it can't get city it searches for a nearest known city. Here is an example: scatter-otl.rhcloud.com/… It says "Basseterre" instead of "Saint John"...Judenberg
That's correct. the algorithm searches the closest city available in the dataset. For above deployed server, I used "cities1000.txt". It has only the major cities. Source code is available at github.com/turgos/Location. You can start your own with more detailed data from "download.geonames.org/export/dump".Asha
It seems cities1000.txt is the more detailed data available. Am i right?Judenberg
B
9

I've used Geocoder, a good Python library that supports multiple providers, including Google, Geonames, and OpenStreetMaps, to mention just a few. I've tried using the GeoPy library, and it often gets timeouts. Developing your own code for GeoNames is not the best use of your time and you may end up getting unstable code. Geocoder is very simple to use in my experience, and has good enough documentation. Below is some sample code for looking up city by latitude and longitude, or finding latitude/longitude by city name.

import geocoder

g = geocoder.osm([53.5343609, -113.5065084], method='reverse')
print g.json['city'] # Prints Edmonton

g = geocoder.osm('Edmonton, Canada')
print g.json['lat'], g.json['lng'] # Prints 53.5343609, -113.5065084
Borras answered 8/3, 2017 at 9:37 Comment(6)
Thanks for sharing this but it doesn't work for all coordinates. Do coordinates' number of digits need to be in a specific size?Nightjar
The only rule for coordinates I know is that the latitude is first, and second is the longitude. Could you provide the value of the coordinates that this doesn't work for?Borras
I believe I chose longitude and latitude correctly. I have thousands of coordinates from which a random coordinate didn't work. It's fine now. I used another approach. Thanks for your response.Nightjar
Welcome. Curious to know what approach worked for you? If it's better than geocoder, I'd like to try it myself too!Borras
I used this: from geopy.geocoders import Nominatim geolocator = Nominatim() location = geolocator.reverse("41.4721, -72.6311") print(location.address) It gives the whole address and then I filter the county from it.Nightjar
Thanks, I worked with a large dataset and in 2017, using GeoPy got me many timeouts. Maybe 3 years later they've relaxed their restrictions, so that's great to know!Borras
J
8

I know this question is really old, but I have been working on the same issue and I found an extremely efficient and convenient package, reverse_geocoder, built by Ajay Thampi. The code is available here. It based on a parallelised implementation of K-D trees which is extremely efficient for large amounts of points (it took me few seconds to get 100,000 points.

It is based on this database, already highlighted by @turgos.

If your task is to quickly find the country and city of a list of coordinates, this is a great tool.

Jacindajacinta answered 25/10, 2017 at 17:38 Comment(0)
O
6

I spent about an 30min trying to find a code example of how to do this in Javascript. I couldn't find a quick clear answer to the question you posted. So... I made my own. Hopefully people can use this without having to go digging into the API or staring at code they have no idea how to read. Ha if nothing else I can reference this post for my own stuff.. Nice question and thanks for the forum of discussion!

This is utilizing the Google API.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=<YOURGOOGLEKEY>&sensor=false&v=3&libraries=geometry"></script>

.

//CHECK IF BROWSER HAS HTML5 GEO LOCATION
if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function (position) {

        //GET USER CURRENT LOCATION
        var locCurrent = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

        //CHECK IF THE USERS GEOLOCATION IS IN AUSTRALIA
        var geocoder = new google.maps.Geocoder();
            geocoder.geocode({ 'latLng': locCurrent }, function (results, status) {
                var locItemCount = results.length;
                var locCountryNameCount = locItemCount - 1;
                var locCountryName = results[locCountryNameCount].formatted_address;

                if (locCountryName == "Australia") {
                    //SET COOKIE FOR GIVING
                    jQuery.cookie('locCountry', locCountryName, { expires: 30, path: '/' }); 
                }
        });
    }
}
Occupier answered 21/1, 2014 at 19:14 Comment(0)
S
3

It really depends on what technology restrictions you have.

One way is to have a spatial database with the outline of the countries and cities you are interested in. By outline I mean that countries and cities are store as the spatial type polygon. Your set of coordinates can be converted to the spatial type point and queried against the polygons to get the country/city name where the point is located.

Here are some of the databases which support spatial type: SQL server 2008, MySQL, postGIS - an extension of postgreSQL and Oracle.

If you would like to use a service in stead of having your own database for this you can use Yahoo's GeoPlanet. For the service approach you might want to check out this answer on gis.stackexchange.com, which covers the availability of services for solving your problem.

Steelmaker answered 15/6, 2011 at 6:31 Comment(0)
L
2

Loc2country is a Golang based tool that returns the ISO alpha-3 country code for given location coordinates (lat/lon). It responds in microseconds. It uses a geohash to country map.

The geohash data is generated using georaptor.

We use geohash at level 6 for this tool, i.e., boxes of size 1.2km x 600m.

Ludewig answered 4/2, 2019 at 5:1 Comment(1)
Damn, I was hoping this was a CLI program rather than a server.Rosemonde
O
1

You can use Google Geocoding API

Bellow is php function that returns Adress, City, State and Country

public function get_location($latitude='', $longitude='')
{
    $geolocation = $latitude.','.$longitude;
    $request = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='.$geolocation.'&sensor=false'; 
    $file_contents = file_get_contents($request);
    $json_decode = json_decode($file_contents);
    if(isset($json_decode->results[0])) {
        $response = array();
        foreach($json_decode->results[0]->address_components as $addressComponet) {
            if(in_array('political', $addressComponet->types)) {
                    $response[] = $addressComponet->long_name; 
            }
        }

        if(isset($response[0])){ $first  =  $response[0];  } else { $first  = 'null'; }
        if(isset($response[1])){ $second =  $response[1];  } else { $second = 'null'; } 
        if(isset($response[2])){ $third  =  $response[2];  } else { $third  = 'null'; }
        if(isset($response[3])){ $fourth =  $response[3];  } else { $fourth = 'null'; }
        if(isset($response[4])){ $fifth  =  $response[4];  } else { $fifth  = 'null'; }


        $loc['address']=''; $loc['city']=''; $loc['state']=''; $loc['country']='';
        if( $first != 'null' && $second != 'null' && $third != 'null' && $fourth != 'null' && $fifth != 'null' ) {
            $loc['address'] = $first;
            $loc['city'] = $second;
            $loc['state'] = $fourth;
            $loc['country'] = $fifth;
        }
        else if ( $first != 'null' && $second != 'null' && $third != 'null' && $fourth != 'null' && $fifth == 'null'  ) {
            $loc['address'] = $first;
            $loc['city'] = $second;
            $loc['state'] = $third;
            $loc['country'] = $fourth;
        }
        else if ( $first != 'null' && $second != 'null' && $third != 'null' && $fourth == 'null' && $fifth == 'null' ) {
            $loc['city'] = $first;
            $loc['state'] = $second;
            $loc['country'] = $third;
        }
        else if ( $first != 'null' && $second != 'null' && $third == 'null' && $fourth == 'null' && $fifth == 'null'  ) {
            $loc['state'] = $first;
            $loc['country'] = $second;
        }
        else if ( $first != 'null' && $second == 'null' && $third == 'null' && $fourth == 'null' && $fifth == 'null'  ) {
            $loc['country'] = $first;
        }
      }
      return $loc;
}
Osteal answered 5/12, 2015 at 7:45 Comment(1)
if I want only administrative_area_level_ 3 or locality (if administrative_area_level_ 3 not available), which one should I modify? new to php..Lyndialyndon
C
1

If you are using Google's Places API, this is how you can get country and city from the place object using Javascript:

function getCityAndCountry(location) {
  var components = {};
  for(var i = 0; i < location.address_components.length; i++) {
    components[location.address_components[i].types[0]] = location.address_components[i].long_name;
  }

  if(!components['country']) {
    console.warn('Couldn\'t extract country');
    return false;
  }

  if(components['locality']) {
    return [components['locality'], components['country']];
  } else if(components['administrative_area_level_1']) {
    return [components['administrative_area_level_1'], components['country']];
  } else {
    console.warn('Couldn\'t extract city');
    return false;
  }
}
Congo answered 3/10, 2016 at 19:27 Comment(0)
F
0

Please check the below answer. It works for me

if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position){

        initialize(position.coords.latitude,position.coords.longitude);
    }); 
}

function initialize(lat,lng) {
    //directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
    //directionsService = new google.maps.DirectionsService();
    var latlng = new google.maps.LatLng(lat, lng);

    //alert(latlng);
    getLocation(latlng);
}

function getLocation(latlng){

    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({'latLng': latlng}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (results[0]) {
                    var loc = getCountry(results);
                    alert("location is::"+loc);
                }
            }
        });

}

function getCountry(results)
{
    for (var i = 0; i < results[0].address_components.length; i++)
    {
        var shortname = results[0].address_components[i].short_name;
        var longname = results[0].address_components[i].long_name;
        var type = results[0].address_components[i].types;
        if (type.indexOf("country") != -1)
        {
            if (!isNullOrWhitespace(shortname))
            {
                return shortname;
            }
            else
            {
                return longname;
            }
        }
    }

}

function isNullOrWhitespace(text) {
    if (text == null) {
        return true;
    }
    return text.replace(/\s/gi, '').length < 1;
}
Felishafelita answered 30/8, 2013 at 8:27 Comment(0)
Q
0

Minimize the amount of libraries.

Get a key to use the api at their website and just get the result in a http request:

curl -i -H "key: YOUR_KEY" -X GET https://api.latlong.dev/lookup?lat=38.7447913&long=-9.1625173
Quandary answered 29/5, 2020 at 7:5 Comment(0)
D
0

Update: My solution was not accurate enough, sometimes it returned incorrect country for coordinates right next to a border, or it would not return any country when the coordinates were at a seashore for example. At the end I went for paid MapBox reverse geocoding API. A request to URL https://api.mapbox.com/geocoding/v5/mapbox.places/<longitude>,<latitude>.json?access_token=<access token> returns geojson with location data - place name, region, country.


Original answer:

Download countries from https://www.naturalearthdata.com/downloads/ (I recommend using 1:10m for better accuracy), generate GeoJSON from it, and use some algorithm to detect if given coordinates are within a country polygon(s).

I used these steps to generate GeoJSON file:

  1. Install Anaconda: https://www.anaconda.com/products/distribution
  2. Install gdal: conda install -c conda-forge gdal (use elevated admin rights, more info on https://anaconda.org/conda-forge/gdal)
  3. Download 1:10m countries form https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_0_countries.zip, extract it.
  4. Set environment variable: setx PROJ_LIB C:\ProgramData\Anaconda3\Library\share\proj\
  5. Run command C:\ProgramData\Anaconda3\Library\bin\ogr2ogr.exe -f GeoJSON -t_srs crs:84 data.geo.json ne_10m_admin_0_countries.shp

This will generate data.geo.json which has around 24MB. You can alternatively download it here.

C#:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace SmartGuide.Core.Services.CountryLocators
{
    public static class CountryLocator
    {
        private static readonly Lazy<List<CountryPolygons>> _countryPolygonsByCountryName = new(() =>
        {
            var dataGeoJsonFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "data.geo.json");
            var stream = new FileStream(dataGeoJsonFileName, FileMode.Open, FileAccess.Read); 
            var geoJson = _Deserialize<Root>(stream);
            var countryPolygonsByCountryName = geoJson.Features.Select(
                feature => new CountryPolygons
                {
                    CountryName = feature.Properties.Name,
                    Polygons =
                        feature.Geometry.Type switch
                        {
                            "Polygon" => new List<List<GpsCoordinate>>(
                                new[]
                                {
                                    feature.Geometry.Coordinates[0]
                                        .Select(x => new GpsCoordinate(
                                                Convert.ToDouble(x[1]),
                                                Convert.ToDouble(x[0])
                                            )
                                        ).ToList()
                                }
                            ),
                            "MultiPolygon" => feature.Geometry.Coordinates.Select(
                                    polygon => polygon[0].Select(x =>
                                        new GpsCoordinate(
                                            Convert.ToDouble(((JArray) x)[1]),
                                            Convert.ToDouble(((JArray) x)[0])
                                        )
                                    ).ToList()
                                )
                                .ToList(),
                            _ => throw new NotImplementedException($"Unknown geometry type {feature.Geometry.Type}")
                        }
                }
            ).ToList();
            return countryPolygonsByCountryName;
        });

        public static string GetCountryName(GpsCoordinate coordinate)
        {
            var country = _countryPolygonsByCountryName.Value.FirstOrDefault(country =>
                country.Polygons.Any(polygon => _IsPointInPolygon(polygon, coordinate)));
            return country?.CountryName;
        }

        // taken from https://mcmap.net/q/144930/-geo-fencing-point-inside-outside-polygon
        private static bool _IsPointInPolygon(IReadOnlyList<GpsCoordinate> polygon, GpsCoordinate point)
        {
            int i, j;
            bool c = false;
            for (i = 0, j = polygon.Count - 1; i < polygon.Count; j = i++)
            {
                if ((((polygon[i].Latitude <= point.Latitude) && (point.Latitude < polygon[j].Latitude))
                        || ((polygon[j].Latitude <= point.Latitude) && (point.Latitude < polygon[i].Latitude)))
                        && (point.Longitude < (polygon[j].Longitude - polygon[i].Longitude) * (point.Latitude - polygon[i].Latitude)
                            / (polygon[j].Latitude - polygon[i].Latitude) + polygon[i].Longitude))
                {

                    c = !c;
                }
            }

            return c;
        }

        private class CountryPolygons
        {
            public string CountryName { get; set; }
            public List<List<GpsCoordinate>> Polygons { get; set; }
        }

        public static TResult _Deserialize<TResult>(Stream stream)
        {
            var serializer = new JsonSerializer();

            using var sr = new StreamReader(stream);
            using var jsonTextReader = new JsonTextReader(sr);
            return serializer.Deserialize<TResult>(jsonTextReader);
        }

        public readonly struct GpsCoordinate
        {
            public GpsCoordinate(
                double latitude,
                double longitude
                )
            {
                Latitude = latitude;
                Longitude = longitude;
            }

            public double Latitude { get; }
            public double Longitude { get; }
        }
    }
}

    // Generated by https://json2csharp.com/ (with Use Pascal Case) from data.geo.json
    public class Feature
    {
        public string Type { get; set; }
        public string Id { get; set; }
        public Properties Properties { get; set; }
        public Geometry Geometry { get; set; }
    }

    public class Geometry
    {
        public string Type { get; set; }
        public List<List<List<object>>> Coordinates { get; set; }
    }

    public class Properties
    {
        public string Name { get; set; }
    }

    public class Root
    {
        public string Type { get; set; }
        public List<Feature> Features { get; set; }
    }

Tests:

    [TestFixture]
    public class when_locating_country
    {
        [TestCase(49.2231391, 17.8545076, "Czechia", TestName = "1 Vizovice, Czech Republic")]
        [TestCase(2.9263126, -75.2891733, "Colombia", TestName = "2 Neiva, Colombia")]
        [TestCase(12, -70, "Venezuela", TestName = "3 Paraguana, Venezuela")]
        [TestCase(-5.0721976, 39.0993457, "Tanzania", TestName = "4 Tanga, Tanzania")]
        [TestCase(42.9830241, 47.5048716, "Russia", TestName = "5 Makhachkala, Russia")]
        public void country_is_located_correctly(double latitude, double longitude, string expectedCountryName)
        {
            var countryName = CountryLocator.GetCountryName(new CountryLocator.GpsCoordinate(latitude, longitude));

            countryName.ShouldBe(expectedCountryName);
        }
    }

JS: you can use https://github.com/vkurchatkin/which-country and replace the not so accurate https://github.com/vkurchatkin/which-country/blob/master/lib/data.geo.json by the generated one. I didn't test it though.

Denver answered 17/5, 2022 at 7:17 Comment(0)
A
0

You can do it with: https://www.weatherapi.com/ its FREE.

My demo is in React and step by step, but you can do it in any way you want, the key is this Weather API, that accepts LON and LAT as a string to produce city and weather info -> https://api.weatherapi.com/v1/forecast.json?key=YOUR_KEY&q=LATITUDE,LONGITUDE&days=1&aqi=no&alerts=n

Note: you will to generate YOUR OWN KEY, by signing up

You will need 3 states for this:

const [latitude, setLatitude] = useState("");
const [longitude, setLongitude] = useState("");
const [city, setCity] = useState("");

First: Request access to 'location' from user (this will have a POP-UP), by using this code and set state to Latitude and Longitude.

useEffect(() => {
    function getPosition() {
        const successCallback = (position) => {
            console.log(position);
            setLatitude(position.coords.latitude);
            setLongitude(position.coords.longitude);
        };

        const errorCallback = (error) => {
            console.log(error);
            
        };

        navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
    }

    getPosition();
}, []);

Second use https://www.weatherapi.com/ API to get City and other intel, based on Lat and Lon

API looks like this: https://api.weatherapi.com/v1/forecast.json?key=3e5e13fac8354c818de152831211305&q=53.3498053,-6.2603097&days=1&aqi=no&alerts=n

API with explanation: https://api.weatherapi.com/v1/forecast.json?key=3e5e13fac8354c818de152831211305&q=LATITUDE,LONGITUDE&days=1&aqi=no&alerts=n

Now call this API with latitude and longitude to get location data, including city. I am using useEffect as a trigger, so as soon as I get info on Latitude I call the api using axios and set City state to what ever comes out of the api object.

useEffect(() => {
    async function getWeather() {
        let res = await axios.get(
            `https://api.weatherapi.com/v1/forecast.json?key=3e5e13fac8354c818de152831211305&q=${latitude},${longitude}&days=1&aqi=no&alerts=no`
        );
        console.log(res.data);
        setCity(res.data.location.name);
    }
    getWeather();
}, [latitude, longitude]);

RESULT from API:

"location": {
"name": "Dublin",
"region": "Dublin",
"country": "Ireland",
"lat": 53.35,
"lon": -6.26,
"tz_id": "Europe/Dublin",
"localtime_epoch": 1673737376,
"localtime": "2023-01-14 23:02"
},

Here is video to my youtube channel, where you can see a demo of this: https://youtu.be/gxcG8V3Fpbk

Agate answered 14/1, 2023 at 23:17 Comment(0)
R
0

Based on previous answers, I took the idea using GeoNames. I needed a way to get approximation city based from a coordinate for Car Dashboard, this require lot of requests (at least 1 per second) and should not rely on a reliable internet connection. Because database is available offline, that was the best solution for me.

Implementation wise, I selected redis for the backend database and GEO* commands to do lookup.

Basically, you download a country info file (eg: http://download.geonames.org/export/dump/BE.zip) which is a text file with fields separated by tabs. Schema is available on http://download.geonames.org/export/dump readme.

For each line, you add the geospatial entry:

GEOADD geonames.main [lon] [lat] [name]

Then using a simple GEORADIUS you can get the nearest entry based on your location. This is not fully accurate and this only give an approximation but for an offline free service, this is pretty good. All depend of your needs obviously.

I wrote a script which download whole Europe and add it into redis and add some sample code to query database, all in python, you can found code here: https://github.com/maxux/magibux-dashboard/blob/master/backend/tools/geonames.py

For whole Europe (excluding Russia which was not needed for my needs and is quite large), in memory database is ~30 MB.

Runnerup answered 24/4, 2024 at 22:55 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.