一、前言
最近公司开发定位打卡功能,通过获取到的经纬度,去后台请求接口调用获得周边200米内相关地址信息,在开发过程种,涉及到经纬度转换问题(姜还是老的辣,解决思路还是经理提供的),以下是开发的大致过程和代码解决思路。
二、开发阶段
1.Flutter引入geolocator插件,获取定位信息
插件的参考文档:传送门
代码中使用如下
await _geolocator.getPosition(LocationAccuracy.high);
其中,括号里面的参数可以大致解释下:
枚举值一共五种,分别代表的含义是定位的精确度问题。
调用以后获取到经纬度如下:
lat、lng就是经纬度。
到此为止,我们的手机经纬度就获取倒了。此外,geo插件还可以根据获得到的经纬度进行一个实际地址的转换,参考如下
// 经纬度转化
void transformAddress(position) async {
// var lnglatXY = [116.396574, 39.992706]; //已知点坐标
// List<Placemark> p = await _geolocator.fromPlacemark(31.982832,118.782222);
List<Placemark> p = await _geolocator.fromPlacemark(position.latitude, position.longitude);
Placemark place = p[0];
var positionNow = position.latitude.toString() + ',' + position.longitude.toString();
var Lat = position.latitude.toString();
var Lng = position.longitude.toString();
//if(place!=null&&'$locationName'==null){
if (place != null) {
setState(() {
_place = place.name;
locationName = place.name;
// LngLat = position.toString();
LngLat = positionNow;
Lng = Lng;
Lat = Lat;
});
}
}
则可以拿到当前的位置信息。
2.重点!!!!!
重点的问题就是:geo插件获取到的经纬度为GPS经纬度,GPS经纬度不可以直接拿去高德API接口请求直接访问!!不会出错,但是该经纬度会有一定的偏差,导致定位距离不准,以我的公司定位来看,定位到了300米开外左右的地方。这样的定位打卡功能一定是有问题的。
下面是我后台的调用方法:
/**
* 高德获取周边接口
*
* @param dto
* @return
*/
@Override
public GaodeListResBean getInformation(GaodeReqBean dto) {
GaodeListResBean res = new GaodeListResBean();
logger.info("高德请求service,入参{}", JSONObject.toJSONString(dto));
StringBuffer gdRequest = new StringBuffer(gdUrl);
String reqParams = reqBody.replace("{key}", this.gdKey).
replace("{location}", dto.getLng() + "," + dto.getLat())
.replace("{keywords}", dto.getKeywords() != null && !"".equals(dto.getKeywords()) ? dto.getKeywords() : "")
.replace("{page}", dto.getPageNo());
gdRequest.append(reqParams);
logger.info("构造高的请求url:{}", gdRequest);
String strResult = "";
try {
strResult = HttpUtils.sendGetWithProxy(null, gdRequest.toString(),
propCfgParam.getJsjnProxyIp(),
propCfgParam.getJsjnProxyPort());
logger.info("请求成功!高德返回结果:{}", strResult);
} catch (Exception e) {
res.setState(FusionMessage.BaseState.STATE_GAODE_FAILD);
logger.info("高德地图请求失败{}", e);
return res;
}
JSONObject jsonObject = JSONObject.parseObject(strResult);
String infocode = (String) jsonObject.get("infocode");
List<GaodeResultDto> list = new ArrayList<>();
if (null != infocode && infocode.equals(FusionConstant.GaodeType.GAOD_SUCCESS_CODE)) {
res.setCount((String) jsonObject.get("count"));
JSONArray pois = JSONArray.fromObject(jsonObject.get("pois"));
//组装前台返回对象
for (int i = 0; i < pois.size(); i++) {
GaodeResultDto gaodeResultDto = new GaodeResultDto();
gaodeResultDto.setAddress(pois.getJSONObject(i).get("address").toString());
gaodeResultDto.setName((String) pois.getJSONObject(i).get("name"));
gaodeResultDto.setLocation((String) pois.getJSONObject(i).get("location"));
list.add(gaodeResultDto);
}
res.setState(FusionMessage.BaseState.STATE_SUCCESS);
res.setDataList(list);
}
return res;
}
请求地址放在了配置文件中,用了一个模板配置,把参数进行一个替换,http请求因我们加了代理所以也封装了方法,这步骤大家可根据自己的项目需求进行考虑开发。此步骤就是将前端geo调用的经纬度传给我进行一个高德API发起。搜索附近200米距离内的位置信息。但是,获取到的位置信息并不准确。因此,我们进行了一些资料的查找和比较,得出结论:Geo插件获得是原始GPS定位,若需要用高德的周边信息API接口,需要将原始的GPS定位进行一个转换,转换的方法高德官网已给出:
请求参数和响应码:
因此需要考虑将经纬度进行一个转换,这才是重中之重!!!!
操作完以上的步骤以后,成功调用接口:
实现功能。