概述
在一个项目需求中,我们需要实现输入一个地区的火车站、汽车站或者飞机场的名字,就能返回其的所在省市信息,要实现这个需求我们首先就需要知道全国火车站、客运站及飞机场的字典表,但是在网上找了一圈,发现能满足这样的需求还是挺少的,于是自己利用百度API的地理位置API实现了一下,过程如下:
过程
- 注册成为百度API开发者
注册地址:http://lbsyun.baidu.com/ 按照注册流程即可,注册完成之后会有属于自己的ak,这个ak是我们访问API的唯一标识
- 使用placeV2 API
开发文档:
http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi
使用示例:
http://api.map.baidu.com/place/v2/search?query=机场®ion=西安市&output=json&ak=XXXXXXXXXXXXX
Java批量获取
@Service
public class LoadResourceDataService {
private static Logger logger = Logger.getLogger(LoadResourceDataService.class);
@Autowired
LoadResourceDataUtil loadResourceDataUtil;
@Autowired
EsSearchService service;
//API
private final String baidu_uri_prefix = "http://api.map.baidu.com/place/v2/search";
//format json
private final String baidu_uri_format = "&output=json";
//你自己的ak
private final String baidu_uri_ak = "&ak=XXXXXXXXXXXXXXXXXXX";
private static Map baiduCityCodeMap;
private static CloseableHttpClient httpClient;
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
static {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(20);
httpClient = HttpClients.custom().setConnectionManager(cm).build();
}
@PostConstruct
private void init() {
baiduCityCodeMap = loadResourceDataUtil.getBaiduCityCodeMap();
}
private Map baiduHttpRequest(String query, String region) {
String url = baidu_uri_prefix + "?query=" + query + "®ion=" + region + baidu_uri_format + baidu_uri_ak;
Map map = new HashMap<>();
try {
HttpGet get = new HttpGet(url);
HttpResponse response = httpClient.execute(get);
Thread.sleep(500);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");
JSONObject object = JSON.parseObject(result);
List list = new ArrayList<>();
JSONArray jsonArray = object.getJSONArray("results");
if (jsonArray == null) {
return map;
}
for (Object o : jsonArray) {
JSONObject jsonObject = (JSONObject) o;
if (jsonObject.getString("uid") == null) {
continue;
}
String name = jsonObject.getString("name");
//过滤一些脏数据
if (!query.equals(name) && name.length() <= 8 && !name.contains("(")) {
list.add(name);
}
}
if (list.size() > 0) {
map.put(region, list);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return map;
}
public void startTask() {
//获取火车站的信息
fixedThreadPool.submit(() -> queryAndSave("railway_station", "火车站"));
//获取客运站的信息
fixedThreadPool.submit(() -> queryAndSave("transport_station", "客运站"));
//获取飞机场的信息
fixedThreadPool.submit(() -> queryAndSave("airport_station", "飞机场"));
}
private void queryAndSave(String index, String query) {
int i = 1;
//迭代 city map 获取每个省市自治区的数据
for (Map.Entry entry : baiduCityCodeMap.entrySet()) {
Map data = baiduHttpRequest(query, entry.getValue());
logger.info(i + ". data:" + data);
if (data != null && !data.isEmpty()) {
//这个方法用于将查询到的数据写入elasticsearch
service.insert(index, entry.getValue(), entry.getKey(), data);
saveLocalFile(index + ".txt", JSON.toJSONString(data));
}
i++;
}
}
//用来将数据写入本地文件
private void saveLocalFile(String fileName, String content) {
FileWriter fw = null;
try {
String path = LoadResourceDataService.class.getClassLoader().getResource("").getPath();
File file = new File(path + "\\" + fileName);
if (!file.exists()) {
file.createNewFile();
}
fw = new FileWriter(file, true);
fw.write(content + "\n");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fw.close();
} catch (IOException e) {
}
}
}
}
Util类,用来初始化百度cityCodeMap(在开发文档的资源下载可下载该文档)
@Component
public class LoadResourceDataUtil extends Constaus {
private Logger logger = Logger.getLogger(LoadResourceDataUtil.class);
private Map baiduCityCodeMap;
public Map getBaiduCityCodeMap() {
return baiduCityCodeMap;
}
@PostConstruct
public void initRegionData() {
try {
baiduCityCodeMap = loadCityCode("BaiduMap_cityCode.txt");
logger.info("init baidu city code success!");
} catch (IOException e) {
logger.error("init region error,", e);
}
}
private Map loadCityCode(String fileName) throws IOException {
File file = new File(this.getClass().getClassLoader().getResource(fileName).getPath());
BufferedReader reader = null;
Map map = new HashMap<>();
try {
reader = new BufferedReader(new FileReader(file));
String temp;
while ((temp = reader.readLine()) != null) {
map.put(temp.split(",")[0], temp.split(",")[1]);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
return map;
}
}
BaiduMap_cityCode.txt内容大概如下(一部分):
33,嘉峪关市
34,金昌市
35,白银市
36,兰州市
37,酒泉市
38,大兴安岭地区
39,黑河市
40,伊春市
41,齐齐哈尔市
42,佳木斯市
...
Controller层代码如下:
@RequestMapping(value = "/test2", method = RequestMethod.GET)
public void test2() throws Exception {
dataService.startTask();
}
获取火车站的数据railway_station.txt如下(部分)
{"保亭黎族苗族自治县":["保亭车站","保亭县幸福超市","海汽快递","七仙美食园","红运来川菜馆","金洲度假休闲宾馆"]}
{"万宁市":["万宁站","神州站","和乐站","万宁车站","万宁兴隆车站","车站永兴商行","万宁车站-西门","万宁车站-西北门","万宁站-进站口"]}
{"儋州市":["儋州火车站","儋州车站","白马井车站","银滩站","海头车站","车站快餐","儋州车站售票大厅","老车站停车场","恒兴石材店"]}
...
获取客运站的数据transport_station.txt如下(部分)
{"保亭黎族苗族自治县":["保亭汽车站"]}
{"万宁市":["长丰汽车站","和乐客运站","万宁兴隆车站","万宁车站"]}
{"儋州市":["洋浦客运站","儋州汽车站","儋州西站","海头车站"]}
{"定安县":["定安汽车站","客运车上落站","定安黄竹车站"]}
{"白沙黎族自治县":["白沙车站","海汽查苗车站"]}
{"琼海市":["琼海汽车站"]}
{"阿拉尔市":["阿拉尔中心客运站"]}
{"济源市":["邵原汽车站","北勋汽车站","承留汽车站","济源市公交客运站","济源汽车客运总站","济源客运西站"]}
...
获取飞机场的数据airport_station.txt如下(部分)
{"儋州市":["西庆通用航空机场","西庆机场大门"]}
{"西沙群岛":["三沙市气象局"]}
{"琼海市":["琼海博鳌机场","博鳌机场进出场路","三亚凤凰机场货运"]}
{"临高县":["加来机场派出所","临高星华宾馆","菀茹商务酒店","临高东盛商务宾馆"]}
{"石河子市":["石河子机场"]}
{"福州市":["义序机场","机场巴士售票处","福州竹岐直升机场","机场货运站停车场"]}
{"惠州市":["惠州平潭机场","惠州机场","白云机场候机楼","白云机场候机楼","白云机场候机楼"]}
{"江门市":["大方航空货运","址山候机楼","江门候机楼"]}
{"汕头市":["汕头机场公司","迎宾机场路口"]}
...
百度API返回的有些数据可能不是特别精确需要自己添加过滤条件进一步清洗。
以上。
完结。