高德地圖API實現web服務端導航和定位等功能


package com.example.combat.gaodemapUtils;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.combat.gaodemapUtils.param.GaodeMapConstant;
import com.example.combat.gaodemapUtils.param.Geocodes;
import com.example.combat.gaodemapUtils.param.req.*;
import com.google.common.collect.Maps;
import com.sun.org.apache.regexp.internal.RE;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URIBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.zip.GZIPOutputStream;

import static com.example.combat.gaodemapUtils.HttpUtil.covertParams2NVPS;

/**
 * @description: 高德地圖工具類
 * @author: zhucj
 * @date: 2019-11-25 17:22
 */
@Component
@Slf4j
public class GaodeMapUtil {


    @Value("${gaodemap.key}")
    private String key;

    @Value("${gaodemap.pathImg}")
    private String pathImg;

    /**
     * 結構化地址信息查詢
     * @param geocodeRequestVo
     * @return
     */
    @ApiOperation(value ="結構化地址信息查詢")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "address",value = "結構化地址信息",required = true,dataType = "String"),
            @ApiImplicitParam(name = "city",value = "指定查詢城市 城市的中文或中文全拼 ",required = false,dataType = "String")
    })
    public R getGeocodes(GeocodeRequestVo geocodeRequestVo) {
        log.info("==>查詢結構化地址:"+geocodeRequestVo.getAddress());
        //是否支持批量查詢 true:支持 false:不支持
        geocodeRequestVo.setBatch(false);
        //支持的格式XML,JSON
        geocodeRequestVo.setOutput(GaodeMapConstant.JSON);
        Map<String, Object> stringObjectMap = beanToMap(geocodeRequestVo);
        stringObjectMap.put(GaodeMapConstant.KEY,key);
        String resultJson = null;
        try {
            resultJson = HttpUtil.httpGet(GaodeMapConstant.GEOCODE_GEO, stringObjectMap);
        } catch (Exception e) {
            log.error("請求服務異常:{}",e.getMessage());
            return R.error("請求服務異常").setCode(SystemConstant.SERVER_ERROR_CODE);
        }
        JSONObject jsonObject = JSON.parseObject(resultJson);
        if (Objects.equals(GaodeMapConstant.SUCCESS,jsonObject.get("status"))){
            String geocodes = JSON.toJSONString(jsonObject.get("geocodes"));
            List<Geocodes> geocodes1 = JSON.parseArray(geocodes, Geocodes.class);
            return R.ok(geocodes1.get(0)).setCode(SystemConstant.SUCCESS_CODE);
        }else {
            log.info("獲取地址信息失敗,原因:{}",jsonObject.get("info"));
            return R.error(jsonObject.get("info").toString()).setCode(SystemConstant.SERVER_ERROR_CODE);
        }
    }

    /**
     * 通過經緯度,獲取地理位置信息
     * @param geocodeRequestVo
     * @return
     */
    @ApiOperation(value = "獲取逆地理編碼信息列表",notes = "朱傳捷")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "location",value = "經緯度(格式:116.481488,39.990464)",required = true,dataType = "String"),
            @ApiImplicitParam(name = "poitype",value = "返回附近POI類型(extensions 參數為 all 時才生效)",required = false,dataType = "String"),
            @ApiImplicitParam(name = "radius",value = "搜索半徑",required = false,dataType = "String"),
            @ApiImplicitParam(name = "extensions",value = "返回結果控制(base和all)",required = false,dataType = "String"),
            @ApiImplicitParam(name = "roadlevel",value = "道路等級",required = false,dataType = "String")
    })
    public R getReGeocodes(GeocodeRequestVo geocodeRequestVo) {
        //是否支持批量查詢 true:支持 false:不支持
        geocodeRequestVo.setBatch(false);
        //支持的格式XML,JSON
        geocodeRequestVo.setOutput(GaodeMapConstant.JSON);
        Map<String, Object> stringObjectMap = beanToMap(geocodeRequestVo);
        stringObjectMap.put(GaodeMapConstant.KEY,key);
        try {
            String resultJson = HttpUtil.httpGet(GaodeMapConstant.GEOCODE_REGEO, stringObjectMap);
            JSONObject jsonObject = JSON.parseObject(resultJson);
            if (Objects.equals(GaodeMapConstant.SUCCESS,jsonObject.get("status"))){
                return R.ok(jsonObject.get("regeocode")).setCode(SystemConstant.SUCCESS_CODE);
            }else {
                return R.error(jsonObject.get("info").toString()).setCode(SystemConstant.SERVER_ERROR_CODE);
            }
        } catch (Exception e) {
            log.error("通過經緯度獲取地址失敗:{}",e.getMessage());
            return R.error("獲取地址失敗").setCode(SystemConstant.SERVER_ERROR_CODE);
        }
    }

    /**
     * 路線規划
     * @param directionRequestVo
     * @return
     */
    @ApiOperation(value = "地圖路線規划,支持步行、公交、駕車方式")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "directionType",value = "交通工具類型1:步行 2:公交 3:駕車",required = true,dataType = "Integer"),
            @ApiImplicitParam(name = "origin",value = "出發點經緯度",required = true,dataType = "String"),
            @ApiImplicitParam(name = "destination",value = "終點經緯度",required = true,dataType = "String"),
            @ApiImplicitParam(name = "city",value = "城市/跨城規划時的起點城市,directionType = 2時必傳",required = false,dataType = "String"),
            @ApiImplicitParam(name = "strategy",value = "換乘策略",required = false,dataType = "Integer")
    })
    public R getDirection(DirectionRequestVo directionRequestVo) {
        if (StringUtils.isEmpty(directionRequestVo.getOrigin())){
            return R.error(GaodeMapConstant.ERR_ORIGIN_PARAM_NULL).setCode(SystemConstant.PARAM_INCORRECT_CODE);
        }
        if (StringUtils.isEmpty(directionRequestVo.getDestination())){
            return R.error(GaodeMapConstant.ERR_DESTINATION_PARAM_NULL).setCode(SystemConstant.PARAM_INCORRECT_CODE);
        }
        //判斷路線規划類型,目前只支持3種,strategy=2時,city城市名稱
        String reqUrl = null;
        switch (directionRequestVo.getStrategy()){
            case 1:
                reqUrl = GaodeMapConstant.DIRECTION_WALKING;
                break;
            case 2:
                if (StringUtils.isEmpty(directionRequestVo.getCity())){
                    return R.error(GaodeMapConstant.ERR_CITY_PARAM_NULL).setCode(SystemConstant.PARAM_INCORRECT_CODE);
                }
                reqUrl = GaodeMapConstant.DIRECTION_INTEGRATED;
                break;

            case 3:
                reqUrl = GaodeMapConstant.DIRECTION_DRIVING;
                break;
                default:
                    return R.error(GaodeMapConstant.ERR_DIRECTIONTYPE_PARAM_NULL).setCode(SystemConstant.PARAM_INCORRECT_CODE);
        }
        Map<String, Object> stringObjectMap = beanToMap(directionRequestVo);
        stringObjectMap.put(GaodeMapConstant.KEY,key);
        try {
            String rusultStr = HttpUtil.httpGet(reqUrl, stringObjectMap);
            JSONObject jsonObject = JSON.parseObject(rusultStr);
            if (Objects.equals(GaodeMapConstant.SUCCESS,jsonObject.get("status"))){
                return R.ok(jsonObject.get("route"));
            }else {
                log.error("查詢路線規划失敗:{}",jsonObject.get("info").toString());
                return R.error(jsonObject.get("info").toString()).setCode(SystemConstant.SERVER_ERROR_CODE);
            }
        } catch (Exception e) {
            log.error("查詢路線規划異常:{}",e.getMessage());
            return R.error("查詢路線規划異常").setCode(SystemConstant.SERVER_ERROR_CODE);
        }
    }

    /**
     * 靜態地圖
     * @param staticMapRequest
     */
    @ApiOperation(value = "生成靜態地圖")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "locations",value = "經緯度集合",required = true,dataType = "List"),
            @ApiImplicitParam(name = "zoom",value = "地圖縮放級別:[1,17]",required = true,dataType = "String"),
            @ApiImplicitParam(name = "size",value = "圖片寬度*圖片高度。最大值為1024*1024",required = true,dataType = "String"),
            @ApiImplicitParam(name = "scale",value = "清晰度",required = true,dataType = "Integer")
    })
    public void staticMap(StaticMapRequest staticMapRequest, HttpServletResponse response){

        //設置地圖縮放級別
        staticMapRequest.setZoom(staticMapRequest.getZoom());
        //地圖大小
        staticMapRequest.setSize(staticMapRequest.getSize());
        //設置高清
        staticMapRequest.setScale(staticMapRequest.getScale());
        List<String> localhosts = staticMapRequest.getLocalhosts();
        //設置默認第一個和最后一個點,標注,起,終
        Markers marker1 = Markers
                .builder()
                .color("0xFF0000")
                .size("mid")
                .label("起:"+localhosts.get(0))
                .build();
        Markers markers2 = Markers
                .builder()
                .size("mid")
                .color("0xFF0000")
                .label("終:"+localhosts.get(localhosts.size()-1))
                .build();
        //拼接markers屬性
        String setMarkers1 = marker1.getSize()+","+marker1.getColor()+","+marker1.getLabel();
        String setMarkers2 = markers2.getSize()+","+markers2.getColor()+","+markers2.getLabel();
        staticMapRequest.setMarkers(setMarkers1+"|"+setMarkers2);
        //繪制折線
        Paths paths = Paths
                .builder()
                .weight(5)
                .color("0xFF0000")
                .transparency("1")
                .build();
        StringBuilder stringBuilder = new StringBuilder();
        for (String localhost:localhosts){
            stringBuilder.append(localhost+";");
        }
        String s = stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString();
        String path = paths.getWeight()+","+paths.getColor()+","+paths.getTransparency()+","+","+":"+s;
        staticMapRequest.setPaths(path);
        Map<String, Object> stringObjectMap = beanToMap(staticMapRequest);
        stringObjectMap.put(GaodeMapConstant.KEY,key);
        try {
            // 轉換請求參數
            List<NameValuePair> pairs = covertParams2NVPS(stringObjectMap);
            // 裝載請求地址和參數
            URIBuilder ub = new URIBuilder();
            ub.setPath(GaodeMapConstant.STATUC_MAP);
            ub.setParameters(pairs);
            String s1 = ub.toString();
            String compress = compress(s1,pathImg );
            exportImg(response,pathImg+compress);
        } catch (Exception e) {
            log.error("下載圖片異常"+e.getMessage());
        }
    }
    /**
     * bean -> map 實體類轉map
     * @param bean
     * @param <T>
     * @return
     */
    public static <T> Map<String, Object> beanToMap(T bean) {
        Map<String, Object> map = Maps.newHashMap();
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            for (Object key : beanMap.keySet()) {
                if (Objects.nonNull(beanMap.get(key)) && !(Objects.equals("",beanMap.get(key)))){
                    map.put(key + "",beanMap.get(key));
                }
            }
        }
        return map;
    }

    /**
     * 下載地圖
     * @param url
     * @param path
     * @return
     */
    public static String compress(String url,String path) {
        try {
            String imageName = "map.png";
            File file = new File(path +  imageName);
            //判斷文件是否已經存在
            if (file.exists()) {
                file.delete();
            }
            file.createNewFile();
            URL uri = new URL(url);
            InputStream in = uri.openStream();
            FileOutputStream fo = new FileOutputStream(file);
            byte[] buf = new byte[1024];
            int length = 0;
            while ((length = in.read(buf, 0, buf.length)) != -1) {
                fo.write(buf, 0, length);
            }
            in.close();
            fo.close();
            return imageName;
        } catch (Exception e) {
            log.error("下載失敗",e.getMessage());
            return null;
        }

    }

    /**
     * 輸出圖片
     * @param response
     * @param filePath
     */
    public static void exportImg(HttpServletResponse response, String filePath) {
        File file = new File(filePath);
        response.setCharacterEncoding("utf-8");
        //設置響應的內容類型
        response.setContentType("text/plain");
        //設置文件的名稱和格式
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment;filename=" + file.getName());
        BufferedOutputStream buff = null;
        ServletOutputStream outStr = null;
        try {
            outStr = response.getOutputStream();
            buff = new BufferedOutputStream(outStr);
            buff.write(FileUtil.readBytes(filePath));
            buff.flush();
            buff.close();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文件導出異常:", e);
        } finally {
            try {
                buff.close();
            } catch (Exception e) {
                log.error("流關閉異常:", e);
            }
            try {
                outStr.close();
            } catch (Exception e) {
                log.error("流關閉異常:", e);
            }
        }
    }

}

 

package com.example.combat.gaodemapUtils;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

@Slf4j
public class HttpUtil {

    public static final ContentType TEXT_PLAIN = ContentType.create("text/plain", StandardCharsets.UTF_8);

    /**
     * HttpClient 連接池
     */
    private static PoolingHttpClientConnectionManager cm = null;

    static {
        // 初始化連接池,可用於請求HTTP/HTTPS(信任所有證書)
        cm = new PoolingHttpClientConnectionManager(getRegistry());
        // 整個連接池最大連接數
        cm.setMaxTotal(200);
        // 每路由最大連接數,默認值是2
        cm.setDefaultMaxPerRoute(5);
    }

    /**
     * 發送 HTTP GET請求
     * <p>不帶請求參數和請求頭</p>
     * @param url 地址
     * @return
     * @throws Exception
     */
    public static String httpGet(String url) throws Exception {
        log.info("請求參數:{}",url);
        HttpGet httpGet = new HttpGet(url);

        return doHttp(httpGet);
    }

    /**
     * 發送 HTTP GET請求
     * <p>帶請求參數,不帶請求頭</p>
     * @param url    地址
     * @param params 參數
     * @return
     * @throws Exception
     * @throws Exception
     */
    public static String httpGet(String url, Map<String, Object> params) throws Exception {
        // 轉換請求參數
        List<NameValuePair> pairs = covertParams2NVPS(params);

        // 裝載請求地址和參數
        URIBuilder ub = new URIBuilder();
        ub.setPath(url);
        ub.setParameters(pairs);
        HttpGet httpGet = new HttpGet(ub.build());

        return doHttp(httpGet);
    }

    /**
     * 發送 HTTP GET請求
     * <p>帶請求參數和請求頭</p>
     * @param url     地址
     * @param headers 請求頭
     * @param params  參數
     * @return
     * @throws Exception
     * @throws Exception
     */
    public static String httpGet(String url, Map<String, Object> headers, Map<String, Object> params) throws Exception {
        // 轉換請求參數
        List<NameValuePair> pairs = covertParams2NVPS(params);

        // 裝載請求地址和參數
        URIBuilder ub = new URIBuilder();
        ub.setPath(url);
        ub.setParameters(pairs);

        HttpGet httpGet = new HttpGet(ub.build());
        // 設置請求頭
        for (Map.Entry<String, Object> param : headers.entrySet()){
            httpGet.addHeader(param.getKey(), String.valueOf(param.getValue()));}

        return doHttp(httpGet);
    }

    /**
     * 發送 HTTP POST請求
     * <p>不帶請求參數和請求頭</p>
     *
     * @param url 地址
     * @return
     * @throws Exception
     */
    public static String httpPost(String url) throws Exception {
        HttpPost httpPost = new HttpPost(url);

        return doHttp(httpPost);
    }

    /**
     * 發送 HTTP POST請求
     * <p>帶請求參數,不帶請求頭</p>
     *
     * @param url    地址
     * @param params 參數
     * @return
     * @throws Exception
     */
    public static String httpPost(String url, Map<String, Object> params) throws Exception {
        // 轉換請求參數
        List<NameValuePair> pairs = covertParams2NVPS(params);

        HttpPost httpPost = new HttpPost(url);
        // 設置請求參數
        httpPost.setEntity(new UrlEncodedFormEntity(pairs, StandardCharsets.UTF_8.name()));

        return doHttp(httpPost);
    }

    /**
     * 發送 HTTP POST請求
     * <p>帶請求參數和請求頭</p>
     *
     * @param url     地址
     * @param headers 請求頭
     * @param params  參數
     * @return
     * @throws Exception
     */
    public static String httpPost(String url, Map<String, Object> headers, Map<String, Object> params) throws Exception {
        log.info("POST請求參數:{}",params);
        HttpPost httpPost = new HttpPost(url);
        // 設置請求參數
        StringEntity entity = new StringEntity(JSON.toJSONString(params),ContentType.APPLICATION_JSON);
        httpPost.setEntity(entity);
        // 設置請求頭
        for (Map.Entry<String, Object> param : headers.entrySet()){
            httpPost.addHeader(param.getKey(), String.valueOf(param.getValue()));}

        return doHttp(httpPost);
    }




    /**
     * 轉換請求參數
     *
     * @param params
     * @return
     */
    public static List<NameValuePair> covertParams2NVPS(Map<String, Object> params) {
        List<NameValuePair> pairs = new ArrayList<NameValuePair>();

        for (Map.Entry<String, Object> param : params.entrySet()){
            pairs.add(new BasicNameValuePair(param.getKey(), String.valueOf(param.getValue())));}

        return pairs;
    }

    /**
     * 發送 HTTP 請求
     *
     * @param request
     * @return
     * @throws Exception
     */
    private static String doHttp(HttpRequestBase request) throws Exception {
        // 通過連接池獲取連接對象
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build();

        return doRequest(httpClient, request);
    }

    /**
     * 發送 HTTPS 請求
     * <p>使用指定的證書文件及密碼</p>
     *
     * @param request
     * @param path
     * @param password
     * @return
     * @throws Exception
     * @throws Exception
     */
    private static String doHttps(HttpRequestBase request, String path, String password) throws Exception {
        // 獲取HTTPS SSL證書
        SSLConnectionSocketFactory csf = getSSLFactory(path, password);
        // 通過連接池獲取連接對象
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();

        return doRequest(httpClient, request);
    }

    /**
     * 獲取HTTPS SSL連接工廠
     * <p>使用指定的證書文件及密碼</p>
     *
     * @param path     證書全路徑
     * @param password 證書密碼
     * @return
     * @throws Exception
     * @throws Exception
     */
    private static SSLConnectionSocketFactory getSSLFactory(String path, String password) throws Exception {

        // 初始化證書,指定證書類型為“PKCS12”
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        // 讀取指定路徑的證書
        FileInputStream input = new FileInputStream(new File(path));

        try {
            // 裝載讀取到的證書,並指定證書密碼
            keyStore.load(input, password.toCharArray());
        } finally {
            input.close();
        }

        // 獲取HTTPS SSL證書連接上下文
        SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, password.toCharArray()).build();

        // 獲取HTTPS連接工廠,指定TSL版本
        SSLConnectionSocketFactory sslCsf = new SSLConnectionSocketFactory(sslContext, new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());

        return sslCsf;
    }

    /**
     * 獲取HTTPS SSL連接工廠
     * <p>跳過證書校驗,即信任所有證書</p>
     *
     * @return
     * @throws Exception
     */
    private static SSLConnectionSocketFactory getSSLFactory() throws Exception {
        // 設置HTTPS SSL證書信息,跳過證書校驗,即信任所有證書請求HTTPS
        SSLContextBuilder sslBuilder = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }
        });

        // 獲取HTTPS SSL證書連接上下文
        SSLContext sslContext = sslBuilder.build();

        // 獲取HTTPS連接工廠
        SSLConnectionSocketFactory sslCsf = new SSLConnectionSocketFactory(sslContext, new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);

        return sslCsf;
    }

    /**
     * 獲取 HTTPClient注冊器
     *
     * @return
     * @throws Exception
     */
    private static Registry<ConnectionSocketFactory> getRegistry() {
        Registry<ConnectionSocketFactory> registry = null;

        try {
            registry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", new PlainConnectionSocketFactory()).register("https", getSSLFactory()).build();
        } catch (Exception e) {
            log.error("獲取 HTTPClient注冊器失敗", e);
        }

        return registry;
    }


    /**
     * 處理Http/Https請求,並返回請求結果
     * <p>注:默認請求編碼方式 UTF-8</p>
     *
     * @param httpClient
     * @param request
     * @return
     * @throws Exception
     */
    private static String doRequest(CloseableHttpClient httpClient, HttpRequestBase request) throws Exception {
        String result = null;
        CloseableHttpResponse response = null;

        try {
            // 獲取請求結果
            response = httpClient.execute(request);
            // 解析請求結果
            HttpEntity entity = response.getEntity();
            if ((entity.getContentEncoding() != null)
                    && entity.getContentEncoding().getValue().contains("gzip")) {
                GZIPInputStream gzip = new GZIPInputStream(
                        new ByteArrayInputStream(EntityUtils.toByteArray(entity)));
                InputStreamReader isr = new InputStreamReader(gzip);
                BufferedReader br = new BufferedReader(isr);
                StringBuilder sb = new StringBuilder();
                String temp;
                while((temp = br.readLine()) != null){
                    sb.append(temp);
                    sb.append("\r\n");
                }
                isr.close();
                gzip.close();
                return sb.toString();
            }
            // 轉換結果
            result = EntityUtils.toString(entity, StandardCharsets.UTF_8.name());
            // 關閉IO流
            EntityUtils.consume(entity);
        } finally {
            if (null != response){
                response.close();}
        }

        return result;
    }


}

 

 

package com.example.combat.gaodemapUtils;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.ToString;

import java.io.Serializable;

/**
 * 返回類型
 * @author choleece
 * @date 2018/9/27
 */
@ApiModel
@ToString
public class R<T> implements Serializable {

    private static final long serialVersionUID = -6287952131441663819L;

    /**
     * 編碼
     */
    @ApiModelProperty(value = "響應碼", example = "200")
    private int code = 200;

    /**
     * 成功標志
     */
    @ApiModelProperty(value = "成功標志", example = "true")
    private Boolean success;

    /**
     * 返回消息
     */
    @ApiModelProperty(value = "返回消息說明", example = "操作成功")
    private String msg="操作成功";

    /**
     * 返回數據
     */
    @ApiModelProperty(value = "返回數據")
    private T data;

    /**
     * 創建實例
     * @return
     */
    public static R instance() {
        return new R();
    }

    public int getCode() {
        return code;
    }

    public R setCode(int code) {
        this.code = code;
        return this;
    }

    public Boolean getSuccess() {
        return success;
    }

    public R setSuccess(Boolean success) {
        this.success = success;
        return this;
    }

    public String getMsg() {
        return msg;
    }

    public R setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    public T getData() {
        return data;
    }
    public R setData(T data) {
        this.data = data;
        return this;
    }

    public static R ok() {
        return R.instance().setSuccess(true);
    }

    public static R ok(Object data) {
        return ok().setData(data);
    }

    public static R ok(Object data, String msg) {
        return ok(data).setMsg(msg);
    }

    public static R error() {
        return R.instance().setSuccess(false);
    }

    public static R error(String msg) {
        return error().setMsg(msg);
    }

    /**
     * 無參
     */
    public R() {
    }

    public R(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public R(int code, T data){
        this.code = code;
        this.data = data;
    }

    /**
     * 有全參
     * @param code
     * @param msg
     * @param data
     * @param success
     */
    public R(int code, String msg, T data, Boolean success) {
        this.code = code;
        this.msg = msg;
        this.data = data;
        this.success = success;
    }

    /**
     * 有參
     * @param code
     * @param msg
     * @param data
     */
    public R(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
}

 

 

package com.example.combat.gaodemapUtils;

/** 前端返回信息
 * @Author: zhucj
 * @Date: 2019/5/21 16:19
 */
public class SystemConstant {


    /** 傳參不規范,code:400*/
    public static final Integer PARAM_INCORRECT_CODE = 400;

    /** 成功,code:200*/
    public static final Integer SUCCESS_CODE = 200;

    /** 服務內部調用失敗,code:500*/
    public static final Integer SERVER_ERROR_CODE = 500;

    /** 登錄失效,code:401*/
    public static final Integer AUTH_FAIL_CODE = 401;

    /** 無對應接口權限,code:402*/
    public static final Integer HAVE_NOT_PERMISSION_CODE = 402;

    /** 操作無記錄,code:403*/
    public static final Integer NO_RECORD_OPERATION = 403;





}
package com.example.combat.gaodemapUtils.param.req;

import io.swagger.annotations.ApiModel;
import lombok.*;

/**
 * @description:
 * @author: zhucj
 * @date: 2019-08-05 11:19
 */
@Data
@ApiModel(description = "路徑規划請求視圖")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class DirectionRequestVo {

    /**
     * 交通工具類型 1:步行 2:公交 3:駕車
     */
    private Integer  directionType;
    /**
     * 出發點 lon,lat(經度,緯度), “,”分割,如117.500244, 40.417801
     */
    private String origin;

    /**
     * 目的地 lon,lat(經度,緯度), “,”分割,如117.500244, 40.417801
     */
    private String destination;

    /**
     * 城市/跨城規划時的起點城市,directionType = 2時必傳
     */
    private String city;

    /**
     * 公交換乘策略 directionType = 2和3時選傳 默認0 可選值:
     * 0:最快捷模式,1:最經濟模式,2:最少換乘模式,3:最少步行模式,5:不乘地鐵模式
     * 下方10~20的策略,會返回多條路徑規划結果。(高德地圖APP策略也包含在內,強烈建議從此策略之中選擇)
     * 下方策略 0~9的策略,僅會返回一條路徑規划結果
     */
    /**
     * 下方策略僅返回一條路徑規划結果
     * 0,速度優先,不考慮當時路況,此路線不一定距離最短
     * 1,費用優先,不走收費路段,且耗時最少的路線
     * 2,距離優先,不考慮路況,僅走距離最短的路線,但是可能存在穿越小路/小區的情況
     * 3,速度優先,不走快速路,例如京通快速路(因為策略迭代,建議使用13)
     * 4,躲避擁堵,但是可能會存在繞路的情況,耗時可能較長
     * 5,多策略(同時使用速度優先、費用優先、距離優先三個策略計算路徑)。
     * 其中必須說明,就算使用三個策略算路,會根據路況不固定的返回一~三條路徑規划信息。
     * 6,速度優先,不走高速,但是不排除走其余收費路段
     * 7,費用優先,不走高速且避免所有收費路段
     * 8,躲避擁堵和收費,可能存在走高速的情況,並且考慮路況不走擁堵路線,但有可能存在繞路和時間較長
     * 9,躲避擁堵和收費,不走高速
     * 下方策略返回多條路徑規划結果
     * 10,返回結果會躲避擁堵,路程較短,盡量縮短時間,與高德地圖的默認策略也就是不進行任何勾選一致
     * 11,返回三個結果包含:時間最短;距離最短;躲避擁堵 (由於有更優秀的算法,建議用10代替)
     * 12,返回的結果考慮路況,盡量躲避擁堵而規划路徑,與高德地圖的“躲避擁堵”策略一致
     * 13,返回的結果不走高速,與高德地圖“不走高速”策略一致
     * 14,返回的結果盡可能規划收費較低甚至免費的路徑,與高德地圖“避免收費”策略一致
     * 15,返回的結果考慮路況,盡量躲避擁堵而規划路徑,並且不走高速,與高德地圖的“躲避擁堵&不走高速”策略一致
     * 16,返回的結果盡量不走高速,並且盡量規划收費較低甚至免費的路徑結果,與高德地圖的“避免收費&不走高速”策略一致
     * 17,返回路徑規划結果會盡量的躲避擁堵,並且規划收費較低甚至免費的路徑結果,與高德地圖的“躲避擁堵&避免收費”策略一致
     * 18,返回的結果盡量躲避擁堵,規划收費較低甚至免費的路徑結果,並且盡量不走高速路,與高德地圖的“避免擁堵&避免收費&不走高速”策略一致
     * 19,返回的結果會優先選擇高速路,與高德地圖的“高速優先”策略一致
     * 20,返回的結果會優先考慮高速路,並且會考慮路況躲避擁堵,與高德地圖的“躲避擁堵&高速優先”策略一致
     */
    private Integer strategy;

}

 

 

package com.example.combat.gaodemapUtils.param.req;

import io.swagger.annotations.ApiModel;
import lombok.*;

/**
 * @description:
 * @author:zhucj
 * @date: 2019-08-02 11:50
 */
@Data
@ApiModel(description = "地理名稱請求視圖")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class GeocodeRequestVo {

    //TODO: 地理編碼參數
    /**
     * 結構化地址信息
     * 如:北京市朝陽區阜通東大街6號。如果需要解析多個地址的話,
     * 請用"|"進行間隔,並且將 batch 參數設置為 true,
     * 最多支持 10 個地址進進行"|"分割形式的請求。
     */
    private String address;

    /**
     * 城市名稱
     * 指定城市的中文(如北京)、指定城市的中文全拼(beijing)、
     * citycode(010)、adcode(110000),不支持縣級市。
     */
    private String city;

    /**
     * 批量查詢控制
     * batch 參數設置為 true 時進行批量查詢操作,最多支持 10 個地址進行批量查詢。
     * batch 參數設置為 false 時進行單點查詢,此時即使傳入多個地址也只返回第一個地址的解析查詢結果。
     */
    private Boolean batch;

    /**
     * 返回數據格式類型
     * 可選輸入內容包括:JSON,XML
     */
    private String output;

    /**
     * 數字簽名
     */
    private String sig;

    /**
     * 回調函數
     */
    private String callback;

    //TODO:逆地理編碼參數

    /**
     * 經緯度坐標
     * 經度在前,緯度在后,經緯度間以“,”分割,經緯度小數點后不要超過 6 位
     */
    private String location;

    /**
     * 搜索半徑
     * radius取值范圍在0~3000,默認是1000。單位:米
     */
    private String radius ;

    /**
     * 返回結果控制
     * extensions 參數默認取值是 base,也就是返回基本地址信息;
     * extensions 參數取值為 all 時會返回基本地址信息、附近 POI 內容、道路信息以及道路交叉口信息。
     */
    private String extensions;

    /**
     *道路等級
     * 以下內容需要 extensions 參數為 all 時才生效。
     * 可選值:0,1
     * 當roadlevel=0時,顯示所有道路
     * 當roadlevel=1時,過濾非主干道路,僅輸出主干道路數據
     */
    private String roadlevel;

    /**
     * 是否優化POI返回順序
     * 以下內容需要 extensions 參數為 all 時才生效。
     * homeorcorp 參數的設置可以影響召回 POI 內容的排序策略,目前提供三個可選參數:
     * 0:不對召回的排序策略進行干擾。
     * 1:綜合大數據分析將居家相關的 POI 內容優先返回,即優化返回結果中 pois 字段的poi順序。
     * 2:綜合大數據分析將公司相關的 POI 內容優先返回,即優化返回結果中 pois 字段的poi順序。
     */
    private String homeorcorp;
}

 

 

package com.example.combat.gaodemapUtils.param.req;

import io.swagger.annotations.ApiModel;
import lombok.*;

/**
 * @description:
 * @author: zhucj
 * @date: 2019-11-26 11:15
 */
@Data
@ApiModel(description = "標注視圖")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Markers {

    /**
     * 可選值: small,mid,large
     */
    private String size;

    /**
     * 0x000000 black,
     * 0x008000 green,
     * 0x800080 purple,
     * 0xFFFF00 yellow,
     * 0x0000FF blue,
     * 0x808080 gray,
     * 0xffa500 orange,
     * 0xFF0000 red,
     * 0xFFFFFF white
     */
    private String color;

    /**
     * 0-9]、[A-Z]、[單個中文字] 當size為small時,圖片不展現標注名。
     * 格式 A:116.31604,39.96491
     */
    private String label;
}

 

 

package com.example.combat.gaodemapUtils.param.req;

import io.swagger.annotations.ApiModel;
import lombok.*;

/**
 * @description:
 * @author: zhucj
 * @date: 2019-11-26 11:20
 */
@Data
@ApiModel(description = "折線視圖")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Paths {

    /**
     * 線條粗細。
     * 可選值: [2,15]
     */
    private Integer weight;

    /**
     * 折線顏色。 選值范圍:[0x000000, 0xffffff]
     * 例如:
     * 0x000000 black,
     * 0x008000 green,
     * 0x800080 purple,
     * 0xFFFF00 yellow,
     * 0x0000FF blue,
     * 0x808080 gray,
     * 0xffa500 orange,
     * 0xFF0000 red,
     * 0xFFFFFF white
     */
    private String color;

    /**
     * 透明度。
     * 可選值[0,1],小數后最多2位,0表示完全透明,1表示完全不透明。
     */
    private String transparency;

    /**
     * 多邊形的填充顏色,此值不為空時折線封閉成多邊形。取值規則同color
     */
    private String fillcolor;

    /**
     * 填充面透明度。
     * 可選值[0,1],小數后最多2位,0表示完全透明,1表示完全不透明
     */
    private String fillTransparency;
}

 

 

package com.example.combat.gaodemapUtils.param.req;

import io.swagger.annotations.ApiModel;
import lombok.*;

import java.util.List;

/**
 * @description: 繪制靜態地圖請求實體
 * @author:zhucj
 * @date: 2019-11-26 10:48
 */
@Data
@ApiModel(description = "繪制靜態地圖請求視圖")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class StaticMapRequest {

    /**
     * 路線主鍵Id
     */
    private Long id;

    /**
     * 地圖中心點 中心點坐標。
     * 規則:經度和緯度用","分隔 經緯度小數點后不得超過6位。
     */
    private String location;

    /**
     * 地圖縮放級別:[1,17]
     */
    private Integer zoom;

    /**
     * 圖片寬度*圖片高度。最大值為1024*1024
     */
    private String size;

    /**
     *1:返回普通圖;
     * 2:調用高清圖,圖片高度和寬度都增加一倍,zoom也增加一倍(當zoom為最大值時,zoom不再改變)。
     */
    private Integer scale;

    /**
     * 標注
     */
    private String markers;

    /**
     * 折線
     */
    private String paths;


    /**
     * 經緯度集合
     */
    private List<String> localhosts;

}

 

 

package com.example.combat.gaodemapUtils.param;

/**
 * @description: 高德地圖服務枚舉
 * @author:zhucj
 * @date: 2019-08-02 11:25
 */
public class GaodeMapConstant {

    /**
     * 前端返回字段不匹配異常信息
     **/
    public static final String ERR_ORIGIN_PARAM_NULL = "出發點經緯度,不為空!";

    public static final String ERR_CITY_PARAM_NULL = "公交路線規划,傳入的城市名稱不為空!";


    public static final String ERR_DESTINATION_PARAM_NULL = "目的地經緯度,不為空!";

    public static final String ERR_DIRECTIONTYPE_PARAM_NULL = "傳入的規划類型,暫不支持目前只有1,2,3";

    /**
     * 地理請求地址
     */
    public static final String GEOCODE_GEO = "https://restapi.amap.com/v3/geocode/geo";


    /**
     * 逆地理請求地址
     */
    public static final String GEOCODE_REGEO = "https://restapi.amap.com/v3/geocode/regeo";

    /**
     * 步行規划路線請求地址
     */
    public static final String DIRECTION_WALKING =  "https://restapi.amap.com/v3/direction/walking";

    /**
     * 公交規划路線請求地址
     */
    public static final String DIRECTION_INTEGRATED =   "https://restapi.amap.com/v3/direction/transit/integrated";

    /**
     * 駕車路線規划
     */
    public static final String DIRECTION_DRIVING =   "https://restapi.amap.com/v3/direction/driving";

    /**
     * 貨車路線規划
     */
    public static final String DIRECTION_TRUCK =  "https://restapi.amap.com/v4/direction/truck";

    /**
     * 距離測量
     */
    public static final String DISTANCE =  "https://restapi.amap.com/v3/distance";

    /**
     * 靜態地圖
     */
    public static final String STATUC_MAP = "https://restapi.amap.com/v3/staticmap";



    /**
     * 返回狀態碼 成功
     */
    public static final String SUCCESS = "1";

    /**
     * 返回狀態碼 失敗
     */
    public static final String FAIL= "0";

    /**
     * 返回數據格式
     */
    public static final String JSON = "JSON";

    /**
     * 高德地圖key秘鑰
     */
    public static final String KEY = "key";
}

 

package com.example.combat.gaodemapUtils.param;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @description: 地址編碼返回參數
 * @author: zhucj
 * @date: 2019-11-25 18:17
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Geocodes {

    private String formatted_address;

    private String country;

    private String province;

    private String city;

    private String citycode;

    private String district;

    private String street;

    private String number;

    private String adcode;

    private String location;

    private String level;
}

 

#高德地圖配置
gaodemap:
  key: ********
  pathImg: E://upload/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM