如何从城市名称获取经纬度的Android代码

7

我希望将从文本字段中获取的城市名称转换为经度和纬度。

以下是我做的:

String location=city.getText().toString();
            String inputLine = "";
            String result = "";
            location=location.replaceAll(" ", "%20");
            String myUrl="http://maps.google.com/maps/geo?q="+location+"&output=csv";
            try{
             URL url=new URL(myUrl);
             URLConnection urlConnection=url.openConnection();
             BufferedReader in = new BufferedReader(new 
             InputStreamReader(urlConnection.getInputStream()));
              while ((inputLine = in.readLine()) != null) {
              result=inputLine;
              }
               lat = result.substring(6, result.lastIndexOf(","));
               longi = result.substring(result.lastIndexOf(",") + 1);
             }
             catch(Exception e){
             e.printStackTrace();
             }

            //////////////////////////////////
            if (location=="" ) 
            {           
             latitude=loc.getLatitude();
            longitude=loc.getLongitude();
            }
            else 
            {
                latitude=Double.parseDouble(lat);
                longitude=Double.parseDouble(longi);
            }

但是代码没有执行else语句。

我把URL改成了这样:

String myUrl="http://maps.googleapis.com/maps/api/geocode/json?address="+location+"&sensor=true";

然后得到了这个结果:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Nablus",
               "short_name" : "Nablus",
               "types" : [ "locality", "political" ]
            }
         ],
         "formatted_address" : "Nablus",
         "geometry" : {
            "location" : {
               "lat" : 32.22504,
               "lng" : 35.260971
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 32.2439165,
                  "lng" : 35.2929858
               },
               "southwest" : {
                  "lat" : 32.20615960000001,
                  "lng" : 35.2289562
               }
            }
         },
         "types" : [ "locality", "political" ]
      }
   ],
   "status" : "OK"
}

如何在我的代码中使用纬度和经度?
6个回答

21

使用Geocoder可以更简单地实现,它和Geocoding API基本相同。

if(Geocoder.isPresent()){
    try {
        String location = "theNameOfTheLocation";
        Geocoder gc = new Geocoder(this);
        List<Address> addresses= gc.getFromLocationName(location, 5); // get the found Address Objects

        List<LatLng> ll = new ArrayList<LatLng>(addresses.size()); // A list to save the coordinates if they are available
        for(Address a : addresses){
            if(a.hasLatitude() && a.hasLongitude()){
                ll.add(new LatLng(a.getLatitude(), a.getLongitude()));
            }  
        }  
    } catch (IOException e) {
         // handle the exception
    }
}

2
这是一个比我提供的选项要好得多的选择,我认为OP将避免在Google更改JSON输出格式时更新您的代码。 - mttdbrd

4

虽然时间有点晚,但对于其他有同样问题的人来说,我希望能提供一些帮助:

经过4天的努力,我最终通过城市名称得到了经度纬度

我使用了以下方法:

http://maps.googleapis.com/maps/api/geocode/json?address=tehran&sensor=false

这里的"tehran"是城市名

通过此链接,您可以获取以下JSON:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Tehran",
               "short_name" : "Tehran",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Tehran",
               "short_name" : "Tehran",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "Tehran Province",
               "short_name" : "Tehran Province",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "Iran",
               "short_name" : "IR",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "Tehran, Tehran Province, Iran",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 35.8345498,
                  "lng" : 51.6062163
               },
               "southwest" : {
                  "lat" : 35.5590784,
                  "lng" : 51.0934209
               }
            },
            "location" : {
               "lat" : 35.6891975,
               "lng" : 51.3889736
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 35.8345498,
                  "lng" : 51.6062163
               },
               "southwest" : {
                  "lat" : 35.5590784,
                  "lng" : 51.0934209
               }
            }
         },
         "place_id" : "ChIJ2dzzH0kAjj8RvCRwVnxps_A",
         "types" : [ "locality", "political" ]
      }
   ],
   "status" : "OK"
}

正如您所看到的,在“位置”对象中,我们需要的属性是这些:
就像这个答案所说的那样,首先我们需要从顶部URL获取Json
因此,我们很容易地添加了JsonTask

private class JsonTask extends AsyncTask<String, String, String> {

    protected void onPreExecute() {
        super.onPreExecute();
        // u can use a dialog here
    }

    protected String doInBackground(String... params) {


        HttpURLConnection connection = null;
        BufferedReader reader = null;

        try {
            URL url = new URL(params[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();


            InputStream stream = connection.getInputStream();

            reader = new BufferedReader(new InputStreamReader(stream));

            StringBuffer buffer = new StringBuffer();
            String line = "";

            while ((line = reader.readLine()) != null) {
                buffer.append(line+"\n");
                Log.d("Response: ", "> " + line);   //here u ll get whole response...... :-) 

            }

            return buffer.toString();


        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        // here "result" is json as stting
    }
}
}

要调用并保存JSON字符串,您需要使用以下代码。
JsonTask getRequest = new JsonTask();
String JSONString = getRequest.execute("Url address here").get();

然后我们需要获取经度和纬度。因此,这是我们所需要的东西。
JSONObject jsonResponse1;
try {
    jsonResponse1 = new JSONObject(jsonMap1);
    JSONArray cast = jsonResponse1.getJSONArray("results");
    for (int i = 0; i < cast.length(); i++) {
        JSONObject actor = cast.getJSONObject(i);
        JSONObject name = actor.getJSONObject("geometry");
        JSONObject location = name.getJSONObject("location");
        lat1 = location.getString("lat");
        lng1 = location.getString("lng");
    }
} catch (JSONException e) {
    Toast.makeText(mContext, e.toString(), Toast.LENGTH_SHORT).show();
}

lat1和lng1有值:)


2
使用新的API,您会得到一个JSON对象。不要将其解析为字符串,而是将其解析为JSON对象。以下是(最终)编译并返回您提供的JSON字符串的正确值的代码。
try
{
    org.json.JSONObject jso = new JSONObject(result);
    org.json.JSONArray jsa = jso.getJSONArray("results");
    org.json.JSONObject js2 = jsa.getJSONObject(0);
    org.json.JSONObject js3 = js2.getJSONObject("geometry");
    org.json.JSONObject js4 = js3.getJSONObject("location");
    Double lat = (Double)js4.getDouble("lat");
    Double lng = (Double)js4.getDouble("lng");

}
catch(JSONException jse)
{
    jse.printStackTrace();
}

我已经将URL更改为:String myUrl="http://maps.googleapis.com/maps/api/geocode/json?address="+location+"&sensor=true";你能看到我的问题吗?我已经编辑过了。 - roa.tah
我现在看到了你的编辑。请查看我提供的代码。显然,我得到的JSONObject与你得到的不同。你可以使用JSONArray来处理结果对象。 - mttdbrd
正如我所指出的,我得到了不同的数据集。我会让它与你得到的数据集一起工作。但请看下面@steve的答案,比使用我提供的方法要好得多。 - mttdbrd

0
Geocoder gcd = new Geocoder(context, Locale.getDefault());
List<Address> addresses = gcd.getFromLocation(lat, lng, 1);
if (addresses.size() > 0) 
    System.out.println(addresses.get(0).getLocality());

OP想要从“位置名称”中得到“纬度”和“经度”。您的代码提供了从“纬度”和“经度”中获取“位置名称”的方法。 - Shoumik

0

public static LatLng getCityLatitude(Context context, String city) { Geocoder geocoder = new Geocoder(context,context.getResources().getConfiguration().locale); List<Address> addresses = null; LatLng latLng = null; try { addresses = geocoder.getFromLocationName(city, 1); Address address = addresses.get(0); latLng = new LatLng(address.getLatitude(), address.getLongitude()); } catch (Exception e) { e.printStackTrace(); } return latLng; }


0

android.location.Geocoder 包含一个名为 getFromLocationName 的方法,该方法返回地址列表。您可以查询地址的纬度和经度。


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