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] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A7=BB=E5=8A=A8=E4=BD=8D?= =?UTF-8?q?=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 @@ + +