From b0088b8bd38c7ddc0c3f88fb2c8485d44e9a6ddb Mon Sep 17 00:00:00 2001
From: Lawrence <1934378145@qq.com>
Date: Fri, 22 Jan 2021 15:36:23 +0800
Subject: [PATCH 01/18] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=8D=E6=94=AF?=
=?UTF-8?q?=E6=8C=81=E7=9A=84method=E5=A4=84=E7=90=86=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../iot/vmp/gb28181/transmit/SIPProcessorFactory.java | 6 +++---
.../transmit/request/impl/OtherRequestProcessor.java | 2 +-
web_src/src/components/UiHeader.vue | 1 -
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
index b50cc957..13866e87 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -132,7 +132,6 @@ public class SIPProcessorFactory {
processor.setRequestEvent(evt);
return processor;
} else if (Request.MESSAGE.equals(method)) {
-
MessageRequestProcessor processor = new MessageRequestProcessor();
processor.setRequestEvent(evt);
processor.setTcpSipProvider(getTcpSipProvider());
@@ -146,12 +145,13 @@ public class SIPProcessorFactory {
processor.setRedisCatchStorage(redisCatchStorage);
return processor;
} else {
- return new OtherRequestProcessor();
+ OtherRequestProcessor processor = new OtherRequestProcessor();
+ processor.setRequestEvent(evt);
+ return processor;
}
}
public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) {
-
Response response = evt.getResponse();
CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
String method = cseqHeader.getMethod();
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java
index 63da9914..028835b3 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java
@@ -21,7 +21,7 @@ public class OtherRequestProcessor extends SIPRequestAbstractProcessor {
*/
@Override
public void process(RequestEvent evt) {
- System.out.println("no support the method! Method:" + evt.getRequest().getMethod());
+ System.out.println("Unsupported the method: " + evt.getRequest().getMethod());
}
}
diff --git a/web_src/src/components/UiHeader.vue b/web_src/src/components/UiHeader.vue
index 282a89d1..8b84ef24 100644
--- a/web_src/src/components/UiHeader.vue
+++ b/web_src/src/components/UiHeader.vue
@@ -21,7 +21,6 @@ export default {
};
},
methods:{
-
loginout(){
// 删除cookie,回到登录页面
this.$cookies.remove("session");
From 9571eb3a15046bf12dae06f58d567b9a8a307e66 Mon Sep 17 00:00:00 2001
From: Lawrence <1934378145@qq.com>
Date: Wed, 27 Jan 2021 15:24:28 +0800
Subject: [PATCH 02/18] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A7=BB=E5=8A=A8?=
=?UTF-8?q?=E4=BD=8D=E7=BD=AE=E6=98=BE=E7=A4=BA=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 8 +
web_src/index.html | 1 +
web_src/package-lock.json | 80 ++++-
web_src/package.json | 1 +
web_src/src/components/GeoConvertTools.js | 250 +++++++++++++++
web_src/src/components/devicePosition.vue | 374 ++++++++++++++++++++++
web_src/src/components/videoList.vue | 38 ++-
web_src/src/main.js | 10 +-
web_src/src/router/index.js | 6 +
9 files changed, 744 insertions(+), 24 deletions(-)
create mode 100644 web_src/src/components/GeoConvertTools.js
create mode 100644 web_src/src/components/devicePosition.vue
diff --git a/README.md b/README.md
index 724cfef7..40a522ce 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,14 @@ https://gitee.com/18010473990/wvp-GB28181.git
12. 支持播放h265, g.711格式的流
13. 支持固定流地址和自动点播,同时支持未点播时直接播放流地址,代码自动发起点播. ( [查看WIKI](https://github.com/648540858/wvp-GB28181-pro/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E5%9B%BA%E5%AE%9A%E6%92%AD%E6%94%BE%E5%9C%B0%E5%9D%80%E4%B8%8E%E8%87%AA%E5%8A%A8%E7%82%B9%E6%92%AD))
14. 报警信息处理,支持向前端推送报警信息
+15. 支持订阅与通知方法
+ [X] 移动位置订阅
+ [X] 移动位置通知处理
+ [ ] 报警事件订阅
+ [X] 报警事件通知处理
+ [ ] 设备目录订阅
+ [X] 设备奴鲁通知处理
+16. 移动位置查询和显示,可通过配置文件设置移动位置历史是否存储
# 待实现:
上级级联
diff --git a/web_src/index.html b/web_src/index.html
index 12241251..8b26e729 100644
--- a/web_src/index.html
+++ b/web_src/index.html
@@ -7,6 +7,7 @@
+
diff --git a/web_src/package-lock.json b/web_src/package-lock.json
index fb6278de..54840f6c 100644
--- a/web_src/package-lock.json
+++ b/web_src/package-lock.json
@@ -1269,6 +1269,34 @@
"integrity": "sha1-nyKcFb4nJFT/qXOs4NvueaGww28=",
"dev": true
},
+ "bmaplib.curveline": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/bmaplib.curveline/-/bmaplib.curveline-1.0.0.tgz",
+ "integrity": "sha512-9wcFMVhiYxNPqpvsLDAADn3qDhNzXp2mA6VyHSHg2XOAgSooC7ZiujdFhy0sp+0QYjTfJ/MjmLuNoUg2HHxH4Q=="
+ },
+ "bmaplib.heatmap": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/bmaplib.heatmap/-/bmaplib.heatmap-1.0.4.tgz",
+ "integrity": "sha512-rmhqUARBpUSJ9jXzUI2j7dIOqnc38bqubkx/8a349U2qtw/ulLUwyzRD535OrA8G7w5cz4aPKm6/rNvUAarg/Q=="
+ },
+ "bmaplib.lushu": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/bmaplib.lushu/-/bmaplib.lushu-1.0.7.tgz",
+ "integrity": "sha512-LVvgpESPii6xGxyjnQjq8u+ic4NjvhdCPV/RiSS/PGTUdZKeTDS7prSpleJLZH3ES0+oc0gYn8bw0LtPYUSz2w=="
+ },
+ "bmaplib.markerclusterer": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/bmaplib.markerclusterer/-/bmaplib.markerclusterer-1.0.13.tgz",
+ "integrity": "sha512-VrLyWSiuDEVNi0yUfwOhFQ6z1oEEHS4w36GNu3iASu6p52QIx9uAXMUkuSCHReNR0bj2Cp9SA1dSx5RpojXajQ==",
+ "requires": {
+ "bmaplib.texticonoverlay": "^1.0.2"
+ }
+ },
+ "bmaplib.texticonoverlay": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bmaplib.texticonoverlay/-/bmaplib.texticonoverlay-1.0.2.tgz",
+ "integrity": "sha512-4ZTWr4ZP3B6qEWput5Tut16CfZgII38YwM3bpyb4gFTQyORlKYryFp9WHWrwZZaHlOyYDAXG9SX0hka43jTADg=="
+ },
"bn.js": {
"version": "5.1.3",
"resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-5.1.3.tgz",
@@ -5266,6 +5294,14 @@
"invert-kv": "^1.0.0"
}
},
+ "linkify-it": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
+ "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
+ "requires": {
+ "uc.micro": "^1.0.1"
+ }
+ },
"load-json-file": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/load-json-file/download/load-json-file-2.0.0.tgz",
@@ -5443,6 +5479,25 @@
"object-visit": "^1.0.0"
}
},
+ "markdown-it": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
+ "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
+ "requires": {
+ "argparse": "^1.0.7",
+ "entities": "~1.1.1",
+ "linkify-it": "^2.0.0",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ },
+ "dependencies": {
+ "entities": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
+ }
+ }
+ },
"math-expression-evaluator": {
"version": "1.2.22",
"resolved": "https://registry.npm.taobao.org/math-expression-evaluator/download/math-expression-evaluator-1.2.22.tgz",
@@ -5466,6 +5521,11 @@
"integrity": "sha1-aZs8OKxvHXKAkaZGULZdOIUC/Vs=",
"dev": true
},
+ "mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
+ },
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz",
@@ -10074,8 +10134,7 @@
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
- "dev": true
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"ssri": {
"version": "5.3.0",
@@ -10489,6 +10548,11 @@
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"dev": true
},
+ "uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
+ },
"uglify-js": {
"version": "3.4.10",
"resolved": "https://registry.npm.taobao.org/uglify-js/download/uglify-js-3.4.10.tgz?cache=0&sync_timestamp=1601823880483&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.4.10.tgz",
@@ -10841,6 +10905,18 @@
"resolved": "https://registry.npm.taobao.org/vue/download/vue-2.6.12.tgz?cache=0&sync_timestamp=1600441238751&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue%2Fdownload%2Fvue-2.6.12.tgz",
"integrity": "sha1-9evU+mvShpQD4pqJau1JBEVskSM="
},
+ "vue-baidu-map": {
+ "version": "0.21.22",
+ "resolved": "https://registry.npmjs.org/vue-baidu-map/-/vue-baidu-map-0.21.22.tgz",
+ "integrity": "sha512-WQMPCih4UTh0AZCKKH/OVOYnyAWjfRNeK6BIeoLmscyY5aF8zzlJhz/NOHLb3mdztIpB0Z6aohn4Jd9mfCSjQw==",
+ "requires": {
+ "bmaplib.curveline": "^1.0.0",
+ "bmaplib.heatmap": "^1.0.4",
+ "bmaplib.lushu": "^1.0.7",
+ "bmaplib.markerclusterer": "^1.0.13",
+ "markdown-it": "^8.4.0"
+ }
+ },
"vue-clipboard2": {
"version": "0.3.1",
"resolved": "https://registry.npm.taobao.org/vue-clipboard2/download/vue-clipboard2-0.3.1.tgz",
diff --git a/web_src/package.json b/web_src/package.json
index d99d7bcd..4a9f7660 100644
--- a/web_src/package.json
+++ b/web_src/package.json
@@ -19,6 +19,7 @@
"moment": "^2.29.1",
"postcss-pxtorem": "^5.1.1",
"vue": "^2.6.11",
+ "vue-baidu-map": "^0.21.22",
"vue-clipboard2": "^0.3.1",
"vue-cookies": "^1.7.4",
"vue-router": "^3.1.6"
diff --git a/web_src/src/components/GeoConvertTools.js b/web_src/src/components/GeoConvertTools.js
new file mode 100644
index 00000000..6866249d
--- /dev/null
+++ b/web_src/src/components/GeoConvertTools.js
@@ -0,0 +1,250 @@
+/**
+ * 经纬度转换
+ */
+export default {
+ PI: 3.1415926535897932384626,
+ //PI: 3.14159265358979324,
+ x_pi: (3.1415926535897932384626 * 3000.0) / 180.0,
+ delta: function (lat, lng) {
+ // Krasovsky 1940
+ //
+ // a = 6378245.0, 1/f = 298.3
+ // b = a * (1 - f)
+ // ee = (a^2 - b^2) / a^2;
+ var a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
+ var ee = 0.00669342162296594323; // ee: 椭球的偏心率。
+ var dLat = this.transformLat(lng - 105.0, lat - 35.0);
+ var dLng = this.transformLng(lng - 105.0, lat - 35.0);
+ var radLat = (lat / 180.0) * this.PI;
+ var magic = Math.sin(radLat);
+ magic = 1 - ee * magic * magic;
+ var sqrtMagic = Math.sqrt(magic);
+ dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * this.PI);
+ dLng = (dLng * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * this.PI);
+ return {
+ lat: dLat,
+ lng: dLng
+ };
+ },
+ /**
+ * WGS-84 to GCJ-02 GPS坐标转中国坐标
+ * @param {number} wgsLat GPS纬度
+ * @param {number} wgsLng GPS经度
+ * @return {object} 返回中国坐标经纬度对象
+ */
+ GPSToChina: function (wgsLat, wgsLng) {
+ if (this.outOfChina(wgsLat, wgsLng)) return {
+ lat: wgsLat,
+ lng: wgsLng
+ };
+ var d = this.delta(wgsLat, wgsLng);
+ return {
+ lat: Number(wgsLat) + Number(d.lat),
+ lng: Number(wgsLng) + Number(d.lng)
+ };
+ },
+ /**
+ * GCJ-02 to WGS-84 中国标准坐标转GPS坐标
+ * @param {number} gcjLat 中国标准坐标纬度
+ * @param {number} gcjLng 中国标准坐标经度
+ * @return {object} 返回GPS经纬度对象
+ */
+ chinaToGPS: function (gcjLat, gcjLng) {
+ if (this.outOfChina(gcjLat, gcjLng)) return {
+ lat: gcjLat,
+ lng: gcjLng
+ };
+ var d = this.delta(gcjLat, gcjLng);
+ return {
+ lat: Number(gcjLat) - Number(d.lat),
+ lng: Number(gcjLng) - Number(d.lng)
+ };
+ },
+ /**
+ * GCJ-02 to WGS-84 exactly 中国标准坐标转GPS坐标(精确)
+ * @param {number} gcjLat 中国标准坐标纬度
+ * @param {number} gcjLng 中国标准坐标经度
+ * @return {object} 返回GPS经纬度对象(精确)
+ */
+ chinaToGPSExact: function (gcjLat, gcjLng) {
+ var initDelta = 0.01;
+ var threshold = 0.000000001;
+ var dLat = initDelta,
+ dLng = initDelta;
+ var mLat = gcjLat - dLat,
+ mLng = gcjLng - dLng;
+ var pLat = gcjLat + dLat,
+ pLng = gcjLng + dLng;
+ var wgsLat,
+ wgsLng,
+ i = 0;
+ while (1) {
+ wgsLat = (mLat + pLat) / 2;
+ wgsLng = (mLng + pLng) / 2;
+ var tmp = this.gcj_encrypt(wgsLat, wgsLng);
+ dLat = tmp.lat - gcjLat;
+ dLng = tmp.lng - gcjLng;
+ if (Math.abs(dLat) < threshold && Math.abs(dLng) < threshold) break;
+
+ if (dLat > 0) pLat = wgsLat;
+ else mLat = wgsLat;
+ if (dLng > 0) pLng = wgsLng;
+ else mLng = wgsLng;
+
+ if (++i > 10000) break;
+ }
+ //console.log(i);
+ return {
+ lat: wgsLat,
+ lng: wgsLng
+ };
+ },
+ /**
+ * GCJ-02 to BD-09 中国标准坐标转百度坐标(精确)
+ * @param {number} gcjLat 中国标准坐标纬度
+ * @param {number} gcjLng 中国标准坐标经度
+ * @return {object} 返回百度经纬度对象
+ */
+ chinaToBaidu: function (gcjLat, gcjLng) {
+ var x = gcjLng,
+ y = gcjLat;
+ var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this.x_pi);
+ var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this.x_pi);
+ var bdLng = z * Math.cos(theta) + 0.0065;
+ var bdLat = z * Math.sin(theta) + 0.006;
+ return {
+ lat: bdLat,
+ lng: bdLng
+ };
+ },
+ /**
+ * BD-09 to GCJ-02 百度坐标转中国标准坐标
+ * @param {number} bdLat 百度坐标纬度
+ * @param {number} bdLng 百度坐标经度
+ * @return {object} 返回中国标准经纬度对象
+ */
+ baiduToChina: function (bdLat, bdLng) {
+ var x = bdLng - 0.0065,
+ y = bdLat - 0.006;
+ var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi);
+ var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi);
+ var gcjLng = z * Math.cos(theta);
+ var gcjLat = z * Math.sin(theta);
+ return {
+ lat: gcjLat,
+ lng: gcjLng
+ };
+ },
+ /**
+ * BD-09 to GCJ-02 百度坐标转gps坐标
+ * @param {number} bdLat 百度坐标纬度
+ * @param {number} bdLng 百度坐标经度
+ * @return {object} 返回gps经纬度对象
+ */
+ baiduToGPS: function (bdLat, bdLng) {
+ let china = this.baiduToChina(bdLat, bdLng);
+ return this.chinaToGPS(china.lat, china.lng);
+ },
+ /**
+ * WGS-84 to to BD-09 GPS坐标转Baidu坐标
+ * @param {number} gpsLat GPS纬度
+ * @param {number} gpsLng GPS经度
+ * @return {object} 返回百度经纬度对象
+ */
+ GPSToBaidu: function (gpsLat, gpsLng) {
+ var china = this.GPSToChina(gpsLat, gpsLng);
+ return this.chinaToBaidu(china.lat, china.lng);
+ },
+ /**
+ * WGS-84 to Web mercator GPS坐标转墨卡托坐标
+ * @param {number} wgsLat GPS纬度
+ * @param {number} wgsLng GPS经度
+ * @return {object} 返回墨卡托经纬度对象
+ */
+ GPSToMercator: function (wgsLat, wgsLng) {
+ var x = (wgsLng * 20037508.34) / 180;
+ var y = Math.log(Math.tan(((90 + wgsLat) * this.PI) / 360)) / (this.PI / 180);
+ y = (y * 20037508.34) / 180;
+ return {
+ lat: y,
+ lng: x
+ };
+ /*
+ if ((Math.abs(wgsLng) > 180 || Math.abs(wgsLat) > 90))
+ return null;
+ var x = 6378137.0 * wgsLng * 0.017453292519943295;
+ var a = wgsLat * 0.017453292519943295;
+ var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
+ return {'lat' : y, 'lng' : x};
+ //*/
+ },
+ /**
+ * Web mercator to WGS-84 墨卡托坐标转GPS坐标
+ * @param {number} mercatorLat 墨卡托纬度
+ * @param {number} mercatorLng 墨卡托经度
+ * @return {object} 返回GPS经纬度对象
+ */
+ mercatorToGPS: function (mercatorLat, mercatorLng) {
+ var x = (mercatorLng / 20037508.34) * 180;
+ var y = (mercatorLat / 20037508.34) * 180;
+ y = (180 / this.PI) * (2 * Math.atan(Math.exp((y * this.PI) / 180)) - this.PI / 2);
+ return {
+ lat: y,
+ lng: x
+ };
+ /*
+ if (Math.abs(mercatorLng) < 180 && Math.abs(mercatorLat) < 90)
+ return null;
+ if ((Math.abs(mercatorLng) > 20037508.3427892) || (Math.abs(mercatorLat) > 20037508.3427892))
+ return null;
+ var a = mercatorLng / 6378137.0 * 57.295779513082323;
+ var x = a - (Math.floor(((a + 180.0) / 360.0)) * 360.0);
+ var y = (1.5707963267948966 - (2.0 * Math.atan(Math.exp((-1.0 * mercatorLat) / 6378137.0)))) * 57.295779513082323;
+ return {'lat' : y, 'lng' : x};
+ //*/
+ },
+ /**
+ * 两点之间的距离
+ * @param {number} latA 起点纬度
+ * @param {number} lngA 起点经度
+ * @param {number} latB 终点纬度
+ * @param {number} lngB 终点经度
+ * @return {number} 返回距离(米)
+ */
+ distance: function (latA, lngA, latB, lngB) {
+ var earthR = 6371000;
+ var x = Math.cos((latA * this.PI) / 180) * Math.cos((latB * this.PI) / 180) * Math.cos(((lngA - lngB) * this.PI) / 180);
+ var y = Math.sin((latA * this.PI) / 180) * Math.sin((latB * this.PI) / 180);
+ var s = x + y;
+ if (s > 1) s = 1;
+ if (s < -1) s = -1;
+ var alpha = Math.acos(s);
+ var distance = alpha * earthR;
+ return distance;
+ },
+ /**
+ * 是否在中国之外
+ * @param {number} lat 纬度
+ * @param {number} lng 经度
+ * @return {boolean]} 返回结果真或假
+ */
+ outOfChina: function (lat, lng) {
+ if (lat < 72.004 || lat > 137.8347) return true;
+ if (lng < 0.8293 || lng > 55.8271) return true;
+ return false;
+ },
+ transformLat: function (x, y) {
+ var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
+ ret += ((20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0) / 3.0;
+ ret += ((20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin((y / 3.0) * this.PI)) * 2.0) / 3.0;
+ ret += ((160.0 * Math.sin((y / 12.0) * this.PI) + 320 * Math.sin((y * this.PI) / 30.0)) * 2.0) / 3.0;
+ return ret;
+ },
+ transformLng: function (x, y) {
+ var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
+ ret += ((20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0) / 3.0;
+ ret += ((20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin((x / 3.0) * this.PI)) * 2.0) / 3.0;
+ ret += ((150.0 * Math.sin((x / 12.0) * this.PI) + 300.0 * Math.sin((x / 30.0) * this.PI)) * 2.0) / 3.0;
+ return ret;
+ }
+};
diff --git a/web_src/src/components/devicePosition.vue b/web_src/src/components/devicePosition.vue
new file mode 100644
index 00000000..29106234
--- /dev/null
+++ b/web_src/src/components/devicePosition.vue
@@ -0,0 +1,374 @@
+
+
+
+
+
+
+
+
+ 设备定位 ({{ parentChannelId == 0 ? deviceId : parentChannelId }})
+
+
+ 返回
+
+
+
+
+ 历史轨迹
+ 最新位置
+
+ 过期时间
+
+ 上报周期
+
+
+ 位置订阅
+ 取消订阅
+
+ 自动刷新
+
+
+
+
+
+
+
+
+
+
diff --git a/web_src/src/components/videoList.vue b/web_src/src/components/videoList.vue
index 01dae2c3..450d736f 100644
--- a/web_src/src/components/videoList.vue
+++ b/web_src/src/components/videoList.vue
@@ -11,7 +11,7 @@
-
+
@@ -40,7 +40,7 @@
-
+
在线
@@ -49,10 +49,11 @@
-
+
刷新通道
查看通道
+ 移动位置
@@ -73,7 +74,7 @@
"})
+ List queryPositionByDeviceIdAndTime(String deviceId, String startTime, String endTime);
+
+ @Select("SELECT * FROM device_mobile_position WHERE deviceId = #{deviceId}" +
+ " ORDER BY time DESC LIMIT 1")
+ MobilePosition queryLatestPositionByDevice(String deviceId);
+
+ @Delete("DELETE FROM device_mobile_position WHERE deviceId = #{deviceId}")
+ int clearMobilePositionsByDeviceId(String deviceId);
+
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
index e11c1416..cc8320cf 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -3,8 +3,10 @@ package com.genersoft.iot.vmp.storager.impl;
import java.util.*;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
+import com.genersoft.iot.vmp.storager.dao.DeviceMobilePositionMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.models.auth.In;
@@ -27,7 +29,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
private DeviceMapper deviceMapper;
@Autowired
- private DeviceChannelMapper deviceChannelMapper;
+ private DeviceChannelMapper deviceChannelMapper;
+
+ @Autowired
+ private DeviceMobilePositionMapper deviceMobilePositionMapper;
/**
@@ -200,11 +205,49 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
return deviceMapper.update(device) > 0;
}
-
+ /**
+ * 清空通道
+ * @param deviceId
+ */
@Override
public void cleanChannelsForDevice(String deviceId) {
int result = deviceChannelMapper.cleanChannelsByDeviceId(deviceId);
}
+ /**
+ * 添加Mobile Position设备移动位置
+ * @param MobilePosition
+ */
+ @Override
+ public synchronized boolean insertMobilePosition(MobilePosition mobilePosition) {
+ return deviceMobilePositionMapper.insertNewPosition(mobilePosition) > 0;
+ }
+ /**
+ * 查询移动位置轨迹
+ * @param deviceId
+ * @param startTime
+ * @param endTime
+ */
+ @Override
+ public synchronized List queryMobilePositions(String deviceId, String startTime, String endTime) {
+ return deviceMobilePositionMapper.queryPositionByDeviceIdAndTime(deviceId, startTime, endTime);
+ }
+
+ /**
+ * 查询最新移动位置
+ * @param deviceId
+ */
+ @Override
+ public MobilePosition queryLatestPosition(String deviceId) {
+ return deviceMobilePositionMapper.queryLatestPositionByDevice(deviceId);
+ }
+
+ /**
+ * 删除指定设备的所有移动位置
+ * @param deviceId
+ */
+ public int clearMobilePositionsByDeviceId(String deviceId) {
+ return deviceMobilePositionMapper.clearMobilePositionsByDeviceId(deviceId);
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/utils/GpsUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/GpsUtil.java
new file mode 100644
index 00000000..16724410
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/utils/GpsUtil.java
@@ -0,0 +1,68 @@
+package com.genersoft.iot.vmp.utils;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Base64;
+
+import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint;
+
+public class GpsUtil {
+ public static BaiduPoint Wgs84ToBd09(String xx, String yy) {
+ try {
+ Socket s = new Socket("api.map.baidu.com", 80);
+ BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
+ OutputStream out = s.getOutputStream();
+ StringBuffer sb = new StringBuffer("GET /ag/coord/convert?from=0&to=4");
+ sb.append("&x=" + xx + "&y=" + yy);
+ sb.append("&callback=BMap.Convertor.cbk_3976 HTTP/1.1\r\n");
+ sb.append("User-Agent: Java/1.6.0_20\r\n");
+ sb.append("Host: api.map.baidu.com:80\r\n");
+ sb.append("Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n");
+ sb.append("Connection: Close\r\n");
+ sb.append("\r\n");
+ out.write(sb.toString().getBytes());
+ String json = "";
+ String tmp = "";
+ while ((tmp = br.readLine()) != null) {
+ // System.out.println(tmp);
+ json += tmp;
+ }
+
+ s.close();
+ int start = json.indexOf("cbk_3976");
+ int end = json.lastIndexOf("}");
+ if (start != -1 && end != -1 && json.contains("\"x\":\"")) {
+ json = json.substring(start, end);
+ String[] point = json.split(",");
+ String x = point[1].split(":")[1].replace("\"", "");
+ String y = point[2].split(":")[1].replace("\"", "");
+ BaiduPoint bdPoint= new BaiduPoint();
+ bdPoint.setBdLng(new String(decode(x)));
+ bdPoint.setBdLat(new String(decode(y)));
+ return bdPoint;
+ //return (new String(decode(x)) + "," + new String(decode(y)));
+ } else {
+ System.out.println("gps坐标无效!!");
+ }
+ out.close();
+ br.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * BASE64解码
+ * @param str
+ * @return string
+ */
+ public static byte[] decode(String str) {
+ byte[] bt = null;
+ final Base64.Decoder decoder = Base64.getDecoder();
+ bt = decoder.decode(str); // .decodeBuffer(str);
+ return bt;
+ }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/MobilePosition/MobilePositionController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/MobilePosition/MobilePositionController.java
new file mode 100644
index 00000000..92806b17
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/MobilePosition/MobilePositionController.java
@@ -0,0 +1,118 @@
+package com.genersoft.iot.vmp.vmanager.MobilePosition;
+
+import java.util.List;
+
+import javax.sip.message.Response;
+
+import com.genersoft.iot.vmp.gb28181.bean.Device;
+import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
+import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
+import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
+import com.github.pagehelper.util.StringUtil;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.context.request.async.DeferredResult;
+
+@CrossOrigin
+@RestController
+@RequestMapping("/api")
+public class MobilePositionController {
+
+ private final static Logger logger = LoggerFactory.getLogger(MobilePositionController.class);
+
+ @Autowired
+ private IVideoManagerStorager storager;
+
+ @Autowired
+ private SIPCommander cmder;
+
+ @Autowired
+ private DeferredResultHolder resultHolder;
+
+ @GetMapping("/positions/{deviceId}/history")
+ public ResponseEntity> positions(@PathVariable String deviceId,
+ @RequestParam(required = false) String start,
+ @RequestParam(required = false) String end) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("查询设备" + deviceId + "的历史轨迹");
+ }
+
+ if (StringUtil.isEmpty(start)) {
+ start = null;
+ }
+ if (StringUtil.isEmpty(end)) {
+ end = null;
+ }
+
+ List result = storager.queryMobilePositions(deviceId, start, end);
+ return new ResponseEntity<>(result, HttpStatus.OK);
+ }
+
+ @GetMapping("/positions/{deviceId}/latest")
+ public ResponseEntity latestPosition(@PathVariable String deviceId) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("查询设备" + deviceId + "的最新位置");
+ }
+ MobilePosition result = storager.queryLatestPosition(deviceId);
+ return new ResponseEntity<>(result, HttpStatus.OK);
+ }
+
+ @GetMapping("/positions/{deviceId}/realtime")
+ public DeferredResult> realTimePosition(@PathVariable String deviceId) {
+ Device device = storager.queryVideoDevice(deviceId);
+ cmder.mobilePostitionQuery(device, event -> {
+ Response response = event.getResponse();
+ RequestMessage msg = new RequestMessage();
+ msg.setId(DeferredResultHolder.CALLBACK_CMD_MOBILEPOSITION + deviceId);
+ msg.setData(String.format("获取移动位置信息失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
+ resultHolder.invokeResult(msg);
+ });
+ DeferredResult> result = new DeferredResult>(5*1000L);
+ result.onTimeout(()->{
+ logger.warn(String.format("获取移动位置信息超时"));
+ // 释放rtpserver
+ RequestMessage msg = new RequestMessage();
+ msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId);
+ msg.setData("Timeout");
+ resultHolder.invokeResult(msg);
+ });
+ resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result);
+ return result;
+ }
+
+ @GetMapping("/positions/{deviceId}/subscribe")
+ public ResponseEntity positionSubscribe(@PathVariable String deviceId,
+ @RequestParam String expires,
+ @RequestParam String interval) {
+ String msg = ((expires.equals("0")) ? "取消" : "") + "订阅设备" + deviceId + "的移动位置";
+ if (logger.isDebugEnabled()) {
+ logger.debug(msg);
+ }
+
+ if (StringUtil.isEmpty(interval)) {
+ interval = "5";
+ }
+ Device device = storager.queryVideoDevice(deviceId);
+
+ String result = msg;
+ if (cmder.mobilePositionSubscribe(device, Integer.parseInt(expires), Integer.parseInt(interval))) {
+ result += ",成功";
+ } else {
+ result += ",失败";
+ }
+
+ return new ResponseEntity<>(result, HttpStatus.OK);
+ }
+}
From 70564219ae079cadf95997e3cfb49a1c8277db52 Mon Sep 17 00:00:00 2001
From: Lawrence <1934378145@qq.com>
Date: Wed, 27 Jan 2021 15:54:14 +0800
Subject: [PATCH 12/18] =?UTF-8?q?=E5=A2=9E=E5=8A=A0SSE=E8=B7=A8=E5=9F=9F?=
=?UTF-8?q?=E6=94=AF=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../genersoft/iot/vmp/vmanager/SseController/SseController.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/SseController/SseController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/SseController/SseController.java
index 01af4a0d..1e55c326 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/SseController/SseController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/SseController/SseController.java
@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.vmanager.SseController;
import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEventListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@@ -13,6 +14,7 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
* @data: 2021-01-20
*/
+@CrossOrigin
@Controller
@RequestMapping("/api")
public class SseController {
From c807572bdfe41723da86d0e2934cb77d858c60fe Mon Sep 17 00:00:00 2001
From: Lawrence <1934378145@qq.com>
Date: Wed, 27 Jan 2021 16:05:08 +0800
Subject: [PATCH 13/18] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=B4=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index 40a522ce..03ee2764 100644
--- a/README.md
+++ b/README.md
@@ -43,12 +43,12 @@ https://gitee.com/18010473990/wvp-GB28181.git
13. 支持固定流地址和自动点播,同时支持未点播时直接播放流地址,代码自动发起点播. ( [查看WIKI](https://github.com/648540858/wvp-GB28181-pro/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E5%9B%BA%E5%AE%9A%E6%92%AD%E6%94%BE%E5%9C%B0%E5%9D%80%E4%B8%8E%E8%87%AA%E5%8A%A8%E7%82%B9%E6%92%AD))
14. 报警信息处理,支持向前端推送报警信息
15. 支持订阅与通知方法
- [X] 移动位置订阅
- [X] 移动位置通知处理
- [ ] 报警事件订阅
- [X] 报警事件通知处理
- [ ] 设备目录订阅
- [X] 设备奴鲁通知处理
+ - [X] 移动位置订阅
+ - [X] 移动位置通知处理
+ - [ ] 报警事件订阅
+ - [X] 报警事件通知处理
+ - [ ] 设备目录订阅
+ - [X] 设备目录通知处理
16. 移动位置查询和显示,可通过配置文件设置移动位置历史是否存储
# 待实现:
From a522d09734844fffec1c7a4f65159bfb6226c2d3 Mon Sep 17 00:00:00 2001
From: Lawrence <1934378145@qq.com>
Date: Thu, 28 Jan 2021 14:26:48 +0800
Subject: [PATCH 14/18] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=84=E9=A1=B5?=
=?UTF-8?q?=E9=9D=A2=E6=8C=89=E4=B8=8B=E5=9B=9E=E8=BD=A6=E9=94=AE=E9=83=BD?=
=?UTF-8?q?=E4=BC=9A=E9=80=80=E5=9B=9EContral=E9=A1=B5=E9=9D=A2=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web_src/src/components/Login.vue | 41 ++++++++++++++++++--------------
1 file changed, 23 insertions(+), 18 deletions(-)
diff --git a/web_src/src/components/Login.vue b/web_src/src/components/Login.vue
index 160197a4..2a918865 100644
--- a/web_src/src/components/Login.vue
+++ b/web_src/src/components/Login.vue
@@ -29,14 +29,13 @@ export default {
}
},
created(){
- var that = this;
- document.onkeydown = function(e) {
- var key = window.event.keyCode;
- if (key == 13) {
- that.login();
+ var that = this;
+ document.onkeydown = function(e) {
+ var key = window.event.keyCode;
+ if (key == 13) {
+ that.login();
+ }
}
- }
-
},
methods:{
@@ -70,6 +69,7 @@ export default {
if (res.data == "success") {
that.$cookies.set("session", {"username": that.username}) ;
//登录成功后
+ that.cancelEnterkeyDefaultAction();
that.$router.push('/');
}else{
that.isLoging = false;
@@ -84,18 +84,23 @@ export default {
that.$message.error(error.response.statusText);
that.isLoging = false;
});
-
-
-
},
- setCookie: function (cname, cvalue, exdays) {
- var d = new Date();
- d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
- var expires = "expires=" + d.toUTCString();
- console.info(cname + "=" + cvalue + "; " + expires);
- document.cookie = cname + "=" + cvalue + "; " + expires;
- console.info(document.cookie);
- },
+ setCookie: function (cname, cvalue, exdays) {
+ var d = new Date();
+ d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
+ var expires = "expires=" + d.toUTCString();
+ console.info(cname + "=" + cvalue + "; " + expires);
+ document.cookie = cname + "=" + cvalue + "; " + expires;
+ console.info(document.cookie);
+ },
+ cancelEnterkeyDefaultAction: function() {
+ document.onkeydown = function(e) {
+ var key = window.event.keyCode;
+ if (key == 13) {
+ return false;
+ }
+ }
+ }
}
}
From 693aac283aace14dbc4847ac4ef3053943d89a8a Mon Sep 17 00:00:00 2001
From: lawrencehj <1934378145@qq.com>
Date: Wed, 3 Feb 2021 10:54:41 +0800
Subject: [PATCH 15/18] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=95=8C=E9=9D=A2?=
=?UTF-8?q?=E5=B8=83=E5=B1=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web_src/src/components/devicePosition.vue | 30 +++++++++++++++++------
web_src/src/components/videoList.vue | 11 ++++++---
2 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/web_src/src/components/devicePosition.vue b/web_src/src/components/devicePosition.vue
index 29106234..f6cf19e4 100644
--- a/web_src/src/components/devicePosition.vue
+++ b/web_src/src/components/devicePosition.vue
@@ -181,10 +181,17 @@ export default {
self.total = res.data.length;
self.mobilePositionList = res.data;
console.log(self.mobilePositionList);
- // 防止出现表格错位
- self.$nextTick(() => {
- self.showMarkPoints(self);
- });
+ if (self.total == 0) {
+ self.$message({
+ showClose: true,
+ message: '未找到符合条件的移动位置信息',
+ type: 'error'
+ });
+ } else {
+ self.$nextTick(() => {
+ self.showMarkPoints(self);
+ });
+ }
})
.catch(function (error) {
console.log(error);
@@ -201,10 +208,17 @@ export default {
self.total = res.data.length;
self.mobilePositionList.push(res.data);
console.log(self.mobilePositionList);
- // 防止出现表格错位
- self.$nextTick(() => {
- self.showMarkPoints(self);
- });
+ if (self.total == 0) {
+ self.$message({
+ showClose: true,
+ message: '未找到符合条件的移动位置信息',
+ type: 'error'
+ });
+ } else {
+ self.$nextTick(() => {
+ self.showMarkPoints(self);
+ });
+ }
})
.catch(function (error) {
console.log(error);
diff --git a/web_src/src/components/videoList.vue b/web_src/src/components/videoList.vue
index 450d736f..8a3f1c0e 100644
--- a/web_src/src/components/videoList.vue
+++ b/web_src/src/components/videoList.vue
@@ -51,10 +51,13 @@
- 刷新通道
- 查看通道
- 移动位置
-
+ 刷新
+
+ 通道
+ 定位
+ 控制
+
+
Date: Wed, 3 Feb 2021 11:00:24 +0800
Subject: [PATCH 16/18] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=A4=9A=E7=A7=8D?=
=?UTF-8?q?=E4=BF=A1=E4=BB=A4=E7=9A=84=E6=94=AF=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../callback/DeferredResultHolder.java | 12 +
.../gb28181/transmit/cmd/ISIPCommander.java | 83 +++-
.../transmit/cmd/impl/SIPCommander.java | 437 ++++++++++++++++--
.../request/impl/MessageRequestProcessor.java | 298 +++++++++---
4 files changed, 721 insertions(+), 109 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
index 574e94c7..edf86797 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
@@ -17,8 +17,16 @@ import org.springframework.web.context.request.async.DeferredResult;
@Component
public class DeferredResultHolder {
+ public static final String CALLBACK_CMD_DEVICESTATUS = "CALLBACK_DEVICESTATUS";
+
public static final String CALLBACK_CMD_DEVICEINFO = "CALLBACK_DEVICEINFO";
+ public static final String CALLBACK_CMD_DEVICECONTROL = "CALLBACK_DEVICECONTROL";
+
+ public static final String CALLBACK_CMD_DEVICECONFIG = "CALLBACK_DEVICECONFIG";
+
+ public static final String CALLBACK_CMD_CONFIGDOWNLOAD = "CALLBACK_CONFIGDOWNLOAD";
+
public static final String CALLBACK_CMD_CATALOG = "CALLBACK_CATALOG";
public static final String CALLBACK_CMD_RECORDINFO = "CALLBACK_RECORDINFO";
@@ -29,6 +37,10 @@ public class DeferredResultHolder {
public static final String CALLBACK_CMD_MOBILEPOSITION = "CALLBACK_MOBILEPOSITION";
+ public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY";
+
+ public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM";
+
private Map map = new ConcurrentHashMap();
public void put(String key, DeferredResult result) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
index 7e63af75..30fbfe94 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -115,24 +115,35 @@ public interface ISIPCommander {
/**
* 音视频录像控制
*
- * @param device 视频设备
- * @param channelId 预览通道
+ * @param device 视频设备
+ * @param channelId 预览通道
+ * @param recordCmdStr 录像命令:Record / StopRecord
*/
- boolean recordCmd(Device device,String channelId);
+ boolean recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent);
+ /**
+ * 远程启动控制命令
+ *
+ * @param device 视频设备
+ */
+ boolean teleBootCmd(Device device);
+
/**
* 报警布防/撤防命令
*
- * @param device 视频设备
+ * @param device 视频设备
+ * @param setGuard true: SetGuard, false: ResetGuard
*/
- boolean guardCmd(Device device);
+ boolean guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent);
/**
* 报警复位命令
*
- * @param device 视频设备
+ * @param device 视频设备
+ * @param alarmMethod 报警方式(可选)
+ * @param alarmType 报警类型(可选)
*/
- boolean alarmCmd(Device device);
+ boolean alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent);
/**
* 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧
@@ -140,14 +151,17 @@ public interface ISIPCommander {
* @param device 视频设备
* @param channelId 预览通道
*/
- boolean iFameCmd(Device device,String channelId);
+ boolean iFrameCmd(Device device, String channelId);
/**
* 看守位控制命令
*
- * @param device 视频设备
+ * @param device 视频设备
+ * @param enabled 看守位使能:1 = 开启,0 = 关闭
+ * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
+ * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
*/
- boolean homePositionCmd(Device device);
+ boolean homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent);
/**
* 设备配置命令
@@ -156,13 +170,24 @@ public interface ISIPCommander {
*/
boolean deviceConfigCmd(Device device);
+ /**
+ * 设备配置命令:basicParam
+ *
+ * @param device 视频设备
+ * @param channelId 通道编码(可选)
+ * @param name 设备/通道名称(可选)
+ * @param expiration 注册过期时间(可选)
+ * @param heartBeatInterval 心跳间隔时间(可选)
+ * @param heartBeatCount 心跳超时次数(可选)
+ */
+ boolean deviceBasicConfigCmd(Device device, String channelId, String name, String expiration, String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent);
/**
* 查询设备状态
*
* @param device 视频设备
*/
- boolean deviceStatusQuery(Device device);
+ boolean deviceStatusQuery(Device device, SipSubscribe.Event errorEvent);
/**
* 查询设备信息
@@ -191,23 +216,33 @@ public interface ISIPCommander {
/**
* 查询报警信息
*
- * @param device 视频设备
+ * @param device 视频设备
+ * @param startPriority 报警起始级别(可选)
+ * @param endPriority 报警终止级别(可选)
+ * @param alarmMethod 报警方式条件(可选)
+ * @param alarmType 报警类型
+ * @param startTime 报警发生起始时间(可选)
+ * @param endTime 报警发生终止时间(可选)
+ * @return true = 命令发送成功
*/
- boolean alarmInfoQuery(Device device);
+ boolean alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod,
+ String alarmType, String startTime, String endTime, SipSubscribe.Event errorEvent);
/**
* 查询设备配置
*
- * @param device 视频设备
+ * @param device 视频设备
+ * @param channelId 通道编码(可选)
+ * @param configType 配置类型:
*/
- boolean configQuery(Device device);
+ boolean deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent);
/**
* 查询设备预置位置
*
* @param device 视频设备
*/
- boolean presetQuery(Device device);
+ boolean presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent);
/**
* 查询移动设备位置数据
@@ -222,9 +257,25 @@ public interface ISIPCommander {
* @param device 视频设备
* @param expires 订阅超时时间(值=0时为取消订阅)
* @param interval 上报时间间隔
+ * @return true = 命令发送成功
*/
boolean mobilePositionSubscribe(Device device, int expires, int interval);
+ /**
+ * 订阅、取消订阅报警信息
+ * @param device 视频设备
+ * @param expires 订阅过期时间(0 = 取消订阅)
+ * @param startPriority 报警起始级别(可选)
+ * @param endPriority 报警终止级别(可选)
+ * @param alarmMethods 报警方式条件(可选)
+ * @param alarmType 报警类型
+ * @param startTime 报警发生起始时间(可选)
+ * @param endTime 报警发生终止时间(可选)
+ * @return true = 命令发送成功
+ */
+ boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime);
+
+
/**
* 释放rtpserver
* @param device
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
index b661c5e6..c174455f 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -34,6 +34,8 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
+import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
+import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
/**
* @Description:设备能力接口,用于定义设备的控制、查询能力
@@ -577,24 +579,89 @@ public class SIPCommander implements ISIPCommander {
/**
* 音视频录像控制
*
- * @param device 视频设备
- * @param channelId 预览通道
+ * @param device 视频设备
+ * @param channelId 预览通道
+ * @param recordCmdStr 录像命令:Record / StopRecord
*/
@Override
- public boolean recordCmd(Device device, String channelId) {
- // TODO Auto-generated method stub
- return false;
+ public boolean recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("DeviceControl\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ if (XmlUtil.isEmpty(channelId)) {
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ } else {
+ cmdXml.append("" + channelId + "\r\n");
+ }
+ cmdXml.append("" + recordCmdStr + "\r\n");
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromRecord" + tm, null);
+ transmitRequest(device, request, errorEvent);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
}
+ /**
+ * 远程启动控制命令
+ *
+ * @param device 视频设备
+ */
+ @Override
+ public boolean teleBootCmd(Device device) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("DeviceControl\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ cmdXml.append("Boot\r\n");
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromBoot" + tm, null);
+ transmitRequest(device, request);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
/**
* 报警布防/撤防命令
*
- * @param device 视频设备
- */
+ * @param device 视频设备
+ * @param guardCmdStr "SetGuard"/"ResetGuard"
+ */
@Override
- public boolean guardCmd(Device device) {
- // TODO Auto-generated method stub
- return false;
+ public boolean guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("DeviceControl\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ cmdXml.append("" + guardCmdStr + "\r\n");
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromGuard" + tm, null);
+ transmitRequest(device, request, errorEvent);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
}
/**
@@ -603,9 +670,37 @@ public class SIPCommander implements ISIPCommander {
* @param device 视频设备
*/
@Override
- public boolean alarmCmd(Device device) {
- // TODO Auto-generated method stub
- return false;
+ public boolean alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("DeviceControl\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ cmdXml.append("ResetAlarm\r\n");
+ if (!XmlUtil.isEmpty(alarmMethod) || !XmlUtil.isEmpty(alarmType)) {
+ cmdXml.append("\r\n");
+ }
+ if (!XmlUtil.isEmpty(alarmMethod)) {
+ cmdXml.append("" + alarmMethod + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(alarmType)) {
+ cmdXml.append("" + alarmType + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(alarmMethod) || !XmlUtil.isEmpty(alarmType)) {
+ cmdXml.append("\r\n");
+ }
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromAlarm" + tm, null);
+ transmitRequest(device, request, errorEvent);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
}
/**
@@ -615,20 +710,79 @@ public class SIPCommander implements ISIPCommander {
* @param channelId 预览通道
*/
@Override
- public boolean iFameCmd(Device device, String channelId) {
- // TODO Auto-generated method stub
- return false;
+ public boolean iFrameCmd(Device device, String channelId) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("DeviceControl\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ if (XmlUtil.isEmpty(channelId)) {
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ } else {
+ cmdXml.append("" + channelId + "\r\n");
+ }
+ cmdXml.append("Send\r\n");
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromBoot" + tm, null);
+ transmitRequest(device, request);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
}
/**
* 看守位控制命令
*
- * @param device 视频设备
+ * @param device 视频设备
+ * @param enabled 看守位使能:1 = 开启,0 = 关闭
+ * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
+ * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
*/
@Override
- public boolean homePositionCmd(Device device) {
- // TODO Auto-generated method stub
- return false;
+ public boolean homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("DeviceControl\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ if (XmlUtil.isEmpty(channelId)) {
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ } else {
+ cmdXml.append("" + channelId + "\r\n");
+ }
+ cmdXml.append("\r\n");
+ if (NumericUtil.isInteger(enabled) && (!enabled.equals("0"))) {
+ cmdXml.append("1\r\n");
+ if (NumericUtil.isInteger(resetTime)) {
+ cmdXml.append("" + resetTime + "\r\n");
+ } else {
+ cmdXml.append("0\r\n");
+ }
+ if (NumericUtil.isInteger(presetIndex)) {
+ cmdXml.append("" + presetIndex + "\r\n");
+ } else {
+ cmdXml.append("0\r\n");
+ }
+ } else {
+ cmdXml.append("0\r\n");
+ }
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromGuard" + tm, null);
+ transmitRequest(device, request, errorEvent);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
}
/**
@@ -642,15 +796,88 @@ public class SIPCommander implements ISIPCommander {
return false;
}
+ /**
+ * 设备配置命令:basicParam
+ *
+ * @param device 视频设备
+ * @param channelId 通道编码(可选)
+ * @param name 设备/通道名称(可选)
+ * @param expiration 注册过期时间(可选)
+ * @param heartBeatInterval 心跳间隔时间(可选)
+ * @param heartBeatCount 心跳超时次数(可选)
+ */
+ @Override
+ public boolean deviceBasicConfigCmd(Device device, String channelId, String name, String expiration,
+ String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("DeviceConfig\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ if (XmlUtil.isEmpty(channelId)) {
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ } else {
+ cmdXml.append("" + channelId + "\r\n");
+ }
+ cmdXml.append("\r\n");
+ if (!XmlUtil.isEmpty(name)) {
+ cmdXml.append("" + name + "\r\n");
+ }
+ if (NumericUtil.isInteger(expiration)) {
+ if (Integer.valueOf(expiration) > 0) {
+ cmdXml.append("" + expiration + "\r\n");
+ }
+ }
+ if (NumericUtil.isInteger(heartBeatInterval)) {
+ if (Integer.valueOf(heartBeatInterval) > 0) {
+ cmdXml.append("" + heartBeatInterval + "\r\n");
+ }
+ }
+ if (NumericUtil.isInteger(heartBeatCount)) {
+ if (Integer.valueOf(heartBeatCount) > 0) {
+ cmdXml.append("" + heartBeatCount + "\r\n");
+ }
+ }
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null);
+ transmitRequest(device, request, errorEvent);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
/**
* 查询设备状态
*
* @param device 视频设备
*/
@Override
- public boolean deviceStatusQuery(Device device) {
- // TODO Auto-generated method stub
- return false;
+ public boolean deviceStatusQuery(Device device, SipSubscribe.Event errorEvent) {
+ try {
+ StringBuffer catalogXml = new StringBuffer(200);
+ catalogXml.append("\r\n");
+ catalogXml.append("\r\n");
+ catalogXml.append("DeviceStatus\r\n");
+ catalogXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ catalogXml.append("" + device.getDeviceId() + "\r\n");
+ catalogXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), null, "FromStatus" + tm, null);
+
+ transmitRequest(device, request, errorEvent);
+ return true;
+
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
}
/**
@@ -748,23 +975,86 @@ public class SIPCommander implements ISIPCommander {
/**
* 查询报警信息
*
- * @param device 视频设备
- */
+ * @param device 视频设备
+ * @param startPriority 报警起始级别(可选)
+ * @param endPriority 报警终止级别(可选)
+ * @param alarmMethods 报警方式条件(可选)
+ * @param alarmType 报警类型
+ * @param startTime 报警发生起始时间(可选)
+ * @param endTime 报警发生终止时间(可选)
+ * @return true = 命令发送成功
+ */
@Override
- public boolean alarmInfoQuery(Device device) {
- // TODO Auto-generated method stub
- return false;
+ public boolean alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod, String alarmType,
+ String startTime, String endTime, SipSubscribe.Event errorEvent) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("Alarm\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ if (!XmlUtil.isEmpty(startPriority)) {
+ cmdXml.append("" + startPriority + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(endPriority)) {
+ cmdXml.append("" + endPriority + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(alarmMethod)) {
+ cmdXml.append("" + alarmMethod + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(alarmType)) {
+ cmdXml.append("" + alarmType + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(startTime)) {
+ cmdXml.append("" + startTime + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(endTime)) {
+ cmdXml.append("" + endTime + "\r\n");
+ }
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromAlarm" + tm, null);
+ transmitRequest(device, request, errorEvent);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
}
/**
* 查询设备配置
*
- * @param device 视频设备
- */
+ * @param device 视频设备
+ * @param channelId 通道编码(可选)
+ * @param configType 配置类型:
+ */
@Override
- public boolean configQuery(Device device) {
- // TODO Auto-generated method stub
- return false;
+ public boolean deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("ConfigDownload\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ if (XmlUtil.isEmpty(channelId)) {
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ } else {
+ cmdXml.append("" + channelId + "\r\n");
+ }
+ cmdXml.append("" + configType + "\r\n");
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null);
+ transmitRequest(device, request, errorEvent);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
}
/**
@@ -773,9 +1063,28 @@ public class SIPCommander implements ISIPCommander {
* @param device 视频设备
*/
@Override
- public boolean presetQuery(Device device) {
- // TODO Auto-generated method stub
- return false;
+ public boolean presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("PresetQuery\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ if (XmlUtil.isEmpty(channelId)) {
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ } else {
+ cmdXml.append("" + channelId + "\r\n");
+ }
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null);
+ transmitRequest(device, request, errorEvent);
+ return true;
+ } catch (SipException | ParseException | InvalidArgumentException e) {
+ e.printStackTrace();
+ return false;
+ }
}
/**
@@ -813,6 +1122,7 @@ public class SIPCommander implements ISIPCommander {
* @param device 视频设备
* @param expires 订阅超时时间
* @param interval 上报时间间隔
+ * @return true = 命令发送成功
*/
public boolean mobilePositionSubscribe(Device device, int expires, int interval) {
try {
@@ -828,7 +1138,60 @@ public class SIPCommander implements ISIPCommander {
subscribePostitionXml.append("\r\n");
String tm = Long.toString(System.currentTimeMillis());
- Request request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null, expires, "Position;id=" + tm.substring(tm.length() - 4));
+ Request request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null, expires, "presence" ); //Position;id=" + tm.substring(tm.length() - 4));
+ transmitRequest(device, request);
+
+ return true;
+
+ } catch ( NumberFormatException | ParseException | InvalidArgumentException | SipException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * 订阅、取消订阅报警信息
+ *
+ * @param device 视频设备
+ * @param expires 订阅过期时间(0 = 取消订阅)
+ * @param startPriority 报警起始级别(可选)
+ * @param endPriority 报警终止级别(可选)
+ * @param alarmMethod 报警方式条件(可选)
+ * @param alarmType 报警类型
+ * @param startTime 报警发生起始时间(可选)
+ * @param endTime 报警发生终止时间(可选)
+ * @return true = 命令发送成功
+ */
+ public boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime) {
+ try {
+ StringBuffer cmdXml = new StringBuffer(200);
+ cmdXml.append("\r\n");
+ cmdXml.append("\r\n");
+ cmdXml.append("Alarm\r\n");
+ cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
+ cmdXml.append("" + device.getDeviceId() + "\r\n");
+ if (!XmlUtil.isEmpty(startPriority)) {
+ cmdXml.append("" + startPriority + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(endPriority)) {
+ cmdXml.append("" + endPriority + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(alarmMethod)) {
+ cmdXml.append("" + alarmMethod + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(alarmType)) {
+ cmdXml.append("" + alarmType + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(startTime)) {
+ cmdXml.append("" + startTime + "\r\n");
+ }
+ if (!XmlUtil.isEmpty(endTime)) {
+ cmdXml.append("" + endTime + "\r\n");
+ }
+ cmdXml.append("\r\n");
+
+ String tm = Long.toString(System.currentTimeMillis());
+ Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null, expires, "presence" );
transmitRequest(device, request);
return true;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
index 1c7c775b..c865ad39 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -10,6 +10,7 @@ import javax.sip.SipException;
import javax.sip.message.Request;
import javax.sip.message.Response;
+import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.UserSetup;
@@ -78,9 +79,12 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
private static final String MESSAGE_RECORD_INFO = "RecordInfo";
private static final String MESSAGE_MEDIA_STATUS = "MediaStatus";
// private static final String MESSAGE_BROADCAST = "Broadcast";
- // private static final String MESSAGE_DEVICE_STATUS = "DeviceStatus";
+ private static final String MESSAGE_DEVICE_STATUS = "DeviceStatus";
+ private static final String MESSAGE_DEVICE_CONTROL = "DeviceControl";
+ private static final String MESSAGE_DEVICE_CONFIG = "DeviceConfig";
private static final String MESSAGE_MOBILE_POSITION = "MobilePosition";
// private static final String MESSAGE_MOBILE_POSITION_INTERVAL = "Interval";
+ private static final String MESSAGE_PRESET_QUERY = "PresetQuery";
/**
* 处理MESSAGE请求
@@ -99,12 +103,22 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
processMessageKeepAlive(evt);
} else if (MESSAGE_CONFIG_DOWNLOAD.equals(cmd)) {
logger.info("接收到ConfigDownload消息");
+ processMessageConfigDownload(evt);
} else if (MESSAGE_CATALOG.equals(cmd)) {
logger.info("接收到Catalog消息");
processMessageCatalogList(evt);
} else if (MESSAGE_DEVICE_INFO.equals(cmd)) {
logger.info("接收到DeviceInfo消息");
processMessageDeviceInfo(evt);
+ } else if (MESSAGE_DEVICE_STATUS.equals(cmd)) {
+ logger.info("接收到DeviceStatus消息");
+ processMessageDeviceStatus(evt);
+ } else if (MESSAGE_DEVICE_CONTROL.equals(cmd)) {
+ logger.info("接收到DeviceControl消息");
+ processMessageDeviceControl(evt);
+ } else if (MESSAGE_DEVICE_CONFIG.equals(cmd)) {
+ logger.info("接收到DeviceConfig消息");
+ processMessageDeviceConfig(evt);
} else if (MESSAGE_ALARM.equals(cmd)) {
logger.info("接收到Alarm消息");
processMessageAlarm(evt);
@@ -117,6 +131,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
} else if (MESSAGE_MOBILE_POSITION.equals(cmd)) {
logger.info("接收到MobilePosition消息");
processMessageMobilePosition(evt);
+ } else if (MESSAGE_PRESET_QUERY.equals(cmd)) {
+ logger.info("接收到PresetQuery消息");
+ processMessagePresetQuery(evt);
} else {
logger.info("接收到消息:" + cmd);
responseAck(evt);
@@ -133,7 +150,6 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/
private void processMessageMobilePosition(RequestEvent evt) {
try {
- //回复 200 OK
Element rootElement = getRootElement(evt);
MobilePosition mobilePosition = new MobilePosition();
Element deviceIdElement = rootElement.element("DeviceID");
@@ -174,12 +190,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
storager.clearMobilePositionsByDeviceId(deviceId);
}
storager.insertMobilePosition(mobilePosition);
- // List all= storager.queryMobilePositions(deviceId, "2021-01-23T00:00:00", "2021-02-28T23:59:59");
- // all= storager.queryMobilePositions(deviceId, null, "2021-01-24T23:59:59");
- // all= storager.queryMobilePositions(deviceId, "2021-01-24T00:00:00", null);
- // //logger.debug(all.toString());
- // MobilePosition mp = storager.queryLatestPosition(deviceId);
- // logger.debug("最新位置:" + mp.getLongitude() + ", " + mp.getLatitude());
+ //回复 200 OK
responseAck(evt);
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
e.printStackTrace();
@@ -187,7 +198,169 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
}
/**
- * 收到deviceInfo设备信息请求 处理
+ * 处理DeviceStatus设备状态Message
+ *
+ * @param evt
+ */
+ private void processMessageDeviceStatus(RequestEvent evt) {
+ try {
+ Element rootElement = getRootElement(evt);
+ String deviceId = XmlUtil.getText(rootElement, "DeviceID");
+ // 检查设备是否存在, 不存在则不回复
+ if (storager.exists(deviceId)) {
+ // 回复200 OK
+ responseAck(evt);
+ JSONObject json = new JSONObject();
+ XmlUtil.node2Json(rootElement, json);
+ if (logger.isDebugEnabled()) {
+ logger.debug(json.toJSONString());
+ }
+ RequestMessage msg = new RequestMessage();
+ msg.setDeviceId(deviceId);
+ msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS);
+ msg.setData(json);
+ deferredResultHolder.invokeResult(msg);
+
+ if (offLineDetector.isOnline(deviceId)) {
+ publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
+ } else {
+ }
+ }
+ } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 处理DeviceControl设备状态Message
+ *
+ * @param evt
+ */
+ private void processMessageDeviceControl(RequestEvent evt) {
+ try {
+ Element rootElement = getRootElement(evt);
+ String deviceId = XmlUtil.getText(rootElement, "DeviceID");
+ String result = XmlUtil.getText(rootElement, "Result");
+ // 回复200 OK
+ responseAck(evt);
+ if (!XmlUtil.isEmpty(result)) {
+ // 此处是对本平台发出DeviceControl指令的应答
+ JSONObject json = new JSONObject();
+ XmlUtil.node2Json(rootElement, json);
+ if (logger.isDebugEnabled()) {
+ logger.debug(json.toJSONString());
+ }
+ RequestMessage msg = new RequestMessage();
+ msg.setDeviceId(deviceId);
+ msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL);
+ msg.setData(json);
+ deferredResultHolder.invokeResult(msg);
+ } else {
+ // 此处是上级发出的DeviceControl指令
+ }
+ } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 处理DeviceConfig设备状态Message
+ *
+ * @param evt
+ */
+ private void processMessageDeviceConfig(RequestEvent evt) {
+ try {
+ Element rootElement = getRootElement(evt);
+ String deviceId = XmlUtil.getText(rootElement, "DeviceID");
+ String result = XmlUtil.getText(rootElement, "Result");
+ // 回复200 OK
+ responseAck(evt);
+ //if (!XmlUtil.isEmpty(result)) {
+ // 此处是对本平台发出DeviceControl指令的应答
+ JSONObject json = new JSONObject();
+ XmlUtil.node2Json(rootElement, json);
+ if (logger.isDebugEnabled()) {
+ logger.debug(json.toJSONString());
+ }
+ RequestMessage msg = new RequestMessage();
+ msg.setDeviceId(deviceId);
+ msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG);
+ msg.setData(json);
+ deferredResultHolder.invokeResult(msg);
+ // } else {
+ // // 此处是上级发出的DeviceConfig指令
+ //}
+ } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 处理ConfigDownload设备状态Message
+ *
+ * @param evt
+ */
+ private void processMessageConfigDownload(RequestEvent evt) {
+ try {
+ Element rootElement = getRootElement(evt);
+ String deviceId = XmlUtil.getText(rootElement, "DeviceID");
+ String result = XmlUtil.getText(rootElement, "Result");
+ // 回复200 OK
+ responseAck(evt);
+ //if (!XmlUtil.isEmpty(result)) {
+ // 此处是对本平台发出DeviceControl指令的应答
+ JSONObject json = new JSONObject();
+ XmlUtil.node2Json(rootElement, json);
+ if (logger.isDebugEnabled()) {
+ logger.debug(json.toJSONString());
+ }
+ RequestMessage msg = new RequestMessage();
+ msg.setDeviceId(deviceId);
+ msg.setType(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD);
+ msg.setData(json);
+ deferredResultHolder.invokeResult(msg);
+ // } else {
+ // // 此处是上级发出的DeviceConfig指令
+ //}
+ } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 处理PresetQuery预置位列表Message
+ *
+ * @param evt
+ */
+ private void processMessagePresetQuery(RequestEvent evt) {
+ try {
+ Element rootElement = getRootElement(evt);
+ String deviceId = XmlUtil.getText(rootElement, "DeviceID");
+ String result = XmlUtil.getText(rootElement, "Result");
+ // 回复200 OK
+ responseAck(evt);
+ if (rootElement.getName().equals("Response")) {// !XmlUtil.isEmpty(result)) {
+ // 此处是对本平台发出DeviceControl指令的应答
+ JSONObject json = new JSONObject();
+ XmlUtil.node2Json(rootElement, json);
+ if (logger.isDebugEnabled()) {
+ logger.debug(json.toJSONString());
+ }
+ RequestMessage msg = new RequestMessage();
+ msg.setDeviceId(deviceId);
+ msg.setType(DeferredResultHolder.CALLBACK_CMD_PRESETQUERY);
+ msg.setData(json);
+ deferredResultHolder.invokeResult(msg);
+ } else {
+ // 此处是上级发出的DeviceControl指令
+ }
+ } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 处理DeviceInfo设备信息Message
*
* @param evt
*/
@@ -354,56 +527,72 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
Element rootElement = getRootElement(evt);
Element deviceIdElement = rootElement.element("DeviceID");
String deviceId = deviceIdElement.getText().toString();
+ // 回复200 OK
+ responseAck(evt);
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
return;
}
- DeviceAlarm deviceAlarm = new DeviceAlarm();
- deviceAlarm.setDeviceId(deviceId);
- deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
- deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod"));
- deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime"));
- if (XmlUtil.getText(rootElement, "AlarmDescription") == null) {
- deviceAlarm.setAlarmDescription("");
- } else {
- deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription"));
- }
- if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) {
- deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
- } else {
- deviceAlarm.setLongitude(0.00);
- }
- if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) {
- deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
- } else {
- deviceAlarm.setLatitude(0.00);
- }
- if ( deviceAlarm.getAlarmMethod().equals("4")) {
- MobilePosition mobilePosition = new MobilePosition();
- mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
- mobilePosition.setTime(deviceAlarm.getAlarmTime());
- mobilePosition.setLongitude(deviceAlarm.getLongitude());
- mobilePosition.setLatitude(deviceAlarm.getLatitude());
- mobilePosition.setReportSource("GPS Alarm");
- BaiduPoint bp = new BaiduPoint();
- bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
- logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
- mobilePosition.setGeodeticSystem("BD-09");
- mobilePosition.setCnLng(bp.getBdLng());
- mobilePosition.setCnLat(bp.getBdLat());
- if (!userSetup.getSavePositionHistory()) {
- storager.clearMobilePositionsByDeviceId(deviceId);
+ if (rootElement.getName().equals("Notify")) { // 处理报警通知
+ DeviceAlarm deviceAlarm = new DeviceAlarm();
+ deviceAlarm.setDeviceId(deviceId);
+ deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
+ deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod"));
+ deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime"));
+ if (XmlUtil.getText(rootElement, "AlarmDescription") == null) {
+ deviceAlarm.setAlarmDescription("");
+ } else {
+ deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription"));
}
- storager.insertMobilePosition(mobilePosition);
- }
- // TODO: 需要实现存储报警信息、报警分类
-
- // 回复200 OK
- responseAck(evt);
- if (offLineDetector.isOnline(deviceId)) {
- publisher.deviceAlarmEventPublish(deviceAlarm);
+ if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) {
+ deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
+ } else {
+ deviceAlarm.setLongitude(0.00);
+ }
+ if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) {
+ deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
+ } else {
+ deviceAlarm.setLatitude(0.00);
+ }
+
+ if (!XmlUtil.isEmpty(deviceAlarm.getAlarmMethod())) {
+ if ( deviceAlarm.getAlarmMethod().equals("4")) {
+ MobilePosition mobilePosition = new MobilePosition();
+ mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
+ mobilePosition.setTime(deviceAlarm.getAlarmTime());
+ mobilePosition.setLongitude(deviceAlarm.getLongitude());
+ mobilePosition.setLatitude(deviceAlarm.getLatitude());
+ mobilePosition.setReportSource("GPS Alarm");
+ BaiduPoint bp = new BaiduPoint();
+ bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
+ logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
+ mobilePosition.setGeodeticSystem("BD-09");
+ mobilePosition.setCnLng(bp.getBdLng());
+ mobilePosition.setCnLat(bp.getBdLat());
+ if (!userSetup.getSavePositionHistory()) {
+ storager.clearMobilePositionsByDeviceId(deviceId);
+ }
+ storager.insertMobilePosition(mobilePosition);
+ }
+ }
+ // TODO: 需要实现存储报警信息、报警分类
+
+ if (offLineDetector.isOnline(deviceId)) {
+ publisher.deviceAlarmEventPublish(deviceAlarm);
+ }
+ } else if (rootElement.getName().equals("Response")) { // 处理报警查询响应
+ JSONObject json = new JSONObject();
+ XmlUtil.node2Json(rootElement, json);
+ if (logger.isDebugEnabled()) {
+ logger.debug(json.toJSONString());
+ }
+ RequestMessage msg = new RequestMessage();
+ msg.setDeviceId(deviceId);
+ msg.setType(DeferredResultHolder.CALLBACK_CMD_ALARM);
+ msg.setData(json);
+ deferredResultHolder.invokeResult(msg);
}
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
// } catch (DocumentException e) {
@@ -435,7 +624,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
}
/***
- * 收到catalog设备目录列表请求 处理 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致
+ * 处理RecordInfo设备录像列表Message请求 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致
*
* @param evt
*/
@@ -522,12 +711,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
// 2、有录像数据,且第一次即收到完整数据,返回响应数据,无redis操作
// 3、有录像数据,在超时时间内收到多次包组装后数量足够,返回数据
- // 对记录进行排序
RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId);
msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO);
- // // 自然顺序排序, 元素进行升序排列
- // recordInfo.getRecordList().sort(Comparator.naturalOrder());
msg.setData(recordInfo);
deferredResultHolder.invokeResult(msg);
logger.info("处理完成,返回结果");
From c1d4e1944df7d3fc09bb3058f827ade448d79167 Mon Sep 17 00:00:00 2001
From: lawrencehj <1934378145@qq.com>
Date: Wed, 3 Feb 2021 11:05:27 +0800
Subject: [PATCH 17/18] =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E6=95=B0=E6=8D=AE?=
=?UTF-8?q?=E6=A0=BC=E5=BC=8F=E6=A0=A1=E9=AA=8C=E5=92=8C=E8=BD=AC=E6=8D=A2?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../iot/vmp/gb28181/utils/NumericUtil.java | 20 ++-
.../iot/vmp/gb28181/utils/XmlUtil.java | 119 ++++++++++++------
2 files changed, 102 insertions(+), 37 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/NumericUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/NumericUtil.java
index 4dc63075..f9fbfb18 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/NumericUtil.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/NumericUtil.java
@@ -15,10 +15,26 @@ public class NumericUtil {
public static boolean isDouble(String str) {
try {
Double num2 = Double.valueOf(str);
- System.out.println("Is Number!" + num2);
+ System.out.println(num2 + " Is an Integer!");
return true;
} catch (Exception e) {
- System.out.println("Is not Number!");
+ System.out.println(str + " Is not an Integer!");
+ return false;
+ }
+ }
+
+ /**
+ * 判断是否Double格式
+ * @param str
+ * @return true/false
+ */
+ public static boolean isInteger(String str) {
+ try {
+ int num2 = Integer.valueOf(str);
+ System.out.println(num2 + " Is Number!");
+ return true;
+ } catch (Exception e) {
+ System.out.println(str + " Is not Number!");
return false;
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
index e0d776c2..c82ba600 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
@@ -7,6 +7,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
@@ -20,8 +23,7 @@ import org.slf4j.LoggerFactory;
*
*
*/
-public class XmlUtil
-{
+public class XmlUtil {
/**
* 日志服务
*/
@@ -30,22 +32,18 @@ public class XmlUtil
/**
* 解析XML为Document对象
*
- * @param xml
- * 被解析的XMl
+ * @param xml 被解析的XMl
+ *
* @return Document
*/
- public static Element parseXml(String xml)
- {
+ public static Element parseXml(String xml) {
Document document = null;
//
StringReader sr = new StringReader(xml);
SAXReader saxReader = new SAXReader();
- try
- {
+ try {
document = saxReader.read(sr);
- }
- catch (DocumentException e)
- {
+ } catch (DocumentException e) {
LOG.error("解析失败", e);
}
return null == document ? null : document.getRootElement();
@@ -54,16 +52,12 @@ public class XmlUtil
/**
* 获取element对象的text的值
*
- * @param em
- * 节点的对象
- * @param tag
- * 节点的tag
+ * @param em 节点的对象
+ * @param tag 节点的tag
* @return 节点
*/
- public static String getText(Element em, String tag)
- {
- if (null == em)
- {
+ public static String getText(Element em, String tag) {
+ if (null == em) {
return null;
}
Element e = em.element(tag);
@@ -74,16 +68,12 @@ public class XmlUtil
/**
* 递归解析xml节点,适用于 多节点数据
*
- * @param node
- * node
- * @param nodeName
- * nodeName
+ * @param node node
+ * @param nodeName nodeName
* @return List