API开发实战----调用高德API实现轨迹纠偏里程校准

一、前言

在一些和车辆设备有关的项目中需要用到回显车辆的运行轨迹、或者是显示车辆的详细信息(比如里程值、速度等等),但是有些时候,安装在车辆上的GPS上报设备上报的数据并不是百分之百的精准,可能的情况有:个别点的经纬度有偏差(并没有在道路上),车辆的里程值有误等等。本实例要解决的就是车辆的轨迹点偏移和里程值的更新校准。

二、 总体思路

在了解实现流程之前,需要对几个属性进行说明。
设备号:安装在车辆上的设备的编号,也是该车辆的唯一标识。
历史轨迹文件:每辆车每天生成的一个文件名为设备号的txt文件,文件中每一行就是一个上报点位,包括速度、里程、方向、经纬度、点火状态等等数据。当车辆上的设备上报数据时,该条数据会增量更新到轨迹文件中。因此,轨迹文件中储存的就是车辆设备上报的原始点位。
每日里程表:记录一天中行驶车辆的总里程总时长等等信息,只要车辆行驶了就会有数据。

1.轨迹纠偏实现流程

1)通过每日里程表获取指定日期行驶车辆的设备号列表。
2)通过设备号列表获取到历史轨迹点位的集合
3)查询此设备号在高德猎鹰平台上的终端号,如果没有就注册该设备并获取终端号
4)通过获取到的终端号在该终端下创建轨迹,获取轨迹ID
5)上传该设备当天的所有上报点位到新创建的轨迹ID下,由于高德平台限制,一次最多只能传100个点,所以需要拆分点集合,分批次上传
6)上传完成后调用轨迹查询接口,查询该车的轨迹信息,查询时传入纠偏的具体参数,返回的结果便是纠偏之后的结果。
7)解析并保存数据,并备份源文件

2.里程校准实现流程

第一部分:先将历史轨迹中的点调一遍纠偏服务,去飘点,减少里程计算的误差。
1)通过每日里程表获取指定日期行驶车辆的设备号列表。
2)通过设备号列表获取到历史轨迹点位的集合
3)查询此设备号在高德猎鹰平台上的终端号,如果没有就注册该设备并获取终端号
4)通过获取到的终端号在该终端下创建轨迹,获取轨迹ID
5)上传该设备当天的所有上报点位到新创建的轨迹ID下,由于高德平台限制,一次最多只能传100个点,所以需要拆分点集合,分批次上传
6)上传完成后调用轨迹查询接口,查询该车的轨迹信息,查询时传入纠偏的具体参数,返回的结果便是纠偏之后的结果。
7)解析数据,并将结果集进行里程计算。
第二部分:拿到纠偏之后的数据,计算里程
1)调用高德路径规划,由于高德API限制,一次最多只能计算18个点,所以需要将点拆分后,分批次调用,累计每次请求的结果之和就是总里程值。
2)把算出来的里程值更新到每日里程表中供项目中其他功能使用。

三、高德API链接

轨迹纠偏:https://lbs.amap.com/api/track/lieying-kaifa/api/grasproad
路径规划:https://lbs.amap.com/api/webservice/guide/api/direction/

四、API实战解析

由于里程校准中包含了轨迹纠偏的步骤,所以重点举例里程校准功能

1.原始数据格式示例

{“acc”:1,“alitiude”:0,“azimuth”:0,“badDriving”:"",“battery”:0,“carId”:“4028814195956584b20164698a18a40761”,“carTel”:"",“deviceType”:"",“eventType”:"",“heightOfWater”:0,“isFloat”:0,“lac”:"",“lat”:40.383385,“lng”:115.94770799999999,“lowPower”:0,“mileage”:84779.8,“oil”:0,“oilDianZu”:0,“reportId”:"",“reportType”:"",“speed”:55.6,“status”:"",“tc”:“0123456789”,“temperature”:0,“time”:1581722832000,“working”:0}

2.部分参考源码

里程校准定时器:

package com.web.job;

import com.alibaba.fastjson.JSONObject;
import com.sdk.container.SpringContextUtil;
import com.socket.bean.TerminalHistorySpot;
import com.socket.utils.OtherUtils;
import com.web.gps.everydayMileage.entity.EverydayMileage;
import com.web.gps.everydayMileage.service.EverydayMileageService;
import com.web.gps.everydayMileage.service.RoadService;
import com.web.gps.lushu.service.LushuService;
import com.web.utils.ConstantUtil;
import com.web.utils.DateUtil;
import com.web.utils.MileageCalibrationUtil;
import com.web.utils.TerminalHistoryUtil;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/*
* 调用高德路径规划--路径规划(驾车) 校准历史轨迹文件中的里程数
*	总体流程:通过前一天的历史轨迹计算出总里程、总时长、有效里程、有效时长。更新到每日里程表中。
	准备工作:先把历史轨迹的点调一遍纠偏服务,去飘点。
	API:调用驾车规划API,每十八个点计算首尾两点的里程。(分组,每组十八个点)
	筛选条件:
			总里程:从速度不为0 的点作为第一个点(每天的第一个点独立,从第一个速度不为0 的点开始。)开始计算到最后一个点。中间速度为0 的点里程自然也不变。工作状态不限。
			总时长:除去所有速度为0的点的总时长。须除去速度为0的点的时间!
			有效里程:总里程范围内,工作状态为1 的点(连续三个以上)的距离 之和。
			有效时长:总里程范围内,工作状态为1 的点(连续三个以上)的时间 之和。

* 每天凌晨执行,获取前一天所有上报车辆的历史轨迹信息,进行里程校准
*
* key---用户唯一标识---用户在高德地图官网申请
* origin--出发点--传三个点,用来计算车头,规划时以最后一个点为起始点.经纬度小数点后不得超过6位。格式为x1,y1|x2,y2|x3,y3。
* destination--目的地--经度在前,纬度在后,经度和纬度用","分割,经纬度小数点后不得超过6位
* strategy--规划策略--推荐:0,速度优先,不考虑当时路况,此路线不一定距离最短
* */
public class MileageCalibrationJob implements Job{
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    private SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
    //日志对象
    private static final Logger log = LoggerFactory.getLogger(MileageCalibrationJob.class);
    //定义获取历史轨迹源数据的对象,第一个String为设备号,第二个String为时间
    Map<String, Map<String, List<TerminalHistorySpot>>> tcMap = new HashMap<String, Map<String, List<TerminalHistorySpot>>>();
    //获取调用服务所需的key,由用户申请
    private static final String GAODE_USER_KEY= "用户申请的kEY";
    /*调用已有Service中的方法,获取历史轨迹数据*/
    private LushuService lushuService;
    private EverydayMileageService everydayMileageService;
    private RoadService roadService;
    //构造方法实例化Service
    public MileageCalibrationJob(){
        super();
        lushuService = (LushuService) SpringContextUtil.getBean("lushuService");
        everydayMileageService = (EverydayMileageService) SpringContextUtil.getBean("everydayMileageService");
        roadService = (RoadService) SpringContextUtil.getBean("roadService");
    }
    /*
    * 定时器执行的方法
    * */
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        //查询每日车辆里程信息表,获取前一天上传过GPS的车辆里程信息
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("day", DateUtil.getPastDate(1));
        List<EverydayMileage> everydayList = everydayMileageService.findList(param, null);
        //查询每日车辆里程信息表,获取前一天上传过GPS的车辆里程信息END获取车辆的设备号集合
		int size = everydayList.size();
		String[] termCodes= new String[size];
		for(int i=0;i<size;i++){
			termCodes[i]=everydayList.get(i).getTermCode();
		}
        //获取车辆的设备号集合END
        //设定查询历史轨迹的始末时间BEGIN
        Date before = DateUtil.getdateByStringFormat(DateUtil.getPastDate(1) + " 00:00:00", ConstantUtil.YYYYMMDD_TIME);
        Date now = DateUtil.getdateByStringFormat(DateUtil.getPastDate(1) + " 23:59:59", ConstantUtil.YYYYMMDD_TIME);
        //设定查询历史轨迹的始末时间END

        /*---------------------------------------------------------testStart----------------*/
        //测试数据先写死
        /*String[] termCodes= new String[1];
        termCodes[0]="01216400739";
        Date before = new Date();
        Date now = new Date();
        try {
            before = sdf.parse("2019-12-10 00:00:00");
            now = sdf.parse("2019-12-10 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }*/
        /*--------------------testEnd--------------------------------------------------*/
        //获取前一天的历史轨迹存放路径
        String path = OtherUtils.gpsHistorySpot(before);
        //查询当天所有设备在该时间段的历史轨迹信息
        tcMap = roadService.queryHistoricalTrajectory(termCodes,before,now,"gaode");//不进行飘点过滤的方法
        if(tcMap!=null){
            //hmap,key为设备号tc,value为Map<String, List<TerminalHistorySpot>>
            for (Map.Entry<String, Map<String, List<TerminalHistorySpot>>> hmap : tcMap.entrySet()) {
                //如果设备号不为空,遍历此设备下的历史轨迹
                if(hmap.getKey()!=null){
                    /*查询此设备在猎鹰平台上的终端号,name为设备号*/
                    Integer Tid = TerminalHistoryUtil.queryTidByTname(hmap.getKey());
                    //如果该设备没有注册,就先注册该设备
                    if(Tid == -1){
                        log.info("当前设备未在猎鹰平台注册,无终端信息,设备号:"+ hmap.getKey());
                        List trCodes = new ArrayList();
                        trCodes.add(hmap.getKey());
                        boolean state = TerminalHistoryUtil.initTerminal(TerminalHistoryUtil.sid,trCodes);
                        if (state == true){
                            log.info("猎鹰平台注册设备成功!设备号:"+ hmap.getKey());
                            Tid = TerminalHistoryUtil.queryTidByTname(hmap.getKey());
                        }else {
                            log.info("猎鹰平台注册设备失败!设备号:"+ hmap.getKey());
                        }
                    }
                    if (Tid != -1){
                        /*创建轨迹,拿到轨迹ID(单车)*/
                        Integer traceId = TerminalHistoryUtil.createTrace(Tid);
                        //listEntry,key为时间,value为List<TerminalHistorySpot> 一天的
                        if(hmap.getValue().size() > 0){
                            for (Map.Entry<String, List<TerminalHistorySpot>> listEntry : hmap.getValue().entrySet()) {
                                //获取到历史轨迹数据
                                List<TerminalHistorySpot> list = listEntry.getValue();
                                if (list != null && list.size() > 0){
                                    //总里程
                                    Double dayKM = 0.0d;
                                    //有效里程
                                    Double workKm = 0.0d;
                                    //先通过原始数据算总时长和有效时长
                                    //总时长
                                    Long totalSecond = MileageCalibrationUtil.countTotalityTime(list);
                                    //有效时长
                                    Long workSecond = MileageCalibrationUtil.countWorkTime(list);
                                    //去除速度为0的点
                                    List<TerminalHistorySpot> clearlist = MileageCalibrationUtil.clearZero(list);
                                    //有效里程---补点
                                    //筛选出有效里程的点
                                    List<List<TerminalHistorySpot>> workPoint = MileageCalibrationUtil.getWorkPoint(clearlist);
                                    for (List<TerminalHistorySpot> terminalHistorySpots : workPoint) {
                                        if (terminalHistorySpots.size() > 3){
                                            /*创建轨迹,拿到轨迹ID(单车)*/
                                            Integer traceIdforwork = TerminalHistoryUtil.createTrace(Tid);
                                            //如果一个片段有三条以上,就纠偏补点
                                            ArrayList<JSONObject> newWorkPoint = MileageCalibrationUtil.getAllPoint(Tid, traceIdforwork, before, now, terminalHistorySpots);
                                            if (newWorkPoint != null){
                                                //转换为pojo对象集合
                                                List<TerminalHistorySpot> worklist = TerminalHistoryUtil.convertResult(newWorkPoint);
                                                //查询里程,并存
                                                workKm += MileageCalibrationUtil.countDayKM(worklist);
                                            }
                                            TerminalHistoryUtil.deleteTrace(Tid, traceIdforwork);
                                        }
                                    }
                                    //总里程---补点
                                    ArrayList<JSONObject> result = MileageCalibrationUtil.getAllPoint(Tid,traceId,before,now,clearlist);
                                    TerminalHistoryUtil.deleteTrace(Tid, traceId);
                                    if (result != null && result.size() > 0){
                                        //先获取返回的状态,判断是否正常调用接口
                                        JSONObject state = (JSONObject)result.get(0);
                                        String errcode = state.getString("errcode");
                                        //返回状态正常
                                        if(errcode.equals("10000")){
                                            //解析并获取返回的数据
                                            List<TerminalHistorySpot> terminalHistorySpots = TerminalHistoryUtil.convertResult(result);
                                            //算总里程
                                            dayKM = MileageCalibrationUtil.countDayKM(terminalHistorySpots);
                                        }
                                    }
                                    log.debug("里程信息查询完成!");

                                    Map params = new HashMap<String,String>();
                                    params.put("termCode",hmap.getKey());
                                    params.put("day",ymd.format(before));
                                    //查询每日里程表中信息,单条
                                    List<EverydayMileage> everydayMileages = everydayMileageService.findList(params, null);
                                    //查询备份表信息,单条
                                    List<EverydayMileage> everydayMileagesCopy = everydayMileageService.queryListForCopy(params);
                                    if (everydayMileages != null && everydayMileages.size() > 0){
                                        //判断备份表中是否有该车的记录,如果有就更新数据,没有就新增
                                        if (everydayMileagesCopy != null && everydayMileagesCopy.size() > 0){
                                            everydayMileageService.updateForCopy(everydayMileages.get(0));
                                        }else {
                                            everydayMileageService.saveForCopy(everydayMileages.get(0));
                                        }

                                        //把算出来的里程数据更新到每日里程表中
                                        EverydayMileage everydayMileage = everydayMileages.get(0);
                                        //把四个属性值存到新表
                                        everydayMileage.setDayKm(dayKM/1000d);
                                        everydayMileage.setTotalSecond(Integer.parseInt(String.valueOf(totalSecond)));
                                        everydayMileage.setWorkKm(workKm/1000d);
                                        everydayMileage.setWorkSecond(Integer.parseInt(String.valueOf(workSecond)));
                                        //更新每日里程表
                                        everydayMileageService.update(everydayMileage);
                                    }
                                }else {
                                    log.error("当前设备无历史轨迹信息,设备号:"+ hmap.getKey()+"---");
                                }
                            }
                        }else {
                            log.error("当前设备无历史轨迹信息,设备号:"+ hmap.getKey()+"---");
                        }
                    }
                }else{
                    log.error("当前设备为null,无历史轨迹信息!");
                }
            }
        }else{
            log.error("获取历史轨迹数据失败!");
        }
    }
}

里程校准工具类:

package com.web.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.socket.bean.Point;
import com.socket.bean.TerminalHistorySpot;
import com.socket.utils.CoordTransformUtils;
import com.web.gps.everydayMileage.entity.HttpClient;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.*;
import java.util.Map.Entry;

/**
 * 里程校准相关工具类
 */
public class MileageCalibrationUtil {
    private static final Logger log = LoggerFactory.getLogger(MileageCalibrationUtil.class);
    private  static final String Key = "用户申请的KEY";
    //路径规划距离测量地址
    private  static final String queryMileageURL = "https://restapi.amap.com/v3/distance";
    //路径规划API地址
    private  static final String drivingURL = "https://restapi.amap.com/v3/direction/driving";


    /*
    * 通过原始数据计算总时长
    * 返回单位--秒
    * */
    public static Long countTotalityTime(List<TerminalHistorySpot> list){
        //总时长变量(秒)
        Long totalSecond = 0l;
        //中间变量
        Long tempSecond = 0l;
        //遍历原始历史轨迹数据
        for (int i = 0;i < list.size();i++){
            if (list.get(i).getSpeed() != 0f){
                if (tempSecond != 0l){
                    totalSecond += list.get(i).getTime() - tempSecond;
                }
            }
            tempSecond = list.get(i).getTime();
        }
        return totalSecond/1000l;
    }

    /*
    * 通过原始数据计算有效时长
    * 返回单位--秒
    * */
    public static Long countWorkTime(List<TerminalHistorySpot> list){
        //有效时长变量
        Long workSecond = 0l;
        //有效点集合
        List<List<TerminalHistorySpot>> workList = getWorkPointforyuanlist(list);
        //参照变量
        Long tempTime = 0l;

        //遍历有效点集合
        for (List<TerminalHistorySpot> terminalHistorySpots : workList) {
            //如果集合长度大于3,就计算时间差
            if (terminalHistorySpots.size() > 3){
                for (int i = 0;i < terminalHistorySpots.size();i++) {
                    //第一次先存参照变量
                    if (i == 0){
                        tempTime = terminalHistorySpots.get(i).getTime();
                    }else {
                        if (tempTime != 0l){
                            //计算后更新参照时间变量
                            workSecond += terminalHistorySpots.get(i).getTime() - tempTime;
                        }
                        tempTime = terminalHistorySpots.get(i).getTime();
                    }
                }
            }
        }
        return workSecond/1000l;
    }


    /*
    * 封装纠偏上传点位和查询点位操作
    * */
    public static ArrayList<JSONObject> getAllPoint(Integer Tid, Integer traceId, Date before, Date now, List<TerminalHistorySpot> clearlist){
        /*给数据分页,最多100条数据*/
        List<List<TerminalHistorySpot>> partition = Lists.partition(clearlist, 100);
        //test---记录重复时间戳
        HashMap<String,String> localtimemap = new HashMap<String, String>();
        //上传轨迹信息,纠偏
        for (List<TerminalHistorySpot> terminalHistorySpots : partition) {
            //根据轨迹ID上传一辆车当天的轨迹信息,一次100条
            TerminalHistoryUtil.uploadTraceData(Tid,traceId,terminalHistorySpots,localtimemap);
        }
        //调用轨迹查询接口,查询该车的轨迹信息,并设置纠偏粒度
        ArrayList<JSONObject> result = null;
        try {
            result = TerminalHistoryUtil.searchTracksByTrid(Tid, traceId, before.getTime(), now.getTime());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return result;
    }

    /*
    * 筛选出有效里程的坐标点
    * list:除0后的坐标集
    * */
    public static List<List<TerminalHistorySpot>> getWorkPoint(List<TerminalHistorySpot> list){
        //有效点集合
        List<List<TerminalHistorySpot>> workList = new ArrayList<List<TerminalHistorySpot>>();
        //有效点子集
        List<TerminalHistorySpot> templist = new ArrayList<TerminalHistorySpot>();
        //遍历源数据,筛选出工作状态的点
        for(int i = 0;i < list.size();i++){
            //工作状态
            if (list.get(i).getWorking() == 1 && list.get(i).getAcc() == 1){
                templist.add(list.get(i));
            }else if (templist.size() > 3){
                //工作状态断了就存一次
                workList.add(templist);
                templist = new ArrayList<TerminalHistorySpot>();
            }else {
                templist = new ArrayList<TerminalHistorySpot>();
            }
            //防止最后一个点也是工作状态
            if (i == list.size() - 1 && templist.size() > 0){
                workList.add(templist);
            }
        }
        return workList;
    }
    /*
     * 筛选出有效里程的坐标点
     * */
    public static List<List<TerminalHistorySpot>> getWorkPointforyuanlist(List<TerminalHistorySpot> list){
        //有效点集合
        List<List<TerminalHistorySpot>> workList = new ArrayList<List<TerminalHistorySpot>>();
        //有效点子集
        List<TerminalHistorySpot> templist = new ArrayList<TerminalHistorySpot>();
        //遍历源数据,筛选出工作状态的点
        for(int i = 0;i < list.size();i++){
            //工作状态
            if (list.get(i).getSpeed() != 0f && list.get(i).getWorking() == 1 && list.get(i).getAcc() == 1){
                templist.add(list.get(i));
            }else if (templist.size() > 3){
                //工作状态断了就存一次
                workList.add(templist);
                templist = new ArrayList<TerminalHistorySpot>();
            }else {
                templist = new ArrayList<TerminalHistorySpot>();
            }
            //防止最后一个点也是工作状态
            if (i == list.size() - 1 && templist.size() > 0){
                workList.add(templist);
            }
        }
        return workList;
    }

    /*
    * 计算里程
    * list --- 纠偏后的点集合
    * */
    public static Double countDayKM(List<TerminalHistorySpot> list){
        //总里程
        Double dayKm = 0.0d;
        /*给数据分页*/
        List<List<TerminalHistorySpot>> partition = Lists.partition(list, 18);
        for (List<TerminalHistorySpot> terminalHistorySpots : partition) {
            //get请求参数
            StringBuffer param = new StringBuffer();
            param.append("key="+Key);
            param.append("&nosteps=1");
            if (terminalHistorySpots.size() > 3){
                //遍历分页后的list,查询里程
                for (int i = 0;i < terminalHistorySpots.size();i++){
                    if (i == 0){
                        param.append("&origin="+ String.format("%.6f",terminalHistorySpots.get(i).getLng()) + "," + String.format("%.6f",terminalHistorySpots.get(i).getLat()));
                    }else if (i == terminalHistorySpots.size() - 1){
                        param.append("&destination="+ String.format("%.6f",terminalHistorySpots.get(i).getLng()) + "," + String.format("%.6f",terminalHistorySpots.get(i).getLat()));
                    }else {
                        param.append("&waypoints="+ String.format("%.6f",terminalHistorySpots.get(i).getLng()) + "," + String.format("%.6f",terminalHistorySpots.get(i).getLat()));
                        //如果不是倒数第二个就加分号
                        if (i != terminalHistorySpots.size() - 2){
                            param.append(";");
                        }
                    }
                }
                //每18个点算一次
                String result = HttpClient.sendRequest(drivingURL, param.toString(), HttpClient.METHOD_GET);
                //解析结果并保存
                JSONObject object = JSONObject.parseObject(result);
                if (object.containsKey("infocode") && object.getString("infocode").equals("10000")){
                    JSONObject route = object.getJSONObject("route");
                    JSONArray paths = route.getJSONArray("paths");
                    JSONObject info = (JSONObject)paths.get(0);
                    String distance = info.getString("distance");
                    dayKm += Double.parseDouble(distance);
                }
            }
        }
        return dayKm;
    }



    /*
    * 调用距离测量服务查询 总里程
    * 传入两个list,第一个为起始点list,第二个取第一个点为终点.
    * */
    public static List<TerminalHistorySpot> queryMileageForGaodeAPI(Double lastMileage, List<TerminalHistorySpot> oldlist1, List<TerminalHistorySpot> oldlist2){

        List<TerminalHistorySpot> list = new ArrayList<TerminalHistorySpot>();
        //拼接参数字符串
        StringBuffer param = new StringBuffer();
        StringBuffer originsTemp = new StringBuffer();
        StringBuffer destinationTemp = new StringBuffer();
        destinationTemp.append(String.format("%.6f", oldlist2.get(0).getLng())+","+ String.format("%.6f", oldlist2.get(0).getLat()));

        try {
            param.append("key="+Key);
            for (TerminalHistorySpot terminalHistorySpot : oldlist1) {
                originsTemp.append(String.format("%.6f", terminalHistorySpot.getLng())+","+ String.format("%.6f", terminalHistorySpot.getLat()));
                originsTemp.append("|");
            }
            param.append("&origins="+originsTemp.substring(0,originsTemp.length() - 1));
            param.append("&destination="+destinationTemp);
            //发送get请求解析数据
            String result = HttpClient.sendRequest(queryMileageURL, param.toString(),HttpClient.METHOD_GET);;
            //解析数据
            JSONObject jsonObject = JSON.parseObject(result);
            Integer errcode = Integer.parseInt((String) jsonObject.get("infocode"));
            if (errcode == 10000){
                //把数组转为json对象
                JSONArray results = jsonObject.getJSONArray("results");
                //更新里程数,前一个减去当前里程就是当前需要加的里程
                for (int i = 0;i < results.size();i++){
                    JSONObject object = (JSONObject)results.get(i);
                    Double distance = object.getDouble("distance");
                    distance = lastMileage - distance;
                    //如果里程差大于零,则累加.如果小于0,则加100米
                    if (distance > 0){
                        //如果大于1000米就舍弃
                        if(distance > 1000){
                            oldlist1.get(i).setMileage(oldlist1.get(i).getMileage()+oldlist1.get(i).getSpeed()/120f);
                        }else {
                            oldlist1.get(i).setMileage(oldlist1.get(i).getMileage()+distance);
                        }
                    }else {
                        oldlist1.get(i).setMileage(oldlist1.get(i).getMileage()+oldlist1.get(i).getSpeed()/120f);
                    }
                    lastMileage = oldlist1.get(i).getMileage();
                }
                return oldlist1;

            }else {
                return null;
            }
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /*
     * 更新轨迹文件中里程数(速度为0的)
     * */
    public static List<TerminalHistorySpot> updataMileage(List<TerminalHistorySpot> list, List<TerminalHistorySpot> listnotzore){

        //里程参照
        Double mileage = list.get(0).getMileage();

        //遍历原集合,查找是否有更新的值,如果有就更新,如果没有就和上一条的里程数相同
        for (int i = 0;i < list.size();i++) {

            //将调高德接口返回的gcj02坐标转换成wgs84坐标
            Point pointcorve = new Point();
            pointcorve.setLng(list.get(i).getLng());
            pointcorve.setLat(list.get(i).getLat());
            pointcorve = CoordTransformUtils.gcj02Towgs84(pointcorve);
            list.get(i).setLng(pointcorve.getLng());
            list.get(i).setLat(pointcorve.getLat());

            Long time = list.get(i).getTime();
            //查找相同时间戳的数据替换
            TerminalHistorySpot terminalForList = findTerminalForList(listnotzore,time);
            if (terminalForList != null){
                list.get(i).setMileage(terminalForList.getMileage());
                mileage = list.get(i).getMileage();
            }else {
                //如果没有更新的数据就和上一条替换过的里程相同
                list.get(i).setMileage(mileage);
            }
        }
        return list;
    }

    /*发送post请求*/
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static String doPost(String url, Map<String,Object> map, String charset){
        org.apache.http.client.HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try{
            httpClient = (org.apache.http.client.HttpClient) new SSLClient();
            httpPost = new HttpPost(url);
            //设置参数
            List<NameValuePair> list = new ArrayList<NameValuePair>();
            Iterator iterator = map.entrySet().iterator();
            while(iterator.hasNext()){
                Entry<String,String> elem = (Entry<String, String>) iterator.next();
                list.add(new BasicNameValuePair(elem.getKey(),elem.getValue()));
            }
            if(list.size() > 0){
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,charset);
                httpPost.setEntity(entity);
            }
            HttpResponse response = httpClient.execute(httpPost);
            if(response != null){
                HttpEntity resEntity = response.getEntity();
                if(resEntity != null){
                    result = EntityUtils.toString(resEntity,charset);
                }
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }
        return result;
    }


    /**
     * 向指定URL发送GET方法的请求
     * @param url 发送请求的URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "/" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }


    /*
    * 返回一辆车List<TerminalHistorySpot>数据中符合时间戳值的TerminalHistorySpot对象
    * */
    public static TerminalHistorySpot findTerminalForList(List<TerminalHistorySpot> list, Long time){
        for (TerminalHistorySpot historySpot : list) {
            if (historySpot.getTime() != null && historySpot.getTime().toString().equals(time.toString())){
                return historySpot;
            }
        }
        return null;
    }

    /*
     * 返回一辆车List<TerminalHistorySpot>数据中大于时间戳值的TerminalHistorySpot对象
     * */
    public static List<TerminalHistorySpot> findBigTerminalForList(List<TerminalHistorySpot> list, Long time){
        List<TerminalHistorySpot> list1 = new ArrayList<TerminalHistorySpot>();

        for (TerminalHistorySpot historySpot : list) {
            if (historySpot.getTime() != null && historySpot.getTime() > time){
                list1.add(historySpot);
            }
        }
        return list1;
    }

	/**编码*/
    public static final String CHAR_ENC = "UTF-8";
    /**毫秒到秒*/
    public static final int MILLIS_TO_SECONDS = 1000;
    /**毫秒到分钟*/
    public static final int MILLIS_TO_MINUTES = 60 * 1000;

    
    /**
     * 获取当前分钟数
     * 
     * @return
     */
    public static long getCurrentTimeOfMinutes() {
        return System.currentTimeMillis() / MILLIS_TO_MINUTES;
    }

    /**
     * 将异常信息转成字符串
     * 
     * @param ex
     * @return
     */
    public static String transExceptionToString(Exception ex) {
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw));
        return sw.toString();
    }

    /**
     * 字符串是否为null或空串
     * 
     * @param str
     * @return
     */
    public static boolean isNullOrEmpty(String str) {
        if (null == str || "".equals(str)) {
            return true;
        }
        return false;
    }
    
  

    /**
     * url编码
     * 
     * @param parameter
     * @return
     */
    public static String urlEncode(String parameter) {
        try {
            return URLEncoder.encode(parameter, CHAR_ENC);
        } catch (UnsupportedEncodingException e) {
            return parameter;
        }
    }
    

	/**
	 * 去除速度为0的点
	 *
	 * @return list
	 */
	public static List<TerminalHistorySpot> clearZero(List<TerminalHistorySpot> list) {
        List<TerminalHistorySpot> clearlist = new ArrayList<TerminalHistorySpot>();
        for (int i = 0;i < list.size();i++) {
            if (list.get(i).getSpeed() != 0f){
                clearlist.add(list.get(i));
            }
        }
		return clearlist;
	}
	/*
	* 给历史轨迹数据中,两点距离超过一千米的点,中间进行补点.
	*
	* */
	public static List<TerminalHistorySpot> replenishPointforjuli(List<TerminalHistorySpot> list){

	    try {
            if (list != null && list.size() > 0){

                //前一个点的时间戳
                Long time = 0l;
                //两个坐标点的拼接
                String locations="";
                String locations2 = "";
                //两个点的间距
                Double distance = 0.0d;
                //补点的个数
                int point = 0;

                //坐标总差
                Double lngcha = 0.0d;
                Double latcha = 0.0d;
                //时间总差
                Long timecha = 0l;

                /*遍历历史数据list*/
                for (int i = 0;i < list.size();i++) {
                    TerminalHistorySpot terminalHistorySpot = list.get(i);
                    if (!locations.equals("") && time != 0){
                        locations2 = terminalHistorySpot.getLat()+","+terminalHistorySpot.getLng();
                        //计算距离
                        distance = distance(locations, locations2);

                        //如果间距大于1000M
                        if (distance >= 999){
                            //计算需要加几个点
                            point = distance.intValue()/999;

                            double[] doubles1 = latlng2double(locations);
                            double[] doubles2 = latlng2double(locations2);
                            //计算坐标差
                            lngcha = doubles2[1] - doubles1[1];
                            latcha = doubles2[0] - doubles1[0];
                            //计算坐标每次加多少值
                            Double lngmeicijia = lngcha/(point+1);
                            Double latmeicijia = latcha/(point+1);
                            //计算时间差
                            timecha = terminalHistorySpot.getTime() - time;
                            //计算每次时间加多少值
                            Long timemeici = timecha/(point+1);

                            /*补点*/
                            for (int j = 0;j<point;j++){
                                TerminalHistorySpot terminalHistorySpot1 = new TerminalHistorySpot();
                                terminalHistorySpot1.setLng(terminalHistorySpot.getLng()+lngmeicijia*(j+1));
                                terminalHistorySpot1.setLat(terminalHistorySpot.getLat()+latmeicijia*(j+1));
                                terminalHistorySpot1.setTime(terminalHistorySpot.getTime()+timemeici*(j+1));
                                terminalHistorySpot1.setSpeed(terminalHistorySpot.getSpeed());
                                terminalHistorySpot1.setAcc(terminalHistorySpot.getAcc());
                                terminalHistorySpot1.setTc(terminalHistorySpot.getTc());
                                terminalHistorySpot1.setAzimuth(terminalHistorySpot.getAzimuth());
                                terminalHistorySpot1.setWorking(terminalHistorySpot.getWorking());
                                terminalHistorySpot1.setMileage(terminalHistorySpot.getMileage());
                                list.add(i+j,terminalHistorySpot1);
                            }
                        }
                    }

                    //结束后更新中间变量
                    time = list.get(i).getTime();
                    locations = list.get(i).getLat()+","+list.get(i).getLng();
                }
            }
        }catch (Exception e){
	        e.printStackTrace();
        }

	    return list;
    }
    /*
    * 微调历史轨迹中坐标相同的点的经纬度坐标.只修改纬度
    *
    * */
    public static List<TerminalHistorySpot> replenishPointforzuobiao(List<TerminalHistorySpot> list){

        if (list != null && list.size() > 0){

            //定义纬度中间变量
            Double latTemp = 0.0d;

            for (int i = 0;i < list.size();i++) {
                TerminalHistorySpot terminalHistorySpot = list.get(i);
                if (latTemp != 0.0d){
                    if (equal(terminalHistorySpot.getLat(),latTemp)){
                        Double v = Double.parseDouble(String.valueOf(i + 1));
                        Double f = 10000000d;
                        Double pianyi = v/f;
                        list.get(i).setLat(add(terminalHistorySpot.getLat(),pianyi));
                    }else {
                        latTemp = terminalHistorySpot.getLat();
                    }
                }else {
                    latTemp = terminalHistorySpot.getLat();
                }
            }
        }
        return list;
    }

    /*double数加法*/
    public static double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }
    /*double判断相同*/
    public static boolean equal(double a, double b) {
        if ((a- b> -0.000001) && (a- b) < 0.000001)
            return true;
        else
            return false;
    }
    /**
     * 计算两个经纬度之间的近似距离
     * 返回单位:米
     */
    public static double distance(double lon1,double lat1,double lon2,double lat2){
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lon1) - rad(lon2);

        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +
                Math.cos(radLat1)* Math.cos(radLat2)* Math.pow(Math.sin(b/2),2)));
        // 取WGS84标准参考椭球中的地球长半径(单位:m)
        s = s *6378137.0;
        s = s * 10000 / 10000;
        return s;
    }
    public static double distance(String latlng, String latlng2){
        double[] p1 = latlng2double(latlng);
        double[] p2 = latlng2double(latlng2);
        if(p1!=null && p2!=null){
            return distance(p1[1],p1[0],p2[1],p2[0]);
        }
        return 0;
    }

    public static double[] latlng2double(String latlng){

        String[] arr =  latlng.split(",");
        if(arr.length==2){
            try{
                double[] r = new double[2];
                r[0] = Double.parseDouble(arr[0]);
                r[1] = Double.parseDouble(arr[1]);
                return r;
            }catch(Exception ex){

            }finally{
                arr = null;
            }
        }
        return null;
    }
    private static double rad(double d)
    {
        return d * Math.PI / 180.0;
    }
}

历史轨迹工具类:

package com.web.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.socket.bean.Point;
import com.socket.bean.TerminalHistorySpot;
import com.socket.utils.CoordTransformUtils;
import com.web.gps.everydayMileage.entity.HttpClient;
import com.web.gps.everydayMileage.entity.NewTerminalHistorySpot;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.*;
import java.util.Map.Entry;

/**
 * 历史轨迹纠偏相关工具类
 */
public class TerminalHistoryUtil {
    private static final Logger log = LoggerFactory.getLogger(TerminalHistoryUtil.class);

	//声明参数
    private  static final String Key = "用户申请的KEY";
    private  static final String initTerminalURL = "https://tsapi.amap.com/v1/track/terminal/add";
    private  static final String queryTidByTnameURL = "https://tsapi.amap.com/v1/track/terminal/list";
    private  static final String createTraceURL = "https://tsapi.amap.com/v1/track/trace/add";
    private  static final String uploadTraceDataURL = "https://tsapi.amap.com/v1/track/point/upload";
    private  static final String trsearchByTridURL = "https://tsapi.amap.com/v1/track/terminal/trsearch";
    private  static final String deleteTraceURL = "https://tsapi.amap.com/v1/track/trace/delete";
    public   static final Integer sid = "KEY下的服务ID";

    //private static Map<String,String> localtimemap = new HashMap<String, String>();


    /*
    * 初始化猎鹰服务,创建轨迹纠偏服务
    * (已改为手动创建)
    * */
    /*public static int initLieyingService(){
        //定义参数map,转为json
        HashMap param = new HashMap();
        param.put("key",Key);
        param.put("name",ServiceName);
        JSONObject json = new JSONObject(param);
        //发送post请求,解析数据
        String result = sendPost(json, initServiceURL);

        JSONObject jsonObject = JSON.parseObject(result);
        Integer sid = (Integer) jsonObject.get("sid");
        return sid;
    }*/

    /*
     * 初始化猎鹰服务,创建轨迹终端(车辆)
     * trCode -- 设备号
     * */
    public static boolean initTerminal(int sid, List<String> trCode){
        //定义参数map
        Map<String,Object> param = null;
        try {
            for (String tr : trCode) {
                param = new HashMap<String, Object>();
                param.put("key",Key);
                param.put("sid", String.valueOf(sid));
                param.put("name",tr);
                //发送post请求,解析数据
                String result = doPost(initTerminalURL,param,"utf-8");
                JSONObject jsonObject = JSON.parseObject(result);
                Integer tid = (Integer) jsonObject.get("errcode");
                if (tid != 10000 ){
                    log.info(tr+"创建终端失败!!!");
                }else {
                    log.info(tr+"创建终端成功!!!");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /*
    *
    * 根据终端name查询终端tid
    *
    * */
    public static Integer queryTidByTname(String Tname) {
        //定义参数map,转为json
        StringBuffer param = new StringBuffer();
        try {
            param.append("key="+Key);
            param.append("&sid="+ String.valueOf(sid));
            param.append("&name="+Tname);
            //发送get请求,解析数据
            String result = HttpClient.sendRequest(queryTidByTnameURL, param.toString(),HttpClient.METHOD_GET);;
            JSONObject jsonObject = JSON.parseObject(result);
            Integer state = (Integer) jsonObject.get("errcode");
            if (state == 10000) {
                JSONObject data = jsonObject.getJSONObject("data");
                JSONArray jsonArray = data.getJSONArray("results");
                JSONObject jsonObject2 = jsonArray.getJSONObject(0);//获取第1条数据中的tid
                String tid = jsonObject2.getString("tid");

                return Integer.parseInt(tid);
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }

    }
    /*
    * 创建轨迹,返回轨迹ID
    */
    public static Integer createTrace(Integer tid){
        //定义参数map
        Map<String,Object> param = null;
        try {
                param = new HashMap<String, Object>();
                param.put("key",Key);
                param.put("sid", String.valueOf(sid));
                param.put("tid", String.valueOf(tid));
                //发送post请求,解析数据
                String result = doPost(createTraceURL,param,"utf-8");
                JSONObject jsonObject = JSON.parseObject(result);
                Integer errcode = (Integer) jsonObject.get("errcode");
                if (errcode == 10000){
                    JSONObject data = jsonObject.getJSONObject("data");
                    String trid =  data.getString("trid");
                    return Integer.parseInt(trid);
                }else {
                    return -1;
                }

        }catch (Exception e){
            e.printStackTrace();
            return -1;
        }
    }

    /*
    * 上传轨迹数据
    * */
    public static void uploadTraceData(Integer tid, Integer trid, List<TerminalHistorySpot> terminalHistorySpots, HashMap<String, String> localtimemap){
        //定义上传点list
        List<HashMap> points = new ArrayList<HashMap>();
        //定义参数map
        Map<String,Object> param = new HashMap<>();
        param.put("key",Key);
        param.put("sid", String.valueOf(sid));
        param.put("tid", String.valueOf(tid));
        param.put("trid", String.valueOf(trid));
        try {
            //添加上传点信息
            if (terminalHistorySpots != null && terminalHistorySpots.size() > 0){
                for (TerminalHistorySpot terminalHistorySpot:terminalHistorySpots) {
                    //添加点位详情信息
                    HashMap infoMap = new HashMap<>();
                    infoMap.put("location", String.format("%.6f", terminalHistorySpot.getLng())+","+ String.format("%.6f", terminalHistorySpot.getLat()));
                    infoMap.put("locatetime",terminalHistorySpot.getTime());
                    HashMap<String, String> map = new HashMap<>();
                    map.put("timetemp",terminalHistorySpot.getTime().toString());
                    infoMap.put("props",JSONObject.toJSON(map));
                    /*infoMap.put("speed",terminalHistorySpot.getSpeed());
                    infoMap.put("direction",terminalHistorySpot.getAzimuth());*/
                    points.add(infoMap);
                    if (localtimemap.containsKey(String.valueOf(terminalHistorySpot.getTime()))){
                        log.info("存在重复的时间戳!");
                    }else {
                        localtimemap.put(String.valueOf(terminalHistorySpot.getTime()), String.format("%.6f", terminalHistorySpot.getLng())+","+ String.format("%.6f", terminalHistorySpot.getLat()));
                    }
                }
                JSONArray jsonArray = (JSONArray)JSON.toJSON(points);
                String string = jsonArray.toString();
                param.put("points", string);
            }
            //发送post请求,解析数据
            String result = doPost(uploadTraceDataURL,param,"utf-8");
            JSONObject jsonObject = JSON.parseObject(result);
            Integer errcode = (Integer) jsonObject.get("errcode");
            if (errcode == 10000){
                log.info("上传成功!");
            }else {
                log.info("上传失败!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /*
    * 分页查询云端历史轨迹数据并纠偏补点
    * */
    public static ArrayList<JSONObject> searchTracksByTrid(Integer tid, Integer trid, Long startTime, Long endTime) throws InterruptedException {
        //Json数据集
        ArrayList<JSONObject> trackList = new ArrayList<JSONObject>();
        //查询页数
        Integer page = 1;
        //至少执行一次:
        JSONObject jsonObject = trsearchByTrid(tid,trid,page,startTime,endTime);
        trackList.add(jsonObject);
        //通过解析第一次执行返回的数据,判断执行次数
        JSONObject data = jsonObject.getJSONObject("data");
        if (data == null){
            return null;
        }
        JSONArray tracks = data.getJSONArray("tracks");
        JSONObject center = (JSONObject) tracks.get(0);
        String counts = center.getString("counts");
        Integer count = Integer.parseInt(counts);
        if (count >500){
            //更新查询页数
            page = (count - 500)/500 + 2;
            //循环从第二页开始查询
            for (int i = 2; i <= page;i++){
                JSONObject jsonObjecttemp = trsearchByTrid(tid,trid,i,startTime,endTime);
                trackList.add(jsonObjecttemp);
            }
        }
        return trackList;
    }
    /*
    * 查询云端的轨迹数据并纠偏补点
    * */
    public static JSONObject trsearchByTrid(Integer tid, Integer trid, Integer page, Long startTime, Long endTime){
        //定义参数map
        StringBuffer param = new StringBuffer();
        try {
            param.append("key="+Key);
            param.append("&sid="+ String.valueOf(sid));
            param.append("&tid="+ String.valueOf(tid));
            param.append("&trid="+ String.valueOf(trid));
/*          param.append("&starttime="+String.valueOf(1575932400000l));
            param.append("&endtime="+String.valueOf(1575936000000l));*/
            param.append("&correction=denoise=1,mapmatch=1,attribute=1,threshold=0,mode=driving");
            param.append("&recoup=1");
            param.append("&gap=50");
            param.append("&page="+page);
            param.append("&pagesize=500");
            //发送get请求解析数据
            String result = HttpClient.sendRequest(trsearchByTridURL, param.toString(),HttpClient.METHOD_GET);;
            //解析数据
            JSONObject jsonObject = JSON.parseObject(result);
            Integer errcode = (Integer) jsonObject.get("errcode");
            if (errcode == 10000){
                return jsonObject;
            }else {
                return null;
            }
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /*
     * 删除指定轨迹ID的轨迹信息
     */
    public static Boolean deleteTrace(Integer tid, Integer trid){
        //定义参数map
        Map<String,Object> param = null;
        try {

            param = new HashMap<String, Object>();
            param.put("key",Key);
            param.put("sid", String.valueOf(sid));
            param.put("tid", String.valueOf(tid));
            param.put("trid", String.valueOf(trid));
            //发送post请求,解析数据
            String result = doPost(deleteTraceURL,param,"utf-8");
            JSONObject jsonObject = JSON.parseObject(result);
            Integer errcode = (Integer) jsonObject.get("errcode");
            if (errcode == 10000){
                return true;
            }else {
                return false;
            }

        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /*发送post请求*/
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static String doPost(String url, Map<String,Object> map, String charset){
        org.apache.http.client.HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try{
            httpClient = (org.apache.http.client.HttpClient) new SSLClient();
            httpPost = new HttpPost(url);
            //设置参数
            List<NameValuePair> list = new ArrayList<NameValuePair>();
            Iterator iterator = map.entrySet().iterator();
            while(iterator.hasNext()){
                Entry<String,String> elem = (Entry<String, String>) iterator.next();
                list.add(new BasicNameValuePair(elem.getKey(),elem.getValue()));
            }
            if(list.size() > 0){
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,charset);
                httpPost.setEntity(entity);
            }
            HttpResponse response = httpClient.execute(httpPost);
            if(response != null){
                HttpEntity resEntity = response.getEntity();
                if(resEntity != null){
                    result = EntityUtils.toString(resEntity,charset);
                }
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }
        return result;
    }


    /**
     * 向指定URL发送GET方法的请求
     * @param url 发送请求的URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "/" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }


    /*
    * 返回一辆车List<TerminalHistorySpot>数据中符合时间戳值的TerminalHistorySpot对象
    * */
    public static TerminalHistorySpot findTerminalForList(List<TerminalHistorySpot> list, Long time){
        for (TerminalHistorySpot historySpot : list) {
            if (historySpot.getTime() != null && historySpot.getTime().toString().equals(time.toString())){
                return historySpot;
            }
        }
        return null;
    }

    /*
     * 返回一辆车List<TerminalHistorySpot>数据中大于时间戳值的TerminalHistorySpot对象
     * */
    public static List<TerminalHistorySpot> findBigTerminalForList(List<TerminalHistorySpot> list, Long time){
        List<TerminalHistorySpot> list1 = new ArrayList<TerminalHistorySpot>();

        for (TerminalHistorySpot historySpot : list) {
            if (historySpot.getTime() != null && historySpot.getTime() > time){
                list1.add(historySpot);
            }
        }
        return list1;
    }



    /*
    * 根据经纬度补纠偏返回后点的附加信息
    * result--纠偏返回的信息
    * list--源坐标列表
    * */
    public static List<NewTerminalHistorySpot> pointinfo(ArrayList<JSONObject> result, List<TerminalHistorySpot> list){

        //test
        int num = 0;
        //新坐标list
        List<NewTerminalHistorySpot> newPointList = new ArrayList<NewTerminalHistorySpot>();
        //解析返回的数据,转化为自定义变量
        if (result != null && result.size() > 0){
            //先获取返回的状态,判断是否正常调用接口
            JSONObject state = (JSONObject)result.get(0);
            Integer errcode = state.getInteger("errcode");
            //返回状态正常
            if(errcode==10000){
                /*解析数据*/
                for (JSONObject jsonObject : result) {
                    JSONObject data = jsonObject.getJSONObject("data");
                    JSONArray tracks = data.getJSONArray("tracks");
                    JSONObject tracks0 = (JSONObject)tracks.get(0);
                    JSONArray points = tracks0.getJSONArray("points");
                    //遍历点位集合数据
                    NewTerminalHistorySpot newTerminalHistorySpot = null;
                    for (Object point : points) {
                        Map<String,Object> map = (Map<String,Object>)(JSONObject)point;
                        String location = (String)map.get("location");
                        String[] split = location.split(",");
                        //保存纠偏返回的经纬度
                        newTerminalHistorySpot = new NewTerminalHistorySpot();
                        newTerminalHistorySpot.setLng(Double.parseDouble(split[0]));
                        newTerminalHistorySpot.setLat(Double.parseDouble(split[1]));
                        //附加信息状态初始化为0(无附加信息)
                        newTerminalHistorySpot.setInfostate(0);

                        //保存新坐标信息
                        newPointList.add(newTerminalHistorySpot);
                    }
                }
                /*遍历源坐标数据,在新列表中找坐标相近的点(test:距离小于10米)*/
                if (list != null && list.size() > 0){
                    //源坐标
                    String oldlocations = "";
                    //新坐标
                    String newlocations = "";
                    //两个坐标的距离
                    Double distance = 0d;
                    //定义新坐标遍历到哪儿一下标,下一轮遍历从此下标开始
                    int index = 0;

                    //新坐标如果有了附加信息,则把附加信息状态改为1,下一轮遍历时,从最后一个附加信息状态为1的新坐标往下遍历。
                    //遍历源坐标
                    for (TerminalHistorySpot terminalHistorySpot : list) {
                        oldlocations = terminalHistorySpot.getLat()+","+terminalHistorySpot.getLng();

                        //定义初始点距为10米
                        Double m = 100d;
                        //定义循环标识
                        Boolean flag = true;
                        do {
                            //防止死循环
                            if(newPointList.size() == index){
                                break;
                            }
                            //遍历新坐标  规定只在当前条数 +- 总条数的 范围
                            /*每个历史轨迹的数据都不一样*/
                            for (int i = index ; i < newPointList.size() && i < index + newPointList.size() * 0.15; i++) {
                                newlocations = newPointList.get(i).getLat()+","+newPointList.get(i).getLng();
                                //查询两个点的距离
                                distance = distance(oldlocations, newlocations);
                                //如果两个点之间距离小于10米,则认为当前点就是纠偏后的源坐标点,把原坐标的信息给新坐标
                                //找第一个最近的点
                                if (distance < m && newPointList.get(i).getInfostate() == 0){
                                    num++;
                                    newPointList.get(i).setTime(terminalHistorySpot.getTime());
                                    newPointList.get(i).setAcc(terminalHistorySpot.getAcc());
                                    newPointList.get(i).setAzimuth(terminalHistorySpot.getAzimuth());
                                    newPointList.get(i).setSpeed(terminalHistorySpot.getSpeed());
                                    newPointList.get(i).setMileage(terminalHistorySpot.getMileage());
                                    newPointList.get(i).setWorking(terminalHistorySpot.getWorking());
                                    newPointList.get(i).setTc(terminalHistorySpot.getTc());
                                    newPointList.get(i).setInfostate(1);
                                    //记录下次遍历的开始坐标为此坐标的下一位
                                    index = i + 1;
                                    //结束dowhile循环
                                    flag = false;
                                    //结束本次循环
                                    break;
                                }
                            }
                            if (flag == true){
                                //每次加
                                m += 10d;
                            }
                        }while (flag);
                    }
                }
            }else{
                log.error("调用高德抓路服务失败!");
            }
        }else {
            log.info("error--调用高德服务返回结果集为空!");
        }
        String strings = "";
        for (NewTerminalHistorySpot newTerminalHistorySpot : newPointList) {
            String string = newTerminalHistorySpot.toString();
            strings += string;
        }
        return newPointList;
    }

    /*
    * 给补了附加信息的新坐标列表补点
    *
    * */
    public static List<TerminalHistorySpot> addPointforNewList(List<NewTerminalHistorySpot> newPointList) {
        //返回结果
        List<TerminalHistorySpot> terminalHistorySpotsList = new ArrayList<TerminalHistorySpot>();

        //定义参照TerminalHistorySpot对象
        TerminalHistorySpot lastTerminalHistorySpot = null;

        //遍历新坐标列表
        for (NewTerminalHistorySpot newTerminalHistorySpot : newPointList) {
            TerminalHistorySpot terminalForlocate = null;
            //如果有附加信息,则不补点
            if (newTerminalHistorySpot.getInfostate() == 1  && !"".equals(newTerminalHistorySpot.getTc())){
                terminalForlocate = new TerminalHistorySpot();

                //保存纠偏后的当前点位
                //将调高德接口返回的gcj02坐标转换成wgs84坐标
                Point pointcorve = new Point();
                pointcorve.setLng(newTerminalHistorySpot.getLng());
                pointcorve.setLat(newTerminalHistorySpot.getLat());
                pointcorve = CoordTransformUtils.gcj02Towgs84(pointcorve);
                terminalForlocate.setLng(pointcorve.getLng());
                terminalForlocate.setLat(pointcorve.getLat());

                //保存别的附加信息
                terminalForlocate.setTc(newTerminalHistorySpot.getTc());
                terminalForlocate.setAzimuth(newTerminalHistorySpot.getAzimuth());
                terminalForlocate.setAcc(newTerminalHistorySpot.getAcc());
                terminalForlocate.setSpeed(newTerminalHistorySpot.getSpeed());
                terminalForlocate.setTime(newTerminalHistorySpot.getTime());
                terminalForlocate.setWorking(newTerminalHistorySpot.getWorking());
                terminalForlocate.setMileage(newTerminalHistorySpot.getMileage());

                //保存源数据到参照变量中
                lastTerminalHistorySpot = terminalForlocate;
                //添加到list中
                terminalHistorySpotsList.add(terminalForlocate);
            } else {
                //保存纠偏补的点(只有经纬度数据)
                if (lastTerminalHistorySpot != null) {
                    terminalForlocate = new TerminalHistorySpot();

                    //保存纠偏后的当前点位
                    //将高德接口返回的gcj02坐标转换成wgs84坐标
                    Point pointcorve = new Point();
                    pointcorve.setLng(newTerminalHistorySpot.getLng());
                    pointcorve.setLat(newTerminalHistorySpot.getLat());
                    pointcorve = CoordTransformUtils.gcj02Towgs84(pointcorve);
                    terminalForlocate.setLng(pointcorve.getLng());
                    terminalForlocate.setLat(pointcorve.getLat());

                    //补附加信息
                    if (lastTerminalHistorySpot.getSpeed() == null || lastTerminalHistorySpot.getSpeed() == 0f) {
                        terminalForlocate.setSpeed(1f);//速度为0时,轨迹不再延申
                    } else {
                        terminalForlocate.setSpeed(lastTerminalHistorySpot.getSpeed());
                    }
                    terminalForlocate.setAzimuth(lastTerminalHistorySpot.getAzimuth());
                    terminalForlocate.setAcc(lastTerminalHistorySpot.getAcc());
                    terminalForlocate.setMileage(lastTerminalHistorySpot.getMileage());
                    terminalForlocate.setWorking(lastTerminalHistorySpot.getWorking());
                    terminalForlocate.setTc(lastTerminalHistorySpot.getTc());
                    terminalForlocate.setTime(lastTerminalHistorySpot.getTime() == null ? 0l : lastTerminalHistorySpot.getTime() + new Long(10l));

                    lastTerminalHistorySpot = terminalForlocate;

                    //添加到list中
                    terminalHistorySpotsList.add(terminalForlocate);
                }
            }


        }
        return terminalHistorySpotsList;

    }
    /*
     * 把纠偏结果转换为List<TerminalHistorySpot>
     * result--纠偏返回的信息
     * */
    public static List<TerminalHistorySpot> convertResult(ArrayList<JSONObject> result){

        //新坐标list
        List<TerminalHistorySpot> newPointList = new ArrayList<TerminalHistorySpot>();
        //解析返回的数据,转化为自定义变量
        if (result != null && result.size() > 0){
            //先获取返回的状态,判断是否正常调用接口
            JSONObject state = (JSONObject)result.get(0);
            Integer errcode = state.getInteger("errcode");
            //返回状态正常
            if(errcode==10000){
                /*解析数据*/
                for (JSONObject jsonObject : result) {
                    JSONObject data = jsonObject.getJSONObject("data");
                    JSONArray tracks = data.getJSONArray("tracks");
                    JSONObject tracks0 = (JSONObject)tracks.get(0);
                    JSONArray points = tracks0.getJSONArray("points");
                    //遍历点位集合数据
                    TerminalHistorySpot newTerminalHistorySpot = null;
                    for (Object point : points) {
                        Map<String,Object> map = (Map<String,Object>)(JSONObject)point;
                        String location = (String)map.get("location");
                        String[] split = location.split(",");
                        //保存纠偏返回的经纬度
                        newTerminalHistorySpot = new TerminalHistorySpot();
                        newTerminalHistorySpot.setLng(Double.parseDouble(split[0]));
                        newTerminalHistorySpot.setLat(Double.parseDouble(split[1]));

                        //保存新坐标信息
                        newPointList.add(newTerminalHistorySpot);
                    }
                }

            }else{
                log.error("调用高德抓路服务失败!");
            }
        }else {
            log.info("error--调用高德服务返回结果集为空!");
        }
        return newPointList;
    }


	/**编码*/
    public static final String CHAR_ENC = "UTF-8";
    /**毫秒到秒*/
    public static final int MILLIS_TO_SECONDS = 1000;
    /**毫秒到分钟*/
    public static final int MILLIS_TO_MINUTES = 60 * 1000;

    
    /**
     * 获取当前分钟数
     * 
     * @return
     */
    public static long getCurrentTimeOfMinutes() {
        return System.currentTimeMillis() / MILLIS_TO_MINUTES;
    }

    /**
     * 将异常信息转成字符串
     * 
     * @param ex
     * @return
     */
    public static String transExceptionToString(Exception ex) {
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw));
        return sw.toString();
    }

    /**
     * 字符串是否为null或空串
     * 
     * @param str
     * @return
     */
    public static boolean isNullOrEmpty(String str) {
        if (null == str || "".equals(str)) {
            return true;
        }
        return false;
    }
    /**
     * url编码
     * 
     * @param parameter
     * @return
     */
    public static String urlEncode(String parameter) {
        try {
            return URLEncoder.encode(parameter, CHAR_ENC);
        } catch (UnsupportedEncodingException e) {
            return parameter;
        }
    }
	/**
	 * 将历史轨迹按时间戳从小到大排序
	 *
	 * @return list
	 */
	public static List<TerminalHistorySpot> sortList(List<TerminalHistorySpot> list) {
		Collections.sort(list, new Comparator<TerminalHistorySpot>() {
			/**
			 * int compare(TerminalLocator ter1, TerminalLocator ter2)
			 * 返回一个基本类型的整型 返回负数表示:ter1小于ter2 返回0表示:ter1和ter2相等 返回正数表示:ter1大于ter2
			 */
			public int compare(TerminalHistorySpot ter1, TerminalHistorySpot ter2) {
				// 按照车辆终端定位设备时间戳从小到大进行升序排列
				if (ter1.getTime() > ter2.getTime()) {
					return 1;
				}
				if (ter1.getTime() == ter2.getTime()) {
					return 0;
				}
				return -1;
			}
		});
		//去掉里程为0的点
		/*Iterator<TerminalHistorySpot> it = list.iterator();
		while(it.hasNext()){
			TerminalHistorySpot ter = it.next();
			if(ter.getMileage()==null || ter.getMileage()==0 || ter.getMileage().equals("")){
				it.remove();
			}
		}*/
		return list;
	}
	/*
	* 给历史轨迹数据中,两点距离超过一千米的点,中间进行补点.
	* */
	public static List<TerminalHistorySpot> replenishPointforjuli(List<TerminalHistorySpot> list){

	    try {
            if (list != null && list.size() > 0){

                //前一个点的时间戳
                Long time = 0l;
                //两个坐标点的拼接
                String locations="";
                String locations2 = "";
                //两个点的间距
                Double distance = 0.0d;
                //补点的个数
                int point = 0;

                //坐标总差
                Double lngcha = 0.0d;
                Double latcha = 0.0d;
                //时间总差
                Long timecha = 0l;

                /*遍历历史数据list*/
                for (int i = 0;i < list.size();i++) {
                    TerminalHistorySpot terminalHistorySpot = list.get(i);
                    if (!locations.equals("") && time != 0){
                        locations2 = terminalHistorySpot.getLat()+","+terminalHistorySpot.getLng();
                        //计算距离
                        distance = distance(locations, locations2);

                        //如果间距大于1000M
                        if (distance >= 999){
                            //计算需要加几个点
                            point = distance.intValue()/999;

                            double[] doubles1 = latlng2double(locations);
                            double[] doubles2 = latlng2double(locations2);
                            //计算坐标差
                            lngcha = doubles2[1] - doubles1[1];
                            latcha = doubles2[0] - doubles1[0];
                            //计算坐标每次加多少值
                            Double lngmeicijia = lngcha/(point+1);
                            Double latmeicijia = latcha/(point+1);
                            //计算时间差
                            timecha = terminalHistorySpot.getTime() - time;
                            //计算每次时间加多少值
                            Long timemeici = timecha/(point+1);

                            /*补点*/
                            for (int j = 0;j<point;j++){
                                TerminalHistorySpot terminalHistorySpot1 = new TerminalHistorySpot();
                                terminalHistorySpot1.setLng(terminalHistorySpot.getLng()+lngmeicijia*(j+1));
                                terminalHistorySpot1.setLat(terminalHistorySpot.getLat()+latmeicijia*(j+1));
                                terminalHistorySpot1.setTime(terminalHistorySpot.getTime()+timemeici*(j+1));
                                terminalHistorySpot1.setSpeed(terminalHistorySpot.getSpeed());
                                terminalHistorySpot1.setAcc(terminalHistorySpot.getAcc());
                                terminalHistorySpot1.setTc(terminalHistorySpot.getTc());
                                terminalHistorySpot1.setAzimuth(terminalHistorySpot.getAzimuth());
                                terminalHistorySpot1.setWorking(terminalHistorySpot.getWorking());
                                terminalHistorySpot1.setMileage(terminalHistorySpot.getMileage());
                                list.add(i+j,terminalHistorySpot1);
                            }
                        }
                    }

                    //结束后更新中间变量
                    time = list.get(i).getTime();
                    locations = list.get(i).getLat()+","+list.get(i).getLng();
                }
            }
        }catch (Exception e){
	        e.printStackTrace();
        }

	    return list;
    }
    /*
    * 微调历史轨迹中坐标相同的点的经纬度坐标.只修改纬度
    *
    * */
    public static List<TerminalHistorySpot> replenishPointforzuobiao(List<TerminalHistorySpot> list){

        if (list != null && list.size() > 0){

            //定义纬度中间变量
            Double latTemp = 0.0d;

            for (int i = 0;i < list.size();i++) {
                TerminalHistorySpot terminalHistorySpot = list.get(i);
                if (latTemp != 0.0d){
                    if (equal(terminalHistorySpot.getLat(),latTemp)){
                        Double v = Double.parseDouble(String.valueOf(i + 1));
                        Double f = 10000000d;
                        Double pianyi = v/f;
                        list.get(i).setLat(add(terminalHistorySpot.getLat(),pianyi));
                    }else {
                        latTemp = terminalHistorySpot.getLat();
                    }
                }else {
                    latTemp = terminalHistorySpot.getLat();
                }
            }
        }
        return list;
    }
    /*double数加法*/
    public static double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }
    /*double判断相同*/
    public static boolean equal(double a, double b) {
        if ((a- b> -0.000001) && (a- b) < 0.000001)
            return true;
        else
            return false;
    }
    /**
     * 计算两个经纬度之间的近似距离
     * 返回单位:米
     */
    public static double distance(double lon1,double lat1,double lon2,double lat2){
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lon1) - rad(lon2);

        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +
                Math.cos(radLat1)* Math.cos(radLat2)* Math.pow(Math.sin(b/2),2)));
        // 取WGS84标准参考椭球中的地球长半径(单位:m)
        s = s *6378137.0;
        s = s * 10000 / 10000;
        return s;
    }
    public static double distance(String latlng, String latlng2){
        double[] p1 = latlng2double(latlng);
        double[] p2 = latlng2double(latlng2);
        if(p1!=null && p2!=null){
            return distance(p1[1],p1[0],p2[1],p2[0]);
        }
        return 0;
    }
    public static double[] latlng2double(String latlng){

        String[] arr =  latlng.split(",");
        if(arr.length==2){
            try{
                double[] r = new double[2];
                r[0] = Double.parseDouble(arr[0]);
                r[1] = Double.parseDouble(arr[1]);
                return r;
            }catch(Exception ex){

            }finally{
                arr = null;
            }
        }
        return null;
    }
    private static double rad(double d)
    {
        return d * Math.PI / 180.0;
    }
    /**
     * @Description:获取某个目录下所有直接下级文件,不包括目录下的子目录的下的文件,所以不用递归获取
     */
    public static List<String> getFiles(String path) {
        List<String> files = new ArrayList<String>();
        File file = new File(path);
        File[] tempList = file.listFiles();

        for (int i = 0; i < tempList.length; i++) {
            //如果是文件,获取名称
            if (tempList[i].isFile()) {
                files.add(tempList[i].getName());
                //files.add(tempList[i].toString());
                //文件名,不包含路径
            }
            //如果是文件夹
            if (tempList[i].isDirectory()) {
                //暂无操作
            }
        }
        return files;
    }
}

日期工具类:

/**
 *
 */
package com.web.utils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期工具类
 */
public class DateUtil {

    private static transient int gregorianCutoverYear = 1582;

    /**
     * 闰年中每月天数
     */
    private static final int[] DAYS_P_MONTH_LY = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    /**
     * 非闰年中每月天数
     */
    private static final int[] DAYS_P_MONTH_CY = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    /**
     * 代表数组里的年、月、日
     */
    private static final int Y = 0, M = 1, D = 2;
    
    public static final String YYYYMMDD_TIME="yyyy-MM-dd HH:mm:ss";
    
    public static final String YYYYMMDD="yyyy-MM-dd";

    public static SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD_TIME);
    public static SimpleDateFormat sdfymd = new SimpleDateFormat(YYYYMMDD);


    /**
     * 获取前一天的日期
     */
    public static final Date getYesterdayDate() {

        Date date = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        // 把日期往后增加一天.整数往后推,负数往前移动
        calendar.add(calendar.DATE, -1);
        // 这个时间就是日期往前推一天的结果
        date = calendar.getTime();
        return date;
    }


    /**
     * 将代表日期的字符串分割为代表年月日的整形数组
     *
     * @param date
     * @return
     */
    public static int[] splitYMD(String date) {
        date = date.replace("-", "");
        int[] ymd = {0, 0, 0};
        ymd[Y] = Integer.parseInt(date.substring(0, 4));
        ymd[M] = Integer.parseInt(date.substring(4, 6));
        ymd[D] = Integer.parseInt(date.substring(6, 8));
        return ymd;
    }

    /**
     * 检查传入的参数代表的年份是否为闰年
     *
     * @param year
     * @return
     */
    public static boolean isLeapYear(int year) {
        return year >= gregorianCutoverYear ?
                ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))) : (year % 4 == 0);
    }

    /**
     * 日期加1天
     *
     * @param year
     * @param month
     * @param day
     * @return
     */
    private static int[] addOneDay(int year, int month, int day) {
        if (isLeapYear(year)) {
            day++;
            if (day > DAYS_P_MONTH_LY[month - 1]) {
                month++;
                if (month > 12) {
                    year++;
                    month = 1;
                }
                day = 1;
            }
        } else {
            day++;
            if (day > DAYS_P_MONTH_CY[month - 1]) {
                month++;
                if (month > 12) {
                    year++;
                    month = 1;
                }
                day = 1;
            }
        }
        int[] ymd = {year, month, day};
        return ymd;
    }

    /**
     * 将不足两位的月份或日期补足为两位
     *
     * @param decimal
     * @return
     */
    public static String formatMonthDay(int decimal) {
        DecimalFormat df = new DecimalFormat("00");
        return df.format(decimal);
    }

    /**
     * 将不足四位的年份补足为四位
     *
     * @param decimal
     * @return
     */
    public static String formatYear(int decimal) {
        DecimalFormat df = new DecimalFormat("0000");
        return df.format(decimal);
    }

    /**
     * 计算两个日期之间相隔的天数
     *
     * @param begin
     * @param end
     * @return
     * @throws ParseException
     */
    public static long countDay(String begin, String end) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate, endDate;
        long day = 0;
        try {
            beginDate = format.parse(begin);
            endDate = format.parse(end);
            day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return day;
    }

    /**
     * 以循环的方式计算日期
     * @param beginDate
     * @param endDate
     * @return
     */
    public static List<String> getEveryday(String beginDate, String endDate) {
        long days = countDay(beginDate, endDate);
        int[] ymd = splitYMD(beginDate);
        List<String> everyDays = new ArrayList<String>();
        everyDays.add(beginDate);
        for (int i = 0; i < days; i++) {
            ymd = addOneDay(ymd[Y], ymd[M], ymd[D]);
            everyDays.add(formatYear(ymd[Y]) + "-" + formatMonthDay(ymd[M]) + "-" + formatMonthDay(ymd[D]));
        }
        return everyDays;
    }

    /**
     * 传String类型的时间,指定时间格式,返回指定格式 date类型的时间
     * @param sdate
     * @return
     */
    public static Date getdateByStringFormat(String sdate,String format){
        if(!StringUtils.isNotBlank(format)){
            format = YYYYMMDD_TIME;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        if(StringUtils.isNotBlank(sdate)){
            try {
                Date date = sdf.parse(sdate);
                return date;
            }catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 到当前日期有多少日
     * @param d 输入月份
     * @return
     */
    public static String formatData(Date d,String format){
        if(d != null){
            if(format ==  null || "".equals(format)){
                format = "yyyy-MM-dd HH:mm:ss";
            }
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            String time = sdf.format(d);
            return time;
        }else{
            return null;
        }
    }

    /**今天开始时间
     * @return
     */
    public static Date getStartTime(){
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    /**
     * 今天结束时间
     * @return
     */
    public static Date getEndTime(){
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }

    /**
     * 获取一个月的最后一天
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));
        return DateUtil.formatData(cal.getTime(),YYYYMMDD);
    }

    /**
     * 获取一个月的第一天
     * @param year
     * @param month
     * @return
     */
    public static String getFirstDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DATE));
        return DateUtil.formatData(cal.getTime(),YYYYMMDD);
    }

    /**
     * 获取过去第几天的日期
     *
     * @param past
     * @return
     */
    public static String getPastDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
        Date today = calendar.getTime();
        return DateUtil.formatData(today,YYYYMMDD);
    }


    /**
     * 获取本季度开始时间 返回字符串 2018-04-01
     * @return
     */
    public static String getCurrentQuarterStartDate() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        String now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3) {
                c.set(Calendar.MONTH, 0);
            }else if (currentMonth >= 4 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 3);
            }else if (currentMonth >= 7 && currentMonth <= 9) {
                c.set(Calendar.MONTH, 6);
            }else if (currentMonth >= 10 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 9);
            }
            c.set(Calendar.DATE, 1);
            now = shortSdf.format(c.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获取本季度开始时间
     * @return
     */
    public static Date getCurrentQuarterStartTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3) {
                c.set(Calendar.MONTH, 0);
            } else if (currentMonth >= 4 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 3);
            } else if (currentMonth >= 7 && currentMonth <= 9) {
                c.set(Calendar.MONTH, 6);
            } else if (currentMonth >= 10 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 9);
            }
            c.set(Calendar.DATE, 0);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;

    }


    /**
    * 当前季度的结束时间,即2012-03-31 23:59:59
    *
    * @return
    */
    public static Date getCurrentQuarterEndTime() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getCurrentQuarterStartTime());
        cal.add(Calendar.MONTH, 3);
        return cal.getTime();
    }

    /**
     * 当前季度的结束时间,即2012-03-31 23:59:59
     *
     * @return
     */
    public static String getCurrentQuarterEndDate() {
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(getCurrentQuarterStartTime());
        cal.add(Calendar.MONTH, 2);
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.add(Calendar.DAY_OF_MONTH, lastDay);
        return shortSdf.format(cal.getTime());
    }

    /**
     * 获得本月的开始时间,即2012-01-01 00:00:00
     *
     * @return
     */
    public static  Date getCurrentMonthStartTime() {
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            now = shortSdf.parse(shortSdf.format(c.getTime()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获得本月的结束时间,即2012-01-31 23:59:59
     *
     * @return
     */
    public static Date getCurrentMonthEndTime() {
        SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            c.add(Calendar.MONTH, 1);
            c.add(Calendar.DATE, -1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获得本月的开始时间,即2012-01-01 00:00:00
     *
     * @return
     */
    public static  Date getLastMonthStartTime() {
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.add(Calendar.MONTH, -1);
            c.set(Calendar.DATE, 1);
            now = shortSdf.parse(shortSdf.format(c.getTime()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获得本月的结束时间,即2012-01-31 23:59:59
     *
     * @return
     */
    public static Date getLastMonthEndTime() {
        SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            //c.add(Calendar.MONTH, 0);
            c.add(Calendar.DATE, -1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    //获取今年是哪一年
    public static Integer getNowYear() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }

    //获取本年的开始时间
    public static Date getBeginDayOfYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        // cal.set
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);

        return getDayStartTime(cal.getTime());
    }

    //获取本年的结束时间
    public static Date getEndDayOfYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        cal.set(Calendar.MONTH, Calendar.DECEMBER);
        cal.set(Calendar.DATE, 31);
        return getDayEndTime(cal.getTime());
    }

    //获取某个日期的开始时间
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    //获取某个日期的结束时间
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }

    //获取某个日期的开始时间
    public static Date getDateForBefore1Hour(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d){
            calendar.setTime(d);
        }
        calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-1);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 获得该月最后一天
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth2(int year,int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month - 1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayOfMonth = sdf.format(cal.getTime());
        return lastDayOfMonth;
    }

    public static void main(String[] args) {
//        System.out.println(DateUtils.formateDate(DateUtil.getBeginDayOfYear(),"yyyy-MM-dd"));
//        System.out.println(DateUtils.formateDate(DateUtil.getEndDayOfYear(),"yyyy-MM-dd"));
//        System.out.println(getLastDayOfMonth2(2018,9));
//        System.out.println(getCurrentQuarterEndDate());
        System.out.println(getDateForBefore1Hour(new Date()));

    }
    
    /** 
    * 判断时间格式是否正确 
    * @param str 
    * @return 
    */ 
    public static boolean isValidDate(String str,String format) { 
    	if(!StringUtils.isNotBlank(format)){
            format = YYYYMMDD_TIME;
        }
	    DateFormat formatter = new SimpleDateFormat(format);  
	    try{ 
		    Date date = (Date)formatter.parse(str); 
		    return str.equals(formatter.format(date)); 
		}catch(Exception e){ 
		    return false; 
	    } 
    }

    /**
     * date2比date1多的天数
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1,Date date2)
    {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1= cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if(year1 != year2)   //同一年
        {
            int timeDistance = 0 ;
            for(int i = year1 ; i < year2 ; i ++)
            {
                if(i%4==0 && i%100!=0 || i%400==0)    //闰年
                {
                    timeDistance += 366;
                }
                else    //不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2-day1) ;
        }
        else    //不同年
        {
            System.out.println("判断day2 - day1 : " + (day2-day1));
            return day2-day1;
        }
    }

    public static HashMap<String,String> createAllDays(String startDate, String endDate){
        HashMap<String,String> allDays = new HashMap<String,String>();
        try{
            for(int i = 0; i < 30; i++) {
                Date date = sdfymd.parse(startDate);
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(date);
                // 把日期增加一天.整数往后推,负数往前移动
                calendar.add(calendar.DATE, 1);
                // 这个时间就是日期往前推一天的结果
                String dateStr = sdfymd.format(calendar.getTime());
                allDays.put(dateStr, dateStr);
                if (dateStr.equals(endDate)) {
                    return allDays;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return allDays;
    }


    /**
     * 获得昨天的日期
     * @return
     */
    public static String getYestDay() {
        SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.DATE,-1);
        Date d=cal.getTime();
        return sdf.format(d);
    }

    /**
     * 获得昨天的日期
     * @param date
     * @return
     */
    public static Date string2Date(String date) {
        SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd");
        try {
            return sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return new Date();
        }
    }

    public static String getPrevQuart(int m){
        String mon = "";
        if(12 == m || m < 3){
            mon = "09,10,11";
        }else if(3 <= m && m  < 6){
            mon = "12,01,02";
        }else if(6 <= m && m  < 9){
            mon = "03,04,05";
        }else{
            mon = "06,07,08";
        }
        return mon;
    }


    /**
     *
     * @param i 过去几天 例如-1 表示过去一天 -2表示过去2天  2表示未来两天
     * @return
     */
    public static Date getStartTime(int i){
        Calendar todayStart = Calendar.getInstance();
        todayStart.add(Calendar.DATE,i);
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }


    /**
     *
     * @param i 过去几天 例如-1 表示过去一天 -2表示过去2天  2表示未来两天
     * @return
     */
    public static Date getEndTime(int i){
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.add(Calendar.DATE,i);
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }




    public static String getAdress(String lat, String lng) throws MalformedURLException {
        long start=System.currentTimeMillis();
        BufferedReader in = null;
        URL tirc = new URL("http://api.map.baidu.com/geocoder/v2/?location="+lat+","+lng+"&output=json&pois=1&ak=KXIElFezuIhKnR45AbOvEwGj");
        String address = null;
        try {
            in = new BufferedReader(new InputStreamReader(tirc.openStream(),"UTF-8"));
            String res;
            StringBuilder sb = new StringBuilder();
            while((res = in.readLine())!=null){
                sb.append(res.trim());
            }
            String str = sb.toString();
            ObjectMapper mapper = new ObjectMapper();
            if(org.apache.commons.lang3.StringUtils.isNotEmpty(str)){
                JsonNode jsonNode = mapper.readTree(str);
                jsonNode.findValue("status").toString();
                JsonNode resultNode = jsonNode.findValue("result");
                address = resultNode.findValue("formatted_address").toString();
                System.out.println(address);
                address = address.substring(1,address.length()-1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(in!=null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(System.currentTimeMillis()-start);
        return address;
    }

    /**
     * 获取从当月开始往前推12个月的值
     * @return
     */
    public static List<String> getTwelvemonthValue(){
        List<String> list = new ArrayList<>();
        Date date = new Date();
        for(int i = 11; i >= 0; i--){
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.MONTH,-i);//减i个月
//            date = calendar.getTime();
            list.add((calendar.getTime().getMonth()+1)+"月");
        }
        return list;
    }

}

HTTP工具类:发送get请求等

package com.web.gps.everydayMileage.entity;


import com.web.utils.CommonUtils;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

/**
 * http客户端
 * 
 */
public class HttpClient {
    public static final String METHOD_POST = "POST";
    public static final String METHOD_GET = "GET";

    /**
     * HTTP连接超时,单位:毫秒
     */
    private static final int CONNECT_TIMEOUT = 5 * 1000;

    /**
     * HTTP读超时,单位:毫秒
     */
    private static final int READ_TIMEOUT = 5 * 1000;

    /**
     * 是否开启HTTPS
     */
    public static boolean isEnableHttps = false;

    /**编码*/
    public static final String CHAR_ENC = "UTF-8";
    /**
     * 发送请求
     * @param url
     * @param parameters
     * @param method
     * @return
     * @throws IOException
     */
    public static String sendRequest(String url, String parameters, String method) {
        HttpURLConnection urlConnection = null;
        try {
            if (isEnableHttps) {
                urlConnection = initHttps(url, parameters, method);
            } else {
                urlConnection = initHttp(url, parameters, method);
            }
        } catch (IOException e) {
            StringBuilder result = new StringBuilder();
            result.append("{\"status\":").append("-1").append(",").append("\"message\":")
                    .append("\"").append(CommonUtils.transExceptionToString(e)).append("\"}");
            return result.toString();
        }

        String result = null;

        switch (method) {
            case METHOD_POST:
                result = sendPostRequest(urlConnection, parameters);
                break;

            case METHOD_GET:
                result = sendGetRequest(urlConnection);
                break;

            default:
                break;
        }

        return result;
    }

    /**
     * 初始化HTTPS连接
     * 
     * @param url
     * @param parameters
     * @param method
     * @return
     * @throws IOException
     */
    private static HttpsURLConnection initHttps(String url, String parameters, String method) throws IOException {
        URL httpUrl = initURL(url, parameters, method);
        HttpsURLConnection urlConnection = (HttpsURLConnection) httpUrl.openConnection();
        initConnection(urlConnection, method);
        ((HttpsURLConnection) urlConnection).setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                HostnameVerifier hVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
                return hVerifier.verify(hostname, session);
            }
        });
        return urlConnection;
    }

    /**
     * 初始化HTTP
     * 
     * @param url
     * @param parameters
     * @param method
     * @return
     * @throws IOException
     */
    private static HttpURLConnection initHttp(String url, String parameters, String method) throws IOException {
        URL httpUrl = initURL(url, parameters, method);
        HttpURLConnection urlConnection = (HttpURLConnection) httpUrl.openConnection();
        initConnection(urlConnection, method);
        return urlConnection;
    }

    /**
     * 初始化URL
     * 
     * @param path
     * @param parameters
     * @param method
     * @return
     * @throws MalformedURLException
     */
    private static URL initURL(String path, String parameters, String method) throws MalformedURLException {
        URL url = null;
        if (METHOD_GET.equalsIgnoreCase(method)) {
            url = new URL(path + "?" + parameters);
        } else {
            url = new URL(path);
        }
        return url;
    }

    /**
     * 初始化Connection(HttpsURLConnection继承于HttpURLConnection)
     * 
     * @param urlConnection
     * @param method
     * @throws ProtocolException
     */
    private static void initConnection(HttpURLConnection urlConnection, String method) throws ProtocolException {
        urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        urlConnection.setRequestMethod(method);
        urlConnection.setConnectTimeout(CONNECT_TIMEOUT);
        urlConnection.setReadTimeout(READ_TIMEOUT);
        urlConnection.setUseCaches(false);
        urlConnection.setDoOutput(true);
        urlConnection.setDoInput(true);
    }

    /**
     * 发送get请求
     * 
     * @param urlConnection
     * @return
     */
    private static String sendGetRequest(HttpURLConnection urlConnection) {
        InputStream inStream = null;
        try {
            int responseCode = urlConnection.getResponseCode();
            if (HttpURLConnection.HTTP_OK == responseCode) {
                inStream = urlConnection.getInputStream();
                return handleInputStream(inStream);
            } else {
                return handleHttpResponseCode(responseCode, urlConnection.getResponseMessage());
            }
        } catch (IOException ex) {
            return handleIOException(ex);
        } finally {
            if (null != inStream) {
                try {
                    inStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 发送post请求
     * 
     * @param urlConnection
     * @param parameters
     * @return
     */
    public static String sendPostRequest(HttpURLConnection urlConnection, String parameters) {
        OutputStream outStream = null;
        InputStream inStream = null;
        try {
            outStream = urlConnection.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outStream,CHAR_ENC));
            writer.write(parameters);
            writer.flush();
            writer.close();
            urlConnection.connect();
            int responseCode = urlConnection.getResponseCode();
            if (HttpURLConnection.HTTP_OK == responseCode) {
                inStream = urlConnection.getInputStream();
                return handleInputStream(inStream);
            } else {
                return handleHttpResponseCode(responseCode, urlConnection.getResponseMessage());
            }
        } catch (IOException ex) {
            return handleIOException(ex);
        } finally {
            try {
                if (null != outStream) {
                    outStream.close();
                }
                if (null != inStream) {
                    inStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 解析输入流
     *
     * @param inputStream
     *
     * @return
     *
     * @throws IOException
     */
    private static String handleInputStream(InputStream inputStream) {
        BufferedReader bufferedReader=null;
		try {
			bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
        StringBuffer result = new StringBuffer("");
        String line;
        try {
            while (null != (line = bufferedReader.readLine())) {
                result.append(line);
            }
        } catch (IOException ex) {
            return handleIOException(ex);
        } finally {
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    bufferedReader = null;
                }
            }
        }
        return result.toString();
    }

    /**
     * 处理IO异常
     * 
     * @param ex
     * @return
     */
    private static String handleIOException(IOException ex) {
        StringBuilder result = new StringBuilder();
        result.append("{\"status\":").append("-1").append(",").append("\"message\":").append("\"")
                .append(CommonUtils.transExceptionToString(ex)).append("\"}");
        return result.toString();
    }

    /**
     * 处理http非ok的响应状态码
     * 
     * @param responseCode
     * @param responseString
     * @return
     */
    private static String handleHttpResponseCode(int responseCode, String responseString) {
        StringBuilder result = new StringBuilder();
        result.append("{\"status\":").append(String.valueOf(responseCode)).append(",").append("\"message\":")
                .append("\"").append(responseString).append("\"}");
        return result.toString();
    }
}

获取历史轨迹的方法

package com.web.gps.everydayMileage.service.impl;

import com.socket.bean.TerminalHistorySpot;
import com.socket.util.gps.BaiduGPSCorrect;
import com.socket.util.gps.GpsCorrect;
import com.socket.utils.OtherUtils;
import com.web.gps.everydayMileage.entity.HttpClient;
import com.web.gps.everydayMileage.service.RoadService;
import com.web.gps.lushu.service.impl.LushuServiceImpl;
import net.sf.json.JSONObject;
import org.json.XML;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @ClassName RoadServiceImpl
 * @Description  抓路服务,校准历史轨迹
 *
 */
@Service("roadService")
public class RoadServiceImpl implements RoadService {
	/** 高德抓路服务的url请求地址,请求方式为GET */
	public static final String GAODE_URL= "https://restapi.amap.com/v3/autograsp";
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static AtomicLong mSequenceGenerator = new AtomicLong();
    private static AtomicInteger successCounter = new AtomicInteger();
    private static AtomicInteger failedCounter = new AtomicInteger();
	static Logger log = LoggerFactory.getLogger(LushuServiceImpl.class);
	/**
	 * 根据历史轨迹点中的经纬度、时间、方向、速度等信息,调用高德的抓路服务,将坐标点匹配到道路之上
	 * @param terminalHistorySpotList
	 * @param  userKey 调用高德服务的用户key
	 * @param  termCode 设备号,用来标识车辆
	 * @return JSONObject
	 */
	@Override
	public JSONObject adjustHistoryTrackByGaoDe(
            List<TerminalHistorySpot> terminalHistorySpotList, String userKey, String termCode) {
		/**
		 * key 用户唯一标识,用户在高德地图官网申请
		   carId 填写key的后四位+企业车辆唯一编号,如“abcd123456”
		   locations 用于抓路的经纬度坐标,要求每次传入按utc时间排列的三个或三个以上经纬度坐标对,且相邻经纬度gps时间间隔小于300s,距离小于1km
				            坐标的经纬度之间用","间隔,坐标对之间用"|"间隔
		   time gps时间,要求为utc时间,与参数locations指定的坐标点一一对应,gps时间个数与坐标点数量一致
		   direction 车辆的方位角,与参数locations指定的坐标点一一对应,方位角个数与坐标点数量一致
					以正北方向为0度,沿顺时针方向为正值,取值范围[0,360),精确到小数点后一位
		   speed 车辆行驶速度,与参数locations指定的坐标点一一对应,速度值个数与坐标点数量一致,单位:km/h
		 */
		//根据terminalHistorySpotList中的数据拼接locations、time、direction和speed
		StringBuffer locations=new StringBuffer();
		StringBuffer time=new StringBuffer();
		StringBuffer direction=new StringBuffer();
		StringBuffer speed=new StringBuffer();
		for (TerminalHistorySpot terminalHistorySpot : terminalHistorySpotList) {
			locations.append(terminalHistorySpot.getLng()+",");
			locations.append(terminalHistorySpot.getLat()+"|");
	        time.append(String.valueOf(terminalHistorySpot.getTime()/1000)+",");
			direction.append(terminalHistorySpot.getAzimuth()+",");
			speed.append(terminalHistorySpot.getSpeed()+",");
		}
		String carId = userKey.substring(userKey.length()-4,userKey.length())+termCode;
		//去掉拼接字符串的最后一个字符“,”或“|”
		locations.deleteCharAt(locations.length()-1);
		time.deleteCharAt(time.length()-1);
		direction.deleteCharAt(direction.length()-1);
		speed.deleteCharAt(speed.length()-1);
		//拼接请求的url参数
		StringBuffer parameters = new StringBuffer();
		parameters.append("carid="+carId);
		parameters.append("&locations="+locations);
		parameters.append("&time="+time);
		parameters.append("&direction="+direction);
		parameters.append("&speed="+speed);
		parameters.append("&output=xml");
		parameters.append("&key="+userKey);
		//发送http请求
		String result = HttpClient.sendRequest(GAODE_URL, parameters.toString(), HttpClient.METHOD_GET);
		//将请求的结果转换成json对象,并返回
		JSONObject json = JSONObject.fromObject(XML.toJSONObject(result).get("response").toString());
		return json;
	}
	/**
	 * 将历史轨迹按时间戳从小到大排序
	 * @return list
	 */
	public List<TerminalHistorySpot> sortList(List<TerminalHistorySpot> list) {
		Collections.sort(list, new Comparator<TerminalHistorySpot>() {
			/**
			 * int compare(TerminalLocator ter1, TerminalLocator ter2)
			 * 返回一个基本类型的整型 返回负数表示:ter1小于ter2 返回0表示:ter1和ter2相等 返回正数表示:ter1大于ter2
			 */
			public int compare(TerminalHistorySpot ter1, TerminalHistorySpot ter2) {
				// 按照车辆终端定位设备时间戳从小到大进行升序排列
				if (ter1.getTime() > ter2.getTime()) {
					return 1;
				}
				if (ter1.getTime() == ter2.getTime()) {
					return 0;
				}
				return -1;
			}
		});
		return list;
	}

	/**查询多车多天的历史轨迹*/
	public Map<String, Map<String, List<TerminalHistorySpot>>> queryHistoricalTrajectory(
            String[] termCodes, Date startDate, Date endDate, String mapType) {
		// 获得要查询的天数集合
		List<Date> dateResult = getBetweenDates(startDate, endDate);
		// 查询
		Map<String, Map<String, List<TerminalHistorySpot>>> tcMap = loadFile(
				termCodes, dateResult, mapType,startDate.getTime(),endDate.getTime());
		return tcMap;
	}
	/**
	 * 查询文件数据,根据设备号分组,每组设备号根据时间进行分组
	 * @param termCodes		多个设备号
	 * @param dateResult	查询哪些天的数据
	 * @param mapType		数据类型	baidu,gaode
	 * @param startTime		开始时间
	 * @param endTime		结束时间
	 * @return
	 */
	public Map<String, Map<String, List<TerminalHistorySpot>>> loadFile(
            String[] termCodes, List<Date> dateResult, String mapType, Long startTime, Long endTime) {
		Long ss = System.currentTimeMillis();

		SimpleDateFormat daySdf = new SimpleDateFormat("yyyy-MM-dd");
		Map<String, Map<String, List<TerminalHistorySpot>>> tcMap = new HashMap<String, Map<String, List<TerminalHistorySpot>>>();
		for (String termCode : termCodes) {
			Map<String, List<TerminalHistorySpot>> dateMap = new TreeMap<String, List<TerminalHistorySpot>>();
			for (Date date : dateResult) {
				String day = daySdf.format(date);
				// 获取文件存放地址
				String path = OtherUtils.gpsHistorySpot(date);
				List<String> jsonList = readLine(path + "Data" + termCode + ".txt");
				List<TerminalHistorySpot> list = new ArrayList<TerminalHistorySpot>();
				for (String json : jsonList) {
					try {
						TerminalHistorySpot ths = com.alibaba.fastjson.JSONObject.parseObject(json, TerminalHistorySpot.class);
						//如果当前点的时间不在范围内则不放到list中
						if (ths != null && ths.time != null && ths.time >= startTime && ths.time <= endTime) {
							if(ths.getLat() <= 1 || ths.getLng() <= 1){
								log.info("当前点不在国内,舍弃-spot not in China----》");
							}else{
								// 转换坐标
								if ("baidu".equals(mapType)) {
									double[] latlng = BaiduGPSCorrect.gps_encrypt(ths.getLat(), ths.getLng());
									ths.setLng(latlng[1]);
									ths.setLat(latlng[0]);
								} else if ("gaode".equals(mapType)) {
									double[] latlng = new double[2];
									GpsCorrect.transform(ths.getLat(), ths.getLng(), latlng);
									ths.setLng(latlng[1]);
									ths.setLat(latlng[0]);
								}
								list.add(ths);
							}
						}
					} catch (Exception e) {
						log.error("read file latlng读取文件转换坐标异常:",e);
					}
				}
				if(list != null && list.size() > 0){
					// 按时间早晚排序坐标
					TerminalHistorySpot comparator = new TerminalHistorySpot();
					Collections.sort(list, comparator);
					dateMap.put(day, list);
				}
			}
			tcMap.put(termCode, dateMap);
		}
		log.info("历史轨迹查询 总共耗时:" + (System.currentTimeMillis() - ss));
		return tcMap;

	}

	/**
	 * 获取两个日期之间的日期
	 * @param start 开始日期
	 * @param end 结束日期
	 * @return 日期集合
	 */
	public List<Date> getBetweenDates(Date start, Date end) {
		try {
			//将起始时间格式化为 yyyy-MM-dd 00:00:00
			start = sdf.parse(sdf.format(start));
		} catch (Exception e) {
			e.printStackTrace();
		}
		List<Date> result = new ArrayList<Date>();
		Calendar tempStart = Calendar.getInstance();
		tempStart.setTime(start);
		while(start.getTime()<=end.getTime()){
			result.add(tempStart.getTime());
			tempStart.add(Calendar.DAY_OF_YEAR, 1);
			start = tempStart.getTime();
		}
		return result;
	}
	/**
	 * 按行读取文件
	 * @param
	 * @return
	 * @exception
	 */
	public List<String> readLine(String url) {
		List<String> jsonList = new ArrayList<String>();
		// Text文件
		File file = new File(url);
		if(!file.exists()){
			return jsonList;
		}
		BufferedReader br = null;
		try {
			// 构造一个BufferedReader类来读取文件
			br = new BufferedReader(new FileReader(file));
			String s = null;
			// 使用readLine方法,一次读一行
			while ((s = br.readLine()) != null) {
				jsonList.add(s);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return jsonList;
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值