高德地图--逆地理编码,批量转化

一.使用场景

​ 因公司需要,新增一个根据经纬度查询所在地址的需求

​ 例如: 113.305377,23.140492

​ 广东省广州市越秀区黄花岗街道广州动物园

二.前期准备

​ 申请高德web服务的key 值,测试够用,如果上线的话,最好用企业账号申请(申请流程高德里面有提示)

三.使用案例

1.所需jar包

		<!--导入httpclient jar包和fastjson包 -->
		<dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.7</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.38</version>
        </dependency>

2.测试代码

package cn.gdmcmc.esi.gaode;


import com.alibaba.fastjson.JSON;
import com.mysql.cj.xdevapi.JsonArray;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @Description:高德逆地理编码
 * @Author:lighter
 * @Date:2019/11/20 16:43
 * @Version 1.0
 */
public class GeoCodeTest {
    public static void main(String[] args) throws Exception {
        //创建一个httpclient对象
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        //创建url 
        //output = json 返回结果数据将会以JSON结构构成
       // batch 参数设置为 true 时进行批量查询操作,设置为 false 时进行单点查询,最多查询20个
        String urlStr = "https://restapi.amap.com/v3/geocode/regeo?					 output=json&batch=true&key=053633e246650ab25ae2f58c504e964b&";
        //坐标点,多个坐标点之间用 | 连接
        //java 中使用String 连接url ,识别 | 错误,要更换成 %7C
        String location = "location=113.313596,23.080083";
        String url =urlStr+location;
 		//生成get 请求对象
        HttpGet httpGet = new HttpGet(newUrl);
        //发送请求
        CloseableHttpResponse response = httpClient.execute(httpGet);
		//获取响应实体对象
        HttpEntity entity = response.getEntity();
        //转换成utf-8 编码的字符串
        String entityStr = EntityUtils.toString(entity, "utf-8");
        //转换成map 的集合
        Map map = JSON.parseObject(entityStr, Map.class);
        //获取逆地理编码列表列表
        //batch=true,此时 regeocodes 标签返回;batch=false,会返回 regeocode对象;
        String regeocodes = map.get("regeocodes").toString();
        //字符串转换成  List<Map<String,Object>> 类型的集合
        List<Map<String,Object>> list = JSON.parseObject(regeocodes,new ArrayList<Map<String,Object>>().getClass());
        //循环
        for (Map<String, Object> regecodeMap : list) {
            //获取结构化地址信息
            String s = regecodeMap.get("formatted_address").toString();
            System.out.println(s);

        }
        //关闭资源
        httpClient.close();
        response.close();
    }
}

3.GeocodeUtil 工具类(批量查询)

package cn.gdmcmc.iovs.common.util;

import cn.gdmcmc.iovs.authbasecommon.common.exception.GlobalException;
import cn.gdmcmc.iovs.module.find.pojo.Transboundary;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.type.MapLikeType;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Author:lighter
 * @Date:2019/11/20 19:23
 * @Version 1.0
 */
public class GeocodeUtil {
	//地址固定
    private static String url = "https://restapi.amap.com/v3/geocode/regeo?output=json&batch=true&key=";
    //传入需要查询的集合,和所需的key ,返回转换后的集合
    public List<Transboundary> getAddress(List<Transboundary> list,String geoKey)throws Exception{
		//分页,每个集合10条数据
        if(list.size() <=  10){
            List<Map<String,String>> addressList = getAddressList(list,geoKey);
            for (int i = 0; i < list.size(); i++) {
                Map<String, String> map = addressList.get(i);
                list.get(i).setProvince(map.get("province"));
                list.get(i).setAddress(map.get("address"));
                list.get(i).setCity(map.get("city"));
            }
		//不分页每个集合20条,查最多经纬度次数20次
        }else{
            //获取一个空集合,用来装包含地址信息
            List<Map<String,String>> addressList = null;
            int index = list.size();
            //循环传过来要转换的集合
            for (int i = 0; i < index; i ++) {
                // i 除 20 能整除,拿集合20个对象去获取地址
                if(i%20 == 0){
                    //当索引在最后一个20个队列中,比如总长度为45,i = 40,0-19,20-39,40-45
                    if(i/20 == index/20){
                        //截取i=40,i=44,subList()截取包前不包后
                        List<Transboundary> newList = list.subList(i,index);
                        //获取地址集合
                        addressList = getAddressList(newList,geoKey);
                    //索引不在最后一个20队列中,i=20
                    }else{
                        //截取i= 20,i= 39 
                        List<Transboundary> newList = list.subList(i, i + 20);
                        addressList = getAddressList(newList,geoKey);
                    }

                }
                //获取对应地址集合的对象,比如 i = 20 ,地址集合的所获得的对象索引为0
                Map<String, String> map = addressList.get(i % 20);
                //一一设置
                list.get(i).setProvince(map.get("province"));
                list.get(i).setAddress(map.get("address"));
                list.get(i).setCity(map.get("city"));
            }

        }
        //返回准换后的集合
        return list;
    }
	//获取经纬度查询地址集合
    public List<Map<String,String>> getAddressList(List<Transboundary> list,String geoKey) throws Exception{
		//先获取一个地址集合
        List<Map<String,String>> returnList = new ArrayList<>();
		//设置坐标对
        String location = "&location=";
        //对传过来的集合进行循环,连接经纬度
        for (int i = 0; i < list.size(); i++) {
            Transboundary transboundary = list.get(i);
            //数据库,有时经纬度为0,所以只能自己替换下,免得查询出来的为null,会报异常,并且后面顺序插入也有问题
            if (transboundary.getLng().compareTo(BigDecimal.ZERO)== 0 || transboundary.getLat().compareTo(BigDecimal.ZERO)==0){
                //自己替代了下坐标点
                location += "113.313596,23.080083%7C";
            }else{
                //在这里我发现,url最后一对坐标点连接 | 这个也没有问题
                //所以不进行判断
                location += transboundary.getLng().stripTrailingZeros().toPlainString()+ "," + transboundary.getLat().stripTrailingZeros().toPlainString()+"%7C";
            }

        }
        //连接地址
        String urlStr = url+ geoKey + location;
        //获取httpclient对象
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        //创建get对象
        HttpGet httpGet = new HttpGet(urlStr);
        //发送请求
        CloseableHttpResponse response = httpClient.execute(httpGet);
        //获取响应体对象
        HttpEntity entity = response.getEntity();
        //转换成字符串
        String entityStr = EntityUtils.toString(entity, "utf-8");
        //转换成map,这里应该可以优化,异步转化成后面所需的格式
        Map map = JSON.parseObject(entityStr, Map.class);
        //获取逆地理编码列表
        String regeocodeStr = map.get("regeocodes").toString();
        //转换成集合
        ArrayList<Map<String, Object>> regeocodeList = JSON.parseObject(regeocodeStr, new ArrayList<Map<String,Object>>().getClass());
        //循环
        for (Map<String, Object> regeocodeMap : regeocodeList) {
            Map<String,String> addMap = new HashMap<>();
			//有的时候获取的地址会返回一个"[]",所以自己设置地址
            if (JSON.toJSONString(regeocodeMap.get("formatted_address")).equals("[]")){
                addMap.put("address","广东省广州市海珠区");
                addMap.put("city","广州市");
                addMap.put("province","广东省");
                returnList.add(addMap);
            } else{
                //获取地址
                addMap.put("address",regeocodeMap.get("formatted_address").toString());
                Map<String,Object> addressComponentMap  = JSON.parseObject(regeocodeMap.get("addressComponent").toString(),new HashMap<String,Object>().getClass());
                //获取省
                addMap.put("province",addressComponentMap.get("province").toString());
                //获取市,直辖市,城市为"[]"
                if(JSON.toJSONString(addressComponentMap.get("city")).equals("[]")){
                    addMap.put("city","");
                }else {
                    addMap.put("city",addressComponentMap.get("city").toString());
                }
                //添加到地址集合中
                returnList.add(addMap);
            }
        }
        httpClient.close();
        response.close();
        //返回
        return returnList;

    }
}

四.所遇问题

​ 1.地址连接

​ | 转换成 %7C

​ 详细请看:

https://blog.csdn.net/weixin_40165317/article/details/81112845

​ 2.返回的地址为[]

​ 进行判断替换

​ 3.坐标点类型

​ gps/北斗为地球坐标系

​ 高德/腾讯为火星坐标系

​ 详细请看:

https://blog.csdn.net/ThinkWon/article/details/101392187

发布了22 篇原创文章 · 获赞 5 · 访问量 1059

猜你喜欢

转载自blog.csdn.net/lighter613/article/details/103233577