GpsServiceImpl.java 9.61 KB
package com.bsth.service.gps;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bsth.data.BasicData;
import com.bsth.data.arrival.ArrivalEntity;
import com.bsth.repository.CarParkRepository;
import com.bsth.repository.StationRepository;
import com.bsth.util.DateUtils;
import com.bsth.util.TransGPS;
import com.bsth.util.TransGPS.Location;
import com.bsth.util.db.DBUtils_MS;

@Service
public class GpsServiceImpl implements GpsService{
	/** 历史gps查询最大范围 24小时 */
	final static Long GPS_RANGE = 60 * 60 * 24L;

	/** jdbc */
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;

	Logger logger = LoggerFactory.getLogger(this.getClass());

	// 历史gps查询
	@Override
	public List<Map<String, Object>> history(String device, Long startTime, Long endTime, int directions) {
		Calendar sCal = Calendar.getInstance();
		sCal.setTime(new Date(startTime));

		Calendar eCal = Calendar.getInstance();
		eCal.setTime(new Date(endTime));

		int dayOfYear = sCal.get(Calendar.DAY_OF_YEAR);
		/*
		 * if(dayOfYear != eCal.get(Calendar.DAY_OF_YEAR)){
		 * System.out.println("暂时不支持跨天查询..."); return null; }
		 */

		String sql = "select DEVICE_ID,LON,LAT,TS,INOUT_STOP,SERVICE_STATE ,STOP_NO from bsth_c_gps_info where days_year=? and device_id=? and ts > ? and ts < ?";
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<Map<String, Object>> list = new ArrayList<>();
		Map<String, Object> map = null;
		try {
			conn = DBUtils_MS.getConnection();
			ps = conn.prepareStatement(sql);
			ps.setInt(1, dayOfYear);
			ps.setString(2, device);
			ps.setLong(3, startTime);
			ps.setLong(4, endTime);

			rs = ps.executeQuery();
			Float lon, lat;
			Location location;
			int upDown;
			while (rs.next()) {
				upDown = getUpOrDown(rs.getLong("SERVICE_STATE"));
				if (upDown != directions)
					continue;

				// to 百度坐标
				lon = rs.getFloat("LON");
				lat = rs.getFloat("LAT");
				location = TransGPS.LocationMake(lon, lat);
				location = TransGPS.bd_encrypt(TransGPS.transformFromWGSToGCJ(location));

				map = new HashMap<>();
				map.put("device", rs.getString("DEVICE_ID"));
				map.put("lon", location.getLng());
				map.put("lat", location.getLat());
				map.put("ts", rs.getLong("TS"));
				map.put("stopNo", rs.getString("STOP_NO"));
				map.put("inout_stop", rs.getInt("INOUT_STOP"));
				// 上下行
				map.put("upDown", upDown);
				list.add(map);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBUtils_MS.close(rs, ps, conn);
		}
		return list;
	}

	/**
	 * 王通 2016/6/29 9:23:24 获取车辆线路上下行
	 * 
	 * @return -1无效 0上行 1下行
	 */
	public static byte getUpOrDown(long serviceState) {
		if ((serviceState & 0x00020000) == 0x00020000 || (serviceState & 0x80000000) == 0x80000000
				|| (serviceState & 0x01000000) == 0x01000000 || (serviceState & 0x08000000) == 0x08000000)
			return -1;
		return (byte) (((serviceState & 0x10000000) == 0x10000000) ? 1 : 0);
	}

	@Override
	public List<Map<String, Object>> history(String[] nbbmArray, Long st, Long et) {
		List<Map<String, Object>> list = new ArrayList<>();
		// 超过最大查询范围,直接忽略
		if (et - st > GPS_RANGE)
			return list;

		// 车辆编码转换成设备号
		String[] devices = new String[nbbmArray.length];
		for (int i = 0; i < nbbmArray.length; i++) {
			devices[i] = BasicData.deviceId2NbbmMap.inverse().get(nbbmArray[i]);
		}
		// day_of_year
		Calendar sCal = Calendar.getInstance();
		sCal.setTime(new Date(st * 1000));
		int sDayOfYear = sCal.get(Calendar.DAY_OF_YEAR)/* 200 */;

		Calendar eCal = Calendar.getInstance();
		eCal.setTime(new Date(et * 1000));
		int eDayOfYear = eCal.get(Calendar.DAY_OF_YEAR)/* 200 */;

		Calendar weekCal = Calendar.getInstance();

		// 如果是同一天
		if (sDayOfYear == eDayOfYear) {
			weekCal.setTimeInMillis(st * 1000);
			list = findByTs(weekCal.get(Calendar.WEEK_OF_YEAR), sDayOfYear, st, et, devices);
		} else {
			// 跨天
			Long tempSt = 0L, tempEt = 0L;
			for (int i = sDayOfYear; i <= eDayOfYear; i++) {

				if (i == sDayOfYear) {
					tempSt = st;
					tempEt = DateUtils.getTimesnight(sCal);
				} else if (i == eDayOfYear) {
					tempSt = DateUtils.getTimesmorning(sCal);
					tempEt = et;
				} else {
					tempSt = DateUtils.getTimesmorning(sCal);
					tempEt = DateUtils.getTimesnight(sCal);
				}

				weekCal.setTimeInMillis(tempSt * 1000);
				list.addAll(findByTs(weekCal.get(Calendar.WEEK_OF_YEAR), i, tempSt, tempEt, devices));
				// 加一天
				sCal.add(Calendar.DATE, 1);
			}
		}

		// 按时间排序
		Collections.sort(list, new Comparator<Map<String, Object>>() {

			@Override
			public int compare(Map<String, Object> o1, Map<String, Object> o2) {
				return (int) (Long.parseLong(o1.get("ts").toString()) - Long.parseLong(o2.get("ts").toString()));
			}
		});
		;
		return list;
	}

	public List<Map<String, Object>> findByTs(int weekOfYear, int dayOfYear, Long st, Long et, String[] devices) {
		List<Map<String, Object>> list = new ArrayList<>();
		Map<String, Object> map = null;

		// setArray 不好用,直接拼 in 语句
		String inv = "";
		for (String device : devices)
			inv += ("'" + device + "',");
		inv = inv.substring(0, inv.length() - 1);

		// 查询到离站数据
		Map<String, ArrivalEntity> arrivalMap = findArrivalByTs(weekOfYear/* 30 */, st, et, inv);

		String sql = "select DEVICE_ID,LON,LAT,TS,INOUT_STOP,SERVICE_STATE ,STOP_NO from bsth_c_gps_info where days_year=? and device_id in ("
				+ inv + ") and ts > ? and ts < ?";
		try {
			conn = DBUtils_MS.getConnection();
			ps = conn.prepareStatement(sql);
			ps.setInt(1, dayOfYear);
			/* ps.setArray(2, conn.createArrayOf("VARCHAR", devices)); */
			ps.setLong(2, st * 1000);
			ps.setLong(3, et * 1000);

			rs = ps.executeQuery();
			Float lon, lat;
			Location bdLoc, gdLoc;
			int upDown, inOutStop;
			ArrivalEntity arrival;
			while (rs.next()) {
				upDown = getUpOrDown(rs.getLong("SERVICE_STATE"));
				map = new HashMap<>();

				lon = rs.getFloat("LON");
				lat = rs.getFloat("LAT");
				// 高德坐标
				gdLoc = TransGPS.transformFromWGSToGCJ(TransGPS.LocationMake(lon, lat));
				map.put("gcj_lon", gdLoc.getLng());
				map.put("gcj_lat", gdLoc.getLat());
				// 百度坐标
				bdLoc = TransGPS.bd_encrypt(gdLoc);
				map.put("bd_lon", bdLoc.getLng());
				map.put("bd_lat", bdLoc.getLat());

				map.put("deviceId", rs.getString("DEVICE_ID"));
				map.put("ts", rs.getLong("TS"));
				map.put("timestamp", rs.getLong("TS"));
				map.put("stopNo", rs.getString("STOP_NO"));

				inOutStop = rs.getInt("INOUT_STOP");
				map.put("inout_stop", inOutStop);

				arrival = arrivalMap.get(rs.getString("DEVICE_ID") + "_" + rs.getLong("TS"));
				if (arrival != null) {
					map.put("inout_stop_info",arrival);
					map.put("inout_stop", arrival.getInOut());
				}
				map.put("nbbm", BasicData.deviceId2NbbmMap.get(rs.getString("DEVICE_ID")));
				map.put("state", 0);
				// 上下行
				map.put("upDown", upDown);
				list.add(map);
			}
		} catch (Exception e) {
			logger.error("", e);
		} finally {
			DBUtils_MS.close(rs, ps, conn);
		}
		return list;
	}

	public Map<String, ArrivalEntity> findArrivalByTs(int weekOfYear, Long st, Long et, String devicesInSql) {
		Map<String, ArrivalEntity> map = new HashMap<>();

		String sql = "SELECT DEVICE_ID,LINE_ID,STOP_NO,TS,UP_DOWN,IN_OUT,WEEKS_YEAR,CREATE_DATE FROM bsth_c_arrival_info where weeks_year=? and device_id in ("
				+ devicesInSql + ") and ts > ? and ts < ?";
		try {
			conn = DBUtils_MS.getConnection();
			ps = conn.prepareStatement(sql);
			ps.setInt(1, weekOfYear);
			ps.setLong(2, st * 1000);
			ps.setLong(3, et * 1000);

			rs = ps.executeQuery();
			ArrivalEntity arr;
			int inOut;
			while (rs.next()) {
				arr = new ArrivalEntity(rs.getString("DEVICE_ID"), rs.getLong("TS"), rs.getString("LINE_ID"),
						rs.getInt("UP_DOWN"), rs.getString("STOP_NO"), rs.getInt("IN_OUT"), rs.getLong("CREATE_DATE"),
						rs.getInt("WEEKS_YEAR"), BasicData.stationCode2NameMap.get(rs.getString("STOP_NO")));

				// 设备号_时间戳_进出状态 为key
				// 反转进出状态
				inOut = arr.getInOut() == 0 ? 1 : 0;
				map.put(arr.getDeviceId() + "_" + arr.getTs(), arr);
			}
		} catch (Exception e) {
			logger.error("", e);
		} finally {
			DBUtils_MS.close(rs, ps, conn);
		}
		return map;
	}

	
	@Autowired
	StationRepository stationRepository;
	
	@Autowired
	CarParkRepository carParkRepository;
	
	@Override
	public Map<String, Object> findBuffAeraByCode(String code, String type) {
		Object[][] obj = null;
		if(type.equals("station"))
			obj = stationRepository.bufferAera(code);
		else if(type.equals("park"))
			obj = carParkRepository.bufferAera(code);
		
		Map<String, Object> rs = new HashMap<>();
		
		Object[] subObj = obj[0];
		if(subObj != null && subObj.length == 6){
			rs.put("polygon", subObj[0]);
			rs.put("type", subObj[1]);
			rs.put("cPoint", subObj[2]);
			rs.put("radius", subObj[3]);
			rs.put("code", subObj[4]);
			rs.put("text", subObj[5]);
		}
		
		return rs;
	}
}