Commit 636b7c5475897d1ca35b112560956e59e1f9bd6c

Authored by Lawrence
1 parent bf762407

增加移动位置API接口支持

src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -4,6 +4,7 @@ import java.util.List; @@ -4,6 +4,7 @@ import java.util.List;
4 4
5 import com.genersoft.iot.vmp.gb28181.bean.Device; 5 import com.genersoft.iot.vmp.gb28181.bean.Device;
6 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 6 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  7 +import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
7 import com.github.pagehelper.PageInfo; 8 import com.github.pagehelper.PageInfo;
8 9
9 /** 10 /**
@@ -151,4 +152,30 @@ public interface IVideoManagerStorager { @@ -151,4 +152,30 @@ public interface IVideoManagerStorager {
151 */ 152 */
152 void cleanChannelsForDevice(String deviceId); 153 void cleanChannelsForDevice(String deviceId);
153 154
  155 + /**
  156 + * 添加Mobile Position设备移动位置
  157 + * @param MobilePosition
  158 + * @return
  159 + */
  160 + public boolean insertMobilePosition(MobilePosition mobilePosition);
  161 +
  162 + /**
  163 + * 查询移动位置轨迹
  164 + * @param deviceId
  165 + * @param startTime
  166 + * @param endTime
  167 + */
  168 + public List<MobilePosition> queryMobilePositions(String deviceId, String startTime, String endTime);
  169 +
  170 + /**
  171 + * 查询最新移动位置
  172 + * @param deviceId
  173 + */
  174 + public MobilePosition queryLatestPosition(String deviceId);
  175 +
  176 + /**
  177 + * 删除指定设备的所有移动位置
  178 + * @param deviceId
  179 + */
  180 + public int clearMobilePositionsByDeviceId(String deviceId);
154 } 181 }
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMobilePositionMapper.java 0 → 100644
  1 +package com.genersoft.iot.vmp.storager.dao;
  2 +
  3 +import java.util.List;
  4 +
  5 +import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
  6 +import org.apache.ibatis.annotations.*;
  7 +//import org.springframework.stereotype.Repository;
  8 +
  9 +@Mapper
  10 +//@Repository
  11 +public interface DeviceMobilePositionMapper {
  12 +
  13 + @Insert("INSERT INTO device_mobile_position (deviceId, deviceName, time, longitude, latitude, altitude, speed, direction, reportSource, geodeticSystem, cnLng, cnLat) " +
  14 + "VALUES ('${deviceId}', '${deviceName}', '${time}', ${longitude}, ${latitude}, ${altitude}, ${speed}, ${direction}, '${reportSource}', '${geodeticSystem}', '${cnLng}', '${cnLat}')")
  15 + int insertNewPosition(MobilePosition mobilePosition);
  16 +
  17 + @Select(value = {" <script>" +
  18 + "SELECT * FROM device_mobile_position" +
  19 + " WHERE deviceId = #{deviceId} " +
  20 + "<if test=\"startTime != null\"> AND time&gt;=#{startTime}</if>" +
  21 + "<if test=\"endTime != null\"> AND time&lt;=#{endTime}</if>" +
  22 + " ORDER BY time ASC" +
  23 + " </script>"})
  24 + List<MobilePosition> queryPositionByDeviceIdAndTime(String deviceId, String startTime, String endTime);
  25 +
  26 + @Select("SELECT * FROM device_mobile_position WHERE deviceId = #{deviceId}" +
  27 + " ORDER BY time DESC LIMIT 1")
  28 + MobilePosition queryLatestPositionByDevice(String deviceId);
  29 +
  30 + @Delete("DELETE FROM device_mobile_position WHERE deviceId = #{deviceId}")
  31 + int clearMobilePositionsByDeviceId(String deviceId);
  32 +
  33 +}
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -3,8 +3,10 @@ package com.genersoft.iot.vmp.storager.impl; @@ -3,8 +3,10 @@ package com.genersoft.iot.vmp.storager.impl;
3 import java.util.*; 3 import java.util.*;
4 4
5 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 5 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  6 +import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
6 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; 7 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
7 import com.genersoft.iot.vmp.storager.dao.DeviceMapper; 8 import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
  9 +import com.genersoft.iot.vmp.storager.dao.DeviceMobilePositionMapper;
8 import com.github.pagehelper.PageHelper; 10 import com.github.pagehelper.PageHelper;
9 import com.github.pagehelper.PageInfo; 11 import com.github.pagehelper.PageInfo;
10 import io.swagger.models.auth.In; 12 import io.swagger.models.auth.In;
@@ -27,7 +29,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -27,7 +29,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
27 private DeviceMapper deviceMapper; 29 private DeviceMapper deviceMapper;
28 30
29 @Autowired 31 @Autowired
30 - private DeviceChannelMapper deviceChannelMapper; 32 + private DeviceChannelMapper deviceChannelMapper;
  33 +
  34 + @Autowired
  35 + private DeviceMobilePositionMapper deviceMobilePositionMapper;
31 36
32 37
33 /** 38 /**
@@ -200,11 +205,49 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -200,11 +205,49 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
200 return deviceMapper.update(device) > 0; 205 return deviceMapper.update(device) > 0;
201 } 206 }
202 207
203 - 208 + /**
  209 + * 清空通道
  210 + * @param deviceId
  211 + */
204 @Override 212 @Override
205 public void cleanChannelsForDevice(String deviceId) { 213 public void cleanChannelsForDevice(String deviceId) {
206 int result = deviceChannelMapper.cleanChannelsByDeviceId(deviceId); 214 int result = deviceChannelMapper.cleanChannelsByDeviceId(deviceId);
207 } 215 }
208 216
  217 + /**
  218 + * 添加Mobile Position设备移动位置
  219 + * @param MobilePosition
  220 + */
  221 + @Override
  222 + public synchronized boolean insertMobilePosition(MobilePosition mobilePosition) {
  223 + return deviceMobilePositionMapper.insertNewPosition(mobilePosition) > 0;
  224 + }
209 225
  226 + /**
  227 + * 查询移动位置轨迹
  228 + * @param deviceId
  229 + * @param startTime
  230 + * @param endTime
  231 + */
  232 + @Override
  233 + public synchronized List<MobilePosition> queryMobilePositions(String deviceId, String startTime, String endTime) {
  234 + return deviceMobilePositionMapper.queryPositionByDeviceIdAndTime(deviceId, startTime, endTime);
  235 + }
  236 +
  237 + /**
  238 + * 查询最新移动位置
  239 + * @param deviceId
  240 + */
  241 + @Override
  242 + public MobilePosition queryLatestPosition(String deviceId) {
  243 + return deviceMobilePositionMapper.queryLatestPositionByDevice(deviceId);
  244 + }
  245 +
  246 + /**
  247 + * 删除指定设备的所有移动位置
  248 + * @param deviceId
  249 + */
  250 + public int clearMobilePositionsByDeviceId(String deviceId) {
  251 + return deviceMobilePositionMapper.clearMobilePositionsByDeviceId(deviceId);
  252 + }
210 } 253 }
src/main/java/com/genersoft/iot/vmp/utils/GpsUtil.java 0 → 100644
  1 +package com.genersoft.iot.vmp.utils;
  2 +
  3 +import java.io.BufferedReader;
  4 +import java.io.InputStreamReader;
  5 +import java.io.OutputStream;
  6 +import java.net.Socket;
  7 +import java.util.Base64;
  8 +
  9 +import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint;
  10 +
  11 +public class GpsUtil {
  12 + public static BaiduPoint Wgs84ToBd09(String xx, String yy) {
  13 + try {
  14 + Socket s = new Socket("api.map.baidu.com", 80);
  15 + BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
  16 + OutputStream out = s.getOutputStream();
  17 + StringBuffer sb = new StringBuffer("GET /ag/coord/convert?from=0&to=4");
  18 + sb.append("&x=" + xx + "&y=" + yy);
  19 + sb.append("&callback=BMap.Convertor.cbk_3976 HTTP/1.1\r\n");
  20 + sb.append("User-Agent: Java/1.6.0_20\r\n");
  21 + sb.append("Host: api.map.baidu.com:80\r\n");
  22 + sb.append("Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n");
  23 + sb.append("Connection: Close\r\n");
  24 + sb.append("\r\n");
  25 + out.write(sb.toString().getBytes());
  26 + String json = "";
  27 + String tmp = "";
  28 + while ((tmp = br.readLine()) != null) {
  29 + // System.out.println(tmp);
  30 + json += tmp;
  31 + }
  32 +
  33 + s.close();
  34 + int start = json.indexOf("cbk_3976");
  35 + int end = json.lastIndexOf("}");
  36 + if (start != -1 && end != -1 && json.contains("\"x\":\"")) {
  37 + json = json.substring(start, end);
  38 + String[] point = json.split(",");
  39 + String x = point[1].split(":")[1].replace("\"", "");
  40 + String y = point[2].split(":")[1].replace("\"", "");
  41 + BaiduPoint bdPoint= new BaiduPoint();
  42 + bdPoint.setBdLng(new String(decode(x)));
  43 + bdPoint.setBdLat(new String(decode(y)));
  44 + return bdPoint;
  45 + //return (new String(decode(x)) + "," + new String(decode(y)));
  46 + } else {
  47 + System.out.println("gps坐标无效!!");
  48 + }
  49 + out.close();
  50 + br.close();
  51 + } catch (Exception e) {
  52 + e.printStackTrace();
  53 + }
  54 + return null;
  55 + }
  56 +
  57 + /**
  58 + * BASE64解码
  59 + * @param str
  60 + * @return string
  61 + */
  62 + public static byte[] decode(String str) {
  63 + byte[] bt = null;
  64 + final Base64.Decoder decoder = Base64.getDecoder();
  65 + bt = decoder.decode(str); // .decodeBuffer(str);
  66 + return bt;
  67 + }
  68 +}
src/main/java/com/genersoft/iot/vmp/vmanager/MobilePosition/MobilePositionController.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.MobilePosition;
  2 +
  3 +import java.util.List;
  4 +
  5 +import javax.sip.message.Response;
  6 +
  7 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  8 +import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
  9 +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
  10 +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
  11 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  12 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  13 +import com.github.pagehelper.util.StringUtil;
  14 +
  15 +import org.slf4j.Logger;
  16 +import org.slf4j.LoggerFactory;
  17 +import org.springframework.beans.factory.annotation.Autowired;
  18 +import org.springframework.http.HttpStatus;
  19 +import org.springframework.http.ResponseEntity;
  20 +import org.springframework.web.bind.annotation.CrossOrigin;
  21 +import org.springframework.web.bind.annotation.GetMapping;
  22 +import org.springframework.web.bind.annotation.PathVariable;
  23 +import org.springframework.web.bind.annotation.RequestMapping;
  24 +import org.springframework.web.bind.annotation.RequestParam;
  25 +import org.springframework.web.bind.annotation.RestController;
  26 +import org.springframework.web.context.request.async.DeferredResult;
  27 +
  28 +@CrossOrigin
  29 +@RestController
  30 +@RequestMapping("/api")
  31 +public class MobilePositionController {
  32 +
  33 + private final static Logger logger = LoggerFactory.getLogger(MobilePositionController.class);
  34 +
  35 + @Autowired
  36 + private IVideoManagerStorager storager;
  37 +
  38 + @Autowired
  39 + private SIPCommander cmder;
  40 +
  41 + @Autowired
  42 + private DeferredResultHolder resultHolder;
  43 +
  44 + @GetMapping("/positions/{deviceId}/history")
  45 + public ResponseEntity<List<MobilePosition>> positions(@PathVariable String deviceId,
  46 + @RequestParam(required = false) String start,
  47 + @RequestParam(required = false) String end) {
  48 + if (logger.isDebugEnabled()) {
  49 + logger.debug("查询设备" + deviceId + "的历史轨迹");
  50 + }
  51 +
  52 + if (StringUtil.isEmpty(start)) {
  53 + start = null;
  54 + }
  55 + if (StringUtil.isEmpty(end)) {
  56 + end = null;
  57 + }
  58 +
  59 + List<MobilePosition> result = storager.queryMobilePositions(deviceId, start, end);
  60 + return new ResponseEntity<>(result, HttpStatus.OK);
  61 + }
  62 +
  63 + @GetMapping("/positions/{deviceId}/latest")
  64 + public ResponseEntity<MobilePosition> latestPosition(@PathVariable String deviceId) {
  65 + if (logger.isDebugEnabled()) {
  66 + logger.debug("查询设备" + deviceId + "的最新位置");
  67 + }
  68 + MobilePosition result = storager.queryLatestPosition(deviceId);
  69 + return new ResponseEntity<>(result, HttpStatus.OK);
  70 + }
  71 +
  72 + @GetMapping("/positions/{deviceId}/realtime")
  73 + public DeferredResult<ResponseEntity<MobilePosition>> realTimePosition(@PathVariable String deviceId) {
  74 + Device device = storager.queryVideoDevice(deviceId);
  75 + cmder.mobilePostitionQuery(device, event -> {
  76 + Response response = event.getResponse();
  77 + RequestMessage msg = new RequestMessage();
  78 + msg.setId(DeferredResultHolder.CALLBACK_CMD_MOBILEPOSITION + deviceId);
  79 + msg.setData(String.format("获取移动位置信息失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
  80 + resultHolder.invokeResult(msg);
  81 + });
  82 + DeferredResult<ResponseEntity<MobilePosition>> result = new DeferredResult<ResponseEntity<MobilePosition>>(5*1000L);
  83 + result.onTimeout(()->{
  84 + logger.warn(String.format("获取移动位置信息超时"));
  85 + // 释放rtpserver
  86 + RequestMessage msg = new RequestMessage();
  87 + msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId);
  88 + msg.setData("Timeout");
  89 + resultHolder.invokeResult(msg);
  90 + });
  91 + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result);
  92 + return result;
  93 + }
  94 +
  95 + @GetMapping("/positions/{deviceId}/subscribe")
  96 + public ResponseEntity<String> positionSubscribe(@PathVariable String deviceId,
  97 + @RequestParam String expires,
  98 + @RequestParam String interval) {
  99 + String msg = ((expires.equals("0")) ? "取消" : "") + "订阅设备" + deviceId + "的移动位置";
  100 + if (logger.isDebugEnabled()) {
  101 + logger.debug(msg);
  102 + }
  103 +
  104 + if (StringUtil.isEmpty(interval)) {
  105 + interval = "5";
  106 + }
  107 + Device device = storager.queryVideoDevice(deviceId);
  108 +
  109 + String result = msg;
  110 + if (cmder.mobilePositionSubscribe(device, Integer.parseInt(expires), Integer.parseInt(interval))) {
  111 + result += ",成功";
  112 + } else {
  113 + result += ",失败";
  114 + }
  115 +
  116 + return new ResponseEntity<>(result, HttpStatus.OK);
  117 + }
  118 +}