从给定的地址名称获取纬度和经度。不使用Geocoder。

11

我有一个地址名称,希望能够获取它的准确经纬度。我知道可以使用Geocoder的getFromLocationName(address, maxresult)来实现这个功能。

问题是,我总是得到一个空结果,而类似于https://maps.google.com/所得到的结果总是非空的,这让我感到很困惑。

我也尝试了另外一种方式:"http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false"(这里有一个链接!)它比Geocoder给出了更好的结果,但常常返回错误信息:(java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer) 这很无聊。

我的问题是:如何在Java代码中获得与在https://maps.google.com/搜索得到的相同的经纬度结果?

附加信息:关于使用"http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false"的API文档在哪里?


GeoCoder并不是完美的科学。请记住这一点。例如,我想要“Wadgaon sheri”,但它显示了靠近EON IT园区的Kharadi主路。所以我在地址中添加了“邮局”。而且我用邮政编码代替了“wadgaon sheri”。长话短说,不要指望Geocodeing为您创造奇迹。由于它们底层也会使用地理编码,所以无论您使用哪个API,最终都会得到相同的结果。 - Siddharth
5个回答

20

Albert,我认为你担心的是你的代码无法运行。下面的代码对我来说运行得非常好。我认为你缺少URIUtil.encodeQuery来将您的字符串转换为URI。

我正在使用gson库,下载它并将其添加到您的路径中。

要获取用于gson解析的类,请转到jsonschema2pojo。只需在浏览器上输入http://maps.googleapis.com/maps/api/geocode/json?address=Sayaji+Hotel+Near+balewadi+stadium+pune&sensor=true,获取结果并将其粘贴到此网站上。它将为您生成POJO。您可能还需要添加一个annotation.jar。

相信我,这很容易实现。不要感到沮丧。

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();
    }

地理编码的 http 请求可以正常工作,我刚刚测试了一下,以下是结果

{
   "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"
}

编辑

关于“答案缺乏足够的细节”

你期望谷歌地图包含每个地点、区域和城市组合的参考信息,但事实是谷歌地图只在其自己的上下文中包含地理和反向地理信息。你不能期望它拥有像普纳市巴勒瓦迪体育场旁萨雅吉酒店这样的组合信息。Web版谷歌地图可以定位到这个位置,因为它使用了更全面的搜索功能,谷歌API只能从他们自己的API中获取反向地理地址。对我来说,这似乎是一种合理的工作方式,考虑到我们印度的地址系统有多么复杂,第二十字路口可能与第一十字路口相隔数英里 :)


干得好,Siddharth,但是如果你在http://ctrlq.org/maps/address/上检查一下这个地方,它并没有给出我精确的位置。正如我们从上面的代码中可以看到的那样,我们得到的latLag是18.52043030 73.85674370,如果我们将其作为输入提供给geocoder,它会指向Pune的Kasaba Peth附近,这是不正确的。这个网站也使用了Geocoder。我已经在我的代码中使用了latLag,但是它给出了同样错误的结果。 - KAsh
好的,我认为我们可以安全地得出结论,谷歌地图没有每个地区、区域、城市组合的参考。事实上,您唯一能够获得适当地址的方法是从谷歌本身获取地址。因此,在您的情况下,您需要从谷歌获取自动完成地址,保存并使用它,并对其进行反向地理编码。您不能只取一个实际地址并转换它(就像您可能会对美国地址做的那样)。对我来说,这似乎是一种合理的工作方式,考虑到我们印度地址系统的复杂性,第二十字路口可能距离第一条十字路口有几英里的距离 :) - Siddharth
2
技术限制不可能通过固执来克服,你需要重新定义范围。如果你找到了解决方案,也请告诉我。 - Siddharth
对于那些被困在没有意义的商业需求中的人,这里有一些帮助。http://laughingsquid.com/the-expert-a-hilarious-sketch-about-the-pain-of-being-the-only-engineer-in-a-business-meeting/ - Siddharth
使用Google GeoCode的限制:a) 每天2500次请求限制 b) 每秒2500次请求限制 c) 结果应在地图上显示! - AVA
显示剩余3条评论

3
希望这能帮到你:

希望这对您有所帮助:

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;
    }

0

我按照以下顺序使用:
- Google Geocoding API v3(在某些情况下存在问题,描述在这里
- Geocoder(在某些情况下存在问题,描述在这里)。

如果我从Google Geocoding API没有收到结果,我就会使用Geocoder。


0

-1
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();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接