Commit 636b7c5475897d1ca35b112560956e59e1f9bd6c
1 parent
bf762407
增加移动位置API接口支持
Showing
5 changed files
with
291 additions
and
2 deletions
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
| ... | ... | @@ -4,6 +4,7 @@ import java.util.List; |
| 4 | 4 | |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 7 | +import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; | |
| 7 | 8 | import com.github.pagehelper.PageInfo; |
| 8 | 9 | |
| 9 | 10 | /** |
| ... | ... | @@ -151,4 +152,30 @@ public interface IVideoManagerStorager { |
| 151 | 152 | */ |
| 152 | 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>=#{startTime}</if>" + | |
| 21 | + "<if test=\"endTime != null\"> AND time<=#{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 | 3 | import java.util.*; |
| 4 | 4 | |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; | |
| 6 | 7 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
| 7 | 8 | import com.genersoft.iot.vmp.storager.dao.DeviceMapper; |
| 9 | +import com.genersoft.iot.vmp.storager.dao.DeviceMobilePositionMapper; | |
| 8 | 10 | import com.github.pagehelper.PageHelper; |
| 9 | 11 | import com.github.pagehelper.PageInfo; |
| 10 | 12 | import io.swagger.models.auth.In; |
| ... | ... | @@ -27,7 +29,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { |
| 27 | 29 | private DeviceMapper deviceMapper; |
| 28 | 30 | |
| 29 | 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 | 205 | return deviceMapper.update(device) > 0; |
| 201 | 206 | } |
| 202 | 207 | |
| 203 | - | |
| 208 | + /** | |
| 209 | + * 清空通道 | |
| 210 | + * @param deviceId | |
| 211 | + */ | |
| 204 | 212 | @Override |
| 205 | 213 | public void cleanChannelsForDevice(String deviceId) { |
| 206 | 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 | +} | ... | ... |