简体   繁体   中英

Get latitude & longitude from given address name. NOT Geocoder

I have an address name and I want to get an accurate latitude & longitude for it. I know we can get this using Geocoder's getFromLocationName(address,maxresult) .

The problem is, the result I get is always null - unlike the result that we get with https://maps.google.com/ . This always allows me to get some results, unlike Geocoder.

I also tried another way: "http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false" (Here's a link !) It gives better results than geocoder, but often returns the error (java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer) . It's boring.

My question is : How can we get the same latlong result we would get by searching on https://maps.google.com/ from within java code?

additional :where is the api document about using " http://maps.google.com/maps/api/geocode/json?address= " + address + "&sensor=false"

Albert, I think your concern is that you code is not working. Here goes, the code below works for me really well. I think you are missing URIUtil.encodeQuery to convert your string to a URI.

I am using gson library, download it and add it to your path.

To get the class's for your gson parsing, you need to goto jsonschema2pojo . Just fire http://maps.googleapis.com/maps/api/geocode/json?address=Sayaji+Hotel+Near+balewadi+stadium+pune&sensor=true on your browser, get the results and paste it on this site. It will generate your pojo's for you. You may need to also add a annotation.jar.

Trust me, it is easy to get working. Don't get frustrated yet.

try {
        URL url = new URL(
                "http://maps.googleapis.com/maps/api/geocode/json?address="
                        + URIUtil.encodeQuery("Sayaji Hotel, Near balewadi stadium, pune") + "&sensor=true");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Accept", "application/json");

        if (conn.getResponseCode() != 200) {
            throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
        }
        BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));

        String output = "", full = "";
        while ((output = br.readLine()) != null) {
            System.out.println(output);
            full += output;
        }

        PincodeVerify gson = new Gson().fromJson(full, PincodeVerify.class); 
        response = new IsPincodeSupportedResponse(new PincodeVerifyConcrete(
                gson.getResults().get(0).getFormatted_address(), 
                gson.getResults().get(0).getGeometry().getLocation().getLat(),
                gson.getResults().get(0).getGeometry().getLocation().getLng())) ;
        try {
            String address = response.getAddress();
            Double latitude = response.getLatitude(), longitude = response.getLongitude();
            if (address == null || address.length() <= 0) {
                log.error("Address is null");
            }
        } catch (NullPointerException e) {
            log.error("Address, latitude on longitude is null");
        }
        conn.disconnect();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

The Geocode http works, I just fired it, results below

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Pune",
               "short_name" : "Pune",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Pune",
               "short_name" : "Pune",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "Maharashtra",
               "short_name" : "MH",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "India",
               "short_name" : "IN",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "Pune, Maharashtra, India",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 18.63469650,
                  "lng" : 73.98948670
               },
               "southwest" : {
                  "lat" : 18.41367390,
                  "lng" : 73.73989109999999
               }
            },
            "location" : {
               "lat" : 18.52043030,
               "lng" : 73.85674370
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 18.63469650,
                  "lng" : 73.98948670
               },
               "southwest" : {
                  "lat" : 18.41367390,
                  "lng" : 73.73989109999999
               }
            }
         },
         "types" : [ "locality", "political" ]
      }
   ],
   "status" : "OK"
}

Edit

On 'answers do not contain enough detail`

From all the research you are expecting that google map have a reference to every combination of locality, area, city. But the fact remains that google map contains geo and reverse-geo in its own context. You cannot expect it to have a combination like Sayaji Hotel, Near balewadi stadium, pune . Web google maps will locate it for you since it uses a more extensive Search rich google backend. The google api's only reverse geo address received from their own api's. To me it seems like a reasonable way to work, considering how complex our Indian address system is, 2nd cross road can be miles away from 1st Cross road :)

Here is a list of web services that provide this function.

One of my Favorite is This

Why dont you try hitting.

http://api.geonames.org/findNearbyPlaceName?lat=18.975&lng=72.825833&username=demo

which returns following output.(Make sure you put your lat & lon in URL)

在此输入图像描述

Hope this helps you:

public static GeoPoint getGeoPointFromAddress(String locationAddress) {
        GeoPoint locationPoint = null;
        String locationAddres = locationAddress.replaceAll(" ", "%20");
        String str = "http://maps.googleapis.com/maps/api/geocode/json?address="
                + locationAddres + "&sensor=true";

        String ss = readWebService(str);
        JSONObject json;
        try {

            String lat, lon;
            json = new JSONObject(ss);
            JSONObject geoMetryObject = new JSONObject();
            JSONObject locations = new JSONObject();
            JSONArray jarr = json.getJSONArray("results");
            int i;
            for (i = 0; i < jarr.length(); i++) {
                json = jarr.getJSONObject(i);
                geoMetryObject = json.getJSONObject("geometry");
                locations = geoMetryObject.getJSONObject("location");
                lat = locations.getString("lat");
                lon = locations.getString("lng");

                locationPoint = Utils.getGeoPoint(Double.parseDouble(lat),
                        Double.parseDouble(lon));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return locationPoint;
    }

I use, in order:
- Google Geocoding API v3 (in few cases there's a problem described here )
- Geocoder (in some cases there's a problem described here ).

If I don't receive results from Google Geocoding API I use the Geocoder.

As far as I noticed Google Maps is using the Google Places API for auto complete and then gets the Details for the Location from which you can get the coordinates.

https://developers.google.com/places/documentation/ https://developers.google.com/places/training/

This method should will give you the expected results.

String locationAddres = anyLocationSpec.replaceAll(" ", "%20");
URL url = new URL("https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address="+locationAddres+"&language=en&key="YourKey");
try(InputStream is = url.openStream(); JsonReader rdr = Json.createReader(is)) {
    JsonObject obj = rdr.readObject();
    JsonArray results = obj.getJsonArray("results");
    JsonObject geoMetryObject, locations;

    for (JsonObject result : results.getValuesAs(JsonObject.class)) {
        geoMetryObject=result.getJsonObject("geometry");
        locations=geoMetryObject.getJsonObject("location");
        log.info("Using Gerocode call - lat : lng value for "+ anyLocationSpec +" is - "+locations.get("lat")+" : "+locations.get("lng"));
        latLng = locations.get("lat").toString() + "," +locations.get("lng").toString();
    }
}

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