高德地图服务端对接APIUtil

高德地图开发文档入口
info

public enum AMapAPIDevAccountInfo {

    //企业开发者key
    KEY("7beb6ccxxxxxxxxxxxx108ade8"),
    //服务ID
    SID("77XXX8");

    public final String value;

    AMapAPIDevAccountInfo(String value) {
        this.value = value;
    }
}

Util

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winsky.carhailing.common.util.PageUtil;
import com.winsky.carhailing.common.util.amap.enums.AMapAPIAddress;
import com.winsky.carhailing.common.util.amap.enums.AMapAPIDevAccountInfo;
import com.winsky.carhailing.common.util.amap.model.bo.AmapBatchBO;
import com.winsky.carhailing.common.util.amap.model.bo.AmapResPathData;
import com.winsky.carhailing.common.util.amap.model.bo.AmapResTrackingData;
import com.winsky.carhailing.common.util.amap.model.res.ReGeoRes;
import com.winsky.carhailing.common.util.amap.model.res.TrackTraceSearchRes;
import com.winsky.carhailing.common.util.amap.model.res.WeatherInfoRes;
import com.winsky.carhailing.common.util.gps.CoordinateConversionUtil;
import com.winsky.carhailing.common.util.gps.GPSPoint;
import com.winsky.carhailing.common.util.httpClient.HttpClientUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.*;

/**
 * 高德API  https://lbs.amap.com/api/webservice/guide/api/direction
 * @date create in
 */
public class AmapApi {
    private static final Logger logger = LoggerFactory.getLogger(AmapApi.class);

    /**
     * 获取驾车规划 -- 起点与终点的驾车规划
     */
    public static AmapResPathData getDriverNavPathData(GPSPoint startPoint, GPSPoint endPoint) {
        AmapResPathData amapResPathData = new AmapResPathData();
        try {
            Map filter = new HashMap();
            //起始经纬度
            filter.put("origin", startPoint.getLng() + "," + startPoint.getLat());
            filter.put("destination", endPoint.getLng() + "," + endPoint.getLat());
            //駕車選擇策略 2:距离优先,不考虑路况,仅走距离最短的路线,但是可能存在穿越小路/小区的情况
            filter.put("strategy", "2");
            //返回结果控制 base:返回基本信息;all:返回全部信息
            filter.put("extensions", "base");
            //返回数据格式类型 可选值:JSON,XML
            filter.put("output", "JSON");
            //高德用户唯一标识 用户在高德地图官网申请
            filter.put("key", AMapAPIDevAccountInfo.KEY.value);
            //https://lbs.amap.com/api/webservice/guide/api/direction 驾车路径规划接口
            String response = HttpClientUtil.getInstance().sendHttpPost(AMapAPIAddress.DRIVER_NAV_API_URL.ADDRESS, filter);
            //高德放回的json
            JSONObject jb = JSON.parseObject(response);
            //结果状态值,0:请求失败;1:请求成功
            if (jb.getIntValue("status") == 1) {
                //route 驾车路径规划信息列表
                if (null != jb && jb.getJSONObject("route") != null) {
                    //paths 	驾车换乘方案 distance :行驶距离 单位:米; duration :	预计行驶时间 单位:秒
                    amapResPathData = jb.getJSONObject("route").getJSONArray("paths").getJSONObject(0).toJavaObject(AmapResPathData.class);
                } else {
                    amapResPathData.setDistance(0L);
                    amapResPathData.setDuration(0L);
                }
            } else {
                logger.error("高德接口请求失败:{}", response);
            }

        } catch (Exception e) {
            logger.error("获取驾车规划", e);
        }
        return amapResPathData;
    }


    /**
     * 获取拼车订单原始驾车规划
     * 订单的起点终点,剩余进行中行程的未接到的起点和未送到的目的地,与订单起点直线距离排序,在起点终点距离范围内的是途经点
     */
    public static AmapResPathData getDriverNavPathData(GPSPoint startPoint, GPSPoint endPoint, List<GPSPoint> waypoints) {
        AmapResPathData amapResPathData = new AmapResPathData();
        try {
            Map filter = new HashMap();
            filter.put("origin", startPoint.getLng() + "," + startPoint.getLat());
            filter.put("extensions", "base");
            filter.put("output", "JSON");
            //排序
            gpsPointsSort(startPoint, waypoints);
            StringBuilder waypointsVal = new StringBuilder();
            StringBuilder endpointVal = new StringBuilder();
            Iterator<GPSPoint> itr = waypoints.iterator();
            Double distance = CoordinateConversionUtil.getDistance(startPoint.getLng(), startPoint.getLat(), endPoint.getLng(), endPoint.getLat());
            while (itr.hasNext()) {
                GPSPoint point = itr.next();
                //重复的点去除
                if(startPoint.equals(point)){
                    continue;
                }
                //按距离排序,途经点算到订单重点为止
                if(endPoint.equals(point)){
                    break;
                }
                //超出起点终点距离范围内的去除
//                if(distance<CoordinateConversionUtil.getDistance(startPoint.getLng(),startPoint.getLat(),point.getLng(),point.getLat())
//                        || distance<CoordinateConversionUtil.getDistance(endPoint.getLng(),endPoint.getLat(),point.getLng(),point.getLat())){
//                    continue;
//                }
                if(itr.hasNext()){
                    waypointsVal.append(point.getLng() + "," + point.getLat()).append(";");
                } else {
                    endpointVal.append(point.getLng() + "," + point.getLat());
                }
            }
            filter.put("waypoints", waypointsVal.toString());
            filter.put("destination", endPoint.getLng() + "," + endPoint.getLat());
            filter.put("key", AMapAPIDevAccountInfo.KEY.value);
            String response = HttpClientUtil.getInstance().sendHttpPost(AMapAPIAddress.DRIVER_NAV_API_URL.ADDRESS, filter);
            JSONObject jb = JSON.parseObject(response);
            if (jb.getIntValue("status") == 1) {
                if (null != jb && jb.getJSONObject("route") != null) {
                    amapResPathData = jb.getJSONObject("route").getJSONArray("paths").getJSONObject(0).toJavaObject(AmapResPathData.class);
                } else {
                    amapResPathData.setDistance(0L);
                    amapResPathData.setDuration(0L);
                }
            } else {
                logger.error("高德接口请求失败:{}", response);
            }

        } catch (Exception e) {
            logger.error("获取驾车规划", e);
        }
        return amapResPathData;
    }


    /**
     * 与起点直线距离由近到远排序
     *
     * @param startPoint
     * @param waypoints
     * @return
     */
    public static List<GPSPoint> gpsPointsSort(GPSPoint startPoint, List<GPSPoint> waypoints) {
        Collections.sort(waypoints, new Comparator<GPSPoint>() {
            @Override
            public int compare(GPSPoint o1, GPSPoint o2) {
                Double distance1 = CoordinateConversionUtil.getDistance(startPoint.getLng(), startPoint.getLat(), o1.getLng(), o1.getLat());
                Double distance2 = CoordinateConversionUtil.getDistance(startPoint.getLng(), startPoint.getLat(), o2.getLng(), o2.getLat());
                return distance1.compareTo(distance2);
            }
        });
        return waypoints;
    }

    /**
     * 轨迹纠偏接口,获取驾驶轨迹路线,里程
     */
    public static AmapResTrackingData getDrivingTracks(List<Map> locDates) {
        AmapResTrackingData resTrackingData = new AmapResTrackingData();
        try {
            JSONArray jsonArray = new JSONArray();
            locDates.stream().forEach(locDate -> {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("x", locDate.get("lgt"));           //经度
                jsonObject.put("y", locDate.get("lat"));           //纬度
                jsonObject.put("ag", locDate.get("direction"));    //角度
                jsonObject.put("tm", locDate.get("time"));         //时间
                jsonObject.put("sp", locDate.get("speed"));        //速度
                jsonArray.add(jsonObject);
            });

            String response = HttpClientUtil.getInstance().postJSON(AMapAPIAddress.GRASP_ROAD_API_URL.ADDRESS + "?key=" + AMapAPIDevAccountInfo.KEY.value, jsonArray.toJSONString());

            JSONObject jb = JSON.parseObject(response);
            if (null != jb && jb.getJSONObject("data") != null) {
                resTrackingData = jb.getJSONObject("data").getJSONArray("distance").getJSONObject(0).toJavaObject(AmapResTrackingData.class);
            } else {
                logger.error("高德接口请求抓路失败:{}", response);
                resTrackingData.setDistance(0L);
            }
//              resTrackingData.setPoints(locDates);
        } catch (Exception e) {
            logger.error("获取轨迹纠偏", e);
        }

        return resTrackingData;
    }

    /**
     * 批量获取驾车规划
     */
    public static List<AmapResPathData> getPathData(List<AmapBatchBO> batchBOS) {
        List<AmapResPathData> amapResPathDataList = new ArrayList<>();
        try {
            JSONObject batchReq = new JSONObject();
            int count = batchBOS.size();
            int index = 0;
            int step = 20;
            while (index < count) {
                List<AmapBatchBO> temp = batchBOS.subList(index, index + step <= count ? index + step : count);
                batchReq.put("ops", temp);
                String res = HttpClientUtil.getInstance().postJSON(AMapAPIAddress.BATCH_API_URL.ADDRESS, batchReq.toJSONString());
                JSONArray jsonArray = JSONObject.parseArray(res);
                Iterator itr = jsonArray.iterator();
                while (itr.hasNext()) {
                    JSONObject jb = ((JSONObject) itr.next()).getJSONObject("body");
                    if (null != jb && jb.getJSONObject("route") != null) {
                        AmapResPathData amapResPathData = jb.getJSONObject("route").getJSONArray("paths").getJSONObject(0).toJavaObject(AmapResPathData.class);
                        amapResPathDataList.add(amapResPathData);
                    } else {
                        AmapResPathData amapResPathData = new AmapResPathData();
                        amapResPathData.setDistance(0L);
                        amapResPathData.setDuration(0L);
                        amapResPathDataList.add(amapResPathData);
                    }
                }
                index += step;
            }

        } catch (Exception e) {
            logger.error("批量获取驾车规划", e);
        }
        return amapResPathDataList;
    }

    /**
     * 创建终端
     *
     * @param key   请求服务权限标识
     * @param sid   服务的唯一编号
     * @param name  终端名称
     * @param desc  终端描述
     * @param props 自定义字段
     */
    public static String terminalAdd(String key, String sid, String name, String desc, String props) {
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        params.put("sid", sid);
        params.put("name", name);
        params.put("desc", desc);
        params.put("props", props);
        return HttpClientUtil.getInstance().post(AMapAPIAddress.TERMINAL_ADD.ADDRESS, params);
    }

    /**
     * 创建轨迹, 创建一条轨迹,一个终端下最多可创建500000条轨迹。
     *
     * @param key 请求服务权限标识
     * @param sid 查询的服务ID
     * @param tid 设备唯一编号
     */
    public static String trackTraceAdd(String key, String sid, String tid) {
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        params.put("sid", sid);
        params.put("tid", tid);
        return HttpClientUtil.getInstance().post(AMapAPIAddress.TRACK_TRACE_ADD.ADDRESS, params);
    }

    /**
     * 获取轨迹全部数据
     *
     * @param tid       设备唯一编号(即t_car表里的Trid)
     * @param trid      轨迹唯一编号(即t_order表里的Trid)
     * @param startTime 起始时间, Unix时间戳(轨迹点的定位时间),需要精准到毫秒
     * @param endTime   结束时间, Unix时间戳(轨迹点的定位时间),需要精准到毫秒
     * @return
     */
    public static TrackTraceSearchRes.Track getAllTrackTrace(String tid, String trid, Long startTime, Long endTime) {
        int pageNum = 1;
        int pageSize = 500;
        TrackTraceSearchRes res = trackTraceSearch(tid, trid, startTime, endTime, null, null, null, null, pageNum, pageSize);
        if (null == res || null == res.getData()) {
            logger.error("未查询到轨迹数据");
            return null;
        } else {
            TrackTraceSearchRes.Track track = res.getData().getTracks().get(0);
            if (track != null && track.getCounts() > 0) {
                int totalPage = PageUtil.getTotalPage(pageSize, track.getCounts());
                for (int i = 1; i < totalPage; i++) {
                    ++pageNum;
                    TrackTraceSearchRes res1 = trackTraceSearch(tid, trid, startTime, endTime, null, null, null, null, pageNum, pageSize);
                    if (null == res1 || null == res1.getData()) {
                        break;
                    } else {
                        TrackTraceSearchRes.Track track1 = res1.getData().getTracks().get(0);
                        track.getPoints().addAll(track1.getPoints());
                    }
                }
            }
            return track;
        }
    }


    /**
     * 查询轨迹信息(里程、时间等)
     *
     * @param key        请求服务权限标识
     * @param sid        查询的服务ID
     * @param tid        设备唯一编号
     * @param trid       轨迹唯一编号
     * @param startTime  起始时间, Unix时间戳(轨迹点的定位时间),需要精准到毫秒
     * @param endTime    结束时间, Unix时间戳(轨迹点的定位时间),需要精准到毫秒, 结束时间不能大于当前时间,且距离开始时间不能超过24小时。 若轨迹较多,建议将时间段进行拆分。
     * @param correction 对轨迹进行处理
     * @param recoup     对轨迹进行补点  缺省值0, 0:代表用直线连接方式进行补点计算; 1:代表用correction的mode方式进行补点计算,当前只开放了driving。
     * @param gap        补点间距  缺省值为5公里,最小50米,最大10公里,单位:米。
     * @param isPoints   是否返回轨迹点信息 默认为返回(1),可以设置为不返回(0)
     * @param page       查询页数  缺省值1
     * @param pageSize   每页点数  缺省值20,当page=1的时候起点、终点的个数不计算在内,pagesize最大值为1000。
     */
    public static TrackTraceSearchRes trackTraceSearch(String tid, String trid, Long startTime, Long endTime, String correction,
                                                       Integer recoup, Integer gap, Integer isPoints, Integer page, Integer pageSize) {
        Map<String, Object> params = new HashMap<>();
        params.put("key", AMapAPIDevAccountInfo.KEY.value);
        params.put("sid", AMapAPIDevAccountInfo.SID.value);
        params.put("tid", tid);
        params.put("trid", trid);
        params.put("starttime", startTime);
        params.put("endtime", endTime);
        params.put("correction", correction);
        params.put("recoup", recoup);
        params.put("gap", gap);
        params.put("ispoints", isPoints);
        params.put("page", page);
        params.put("pagesize", pageSize);
        String result = HttpClientUtil.getInstance().get(AMapAPIAddress.TRACK_TRACE_SEARCH.ADDRESS, params);
        return JSONObject.parseObject(result, TrackTraceSearchRes.class);
    }

    /**
     * 天气接口 https://lbs.amap.com/api/webservice/guide/tools/weather-code/
     *
     * @param key        请求服务权限标识
     * @param city       城市编码    输入城市的adcode,adcode信息可参考城市编码表
     * @param extensions 气象类型    可选值:base/all base:返回实况天气 all:返回预报天气
     * @param output     返回格式    可选值:JSON(默认),XML
     */
    public static WeatherInfoRes getWeatherInfo(String key, String city, String extensions, String output) {
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        params.put("city", city);
        params.put("extensions", extensions);
        params.put("output", output);
        String result = HttpClientUtil.getInstance().get(AMapAPIAddress.WEATHER_INFO.ADDRESS, params);
        return JSONObject.parseObject(result, WeatherInfoRes.class);
    }

    /**
     * 逆地理编码
     *
     * @param key      高德Key
     * @param location 经纬度坐标 传入内容规则:经度在前,纬度在后,经纬度间以“,”分割,经纬度小数点后不要超过 6 位。如果需要解析多个经纬度的话,请用"|"进行间隔,并且将 batch 参数设置为 true,最多支持传入 20 对坐标点。每对点坐标之间用"|"分割。
     * @param other    其他非必填参数,参考文档:https://lbs.amap.com/api/webservice/guide/api/georegeo
     * @return
     */
    public static ReGeoRes getLocationReGeo(String key, String location, Map<String, Object> other) {
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);
        params.put("location", location);
        if (null != other) {
            other.forEach((keys, values) -> {
                params.put(keys, values);
            });
        }
        String result = HttpClientUtil.getInstance().get(AMapAPIAddress.GEOCODE_REGEO_API_URL.ADDRESS, params);
        return JSONObject.parseObject(result, ReGeoRes.class);
    }

    public static void main(String[] args) {
        GPSPoint a1 = new GPSPoint(Double.valueOf("117.130525"), Double.valueOf("29.258724"));
        GPSPoint a2 = new GPSPoint(Double.valueOf("117.214981"), Double.valueOf("29.293871"));

        GPSPoint b1 = new GPSPoint(Double.valueOf("117.1304215"), Double.valueOf("29.2585618"));
        GPSPoint b2 = new GPSPoint(Double.valueOf("117.216467"), Double.valueOf("29.289589"));
        List<GPSPoint> waypoints = new ArrayList<>();
        waypoints.add(a1);
        waypoints.add(a2);
        waypoints.add(b1);
        waypoints.add(b2);
        //自己加入行程后绕路里程
        AmapResPathData beforeJoin = AmapApi.getDriverNavPathData(a1,a2);
        AmapResPathData afterJoin = AmapApi.getDriverNavPathData(a1,a2, waypoints);
        BigDecimal detourMileagePec= BigDecimal.valueOf(afterJoin.getDistance() - beforeJoin.getDistance()).divide(BigDecimal.valueOf(beforeJoin.getDistance()),2,BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
        if (detourMileagePec.compareTo(BigDecimal.ZERO)==-1 ||detourMileagePec.compareTo(BigDecimal.valueOf(20))==1) {
            System.out.println("false");
            return;
        }
        //加入行程后对其他乘客的绕路里程
            beforeJoin = AmapApi.getDriverNavPathData(b1,b2);
            afterJoin = AmapApi.getDriverNavPathData(b1,b2, waypoints);
            if (BigDecimal.valueOf(afterJoin.getDistance() - beforeJoin.getDistance()).divide(BigDecimal.valueOf(beforeJoin.getDistance()),2,BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).compareTo(BigDecimal.valueOf(20))==1) {
                System.out.println("false1");
                return;
            }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值