简体   繁体   中英

Google Geolocation API - Use longitude and latitude to get address in textbox?

I have noticed a lot of information about how to get your location using Google geolocation looks, based on IP address. But I am wondering if and how I could use this service to input a location (longitude and latitude) and get back the current address, or at least a city, state.

I would like to do this in C#, but I'll work with any language.

Any advice?

What you describe is called Reverse Geocoding . Google provides a Geocoding Web Service API which you can call from your server-side application (using any language) to do reverse geocoding .

For example, the following request:

http://maps.google.com/maps/api/geocode/xml?latlng=40.714224,-73.961452&sensor=false

... will return a response that looks like the following (truncated):

<GeocodeResponse> 
 <status>OK</status> 
 <result> 
  <type>street_address</type> 
  <formatted_address>277 Bedford Ave, Brooklyn, NY 11211, USA</formatted_address> 
  <address_component> 
   <long_name>277</long_name> 
   <short_name>277</short_name> 
   <type>street_number</type> 
  </address_component> 
  <address_component> 
   <long_name>Bedford Ave</long_name> 
   <short_name>Bedford Ave</short_name> 
   <type>route</type> 
  </address_component> 
  <address_component> 
   <long_name>Brooklyn</long_name> 
   <short_name>Brooklyn</short_name> 
   <type>sublocality</type> 
   <type>political</type> 
  </address_component> 
  <address_component> 
   <long_name>New York</long_name> 
   <short_name>New York</short_name> 
   <type>locality</type> 
   <type>political</type> 
  </address_component> 
  <address_component> 
   <long_name>Kings</long_name> 
   <short_name>Kings</short_name> 
   <type>administrative_area_level_2</type> 
   <type>political</type> 
  </address_component> 
  <address_component> 
   <long_name>New York</long_name> 
   <short_name>NY</short_name> 
   <type>administrative_area_level_1</type> 
   <type>political</type> 
  </address_component> 
  <address_component> 
   <long_name>United States</long_name> 
   <short_name>US</short_name> 
   <type>country</type> 
   <type>political</type> 
  </address_component> 
  <address_component> 
   <long_name>11211</long_name> 
   <short_name>11211</short_name> 
   <type>postal_code</type> 
  </address_component> 
  <geometry> 
   <location> 
    <lat>40.7142330</lat> 
    <lng>-73.9612910</lng> 
   </location> 
   <location_type>ROOFTOP</location_type> 
   <viewport> 
    <southwest> 
     <lat>40.7110854</lat> 
     <lng>-73.9644386</lng> 
    </southwest> 
    <northeast> 
     <lat>40.7173806</lat> 
     <lng>-73.9581434</lng> 
    </northeast> 
   </viewport> 
  </geometry> 
 </result> 
</GeocodeResponse> 

However be aware that the Google Maps API Terms of Use seem to prohibit the storage of the results , unless the store acts as a cache for data that will used in Google Maps. You may want to get in touch with Google and enquire on the Google Maps API Premier to have more flexible terms of use for your geocoding requirements.

Here is ac# implementation. Please note that I am no c# programmer - so the code might be ugly. But it works. It gives you more than just the address. This is a console application, you should be able to adapt it for webforms or winforms easily.

using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.XPath;

namespace ReverseGeoLookup
{
 // http://code.google.com/apis/maps/documentation/geocoding/#ReverseGeocoding
    public static string ReverseGeoLoc(string longitude, string latitude,
        out string Address_ShortName,
        out string Address_country,
        out string Address_administrative_area_level_1,
        out string Address_administrative_area_level_2,
        out string Address_administrative_area_level_3,
        out string Address_colloquial_area,
        out string Address_locality,
        out string Address_sublocality,
        out string Address_neighborhood)
    {

        Address_ShortName = "";
        Address_country = "";
        Address_administrative_area_level_1 = "";
        Address_administrative_area_level_2 = "";
        Address_administrative_area_level_3 = "";
        Address_colloquial_area = "";
        Address_locality = "";
        Address_sublocality = "";
        Address_neighborhood = "";

        XmlDocument doc = new XmlDocument();

        try
        {
            doc.Load("http://maps.googleapis.com/maps/api/geocode/xml?latlng=" + latitude + "," + longitude + "&sensor=false");
            XmlNode element = doc.SelectSingleNode("//GeocodeResponse/status");
            if (element.InnerText == "ZERO_RESULTS")
            {
                return ("No data available for the specified location");
            }
            else
            {

                element = doc.SelectSingleNode("//GeocodeResponse/result/formatted_address");

                string longname="";
                string shortname="";
                string typename ="";
                bool fHit=false;


                XmlNodeList xnList = doc.SelectNodes("//GeocodeResponse/result/address_component");
                foreach (XmlNode xn in xnList)
                {
                    try
                    {
                        longname = xn["long_name"].InnerText;
                        shortname = xn["short_name"].InnerText;
                        typename = xn["type"].InnerText;


                        fHit = true;
                        switch (typename)
                        {
                            //Add whatever you are looking for below
                            case "country":
                                {
                                    Address_country = longname;
                                    Address_ShortName = shortname;
                                    break;
                                }

                            case "locality":
                                {
                                    Address_locality = longname;
                                    //Address_locality = shortname; //Om Longname visar sig innehålla konstigheter kan man använda shortname istället
                                    break;
                                }

                            case "sublocality":
                                {
                                    Address_sublocality = longname;
                                    break;
                                }

                            case "neighborhood":
                                {
                                    Address_neighborhood = longname;
                                    break;
                                }

                            case "colloquial_area":
                                {
                                    Address_colloquial_area = longname;
                                    break;
                                }

                            case "administrative_area_level_1":
                                {
                                    Address_administrative_area_level_1 = longname;
                                    break;
                                }

                            case "administrative_area_level_2":
                                {
                                    Address_administrative_area_level_2 = longname;
                                    break;
                                }

                            case "administrative_area_level_3":
                                {
                                    Address_administrative_area_level_3 = longname;
                                    break;
                                }

                            default:
                                fHit = false;
                                break;
                        }


                        if (fHit)
                        {
                            Console.Write(typename);
                            Console.ForegroundColor = ConsoleColor.Green;
                            Console.Write("\tL: " + longname + "\tS:" + shortname + "\r\n");
                            Console.ForegroundColor = ConsoleColor.Gray;
                        }
                    }

                    catch (Exception e)
                    {
                        //Node missing either, longname, shortname or typename
                        fHit = false;
                        Console.Write(" Invalid data: ");
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.Write("\tX: " + xn.InnerXml + "\r\n");
                        Console.ForegroundColor = ConsoleColor.Gray;
                    }


                }

                //Console.ReadKey();
                return (element.InnerText);
            }

        }
        catch (Exception ex)
        {
            return ("(Address lookup failed: ) " + ex.Message);
        }
        }
}

What you are trying to do is reverse geocoding (See Daniel's answer).

An example implementation in PHP:

/**
* reverse geocoding via google maps api
* convert lat/lon into a name
*/
function reverse_geocode($lat, $lon) {
    $url = "http://maps.google.com/maps/api/geocode/json?latlng=$lat,$lon&sensor=false";
    $data = json_decode(file_get_contents($url));
    if (!isset($data->results[0]->formatted_address)){
        return "unknown Place";
    }
    return $data->results[0]->formatted_address;
}
protected void Button1_Click(object sender, EventArgs e)
    {
        this.calcularRota(txtOrigem.Text.Trim(), txtDestino.Text.Trim());
    }


    public void calcularRota(string latitude, string longitude)
    {
        //URL do distancematrix - adicionando endereco de origem e destino
        string url = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&sensor=false", latitude, longitude);
        XElement xml = XElement.Load(url);

        // verifica se o status é ok
        if (xml.Element("status").Value == "OK")
        {
            //Formatar a resposta
            Label3.Text = string.Format("<strong>Origem</strong>: {0}",
                //Pegar endereço de origem 
                xml.Element("result").Element("formatted_address").Value);
            //Pegar endereço de destino                    
        }
        else
        {
            Label3.Text = String.Concat("Ocorreu o seguinte erro: ", xml.Element("status").Value);
        }
    }
}

Google's Maps APIs goes over http, so sending request with get and then parsing the request... It should be possible to do in any language.

For example, in PHP:

$ret = file_get_contents("http://maps.google.com/maps/api/geocode/xml?address=" .
            urlencode($address) .
            "&sensor=false" .
            "&key=" . $this->key
    );

$xml = new SimpleXMLElement($ret);
$error = $xml->status;

Same works for all APIs.

An easy way to get an Address is through google's API.

For example.

using System.Xml;

//Console.WriteLine("enter coordinate:");
string coordinate = "32.797821,-96.781720"; //Console.ReadLine();

XmlDocument xDoc = new XmlDocument();
xDoc.Load("https://maps.googleapis.com/maps/api/geocode/xml?latlng=" + coordinate);

XmlNodeList xNodelst = xDoc.GetElementsByTagName("result");
XmlNode xNode = xNodelst.Item(0);
string FullAddress = xNode.SelectSingleNode("formatted_address").InnerText;
string Number = xNode.SelectSingleNode("address_component[1]/long_name").InnerText;
string Street = xNode.SelectSingleNode("address_component[2]/long_name").InnerText;
string Village = xNode.SelectSingleNode("address_component[3]/long_name").InnerText;
string Area = xNode.SelectSingleNode("address_component[4]/long_name").InnerText;
string County = xNode.SelectSingleNode("address_component[5]/long_name").InnerText;
string State = xNode.SelectSingleNode("address_component[6]/long_name").InnerText;
string Zip = xNode.SelectSingleNode("address_component[8]/long_name").InnerText;
string Country = xNode.SelectSingleNode("address_component[7]/long_name").InnerText;
Console.WriteLine("Full Address: " + FullAddress);
Console.WriteLine("Number: " + Number);
Console.WriteLine("Street: " + Street);
Console.WriteLine("Village: " + Village);
Console.WriteLine("Area: " + Area);
Console.WriteLine("County: " + County);
Console.WriteLine("State: " + State);
Console.WriteLine("Zip: " + Zip);
Console.WriteLine("Country: " + Country);

Console.ReadLine();

PS be careful with different addresses with different components.

reverse geocoding: get address from latitude and longitude using google maps geocoding api in asp.net

protected void Page_Load(object sender, EventArgs e)
    {
        GetAddress("53.2734", "-7.77832031");
    }
    private string GetAddress(string latitude, string longitude)
    {
        string locationName = "";
        string url = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&sensor=false", latitude, longitude);
        XElement xml = XElement.Load(url);
        if (xml.Element("status").Value == "OK")
        {
            locationName = string.Format("{0}",
                xml.Element("result").Element("formatted_address").Value);
            Label1.Text = locationName;
        }
        return locationName;

    }  
private string getLocationByGeoLocation(string longitude, string latitude)
    {
        string locationName = string.Empty;

        try
        {
            if (string.IsNullOrEmpty(longitude) || string.IsNullOrEmpty(latitude))
                return "";

            string url = string.Format("https://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&sensor=false", latitude, longitude);


            WebRequest request = WebRequest.Create(url);

            using (WebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    DataSet dsResult = new DataSet();
                    dsResult.ReadXml(reader);
                    try
                    {
                        foreach (DataRow row in dsResult.Tables["result"].Rows)
                        {
                            string fullAddress = row["formatted_address"].ToString();
                        }
                    }
                    catch (Exception)
                    {

                    }

                }
            }
        }
        catch (Exception ex)
        {
            lblError.Text = ex.Message;
        }


        return locationName;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM