1.这个接口是传入一个 中文地址 获取对应的 地理编码即经纬度。以下是接口文档:
http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
接口文档提供了请求路径:
http://api.map.baidu.com/geocoder/v2/?address=北京市海淀区上地十街10号&output=json&ak=您的ak&callback=showLocation //GET请求
由于我们使用的是java,这个callback请求是不用的,所以请求的url应该是:
http://api.map.baidu.com/geocoder/v2/?address=请求地址&output=json&ak=您的ak //GET请求
其中ak的申请在http://lbsyun.baidu.com/apiconsole/key?application=key。
2.我们在这里请求的参数有两个,一个地址,一个ak。这里对地址做了处理,这个因为用户的输入很难确认,有的地址里有,
有的地址有\n
, 更加夸张的是居然会有这种上海市xxxx22号楼207室
由于地址信息比较敏感,中间我做了处理。
参数这里有一个限制条件:最多支持84个字节。一个中文字符两个字节,那么string的长度不能超过84/2=41,但是由于奇葩的数据真的多,一般长度到25已经是能到街道了,所以这里又做了一个处理。
public static String convertAddress(String address, String ak) {
URL url = null;
HttpURLConnection urlConnection = null;
BufferedReader rd = null;
Double lng = null;
Double lat = null;
Map<String, Object> map = null;
Map<String, Object> result = null;
Map<String, Object> location = null;
address = address.trim();
address = address.replaceAll("\\\\", "");
String regEx = "[`~!@#$%^&*()\\-+={}':;,\\[\\].<>/?¥%…()_+|【】‘;:”“’。,、?\\s]";
address = address.replaceAll(regEx,"").trim();
if (address.length()>=25)address = address.substring(0,25);
String urlString = new StringBuilder().append("http://api.map.baidu.com/geocoder/v2/?").append("address=").append(address).append("&output=json").append("&ak=").append(ak).toString();
try {
URLEncoder.encode(urlString,"UTF-8");
url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
rd = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),"UTF-8"));
StringBuffer sb = new StringBuffer();
String data = null;
while ((data = rd.readLine()) != null) {
sb.append(data);
}
System.out.println(sb);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
urlConnection.disconnect();
try {
rd.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
在项目里:
1. jdbc建立和数据库的连接,获取地址
2. 使用上述方法将地址转换成经纬度
3. 将地址转换的经纬度存回数据库。
我们会发现一个问题:由于单纯调用这种方法,打开连接和释放连接的时间太久。
数据库里我有5880条数据,居然跑了17分钟!
为此我想了一下可能有下面3个解决方案:
- http连接池减少建立http连接,释放的时间
- 数据库连接池批量插入数据
- 多线程?
最后我采用了httpclient及相关连接池+多线程将时间压缩到了2分30s。
这里我就不做相关描述了。