在做一个电商项目过程中,需要获取设备地理信息,包括经纬度定位,附近地址等,于是写了一个工具类方便使用。

1.在使用百度地图API使,首先要获取官方授权,在http://lbsyun.baidu.com/index.php?title=androidsdk页面获取秘钥,然后按照要求申请即可,需要手机和百度账号及邮箱认证。激活后可看到后台页面,现在可以开始创建应用了,这里请求校验方式有两种,一种是白名单IP,另一种是SN校验(旁边有计算的说明),我选择SN校验:

计算sn:

**
 * Description:获取百度地理编码的sn的工具类
 **/
public class BaiDuGeocodingSnCalUtil {
 
    private static final String HEADER = "/geocoder/v2/?";
 
    public static String getSnCalString(String paramsStr) {
        String tempStr = null;
        try {
            // 对paramsStr前面拼接上/geocoder/v2/?,后面直接拼接yoursk得到/geocoder/v2/?address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourakyoursk
            String wholeStr = HEADER + paramsStr + Constants.BaiDu.SK;
            // 对上面wholeStr再作utf8编码
            tempStr = URLEncoder.encode(wholeStr, Constants.UTF_8);
            tempStr = MD5(tempStr);
        } catch (Exception e) {
            Logger.debug(e.getMessage());
        }
        return tempStr;
    }
 
    /**
     * 对Map内所有value作utf8编码,拼接返回结果
     */
    public static String toQueryString(Map<?, ?> data)
            throws UnsupportedEncodingException {
        StringBuilder queryString = new StringBuilder();
        for (Map.Entry<?, ?> pair : data.entrySet()) {
            queryString.append(pair.getKey());
            queryString.append("=");
            queryString.append(URLEncoder.encode((String) pair.getValue(), Constants.UTF_8));
            queryString.append("&");
        }
        if (queryString.length() > 0) {
            queryString.deleteCharAt(queryString.length() - 1);
        }
        return queryString.toString();
    }
 
    /**
     * 来自stackoverflow的MD5计算方法,调用了MessageDigest库函数,并把byte数组结果转换成16进制
     */
    public static String MD5(String md5) {
        try {
            java.security.MessageDigest md = java.security.MessageDigest
                    .getInstance("MD5");
            byte[] array = md.digest(md5.getBytes());
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < array.length; ++i) {
                sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100)
                        .substring(1, 3));
            }
            return sb.toString();
        } catch (java.security.NoSuchAlgorithmException e) {
            Logger.debug(e.getMessage());
        }
        return null;
    }
 
}

发送请求也简单封装了一个http工具类:

public class SimulationRequestUtil {
 
    public static final int SUCCESS = 200;
 
    private SimulationRequestUtil() {
    }
 
    /**
     * get请求
     *
     * @param url 请求路径
     * @return 返回参数
     */
    public static String doGet(String url) {
        CloseableHttpClient client = null;
        try {
            client = HttpClients.createDefault();
            //发送get请求
            HttpResponse response = client.execute(new HttpGet(url));
            //请求发送成功,并得到响应
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                //读取服务器返回过来的json字符串数据
                return EntityUtils.toString(response.getEntity());
            }
        } catch (IOException e) {
            Logger.warn(e.getMessage());
        } finally {
            if (client != null) {
                try {
                    client.close();
                } catch (Exception e) {
                    Logger.warn(e.getMessage());
                }
            }
        }
        return null;
    }
 
    /**
     * post请求(用于key-value格式的参数)
     *
     * @param url    请求路径
     * @param params 参数
     * @return 返回数据
     */
    @SuppressWarnings("unchecked")
    public static String doPost(String url, Map params) {
        CloseableHttpClient client = null;
        BufferedReader in = null;
        try {
            // 定义HttpClient
            client = HttpClients.createDefault();
            // 实例化HTTP方法
            HttpPost request = new HttpPost();
            request.setURI(new URI(url));
 
            //设置参数
            List<NameValuePair> nvps = new ArrayList<>();
            for (Iterator<Map.Entry<Object, Object>> iterator = params.entrySet().iterator(); iterator.hasNext();) {
                Map.Entry<Object, Object> entry = iterator.next();
                String name = (String) entry.getKey();
                String value = String.valueOf(entry.getValue());
                nvps.add(new BasicNameValuePair(name, value));
            }
            request.setEntity(new UrlEncodedFormEntity(nvps, StandardCharsets.UTF_8));
 
            HttpResponse response = client.execute(request);
            int code = response.getStatusLine().getStatusCode();
            if (code == SUCCESS) {
                //请求成功
                in = new BufferedReader(new InputStreamReader(response.getEntity()
                        .getContent(), StandardCharsets.UTF_8));
                StringBuilder sb = new StringBuilder();
                String line = "";
                String nl = System.getProperty("line.separator");
                while ((line = in.readLine()) != null) {
                    sb.append(line);
                    sb.append(nl);
                }
                return sb.toString();
            } else {
                return null;
            }
        } catch (Exception e) {
            Logger.warn(e.getMessage());
            return null;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                    Logger.warn(e.getMessage());
                }
            }
            if (client != null) {
                try {
                    client.close();
                } catch (Exception e) {
                    Logger.warn(e.getMessage());
                }
            }
        }
    }
 
    /**
     * post请求(用于请求json格式的参数)
     *
     * @param url    请求路径
     * @param params 参数
     * @return 返回数据
     */
    public static String doPost(String url, String params) throws Exception {
 
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建httpPost
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("Content-Type", "application/json");
        String charSet = "UTF-8";
        StringEntity entity = new StringEntity(params, charSet);
        httpPost.setEntity(entity);
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpPost);
            StatusLine status = response.getStatusLine();
            int state = status.getStatusCode();
            if (state == HttpStatus.SC_OK) {
                HttpEntity responseEntity = response.getEntity();
                return EntityUtils.toString(responseEntity);
            } else {
                Logger.warn("请求返回:" + state + "(" + url + ")");
            }
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    Logger.warn(e.getMessage());
                }
            }
            try {
                httpclient.close();
            } catch (IOException e) {
                Logger.warn(e.getMessage());
            }
        }
        return null;
    }
 
}

2.准备就绪之后就是最重要的就是访问api接口获取想要的信息,可根据官方文档调整参数,http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding

CityLatitudeAndLongitudeUtil

public class CityLatitudeAndLongitudeUtil {
 
    private static double EARTH_RADIUS = 6371.393;
 
    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }
 
    /**
     * 根据地址获取经纬度信息
     * @param area 区域
     * @param location 地址
     * @return CityLatitudeAndLongitudeBean 城市经纬度信息
     */
    public static CityLatitudeAndLongitudeBean getLatitudeAndLongitude(String area, String location) {
        CityLatitudeAndLongitudeBean result = null;
        try {
            StringBuilder url = new StringBuilder("http://api.map.baidu.com/geocoder/v2/?");
            LinkedHashMap<String, String> paramsMap = new LinkedHashMap<>();
            paramsMap.put("address", area + (StringUtils.isNotEmpty(location) ? location : StringUtils.EMPTY));
            paramsMap.put("output", "json");
            paramsMap.put("ak", Constants.BaiDu.AK);
            // 调用下面的toQueryString方法,对LinkedHashMap内所有value作utf8编码,拼接返回结果address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourak
            String paramsStr = BaiDuGeocodingSnCalUtil.toQueryString(paramsMap);
            url.append(paramsStr);
            String sn = BaiDuGeocodingSnCalUtil.getSnCalString(paramsStr);
            url.append("&sn=");
            url.append(sn);
            result = JSON.parseObject(SimulationRequestUtil.doGet(url.toString()), new TypeReference<CityLatitudeAndLongitudeBean>() {
            });
            if (result == null || result.getStatus() == null || result.getStatus() != 0) {
                return null;
            }
        } catch (Exception e) {
            Logger.debug(e.getMessage());
        }
        return result;
    }
 
    /**
     * 根据经纬度获取地址及周边信息
     * @param lat 纬度
     * @param lng 经度
     * @return ProvinceBean 城市信息
     */
    public static ProvinceBean getProvince(String lat, String lng) {
        ProvinceBean result = null;
        try {
            StringBuilder url = new StringBuilder("http://api.map.baidu.com/geocoder/v2/?");
            LinkedHashMap<String, String> paramsMap = new LinkedHashMap<>();
            paramsMap.put("location", lat+","+lng);
            String put = paramsMap.put("output", "json");
            paramsMap.put("pois", "1");
            paramsMap.put("latest_admin", "1");
            paramsMap.put("ak", Constants.BaiDu.AK);
            String paramsStr = BaiDuGeocodingSnCalUtil.toQueryString(paramsMap);
            url.append(paramsStr);
            String sn = BaiDuGeocodingSnCalUtil.getSnCalString(paramsStr);
            url.append("&sn=");
            url.append(sn);
            String json = SimulationRequestUtil.doGet(url.toString());
            System.out.println(json);
            result = JSON.parseObject(json, new TypeReference<ProvinceBean>() {
            });
            if (result == null || result.getStatus() == null || result.getStatus() != 0) {
                return null;
            }
        } catch (Exception e) {
            Logger.debug(e.getMessage());
        }
        return result;
    }
 
    /**
     * 计算两个经纬度之间的距离
     *
     * @param lat1
     * @param lng1
     * @param lat2
     * @param lng2
     * @return
     */
    public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.abs(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 1000);
        return s;
    }
 
    /**
     * 测试
     * @param args
     */
    public static void main(String []args){
        System.out.println(getLatitudeAndLongitude("福州","福州"));
        System.out.println(getProvince("26.080429420698079","119.30346983854001"));
    }
 
}

3.返回结果是json数据,可以自行封装需要的数据,在此附上我的信息封装类:

@Data是引入了lombok插件,简化开发,不理解的可自行百度。 其余是一些swagger注解。

CityLatitudeAndLongitudeBean

/**
 * Description:城市经纬度
 **/
@Data
public class CityLatitudeAndLongitudeBean implements Serializable {
 
    private static final long serialVersionUID = 9112556610655198188L;
    private Integer status;
    private Result result;
}

Result

/**
 * Description:城市经纬度的结果
 **/
@Data
public class Result implements Serializable {
 
    private static final long serialVersionUID = 5142442006448398929L;
    private Location location;
    private String precise;
    private String confidence;
    private String level;
}

ProvinceBean

/**
 * Description:经纬度城市
 **/
@Data
@ApiModel(value = "经纬度城市")
public class ProvinceBean implements Serializable {
 
    private static final long serialVersionUID = 9112556610655198166L;
    private Integer status;
    private ProvinceLocation result;
 
}

ProvinceLocation

/**
 * Description:经纬度城市
 **/
@Data
@ApiModel(value = "经纬度城市")
public class ProvinceLocation implements Serializable {
 
    private static final long serialVersionUID = 1570896924286528777L;
    @ApiModelProperty(value = "纬度")
    private String lng;
    @ApiModelProperty(value = "经度")
    private String lat;
    @ApiModelProperty(value = "地址信息")
    private AddressComponent addressComponent;
    @ApiModelProperty(value = "附近地址")
    private List<AddressPois> pois;
 
}

AddressComponent

**
 * Description:城市
 **/
@Data
public class AddressComponent implements Serializable {
 
    private static final long serialVersionUID = 1570896924286528788L;
 
    private String country;
    private String province;
    private String city;
    private String district;
    private String street;
}

AddressPois

/**
 * Description:城市周边信息
 **/
@Data
@ApiModel(value = "城市周边信息")
public class AddressPois implements Serializable {
 
    private static final long serialVersionUID = 1570896924286528755L;
 
    @ApiModelProperty(value = "地址")
    private String addr;
    @ApiModelProperty(value = "名称")
    private String name;
    @ApiModelProperty(value = "经纬度")
    private ProvincePoint point;
    @ApiModelProperty(value = "类型")
    private String poiType;
    @ApiModelProperty(value = "标签")
    private String tag;
}

测试结果

CityLatitudeAndLongitudeBean(status=0, result=Result(location=Location(lng=119.30346983854001, lat=26.080429420698079), precise=0, confidence=10, level=城市))
ProvinceBean(status=0, result=ProvinceLocation(lng=null, lat=null, addressComponent=AddressComponent(country=中国, province=福建省, city=福州市, district=鼓楼区, street=乌山路), pois=[AddressPois(addr=福州市鼓楼区乌山路96号, name=福州市人民政府, point=ProvincePoint(x=119.30289474335273, y=26.0805464063163), poiType=政府机构, tag=政府机构;各级政府), AddressPois(addr=光禄新坊2座1楼16号店面, name=中国工商银行(福州灵响支行), point=ProvincePoint(x=119.30390084552356, y=26.080724886227349), poiType=金融, tag=金融;银行), AddressPois(addr=乌山路92, name=福州市机关事务管理局, point=ProvincePoint(x=119.30403559135002, y=26.08070866079226), poiType=政府机构, tag=政府机构;行政单位), AddressPois(addr=福建省福州市鼓楼区乌山路92号, name=市委大院, point=ProvincePoint(x=119.30382898108279, y=26.080789787944974), poiType=房地产, tag=房地产;住宅区), AddressPois(addr=乌山路59, name=福建移动通信大厦, point=ProvincePoint(x=119.30229287866124, y=26.079353828941117), poiType=房地产, tag=房地产;写字楼), AddressPois(addr=福州市鼓楼区加洋路26号, name=协和公寓, point=ProvincePoint(x=119.30431406605801, y=26.078940074737014), poiType=房地产, tag=房地产;住宅区), AddressPois(addr=福州市鼓楼区乌山路53号福建黎明大酒店, name=中国工商银行(福州南门支行营业室), point=ProvincePoint(x=119.30562559210215, y=26.0808790277473), poiType=金融, tag=金融;银行), AddressPois(addr=福州市鼓楼区加洋路23号, name=福建煤田地质博物馆, point=ProvincePoint(x=119.30494287991479, y=26.079004977455033), poiType=旅游景点, tag=旅游景点;博物馆), AddressPois(addr=福州市鼓楼区乌山路80号, name=山水知音, point=ProvincePoint(x=119.30537406655944, y=26.081665957572313), poiType=购物, tag=购物;商铺), AddressPois(addr=鼓楼区乌山路53号(市政府对面), name=海通商务酒店(斗西路), point=ProvincePoint(x=119.30562559210215, y=26.080294911429247), poiType=酒店, tag=酒店;二星级)]))

版权声明:文章转载请注明来源,如有侵权请联系博主删除!
最后修改:2019 年 12 月 25 日 11 : 56 AM
如果觉得我的文章对你有用,请随意赞赏