Merge branch 'master' of http://s16s652780.51mypc.cn:49896/r/srs-police-affairs
12 files modified
2 files added
| New file |
| | |
| | | /* |
| | | * heatmap.js v2.0.0 | JavaScript Heatmap Library |
| | | * |
| | | * Copyright 2008-2014 Patrick Wied <heatmapjs@patrick-wied.at> - All rights reserved. |
| | | * Dual licensed under MIT and Beerware license |
| | | * |
| | | * :: 2015-07-19 15:42 |
| | | */ |
| | | (function (a, b, c) { if (typeof module !== "undefined" && module.exports) { module.exports = c() } else if (typeof define === "function" && define.amd) { define(c) } else { b[a] = c() } })("h337", this, function () { var a = { defaultRadius: 40, defaultRenderer: "canvas2d", defaultGradient: { .25: "rgb(0,0,255)", .55: "rgb(0,255,0)", .85: "yellow", 1: "rgb(255,0,0)" }, defaultMaxOpacity: 1, defaultMinOpacity: 0, defaultBlur: .85, defaultXField: "x", defaultYField: "y", defaultValueField: "value", plugins: {} }; var b = function h () { var b = function d (a) { this._coordinator = {}; this._data = []; this._radi = []; this._min = 0; this._max = 1; this._xField = a["xField"] || a.defaultXField; this._yField = a["yField"] || a.defaultYField; this._valueField = a["valueField"] || a.defaultValueField; if (a["radius"]) { this._cfgRadius = a["radius"] } }; var c = a.defaultRadius; b.prototype = { _organiseData: function (a, b) { var d = a[this._xField]; var e = a[this._yField]; var f = this._radi; var g = this._data; var h = this._max; var i = this._min; var j = a[this._valueField] || 1; var k = a.radius || this._cfgRadius || c; if (!g[d]) { g[d] = []; f[d] = [] } if (!g[d][e]) { g[d][e] = j; f[d][e] = k } else { g[d][e] += j } if (g[d][e] > h) { if (!b) { this._max = g[d][e] } else { this.setDataMax(g[d][e]) } return false } else { return { x: d, y: e, value: j, radius: k, min: i, max: h } } }, _unOrganizeData: function () { var a = []; var b = this._data; var c = this._radi; for (var d in b) { for (var e in b[d]) { a.push({ x: d, y: e, radius: c[d][e], value: b[d][e] }) } } return { min: this._min, max: this._max, data: a } }, _onExtremaChange: function () { this._coordinator.emit("extremachange", { min: this._min, max: this._max }) }, addData: function () { if (arguments[0].length > 0) { var a = arguments[0]; var b = a.length; while (b--) { this.addData.call(this, a[b]) } } else { var c = this._organiseData(arguments[0], true); if (c) { this._coordinator.emit("renderpartial", { min: this._min, max: this._max, data: [c] }) } } return this }, setData: function (a) { var b = a.data; var c = b.length; this._data = []; this._radi = []; for (var d = 0; d < c; d++) { this._organiseData(b[d], false) } this._max = a.max; this._min = a.min || 0; this._onExtremaChange(); this._coordinator.emit("renderall", this._getInternalData()); return this }, removeData: function () { }, setDataMax: function (a) { this._max = a; this._onExtremaChange(); this._coordinator.emit("renderall", this._getInternalData()); return this }, setDataMin: function (a) { this._min = a; this._onExtremaChange(); this._coordinator.emit("renderall", this._getInternalData()); return this }, setCoordinator: function (a) { this._coordinator = a }, _getInternalData: function () { return { max: this._max, min: this._min, data: this._data, radi: this._radi } }, getData: function () { return this._unOrganizeData() } }; return b }(); var c = function i () { var a = function (a) { var b = a.gradient || a.defaultGradient; var c = document.createElement("canvas"); var d = c.getContext("2d"); c.width = 256; c.height = 1; var e = d.createLinearGradient(0, 0, 256, 1); for (var f in b) { e.addColorStop(f, b[f]) } d.fillStyle = e; d.fillRect(0, 0, 256, 1); return d.getImageData(0, 0, 256, 1).data }; var b = function (a, b) { var c = document.createElement("canvas"); var d = c.getContext("2d"); var e = a; var f = a; c.width = c.height = a * 2; if (b == 1) { d.beginPath(); d.arc(e, f, a, 0, 2 * Math.PI, false); d.fillStyle = "rgba(0,0,0,1)"; d.fill() } else { var g = d.createRadialGradient(e, f, a * b, e, f, a); g.addColorStop(0, "rgba(0,0,0,1)"); g.addColorStop(1, "rgba(0,0,0,0)"); d.fillStyle = g; d.fillRect(0, 0, 2 * a, 2 * a) } return c }; var c = function (a) { var b = []; var c = a.min; var d = a.max; var e = a.radi; var a = a.data; var f = Object.keys(a); var g = f.length; while (g--) { var h = f[g]; var i = Object.keys(a[h]); var j = i.length; while (j--) { var k = i[j]; var l = a[h][k]; var m = e[h][k]; b.push({ x: h, y: k, value: l, radius: m }) } } return { min: c, max: d, data: b } }; function d (b) { var c = b.container; var d = this.shadowCanvas = document.createElement("canvas"); var e = this.canvas = b.canvas || document.createElement("canvas"); var f = this._renderBoundaries = [1e4, 1e4, 0, 0]; var g = getComputedStyle(b.container) || {}; e.className = "heatmap-canvas"; this._width = e.width = d.width = +g.width.replace(/px/, ""); this._height = e.height = d.height = +g.height.replace(/px/, ""); this.shadowCtx = d.getContext("2d"); this.ctx = e.getContext("2d"); e.style.cssText = d.style.cssText = "position:absolute;left:0;top:0;"; c.style.position = "relative"; c.appendChild(e); this._palette = a(b); this._templates = {}; this._setStyles(b) } d.prototype = { renderPartial: function (a) { this._drawAlpha(a); this._colorize() }, renderAll: function (a) { this._clear(); this._drawAlpha(c(a)); this._colorize() }, _updateGradient: function (b) { this._palette = a(b) }, updateConfig: function (a) { if (a["gradient"]) { this._updateGradient(a) } this._setStyles(a) }, setDimensions: function (a, b) { this._width = a; this._height = b; this.canvas.width = this.shadowCanvas.width = a; this.canvas.height = this.shadowCanvas.height = b }, _clear: function () { this.shadowCtx.clearRect(0, 0, this._width, this._height); this.ctx.clearRect(0, 0, this._width, this._height) }, _setStyles: function (a) { this._blur = a.blur == 0 ? 0 : a.blur || a.defaultBlur; if (a.backgroundColor) { this.canvas.style.backgroundColor = a.backgroundColor } this._opacity = (a.opacity || 0) * 255; this._maxOpacity = (a.maxOpacity || a.defaultMaxOpacity) * 255; this._minOpacity = (a.minOpacity || a.defaultMinOpacity) * 255; this._useGradientOpacity = !!a.useGradientOpacity }, _drawAlpha: function (a) { var c = this._min = a.min; var d = this._max = a.max; var a = a.data || []; var e = a.length; var f = 1 - this._blur; while (e--) { var g = a[e]; var h = g.x; var i = g.y; var j = g.radius; var k = Math.min(g.value, d); var l = h - j; var m = i - j; var n = this.shadowCtx; var o; if (!this._templates[j]) { this._templates[j] = o = b(j, f) } else { o = this._templates[j] } n.globalAlpha = (k - c) / (d - c); n.drawImage(o, l, m); if (l < this._renderBoundaries[0]) { this._renderBoundaries[0] = l } if (m < this._renderBoundaries[1]) { this._renderBoundaries[1] = m } if (l + 2 * j > this._renderBoundaries[2]) { this._renderBoundaries[2] = l + 2 * j } if (m + 2 * j > this._renderBoundaries[3]) { this._renderBoundaries[3] = m + 2 * j } } }, _colorize: function () { var a = this._renderBoundaries[0]; var b = this._renderBoundaries[1]; var c = this._renderBoundaries[2] - a; var d = this._renderBoundaries[3] - b; var e = this._width; var f = this._height; var g = this._opacity; var h = this._maxOpacity; var i = this._minOpacity; var j = this._useGradientOpacity; if (a < 0) { a = 0 } if (b < 0) { b = 0 } if (a + c > e) { c = e - a } if (b + d > f) { d = f - b } var k = this.shadowCtx.getImageData(a, b, c, d); var l = k.data; var m = l.length; var n = this._palette; for (var o = 3; o < m; o += 4) { var p = l[o]; var q = p * 4; if (!q) { continue } var r; if (g > 0) { r = g } else { if (p < h) { if (p < i) { r = i } else { r = p } } else { r = h } } l[o - 3] = n[q]; l[o - 2] = n[q + 1]; l[o - 1] = n[q + 2]; l[o] = j ? n[q + 3] : r } k.data = l; this.ctx.putImageData(k, a, b); this._renderBoundaries = [1e3, 1e3, 0, 0] }, getValueAt: function (a) { var b; var c = this.shadowCtx; var d = c.getImageData(a.x, a.y, 1, 1); var e = d.data[3]; var f = this._max; var g = this._min; b = Math.abs(f - g) * (e / 255) >> 0; return b }, getDataURL: function () { return this.canvas.toDataURL() } }; return d }(); var d = function j () { var b = false; if (a["defaultRenderer"] === "canvas2d") { b = c } return b }(); var e = { merge: function () { var a = {}; var b = arguments.length; for (var c = 0; c < b; c++) { var d = arguments[c]; for (var e in d) { a[e] = d[e] } } return a } }; var f = function k () { var c = function h () { function a () { this.cStore = {} } a.prototype = { on: function (a, b, c) { var d = this.cStore; if (!d[a]) { d[a] = [] } d[a].push(function (a) { return b.call(c, a) }) }, emit: function (a, b) { var c = this.cStore; if (c[a]) { var d = c[a].length; for (var e = 0; e < d; e++) { var f = c[a][e]; f(b) } } } }; return a }(); var f = function (a) { var b = a._renderer; var c = a._coordinator; var d = a._store; c.on("renderpartial", b.renderPartial, b); c.on("renderall", b.renderAll, b); c.on("extremachange", function (b) { a._config.onExtremaChange && a._config.onExtremaChange({ min: b.min, max: b.max, gradient: a._config["gradient"] || a._config["defaultGradient"] }) }); d.setCoordinator(c) }; function g () { var g = this._config = e.merge(a, arguments[0] || {}); this._coordinator = new c; if (g["plugin"]) { var h = g["plugin"]; if (!a.plugins[h]) { throw new Error("Plugin '" + h + "' not found. Maybe it was not registered.") } else { var i = a.plugins[h]; this._renderer = new i.renderer(g); this._store = new i.store(g) } } else { this._renderer = new d(g); this._store = new b(g) } f(this) } g.prototype = { addData: function () { this._store.addData.apply(this._store, arguments); return this }, removeData: function () { this._store.removeData && this._store.removeData.apply(this._store, arguments); return this }, setData: function () { this._store.setData.apply(this._store, arguments); return this }, setDataMax: function () { this._store.setDataMax.apply(this._store, arguments); return this }, setDataMin: function () { this._store.setDataMin.apply(this._store, arguments); return this }, configure: function (a) { this._config = e.merge(this._config, a); this._renderer.updateConfig(this._config); this._coordinator.emit("renderall", this._store._getInternalData()); return this }, repaint: function () { this._coordinator.emit("renderall", this._store._getInternalData()); return this }, getData: function () { return this._store.getData() }, getDataURL: function () { return this._renderer.getDataURL() }, getValueAt: function (a) { if (this._store.getValueAt) { return this._store.getValueAt(a) } else if (this._renderer.getValueAt) { return this._renderer.getValueAt(a) } else { return null } } }; return g }(); var g = { create: function (a) { return new f(a) }, register: function (b, c) { a.plugins[b] = c } }; return g }) |
| | |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-09-07 09:34:58 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-03-24 17:06:34 |
| | | * @LastEditTime: 2023-05-06 20:29:19 |
| | | * @FilePath: \srs-police-affairs\public\index.html |
| | | * @Description: |
| | | * |
| | |
| | | |
| | | <script src="./depend/echarts.min.js"></script> |
| | | |
| | | <script src="./depend/heatmap.min.js"></script> |
| | | |
| | | <script> |
| | | window._axiosPromiseArr = [] |
| | | </script> |
| | |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-08-18 17:00:30 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-05-03 22:39:23 |
| | | * @LastEditTime: 2023-05-06 20:17:16 |
| | | * @FilePath: \srs-police-affairs\src\components\map\index.vue |
| | | * @Description: 公用地图组件 |
| | | * |
| | |
| | | // global.viewer.addTerrain(terrain) |
| | | |
| | | // 内网 |
| | | that.switchImg() |
| | | // that.switchImg() |
| | | |
| | | // 地形数据添加 |
| | | that.addTerrain() |
| | | // that.addTerrain() |
| | | |
| | | // 外网 |
| | | // global.viewer.imageryLayers.addImageryProvider( |
| | | // new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({ |
| | | // url: 'http://t{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=d083e4cf30bfc438ef93436c10c2c20a', |
| | | // subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], |
| | | // format: 'image/jpeg', |
| | | // show: true, |
| | | // maximumLevel: 18 |
| | | // }) |
| | | // ) |
| | | global.viewer.imageryLayers.addImageryProvider( |
| | | new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({ |
| | | url: 'http://t{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=d083e4cf30bfc438ef93436c10c2c20a', |
| | | subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], |
| | | format: 'image/jpeg', |
| | | show: true, |
| | | maximumLevel: 18 |
| | | }) |
| | | ) |
| | | |
| | | // 设置地图初始位置,角度等 |
| | | global.viewer.camera.setView({ |
| | |
| | | * @param {*} type 图层类型 |
| | | */ |
| | | mapAddLayer (layerName, type, ClusterLayerType) { |
| | | if (!layersObjcect[layerName]) { |
| | | this.mapRemoveLayer(layerName, type) |
| | | layersObjcect[layerName] = null |
| | | } |
| | | |
| | | if (type == 'VectorLayer') { |
| | | if (!layersObjcect[layerName]) layersObjcect[layerName] = null |
| | | |
| | | layersObjcect[layerName] = new global.DC.VectorLayer(layerName) |
| | | |
| | | layersObjcect[layerName].addTo(global.viewer) |
| | | } else if (type == 'ClusterLayer') { |
| | | if (!layersObjcect[layerName]) { |
| | | this.mapRemoveLayer(layerName, type) |
| | | layersObjcect[layerName] = null |
| | | } |
| | | |
| | | layersObjcect[layerName] = new global.DC.ClusterLayer(layerName, { |
| | | pixelRange: 40, style: ClusterLayerType |
| | | }) |
| | | |
| | | layersObjcect[layerName].addTo(global.viewer) |
| | | } else if (type == 'HeatLayer') { |
| | | if (!layersObjcect[layerName]) layersObjcect[layerName] = null |
| | | |
| | | layersObjcect[layerName] = new global.DC.HeatLayer(layerName) |
| | | |
| | | layersObjcect[layerName].addTo(global.viewer) |
| | | layersObjcect[layerName] = new global.DC.HeatLayer(layerName, { |
| | | gradient: { |
| | | "0.5": "green", |
| | | "0.6": "orange", |
| | | "0.95": "red" |
| | | }, //颜色设置 |
| | | height: 0, // 高度 |
| | | radius: 100, // 半径 |
| | | useGround: false, //是否使用贴地模式 |
| | | classificationType: 2 //分类 是否影响地形,3D切片或同时影响这两者。0:地形、1:3D切片、2:两者。贴地模式下生效 |
| | | }) |
| | | } |
| | | |
| | | global.viewer.addLayer(layersObjcect[layerName]) |
| | | }, |
| | | |
| | | /** |
| | |
| | | |
| | | .timeTab { |
| | | top: countSizeVh(22); |
| | | right: countSizeVw(400, 1920); |
| | | right: countSizeVw(670, 1920); |
| | | border-radius: countSizeVh(6); |
| | | |
| | | span { |
| | |
| | | } |
| | | |
| | | .timeSeclect { |
| | | top: countSizeVh(15); |
| | | width: countSizeVw(520, 1920); |
| | | height: countSizeVh(30); |
| | | top: countSizeVh(20); |
| | | right: countSizeVw(128, 1920); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | .police-page { |
| | | .time-select { |
| | | .search-item-box { |
| | | margin: countSizeVh(10); |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | } |
| | | |
| | | .switch-box { |
| | | padding: countSizeVh(6); |
| | | |
| New file |
| | |
| | | /* |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-05-06 20:24:41 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-05-06 21:15:24 |
| | | * @FilePath: \srs-police-affairs\src\utils\CesiumHeatmap.js |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | */ |
| | | /* eslint-disable no-undef */ |
| | | /* |
| | | * CesiumHeatmap.js v0.1 | global.DC.Namespace.Cesium Heatmap Library |
| | | * |
| | | * Works with heatmap.js v2.0.0: http://www.patrick-wied.at/static/heatmapjs/ |
| | | */ |
| | | (function (window) { |
| | | 'use strict' |
| | | |
| | | function define_CesiumHeatmap () { |
| | | var CesiumHeatmap = { |
| | | defaults: { |
| | | useEntitiesIfAvailable: true, //whether to use entities if a Viewer is supplied or always use an ImageryProvider |
| | | minCanvasSize: 700, // minimum size (in pixels) for the heatmap canvas |
| | | maxCanvasSize: 2000, // maximum size (in pixels) for the heatmap canvas |
| | | radiusFactor: 60, // data point size factor used if no radius is given (the greater of height and width divided by this number yields the used radius) |
| | | spacingFactor: 1.5, // extra space around the borders (point radius multiplied by this number yields the spacing) |
| | | maxOpacity: 0.8, // the maximum opacity used if not given in the heatmap options object |
| | | minOpacity: 0.1, // the minimum opacity used if not given in the heatmap options object |
| | | blur: 0.85, // the blur used if not given in the heatmap options object |
| | | gradient: { // the gradient used if not given in the heatmap options object |
| | | '0.9': 'red', |
| | | '0.8': 'orange', |
| | | '0.7': 'yellow', |
| | | '0.5': 'blue', |
| | | '0.3': 'green', |
| | | }, |
| | | } |
| | | } |
| | | |
| | | /* Create a CesiumHeatmap instance |
| | | * |
| | | * cesium: the CesiumWidget or Viewer instance |
| | | * bb: the WGS84 bounding box like {north, east, south, west} |
| | | * options: a heatmap.js options object (see http://www.patrick-wied.at/static/heatmapjs/docs.html#h337-create) |
| | | */ |
| | | CesiumHeatmap.create = function (cesium, bb, options) { |
| | | var instance = new CHInstance(cesium, bb, options) |
| | | return instance |
| | | } |
| | | |
| | | CesiumHeatmap._getContainer = function (width, height, id) { |
| | | var c = document.createElement("div") |
| | | if (id) { |
| | | c.setAttribute("id", id) |
| | | } |
| | | c.setAttribute("style", "width: " + width + "px; height: " + height + "px; margin: 0px; display: none;") |
| | | document.body.appendChild(c) |
| | | return c |
| | | } |
| | | |
| | | CesiumHeatmap._getImageryProvider = function (instance) { |
| | | //var n = (new Date()).getTime(); |
| | | var d = instance._heatmap.getDataURL() |
| | | //console.log("Create data URL: " + ((new Date()).getTime() - n)); |
| | | |
| | | //var n = (new Date()).getTime(); |
| | | var imgprov = new global.DC.Namespace.Cesium.SingleTileImageryProvider({ |
| | | url: d, |
| | | rectangle: instance._rectangle |
| | | }) |
| | | //console.log("Create imageryprovider: " + ((new Date()).getTime() - n)); |
| | | |
| | | imgprov._tilingScheme = new global.DC.Namespace.Cesium.WebMercatorTilingScheme({ |
| | | rectangleSouthwestInMeters: new global.DC.Namespace.Cesium.Cartesian2(instance._mbounds.west, instance._mbounds.south), |
| | | rectangleNortheastInMeters: new global.DC.Namespace.Cesium.Cartesian2(instance._mbounds.east, instance._mbounds.north) |
| | | }) |
| | | |
| | | return imgprov |
| | | } |
| | | |
| | | CesiumHeatmap._getID = function (len) { |
| | | var text = "" |
| | | var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" |
| | | |
| | | for (var i = 0; i < ((len) ? len : 8); i++) |
| | | text += possible.charAt(Math.floor(Math.random() * possible.length)) |
| | | |
| | | return text |
| | | } |
| | | |
| | | var WMP = new global.DC.Namespace.Cesium.WebMercatorProjection() |
| | | var Cesium = global.DC.Namespace.Cesium |
| | | |
| | | /* Convert a WGS84 location into a mercator location |
| | | * |
| | | * p: the WGS84 location like {x: lon, y: lat} |
| | | */ |
| | | CesiumHeatmap.wgs84ToMercator = function (p) { |
| | | var mp = WMP.project(Cesium.Cartographic.fromDegrees(p.x, p.y)) |
| | | return { |
| | | x: mp.x, |
| | | y: mp.y |
| | | } |
| | | } |
| | | |
| | | /* Convert a WGS84 bounding box into a mercator bounding box |
| | | * |
| | | * bb: the WGS84 bounding box like {north, east, south, west} |
| | | */ |
| | | CesiumHeatmap.wgs84ToMercatorBB = function (bb) { |
| | | var sw = WMP.project(Cesium.Cartographic.fromDegrees(bb.west, bb.south)) |
| | | var ne = WMP.project(Cesium.Cartographic.fromDegrees(bb.east, bb.north)) |
| | | return { |
| | | north: ne.y, |
| | | east: ne.x, |
| | | south: sw.y, |
| | | west: sw.x |
| | | } |
| | | } |
| | | |
| | | /* Convert a mercator location into a WGS84 location |
| | | * |
| | | * p: the mercator lcation like {x, y} |
| | | */ |
| | | CesiumHeatmap.mercatorToWgs84 = function (p) { |
| | | var wp = WMP.unproject(new Cesium.Cartesian3(p.x, p.y)) |
| | | return { |
| | | x: wp.longitude, |
| | | y: wp.latitude |
| | | } |
| | | } |
| | | |
| | | /* Convert a mercator bounding box into a WGS84 bounding box |
| | | * |
| | | * bb: the mercator bounding box like {north, east, south, west} |
| | | */ |
| | | CesiumHeatmap.mercatorToWgs84BB = function (bb) { |
| | | var sw = WMP.unproject(new Cesium.Cartesian3(bb.west, bb.south)) |
| | | var ne = WMP.unproject(new Cesium.Cartesian3(bb.east, bb.north)) |
| | | return { |
| | | north: this.rad2deg(ne.latitude), |
| | | east: this.rad2deg(ne.longitude), |
| | | south: this.rad2deg(sw.latitude), |
| | | west: this.rad2deg(sw.longitude) |
| | | } |
| | | } |
| | | |
| | | /* Convert degrees into radians |
| | | * |
| | | * d: the degrees to be converted to radians |
| | | */ |
| | | CesiumHeatmap.deg2rad = function (d) { |
| | | var r = d * (Math.PI / 180.0) |
| | | return r |
| | | } |
| | | |
| | | /* Convert radians into degrees |
| | | * |
| | | * r: the radians to be converted to degrees |
| | | */ |
| | | CesiumHeatmap.rad2deg = function (r) { |
| | | var d = r / (Math.PI / 180.0) |
| | | return d |
| | | } |
| | | |
| | | return CesiumHeatmap |
| | | } |
| | | |
| | | if (typeof (CesiumHeatmap) === 'undefined') { |
| | | window.CesiumHeatmap = define_CesiumHeatmap(global.DC.Namespace.Cesium) |
| | | } else { |
| | | console.log("CesiumHeatmap already defined.") |
| | | } |
| | | })(window) |
| | | |
| | | /* Initiate a CesiumHeatmap instance |
| | | * |
| | | * c: CesiumWidget instance |
| | | * bb: a WGS84 bounding box like {north, east, south, west} |
| | | * o: a heatmap.js options object (see http://www.patrick-wied.at/static/heatmapjs/docs.html#h337-create) |
| | | */ |
| | | function CHInstance (c, bb, o) { |
| | | if (!bb) { |
| | | return null |
| | | } |
| | | if (!o) { |
| | | o = {} |
| | | } |
| | | |
| | | this._cesium = c |
| | | this._options = o |
| | | this._id = CesiumHeatmap._getID() |
| | | |
| | | this._options.gradient = ((this._options.gradient) ? this._options.gradient : CesiumHeatmap.defaults.gradient) |
| | | this._options.maxOpacity = ((this._options.maxOpacity) ? this._options.maxOpacity : CesiumHeatmap.defaults.maxOpacity) |
| | | this._options.minOpacity = ((this._options.minOpacity) ? this._options.minOpacity : CesiumHeatmap.defaults.minOpacity) |
| | | this._options.blur = ((this._options.blur) ? this._options.blur : CesiumHeatmap.defaults.blur) |
| | | |
| | | this._mbounds = CesiumHeatmap.wgs84ToMercatorBB(bb) |
| | | this._setWidthAndHeight(this._mbounds) |
| | | |
| | | this._options.radius = Math.round((this._options.radius) ? this._options.radius : ((this.width > this.height) ? this.width / CesiumHeatmap.defaults.radiusFactor : this.height / CesiumHeatmap.defaults.radiusFactor)) |
| | | |
| | | this._spacing = this._options.radius * CesiumHeatmap.defaults.spacingFactor |
| | | this._xoffset = this._mbounds.west |
| | | this._yoffset = this._mbounds.south |
| | | |
| | | this.width = Math.round(this.width + this._spacing * 2) |
| | | this.height = Math.round(this.height + this._spacing * 2) |
| | | |
| | | this._mbounds.west -= this._spacing * this._factor |
| | | this._mbounds.east += this._spacing * this._factor |
| | | this._mbounds.south -= this._spacing * this._factor |
| | | this._mbounds.north += this._spacing * this._factor |
| | | |
| | | this.bounds = CesiumHeatmap.mercatorToWgs84BB(this._mbounds) |
| | | |
| | | this._rectangle = global.DC.Namespace.Cesium.Rectangle.fromDegrees(this.bounds.west, this.bounds.south, this.bounds.east, this.bounds.north) |
| | | this._container = CesiumHeatmap._getContainer(this.width, this.height, this._id) |
| | | this._options.container = this._container |
| | | this._heatmap = window.h337.create(this._options) |
| | | this._container.children[0].setAttribute("id", this._id + "-hm") |
| | | } |
| | | |
| | | /* Convert a WGS84 location to the corresponding heatmap location |
| | | * |
| | | * p: a WGS84 location like {x:lon, y:lat} |
| | | */ |
| | | CHInstance.prototype.wgs84PointToHeatmapPoint = function (p) { |
| | | return this.mercatorPointToHeatmapPoint(CesiumHeatmap.wgs84ToMercator(p)) |
| | | } |
| | | |
| | | /* Convert a mercator location to the corresponding heatmap location |
| | | * |
| | | * p: a WGS84 location like {x: lon, y:lat} |
| | | */ |
| | | CHInstance.prototype.mercatorPointToHeatmapPoint = function (p) { |
| | | var pn = {} |
| | | |
| | | pn.x = Math.round((p.x - this._xoffset) / this._factor + this._spacing) |
| | | pn.y = Math.round((p.y - this._yoffset) / this._factor + this._spacing) |
| | | pn.y = this.height - pn.y |
| | | |
| | | return pn |
| | | } |
| | | |
| | | CHInstance.prototype._setWidthAndHeight = function (mbb) { |
| | | this.width = ((mbb.east > 0 && mbb.west < 0) ? mbb.east + Math.abs(mbb.west) : Math.abs(mbb.east - mbb.west)) |
| | | this.height = ((mbb.north > 0 && mbb.south < 0) ? mbb.north + Math.abs(mbb.south) : Math.abs(mbb.north - mbb.south)) |
| | | this._factor = 1 |
| | | |
| | | if (this.width > this.height && this.width > CesiumHeatmap.defaults.maxCanvasSize) { |
| | | this._factor = this.width / CesiumHeatmap.defaults.maxCanvasSize |
| | | |
| | | if (this.height / this._factor < CesiumHeatmap.defaults.minCanvasSize) { |
| | | this._factor = this.height / CesiumHeatmap.defaults.minCanvasSize |
| | | } |
| | | } else if (this.height > this.width && this.height > CesiumHeatmap.defaults.maxCanvasSize) { |
| | | this._factor = this.height / CesiumHeatmap.defaults.maxCanvasSize |
| | | |
| | | if (this.width / this._factor < CesiumHeatmap.defaults.minCanvasSize) { |
| | | this._factor = this.width / CesiumHeatmap.defaults.minCanvasSize |
| | | } |
| | | } else if (this.width < this.height && this.width < CesiumHeatmap.defaults.minCanvasSize) { |
| | | this._factor = this.width / CesiumHeatmap.defaults.minCanvasSize |
| | | |
| | | if (this.height / this._factor > CesiumHeatmap.defaults.maxCanvasSize) { |
| | | this._factor = this.height / CesiumHeatmap.defaults.maxCanvasSize |
| | | } |
| | | } else if (this.height < this.width && this.height < CesiumHeatmap.defaults.minCanvasSize) { |
| | | this._factor = this.height / CesiumHeatmap.defaults.minCanvasSize |
| | | |
| | | if (this.width / this._factor > CesiumHeatmap.defaults.maxCanvasSize) { |
| | | this._factor = this.width / CesiumHeatmap.defaults.maxCanvasSize |
| | | } |
| | | } |
| | | |
| | | this.width = this.width / this._factor |
| | | this.height = this.height / this._factor |
| | | } |
| | | |
| | | /* Set an array of heatmap locations |
| | | * |
| | | * min: the minimum allowed value for the data values |
| | | * max: the maximum allowed value for the data values |
| | | * data: an array of data points in heatmap coordinates and values like {x, y, value} |
| | | */ |
| | | CHInstance.prototype.setData = function (min, max, data) { |
| | | if (data && data.length > 0 && min !== null && min !== false && max !== null && max !== false) { |
| | | this._heatmap.setData({ |
| | | min: min, |
| | | max: max, |
| | | data: data |
| | | }) |
| | | |
| | | this.updateLayer() |
| | | return true |
| | | } |
| | | |
| | | return false |
| | | } |
| | | |
| | | /* Set an array of WGS84 locations |
| | | * |
| | | * min: the minimum allowed value for the data values |
| | | * max: the maximum allowed value for the data values |
| | | * data: an array of data points in WGS84 coordinates and values like { x:lon, y:lat, value } |
| | | */ |
| | | CHInstance.prototype.setWGS84Data = function (min, max, data) { |
| | | if (data && data.length > 0 && min !== null && min !== false && max !== null && max !== false) { |
| | | var convdata = [] |
| | | |
| | | for (var i = 0; i < data.length; i++) { |
| | | var gp = data[i] |
| | | |
| | | var hp = this.wgs84PointToHeatmapPoint(gp) |
| | | if (gp.value || gp.value === 0) { |
| | | hp.value = gp.value |
| | | } |
| | | |
| | | convdata.push(hp) |
| | | } |
| | | |
| | | return this.setData(min, max, convdata) |
| | | } |
| | | |
| | | return false |
| | | } |
| | | |
| | | /* Set whether or not the heatmap is shown on the map |
| | | * |
| | | * s: true means the heatmap is shown, false means the heatmap is hidden |
| | | */ |
| | | CHInstance.prototype.show = function (s) { |
| | | if (this._layer) { |
| | | this._layer.show = s |
| | | } |
| | | } |
| | | |
| | | /* Update/(re)draw the heatmap |
| | | */ |
| | | CHInstance.prototype.updateLayer = function () { |
| | | |
| | | // only works with a Viewer instance since the cesiumWidget |
| | | // instance doesn't contain an entities property |
| | | if (CesiumHeatmap.defaults.useEntitiesIfAvailable && this._cesium.entities) { |
| | | if (this._layer) { |
| | | this._cesium.entities.remove(this._layer) |
| | | } |
| | | |
| | | // Work around issue with material rendering in global.DC.Namespace.Cesium |
| | | // provided by https://github.com/criis |
| | | material = new global.DC.Namespace.Cesium.ImageMaterialProperty({ |
| | | image: this._heatmap._renderer.canvas, |
| | | }) |
| | | if (global.DC.Namespace.Cesium.VERSION >= "1.21") { |
| | | material.transparent = true |
| | | } else if (global.DC.Namespace.Cesium.VERSION >= "1.16") { |
| | | material.alpha = 0.99 |
| | | } |
| | | |
| | | this._layer = this._cesium.entities.add({ |
| | | show: true, |
| | | rectangle: { |
| | | coordinates: this._rectangle, |
| | | material: material |
| | | } |
| | | }) |
| | | } else { |
| | | if (this._layer) { |
| | | this._cesium.scene.imageryLayers.remove(this._layer) |
| | | } |
| | | this._layer = this._cesium.scene.imageryLayers.addImageryProvider(CesiumHeatmap._getImageryProvider(this)) |
| | | } |
| | | }; |
| | | |
| | | /* DON'T TOUCH: |
| | | * |
| | | * heatmap.js v2.0.0 | JavaScript Heatmap Library: http://www.patrick-wied.at/static/heatmapjs/ |
| | | * |
| | | * Copyright 2008-2014 Patrick Wied <heatmapjs@patrick-wied.at> - All rights reserved. |
| | | * Dual licensed under MIT and Beerware license |
| | | * |
| | | * :: 2014-10-31 21:16 |
| | | */ |
| | | (function (a, b, c) { |
| | | b[a] = c()//稍微改了下 |
| | | })("h337", this, function () { |
| | | var a = { |
| | | defaultRadius: 40, |
| | | defaultRenderer: "canvas2d", |
| | | defaultGradient: { .25: "rgb(0,0,255)", .55: "rgb(0,255,0)", .85: "yellow", 1: "rgb(255,0,0)" }, |
| | | defaultMaxOpacity: 1, |
| | | defaultMinOpacity: 0, |
| | | defaultBlur: .85, |
| | | defaultXField: "x", |
| | | defaultYField: "y", |
| | | defaultValueField: "value", |
| | | plugins: {} |
| | | } |
| | | var b = function h () { |
| | | var b = function d (a) { |
| | | this._coordinator = {} |
| | | this._data = [] |
| | | this._radi = [] |
| | | this._min = 0 |
| | | this._max = 1 |
| | | this._xField = a["xField"] || a.defaultXField |
| | | this._yField = a["yField"] || a.defaultYField |
| | | this._valueField = a["valueField"] || a.defaultValueField |
| | | if (a["radius"]) { |
| | | this._cfgRadius = a["radius"] |
| | | } |
| | | } |
| | | var c = a.defaultRadius |
| | | b.prototype = { |
| | | _organiseData: function (a, b) { |
| | | var d = a[this._xField] |
| | | var e = a[this._yField] |
| | | var f = this._radi |
| | | var g = this._data |
| | | var h = this._max |
| | | var i = this._min |
| | | var j = a[this._valueField] || 1 |
| | | var k = a.radius || this._cfgRadius || c |
| | | if (!g[d]) { |
| | | g[d] = [] |
| | | f[d] = [] |
| | | } |
| | | if (!g[d][e]) { |
| | | g[d][e] = j |
| | | f[d][e] = k |
| | | } else { |
| | | g[d][e] += j |
| | | } |
| | | if (g[d][e] > h) { |
| | | if (!b) { |
| | | this._max = g[d][e] |
| | | } else { |
| | | this.setDataMax(g[d][e]) |
| | | } |
| | | return false |
| | | } else { |
| | | return { x: d, y: e, value: j, radius: k, min: i, max: h } |
| | | } |
| | | }, _unOrganizeData: function () { |
| | | var a = [] |
| | | var b = this._data |
| | | var c = this._radi |
| | | for (var d in b) { |
| | | for (var e in b[d]) { |
| | | a.push({ x: d, y: e, radius: c[d][e], value: b[d][e] }) |
| | | } |
| | | } |
| | | return { min: this._min, max: this._max, data: a } |
| | | }, _onExtremaChange: function () { |
| | | this._coordinator.emit("extremachange", { min: this._min, max: this._max }) |
| | | }, addData: function () { |
| | | if (arguments[0].length > 0) { |
| | | var a = arguments[0] |
| | | var b = a.length |
| | | while (b--) { |
| | | this.addData.call(this, a[b]) |
| | | } |
| | | } else { |
| | | var c = this._organiseData(arguments[0], true) |
| | | if (c) { |
| | | this._coordinator.emit("renderpartial", { min: this._min, max: this._max, data: [c] }) |
| | | } |
| | | } |
| | | return this |
| | | }, setData: function (a) { |
| | | var b = a.data |
| | | var c = b.length |
| | | this._data = [] |
| | | this._radi = [] |
| | | for (var d = 0; d < c; d++) { |
| | | this._organiseData(b[d], false) |
| | | } |
| | | this._max = a.max |
| | | this._min = a.min || 0 |
| | | this._onExtremaChange() |
| | | this._coordinator.emit("renderall", this._getInternalData()) |
| | | return this |
| | | }, removeData: function () { |
| | | }, setDataMax: function (a) { |
| | | this._max = a |
| | | this._onExtremaChange() |
| | | this._coordinator.emit("renderall", this._getInternalData()) |
| | | return this |
| | | }, setDataMin: function (a) { |
| | | this._min = a |
| | | this._onExtremaChange() |
| | | this._coordinator.emit("renderall", this._getInternalData()) |
| | | return this |
| | | }, setCoordinator: function (a) { |
| | | this._coordinator = a |
| | | }, _getInternalData: function () { |
| | | return { max: this._max, min: this._min, data: this._data, radi: this._radi } |
| | | }, getData: function () { |
| | | return this._unOrganizeData() |
| | | } |
| | | } |
| | | return b |
| | | }() |
| | | var c = function i () { |
| | | var a = function (a) { |
| | | var b = a.gradient || a.defaultGradient |
| | | var c = document.createElement("canvas") |
| | | var d = c.getContext("2d") |
| | | c.width = 256 |
| | | c.height = 1 |
| | | var e = d.createLinearGradient(0, 0, 256, 1) |
| | | for (var f in b) { |
| | | e.addColorStop(f, b[f]) |
| | | } |
| | | d.fillStyle = e |
| | | d.fillRect(0, 0, 256, 1) |
| | | return d.getImageData(0, 0, 256, 1).data |
| | | } |
| | | var b = function (a, b) { |
| | | var c = document.createElement("canvas") |
| | | var d = c.getContext("2d") |
| | | var e = a |
| | | var f = a |
| | | c.width = c.height = a * 2 |
| | | if (b == 1) { |
| | | d.beginPath() |
| | | d.arc(e, f, a, 0, 2 * Math.PI, false) |
| | | d.fillStyle = "rgba(0,0,0,1)" |
| | | d.fill() |
| | | } else { |
| | | var g = d.createRadialGradient(e, f, a * b, e, f, a) |
| | | g.addColorStop(0, "rgba(0,0,0,1)") |
| | | g.addColorStop(1, "rgba(0,0,0,0)") |
| | | d.fillStyle = g |
| | | d.fillRect(0, 0, 2 * a, 2 * a) |
| | | } |
| | | return c |
| | | } |
| | | var c = function (a) { |
| | | var b = [] |
| | | var c = a.min |
| | | var d = a.max |
| | | var e = a.radi |
| | | // eslint-disable-next-line no-redeclare |
| | | var a = a.data |
| | | var f = Object.keys(a) |
| | | var g = f.length |
| | | while (g--) { |
| | | var h = f[g] |
| | | var i = Object.keys(a[h]) |
| | | var j = i.length |
| | | while (j--) { |
| | | var k = i[j] |
| | | var l = a[h][k] |
| | | var m = e[h][k] |
| | | b.push({ x: h, y: k, value: l, radius: m }) |
| | | } |
| | | } |
| | | return { min: c, max: d, data: b } |
| | | } |
| | | |
| | | function d (b) { |
| | | var c = b.container |
| | | var d = this.shadowCanvas = document.createElement("canvas") |
| | | var e = this.canvas = b.canvas || document.createElement("canvas") |
| | | var f = this._renderBoundaries = [1e4, 1e4, 0, 0] |
| | | var g = getComputedStyle(b.container) || {} |
| | | e.className = "heatmap-canvas" |
| | | this._width = e.width = d.width = +g.width.replace(/px/, "") |
| | | this._height = e.height = d.height = +g.height.replace(/px/, "") |
| | | this.shadowCtx = d.getContext("2d") |
| | | this.ctx = e.getContext("2d") |
| | | e.style.cssText = d.style.cssText = "position:absolute;left:0;top:0;" |
| | | c.style.position = "relative" |
| | | c.appendChild(e) |
| | | this._palette = a(b) |
| | | this._templates = {} |
| | | this._setStyles(b) |
| | | } |
| | | |
| | | d.prototype = { |
| | | renderPartial: function (a) { |
| | | this._drawAlpha(a) |
| | | this._colorize() |
| | | }, renderAll: function (a) { |
| | | this._clear() |
| | | this._drawAlpha(c(a)) |
| | | this._colorize() |
| | | }, _updateGradient: function (b) { |
| | | this._palette = a(b) |
| | | }, updateConfig: function (a) { |
| | | if (a["gradient"]) { |
| | | this._updateGradient(a) |
| | | } |
| | | this._setStyles(a) |
| | | }, setDimensions: function (a, b) { |
| | | this._width = a |
| | | this._height = b |
| | | this.canvas.width = this.shadowCanvas.width = a |
| | | this.canvas.height = this.shadowCanvas.height = b |
| | | }, _clear: function () { |
| | | this.shadowCtx.clearRect(0, 0, this._width, this._height) |
| | | this.ctx.clearRect(0, 0, this._width, this._height) |
| | | }, _setStyles: function (a) { |
| | | this._blur = a.blur == 0 ? 0 : a.blur || a.defaultBlur |
| | | if (a.backgroundColor) { |
| | | this.canvas.style.backgroundColor = a.backgroundColor |
| | | } |
| | | this._opacity = (a.opacity || 0) * 255 |
| | | this._maxOpacity = (a.maxOpacity || a.defaultMaxOpacity) * 255 |
| | | this._minOpacity = (a.minOpacity || a.defaultMinOpacity) * 255 |
| | | this._useGradientOpacity = !!a.useGradientOpacity |
| | | }, _drawAlpha: function (a) { |
| | | var c = this._min = a.min |
| | | var d = this._max = a.max |
| | | // eslint-disable-next-line no-redeclare |
| | | var a = a.data || [] |
| | | var e = a.length |
| | | var f = 1 - this._blur |
| | | while (e--) { |
| | | var g = a[e] |
| | | var h = g.x |
| | | var i = g.y |
| | | var j = g.radius |
| | | var k = Math.min(g.value, d) |
| | | var l = h - j |
| | | var m = i - j |
| | | var n = this.shadowCtx |
| | | var o |
| | | if (!this._templates[j]) { |
| | | this._templates[j] = o = b(j, f) |
| | | } else { |
| | | o = this._templates[j] |
| | | } |
| | | n.globalAlpha = (k - c) / (d - c) |
| | | n.drawImage(o, l, m) |
| | | if (l < this._renderBoundaries[0]) { |
| | | this._renderBoundaries[0] = l |
| | | } |
| | | if (m < this._renderBoundaries[1]) { |
| | | this._renderBoundaries[1] = m |
| | | } |
| | | if (l + 2 * j > this._renderBoundaries[2]) { |
| | | this._renderBoundaries[2] = l + 2 * j |
| | | } |
| | | if (m + 2 * j > this._renderBoundaries[3]) { |
| | | this._renderBoundaries[3] = m + 2 * j |
| | | } |
| | | } |
| | | }, _colorize: function () { |
| | | var a = this._renderBoundaries[0] |
| | | var b = this._renderBoundaries[1] |
| | | var c = this._renderBoundaries[2] - a |
| | | var d = this._renderBoundaries[3] - b |
| | | var e = this._width |
| | | var f = this._height |
| | | var g = this._opacity |
| | | var h = this._maxOpacity |
| | | var i = this._minOpacity |
| | | var j = this._useGradientOpacity |
| | | if (a < 0) { |
| | | a = 0 |
| | | } |
| | | if (b < 0) { |
| | | b = 0 |
| | | } |
| | | if (a + c > e) { |
| | | c = e - a |
| | | } |
| | | if (b + d > f) { |
| | | d = f - b |
| | | } |
| | | var k = this.shadowCtx.getImageData(a, b, c, d) |
| | | var l = k.data |
| | | var m = l.length |
| | | var n = this._palette |
| | | for (var o = 3; o < m; o += 4) { |
| | | var p = l[o] |
| | | var q = p * 4 |
| | | if (!q) { |
| | | continue |
| | | } |
| | | var r |
| | | if (g > 0) { |
| | | r = g |
| | | } else { |
| | | if (p < h) { |
| | | if (p < i) { |
| | | r = i |
| | | } else { |
| | | r = p |
| | | } |
| | | } else { |
| | | r = h |
| | | } |
| | | } |
| | | l[o - 3] = n[q] |
| | | l[o - 2] = n[q + 1] |
| | | l[o - 1] = n[q + 2] |
| | | l[o] = j ? n[q + 3] : r |
| | | } |
| | | k.data = l |
| | | this.ctx.putImageData(k, a, b) |
| | | this._renderBoundaries = [1e3, 1e3, 0, 0] |
| | | }, getValueAt: function (a) { |
| | | var b |
| | | var c = this.shadowCtx |
| | | var d = c.getImageData(a.x, a.y, 1, 1) |
| | | var e = d.data[3] |
| | | var f = this._max |
| | | var g = this._min |
| | | b = Math.abs(f - g) * (e / 255) >> 0 |
| | | return b |
| | | }, getDataURL: function () { |
| | | return this.canvas.toDataURL() |
| | | } |
| | | } |
| | | return d |
| | | }() |
| | | var d = function j () { |
| | | var b = false |
| | | if (a["defaultRenderer"] === "canvas2d") { |
| | | b = c |
| | | } |
| | | return b |
| | | }() |
| | | var e = { |
| | | merge: function () { |
| | | var a = {} |
| | | var b = arguments.length |
| | | for (var c = 0; c < b; c++) { |
| | | var d = arguments[c] |
| | | for (var e in d) { |
| | | a[e] = d[e] |
| | | } |
| | | } |
| | | return a |
| | | } |
| | | } |
| | | var f = function k () { |
| | | var c = function h () { |
| | | function a () { |
| | | this.cStore = {} |
| | | } |
| | | |
| | | a.prototype = { |
| | | on: function (a, b, c) { |
| | | var d = this.cStore |
| | | if (!d[a]) { |
| | | d[a] = [] |
| | | } |
| | | d[a].push(function (a) { |
| | | return b.call(c, a) |
| | | }) |
| | | }, emit: function (a, b) { |
| | | var c = this.cStore |
| | | if (c[a]) { |
| | | var d = c[a].length |
| | | for (var e = 0; e < d; e++) { |
| | | var f = c[a][e] |
| | | f(b) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return a |
| | | }() |
| | | var f = function (a) { |
| | | var b = a._renderer |
| | | var c = a._coordinator |
| | | var d = a._store |
| | | c.on("renderpartial", b.renderPartial, b) |
| | | c.on("renderall", b.renderAll, b) |
| | | c.on("extremachange", function (b) { |
| | | a._config.onExtremaChange && a._config.onExtremaChange({ |
| | | min: b.min, |
| | | max: b.max, |
| | | gradient: a._config["gradient"] || a._config["defaultGradient"] |
| | | }) |
| | | }) |
| | | d.setCoordinator(c) |
| | | } |
| | | |
| | | function g () { |
| | | var g = this._config = e.merge(a, arguments[0] || {}) |
| | | this._coordinator = new c |
| | | if (g["plugin"]) { |
| | | var h = g["plugin"] |
| | | if (!a.plugins[h]) { |
| | | throw new Error("Plugin '" + h + "' not found. Maybe it was not registered.") |
| | | } else { |
| | | var i = a.plugins[h] |
| | | this._renderer = new i.renderer(g) |
| | | this._store = new i.store(g) |
| | | } |
| | | } else { |
| | | this._renderer = new d(g) |
| | | this._store = new b(g) |
| | | } |
| | | f(this) |
| | | } |
| | | |
| | | g.prototype = { |
| | | addData: function () { |
| | | this._store.addData.apply(this._store, arguments) |
| | | return this |
| | | }, removeData: function () { |
| | | this._store.removeData && this._store.removeData.apply(this._store, arguments) |
| | | return this |
| | | }, setData: function () { |
| | | this._store.setData.apply(this._store, arguments) |
| | | return this |
| | | }, setDataMax: function () { |
| | | this._store.setDataMax.apply(this._store, arguments) |
| | | return this |
| | | }, setDataMin: function () { |
| | | this._store.setDataMin.apply(this._store, arguments) |
| | | return this |
| | | }, configure: function (a) { |
| | | this._config = e.merge(this._config, a) |
| | | this._renderer.updateConfig(this._config) |
| | | this._coordinator.emit("renderall", this._store._getInternalData()) |
| | | return this |
| | | }, repaint: function () { |
| | | this._coordinator.emit("renderall", this._store._getInternalData()) |
| | | return this |
| | | }, getData: function () { |
| | | return this._store.getData() |
| | | }, getDataURL: function () { |
| | | return this._renderer.getDataURL() |
| | | }, getValueAt: function (a) { |
| | | if (this._store.getValueAt) { |
| | | return this._store.getValueAt(a) |
| | | } else if (this._renderer.getValueAt) { |
| | | return this._renderer.getValueAt(a) |
| | | } else { |
| | | return null |
| | | } |
| | | } |
| | | } |
| | | return g |
| | | }() |
| | | var g = { |
| | | create: function (a) { |
| | | return new f(a) |
| | | }, register: function (b, c) { |
| | | a.plugins[b] = c |
| | | } |
| | | } |
| | | return g |
| | | }) |
| | |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-31 10:52:25 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-04-18 20:13:04 |
| | | * @LastEditTime: 2023-05-06 16:52:41 |
| | | * @FilePath: \srs-police-affairs\src\utils\turfPolygon.js |
| | | * @Description: |
| | | * |
| | |
| | | return turf.centroid(turf.polygon([arr])).geometry.coordinates |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | export const computerCapacity = (data, type = '') => { |
| | | |
| | |
| | | 3 |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export const getMapBounds = (data, type = '') => { |
| | | let pointArr = [] |
| | | |
| | | data.forEach(item => { |
| | | pointArr.push(turf.point([item.x, item.y])) |
| | | return |
| | | }) |
| | | |
| | | const features = turf.featureCollection(pointArr) |
| | | |
| | | const scope = turf.envelope(features).bbox |
| | | |
| | | // const poly = turf.polygon([[[0, 29], [3.5, 29], [2.5, 32], [0, 29]]]) |
| | | |
| | | return scope |
| | | } |
| | | |
| | | export const getLineSpeed = (data) => { |
| | | var line = turf.lineString(data) |
| | | var length = turf.length(line, { units: 'miles' }) |
| | | |
| | | return length * 1000 / 50 |
| | | } |
| | |
| | | <span>要素资源:</span> |
| | | <ul> |
| | | <li> |
| | | <button @click="drawThreeArrow('billboard', 'police', 'policeman')" title="警员"> |
| | | <button |
| | | @click="drawThreeArrow('billboard', 'police', 'policeman')" |
| | | title="警员" |
| | | > |
| | | <img src="/img/icon/police-people-btn.png" style="height:100%" /> |
| | | </button> |
| | | </li> |
| | | <li> |
| | | <button @click="drawThreeArrow('billboard', 'police', 'policecar')" title="警车"> |
| | | <button |
| | | @click="drawThreeArrow('billboard', 'police', 'policecar')" |
| | | title="警车" |
| | | > |
| | | <img src="/img/icon/car-btn.png" style="height:100%" /> |
| | | </button> |
| | | </li> |
| | | <li> |
| | | <button @click="drawThreeArrow('billboard', 'icon', 'icon4')" title="自定义图片标注">自定义图片标注</button> |
| | | <button |
| | | @click="drawThreeArrow('billboard', 'icon', 'icon4')" |
| | | title="自定义图片标注" |
| | | >自定义图片标注</button> |
| | | </li> |
| | | <li> |
| | | <button @click="drawThreeArrow('billboard', 'icon', 'icon5')" title="其他">其他</button> |
| | |
| | | <span>作战标绘:</span> |
| | | <ul> |
| | | <li> |
| | | <button @click="drawThreeArrow('polygon', 'polygon', 'polygon')" title="多边形">多边形</button> |
| | | <button |
| | | @click="drawThreeArrow('polygon', 'polygon', 'polygon')" |
| | | title="多边形" |
| | | >多边形</button> |
| | | </li> |
| | | <li> |
| | | <button @click="drawThreeArrow('brokenline', 'brokenline', 'brokenline')" title="折线">折线</button> |
| | | <button |
| | | @click="drawThreeArrow('brokenline', 'brokenline', 'brokenline')" |
| | | title="折线" |
| | | >折线</button> |
| | | </li> |
| | | </ul> |
| | | </div> |
| | |
| | | <ul> |
| | | <li> |
| | | <!-- <el-button |
| | | ></el-button>--> |
| | | <button @click="drawThreeArrow('polyline', 'policecar', 'polyline')" title="巡逻路线"> |
| | | ></el-button>--> |
| | | <button |
| | | @click="drawThreeArrow('polyline', 'policecar', 'polyline')" |
| | | title="巡逻路线" |
| | | > |
| | | <img src="/img/icon/route1.png" style="height:100%" /> |
| | | </button> |
| | | </li> |
| | |
| | | } from '@/api/activity/index.js' |
| | | |
| | | import Plot from "@/utils/plot/Plot.js" |
| | | |
| | | import { getLineSpeed } from '@/utils/turfPolygon' |
| | | let addPlotOverlayData = null |
| | | |
| | | let currentEmitEl = null |
| | |
| | | currentEmitEl = overlayData |
| | | global.viewer.scene.globe.depthTestAgainstTerrain = true |
| | | if (overlayData.customType == 'polygon' || overlayData.customType == 'brokenline') { |
| | | drawThreeTool.edit(overlayData, (e) => { |
| | | let polygonPosition = e.positions.map(item => `${item.lng} ${item.lat}`).join() |
| | | const altitude = e.positions.map(item => item.alt).join() |
| | | this.updateSecurityPlot({ id: overlayData.attrParams.id, position: polygonPosition, altitude }) |
| | | global.viewer.scene.globe.depthTestAgainstTerrain = false |
| | | currentStatus = '' |
| | | }, true) |
| | | if (overlayData.attrParams.item.areaType != 2) { |
| | | drawThreeTool.edit(overlayData, (e) => { |
| | | let polygonPosition = e.positions.map(item => `${item.lng} ${item.lat}`).join() |
| | | const altitude = e.positions.map(item => item.alt).join() |
| | | this.updateSecurityPlot({ id: overlayData.attrParams.id, position: polygonPosition, altitude }) |
| | | global.viewer.scene.globe.depthTestAgainstTerrain = false |
| | | currentStatus = '' |
| | | }, true) |
| | | } else { |
| | | overlayData.show = false |
| | | // this.$parent.removeArrowsListLayer(overlayData) |
| | | let altitude = overlayData.attrParams.item.altitude.split(',') |
| | | let position = overlayData.attrParams.item.position.slice(11, overlayData.attrParams.item.position.length - 1).replace(/,/g, ';').replace(/ /g, ',') |
| | | let positions |
| | | if (altitude && altitude.length) positions = position.split(';').map((item, index) => `${item},${altitude[index]}`).join(';') |
| | | let coverage = new global.DC.Polygon(positions) |
| | | |
| | | let color = this.$parent.getCoverageColor(overlayData.attrParams.item.color) |
| | | |
| | | coverage.setStyle({ |
| | | material: color.curColor, |
| | | extrudedHeight: null, |
| | | perPositionHeight: this.$parent.currentPlotType == 3 ? true : false, |
| | | closeTop: false, |
| | | closeBottom: false, |
| | | // classificationType: global.DC.Namespace.Cesium.ClassificationType.TERRAIN |
| | | outline: true, |
| | | outlineColor: color.outColor, |
| | | outlineWidth: 4.0, |
| | | }) |
| | | |
| | | coverage.customType = 'polygon' |
| | | |
| | | this.$parent.addArrowsListLayer(coverage) |
| | | |
| | | drawThreeTool.edit(coverage, (e) => { |
| | | this.$parent.removeArrowsListLayer(coverage) |
| | | |
| | | let polygonPosition = e.positions.map(item => `${item.lng} ${item.lat}`).join() |
| | | const altitude = e.positions.map(item => item.alt).join() |
| | | this.updateSecurityPlot({ id: overlayData.attrParams.id, position: polygonPosition, areaType: 2, altitude }, overlayData) |
| | | global.viewer.scene.globe.depthTestAgainstTerrain = false |
| | | currentStatus = '' |
| | | }, true) |
| | | } |
| | | } else if (overlayData.customType == 'billboard') { |
| | | drawThreeTool.edit(overlayData, (e) => { |
| | | const position = `${e.position.lng} ${e.position.lat},${e.position.lng} ${e.position.lat}` |
| | |
| | | let b = parseInt(item.color.slice(5, 7), 16) |
| | | let a = Math.floor(Number(item.color.split(',')[1]) * 2.55) ? Math.floor(Number(item.color.split(',')[1]) * 2.55) : 255 |
| | | let color = global.DC.Namespace.Cesium.Color.fromBytes(r, g, b, a) |
| | | let position = item.position.slice(12, item.position.length - 2).replace(/,/g, ';').replace(/ /g, ',') |
| | | |
| | | let positions = position.split(';').map((item, index) => `${item},140`) |
| | | positions.push(positions[0]) |
| | | positions = positions.join(';') |
| | | if (item.type == 5 || item.areaType == 2) { |
| | | this.$parent.removeArrowsListLayer(addPlotOverlayData) |
| | | |
| | | addPlotOverlayData = new global.DC.Wall(positions) |
| | | |
| | | addPlotOverlayData.customType = 'polygon' |
| | | |
| | | this.$parent.addArrowsListLayer(addPlotOverlayData) |
| | | } |
| | | |
| | | |
| | | addPlotOverlayData.attrParams = { id: item.id, color: item.color, item } |
| | | |
| | |
| | | |
| | | this.$parent.isHaveFactor = true |
| | | } else if (item.type == 5) { |
| | | addPlotOverlayData.setStyle({ |
| | | material: color, |
| | | outlineColor: global.DC.Namespace.Cesium.Color.fromBytes(r, g, b, 255) |
| | | }) |
| | | |
| | | if (item.areaType != 2) { |
| | | addPlotOverlayData.setStyle({ |
| | | material: color, |
| | | outlineColor: global.DC.Namespace.Cesium.Color.fromBytes(r, g, b, 255) |
| | | }) |
| | | } else { |
| | | addPlotOverlayData.setStyle({ |
| | | material: new global.DC.WallImageTrailMaterialProperty({ |
| | | image: '/images/jjx.png', |
| | | color: color, |
| | | repeat: { |
| | | x: getLineSpeed(position.split(';').map(item => { |
| | | item.split(',') |
| | | |
| | | return [Number(item.split(',')[0]), Number(item.split(',')[1])] |
| | | })), y: 1 |
| | | }, |
| | | speed: 10 |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | this.$parent.isHaveArrow = true |
| | | } else { |
| | |
| | | let outColor = global.DC.Namespace.Cesium.Color.fromBytes(r, g, b, 255) |
| | | overlay.attrParams.color = params.color |
| | | |
| | | let position = overlay.attrParams.item.position.slice(11, overlay.attrParams.item.position.length - 1).replace(/,/g, ';').replace(/ /g, ',') |
| | | |
| | | if (overlay.customType == 'polygon') { |
| | | overlay.setStyle({ |
| | | material: color, |
| | | outlineColor: outColor |
| | | }) |
| | | |
| | | if (overlay.attrParams.item.areaType != 2) { |
| | | overlay.setStyle({ |
| | | material: color, |
| | | outlineColor: outColor |
| | | }) |
| | | } else { |
| | | overlay.setStyle({ |
| | | material: new global.DC.WallImageTrailMaterialProperty({ |
| | | image: '/images/jjx.png', |
| | | color: color, |
| | | repeat: { |
| | | x: getLineSpeed(position.split(';').map(item => { |
| | | item.split(',') |
| | | |
| | | return [Number(item.split(',')[0]), Number(item.split(',')[1])] |
| | | })), y: 1 |
| | | }, |
| | | speed: 10 |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | } else if (overlay.customType == 'billboard') { |
| | | overlay.setStyle({ |
| | | color: color |
| | |
| | | |
| | | if ('type' in params && params.type != '') { |
| | | overlay.attrParams.item.type = params.type |
| | | } |
| | | |
| | | if (params.areaType == 2) { |
| | | overlay.attrParams.item.altitude = params.altitude |
| | | overlay.attrParams.item.position = `LINESTRING(${params.position})` |
| | | let positions = params.position.split(',').map(item => { |
| | | item = item.split(' ') |
| | | item = new global.DC.Position(item[0], item[1], 140) |
| | | |
| | | return item |
| | | }) |
| | | |
| | | positions.push(positions[0]) |
| | | |
| | | overlay.positions = positions |
| | | |
| | | overlay.show = true |
| | | } |
| | | }, |
| | | |
| | |
| | | .right { |
| | | height: 100%; |
| | | |
| | | &>div { |
| | | & > div { |
| | | display: flex; |
| | | } |
| | | |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog title="修改标绘" :visible.sync="editPlotVisible" :modal="true" :close-on-click-modal="false" |
| | | :modal-append-to-body="true" :append-to-body="true" class="edit-plot-box"> |
| | | <el-dialog |
| | | title="修改标绘" |
| | | :visible.sync="editPlotVisible" |
| | | :modal="true" |
| | | :close-on-click-modal="false" |
| | | :modal-append-to-body="true" |
| | | :append-to-body="true" |
| | | class="edit-plot-box" |
| | | > |
| | | <div> |
| | | <div class="line"> |
| | | <div class="value-name-box">描述:</div> |
| | | <div class="input-width-box" style="flex: 1;"> |
| | | <input style="width: 100%;" type="text" v-model="polygonRemark" placeholder="请输入..." /> |
| | | <input |
| | | style="width: 100%;" |
| | | type="text" |
| | | v-model="polygonRemark" |
| | | placeholder="请输入..." |
| | | /> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | <div class="value-name-box">选择类型:</div> |
| | | <div class="select-type" style="flex: 1;"> |
| | | <el-select size="small" v-model="restPlotType" placeholder="请选择类型"> |
| | | <el-option v-for="item in restPlotSelectArray" :key="item.value" :label="item.label" |
| | | :value="item.value"></el-option> |
| | | <el-option |
| | | v-for="item in restPlotSelectArray" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="line" v-show="customImageShow"> |
| | | <div class="value-name-box"> |
| | | 选择图片: |
| | | </div> |
| | | <div class="select-image" style="position: relative; display: flex; align-items: center;"> |
| | | <el-button style="margin-top: 0; position: relative; background: transparent; border-color: #fff;" |
| | | @click="imagesListShow = !imagesListShow"> |
| | | <img :src="curImgUrl" alt="" |
| | | style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; z-index: 999; width: 20px; height: 20px;"> |
| | | <div class="value-name-box">选择图片:</div> |
| | | <div |
| | | class="select-image" |
| | | style="position: relative; display: flex; align-items: center;" |
| | | > |
| | | <el-button |
| | | style="margin-top: 0; position: relative; background: transparent; border-color: #fff;" |
| | | @click="imagesListShow = !imagesListShow" |
| | | > |
| | | <img |
| | | :src="curImgUrl" |
| | | alt |
| | | style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; z-index: 999; width: 20px; height: 20px;" |
| | | /> |
| | | </el-button> |
| | | |
| | | <images-select v-show="imagesListShow" @curClick="curClick"></images-select> |
| | |
| | | <div class="line"> |
| | | <div class="value-name-box">选择标绘颜色:</div> |
| | | <div class="pick-color-box"> |
| | | <el-color-picker v-model="choosePlotColor" :predefine="predefineColors" size="small"> |
| | | </el-color-picker> |
| | | <el-color-picker |
| | | v-model="choosePlotColor" |
| | | :predefine="predefineColors" |
| | | size="small" |
| | | ></el-color-picker> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="line"> |
| | | <div class="value-name-box">设置透明度:</div> |
| | | <div class="alpha"> |
| | | <el-slider :min="1" v-model="choosePlotColorAlpha" :format-tooltip="formatTooltip"></el-slider> |
| | | <el-slider |
| | | :min="1" |
| | | v-model="choosePlotColorAlpha" |
| | | :format-tooltip="formatTooltip" |
| | | ></el-slider> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | <el-button @click="editPlotVisible = false">取消</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | </el-dialog> |
| | | |
| | | <el-dialog title="新增标绘" :visible.sync="polygonAddVisible" :modal="true" :close-on-click-modal="false" |
| | | :modal-append-to-body="true" :append-to-body="true" class="add-polygon-box" :before-close="cancelSavePolygon"> |
| | | |
| | | <el-dialog |
| | | title="新增标绘" |
| | | :visible.sync="polygonAddVisible" |
| | | :modal="true" |
| | | :close-on-click-modal="false" |
| | | :modal-append-to-body="true" |
| | | :append-to-body="true" |
| | | class="add-polygon-box" |
| | | :before-close="cancelSavePolygon" |
| | | > |
| | | <div> |
| | | <div class="line"> |
| | | <div class="value-name-box">描述:</div> |
| | | <div class="input-width-box" style="flex: 1;"> |
| | | <input style="width: 100%;" type="text" v-model="polygonRemark" placeholder="请输入..." /> |
| | | <input |
| | | style="width: 100%;" |
| | | type="text" |
| | | v-model="polygonRemark" |
| | | placeholder="请输入..." |
| | | /> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | <div class="value-name-box">选择类型:</div> |
| | | <div class="select-type" style="flex: 1;"> |
| | | <el-select size="small" v-model="restPlotType" placeholder="请选择类型"> |
| | | <el-option v-for="item in restPlotSelectArray" :key="item.value" :label="item.label" |
| | | :value="item.value"></el-option> |
| | | <el-option |
| | | v-for="item in restPlotSelectArray" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="line" v-show="isNeedPolygonType"> |
| | | <div class="value-name-box">选择类型:</div> |
| | | <div class="select-type"> |
| | | <div class="select-type" style="flex: 1;"> |
| | | <el-select size="small" v-model="polygonAreaType" placeholder="请选择区域类型"> |
| | | <el-option v-for="item in polygonAreaOption" :key="item.value" :label="item.label" |
| | | :value="item.value"></el-option> |
| | | <el-option |
| | | v-for="item in polygonAreaOption" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="line" v-show="customImageShow"> |
| | | <div class="value-name-box"> |
| | | 选择图片: |
| | | </div> |
| | | <div class="select-image" style="position: relative; display: flex; align-items: center;"> |
| | | <el-button style="margin-top: 0; position: relative; background: transparent; border-color: #fff;" |
| | | @click="imagesListShow = !imagesListShow"> |
| | | <img :src="curImgUrl" alt="" |
| | | style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; z-index: 999; width: 20px; height: 20px;"> |
| | | <div class="value-name-box">选择图片:</div> |
| | | <div |
| | | class="select-image" |
| | | style="position: relative; display: flex; align-items: center;" |
| | | > |
| | | <el-button |
| | | style="margin-top: 0; position: relative; background: transparent; border-color: #fff;" |
| | | @click="imagesListShow = !imagesListShow" |
| | | > |
| | | <img |
| | | :src="curImgUrl" |
| | | alt |
| | | style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; z-index: 999; width: 20px; height: 20px;" |
| | | /> |
| | | </el-button> |
| | | <images-select v-show="imagesListShow" @curClick="curClick"></images-select> |
| | | </div> |
| | |
| | | <div class="line"> |
| | | <div class="value-name-box">选择标绘颜色:</div> |
| | | <div class="pick-color-box"> |
| | | <el-color-picker v-model="choosePlotColor" :predefine="predefineColors" size="small"> |
| | | </el-color-picker> |
| | | <el-color-picker |
| | | v-model="choosePlotColor" |
| | | :predefine="predefineColors" |
| | | size="small" |
| | | ></el-color-picker> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="line"> |
| | | <div class="value-name-box">设置透明度:</div> |
| | | <div class="alpha"> |
| | | <el-slider :min="1" v-model="choosePlotColorAlpha" :format-tooltip="formatTooltip"></el-slider> |
| | | <el-slider |
| | | :min="1" |
| | | v-model="choosePlotColorAlpha" |
| | | :format-tooltip="formatTooltip" |
| | | ></el-slider> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | <el-button @click="cancelSavePolygon">取消</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | |
| | | polygonAreaOption: [{ |
| | | value: 1, |
| | | label: '核心区' |
| | | label: '多边形' |
| | | }, { |
| | | value: 2, |
| | | label: '缓冲区' |
| | | label: '电子围栏' |
| | | }], |
| | | |
| | | restPlotSelectArray: [ |
| | |
| | | |
| | | if (type == 5) { |
| | | this.polygonAreaType = 1 |
| | | this.isNeedPolygonType = false |
| | | this.isNeedPolygonType = true |
| | | } else { |
| | | this.isNeedPolygonType = false |
| | | } |
| | |
| | | |
| | | setCurOver (e) { |
| | | this.restSelectBox = false |
| | | this.customImageShow = false |
| | | |
| | | plotOverlayData = e |
| | | |
| | |
| | | <template> |
| | | <div> |
| | | <layers-show-control :dialogVisible="dialogVisible" :isHavePolice="isHavePolice" :isHaveArrow="isHaveArrow" |
| | | :isHaveLine="isHaveLine" :policeSwitch="policeSwitch" :arrowBtnSwitch="arrowBtnSwitch" |
| | | :polylineBtnSwitch="polylineBtnSwitch"></layers-show-control> |
| | | <layers-show-control |
| | | :dialogVisible="dialogVisible" |
| | | :isHavePolice="isHavePolice" |
| | | :isHaveArrow="isHaveArrow" |
| | | :isHaveLine="isHaveLine" |
| | | :policeSwitch="policeSwitch" |
| | | :arrowBtnSwitch="arrowBtnSwitch" |
| | | :polylineBtnSwitch="polylineBtnSwitch" |
| | | ></layers-show-control> |
| | | |
| | | <draw-btn-box v-if="currentPlotType == 3" ref="DRAWBTNBOX" :dialogVisible="dialogVisible" |
| | | :isShowActivityEditBox="isShowActivityEditBox" :showingSecurityId="showingSecurityId" |
| | | :policeSwitch="policeSwitch" :polylineBtnSwitch="polylineBtnSwitch" :arrowBtnSwitch="arrowBtnSwitch" |
| | | :policeIconId="policeIconId" :lineWidth="lineWidth" @setPoliceOption="setPoliceOption"></draw-btn-box> |
| | | <draw-btn-box |
| | | v-if="currentPlotType == 3" |
| | | ref="DRAWBTNBOX" |
| | | :dialogVisible="dialogVisible" |
| | | :isShowActivityEditBox="isShowActivityEditBox" |
| | | :showingSecurityId="showingSecurityId" |
| | | :policeSwitch="policeSwitch" |
| | | :polylineBtnSwitch="polylineBtnSwitch" |
| | | :arrowBtnSwitch="arrowBtnSwitch" |
| | | :policeIconId="policeIconId" |
| | | :lineWidth="lineWidth" |
| | | @setPoliceOption="setPoliceOption" |
| | | ></draw-btn-box> |
| | | |
| | | <two-draw-btn-box v-if="currentPlotType == 1" ref="DRAWBTNBOX" :dialogVisible="dialogVisible" |
| | | :isShowActivityEditBox="isShowActivityEditBox" :showingSecurityId="showingSecurityId" |
| | | :policeSwitch="policeSwitch" :polylineBtnSwitch="polylineBtnSwitch" :arrowBtnSwitch="arrowBtnSwitch" |
| | | :policeIconId="policeIconId" :lineWidth="lineWidth" @setPoliceOption="setPoliceOption"></two-draw-btn-box> |
| | | <two-draw-btn-box |
| | | v-if="currentPlotType == 1" |
| | | ref="DRAWBTNBOX" |
| | | :dialogVisible="dialogVisible" |
| | | :isShowActivityEditBox="isShowActivityEditBox" |
| | | :showingSecurityId="showingSecurityId" |
| | | :policeSwitch="policeSwitch" |
| | | :polylineBtnSwitch="polylineBtnSwitch" |
| | | :arrowBtnSwitch="arrowBtnSwitch" |
| | | :policeIconId="policeIconId" |
| | | :lineWidth="lineWidth" |
| | | @setPoliceOption="setPoliceOption" |
| | | ></two-draw-btn-box> |
| | | |
| | | <polygon-plot ref="PolygonPlotPage" :showingSecurityId="showingSecurityId"></polygon-plot> |
| | | |
| | | <polyline-plot ref="PolylinePlotPage" :showingSecurityId="showingSecurityId"></polyline-plot> |
| | | |
| | | <police-car-change ref="PoliceCarChange" :policeOption="policeOption" |
| | | :showingSecurityId="showingSecurityId"></police-car-change> |
| | | <police-car-change |
| | | ref="PoliceCarChange" |
| | | :policeOption="policeOption" |
| | | :showingSecurityId="showingSecurityId" |
| | | ></police-car-change> |
| | | |
| | | <police-person-change ref="PolicePersonChange" :policeTreeData="policeTreeData" |
| | | :showingSecurityId="showingSecurityId"></police-person-change> |
| | | <police-person-change |
| | | ref="PolicePersonChange" |
| | | :policeTreeData="policeTreeData" |
| | | :showingSecurityId="showingSecurityId" |
| | | ></police-person-change> |
| | | |
| | | <activity-detail :dialogVisible="dialogVisible" :activityDetails="activityDetails" |
| | | @closeActivityDetails="closeActivityDetails"></activity-detail> |
| | | <activity-detail |
| | | :dialogVisible="dialogVisible" |
| | | :activityDetails="activityDetails" |
| | | @closeActivityDetails="closeActivityDetails" |
| | | ></activity-detail> |
| | | |
| | | <video-control-box ref="VIDEOCONTROLBOX"></video-control-box> |
| | | </div> |
| | |
| | | import policePersonChange from './policePersonChange.vue' |
| | | import activityDetail from './activityDetail.vue' |
| | | import videoControlBox from './videoControlBox.vue' |
| | | import { getLineSpeed } from '@/utils/turfPolygon' |
| | | |
| | | // 要素的 |
| | | let pointCircleCarLayer = null |
| | |
| | | // 作战标绘的添加 |
| | | addArrowsListLayer (overlay) { |
| | | arrowsListLayer.addOverlay(overlay) |
| | | }, |
| | | |
| | | removeArrowsListLayer (overlay) { |
| | | arrowsListLayer.removeOverlay(overlay) |
| | | }, |
| | | |
| | | addSaveNewDrawLine (positions, altitude) { |
| | |
| | | this.arrowBtnSwitch = true |
| | | this.polylineBtnSwitch = true |
| | | |
| | | // 加载当前活动区域 |
| | | if (params.item.activityArea && params.item.activityArea.length > 0) { |
| | | |
| | | console.log(params.item.activityArea, 36223322) |
| | | |
| | | let polyGonData = params.item.activityArea.slice(11, params.item.activityArea.length - 1) |
| | | polyGonData = polyGonData.replace(/,/g, ";") |
| | | polyGonData = polyGonData.replace(/ /g, ",") |
| | | let newPolyData = polyGonData.split(';').map(item => { |
| | | let lngOrlat = item.split(',') |
| | | lngOrlat.push(140) |
| | | |
| | | lngOrlat = lngOrlat.join(',') |
| | | |
| | | return lngOrlat |
| | | }).join(';') |
| | | |
| | | console.log(newPolyData, 456) |
| | | |
| | | this.$EventBus.$emit('rowLayerWallAdd', { |
| | | layerName: 'polygonWallLayer', |
| | | positions: newPolyData |
| | | }) |
| | | } |
| | | |
| | | this.getPolicemanTree({ deptId: params.deptId }) |
| | | this.getCarList({ deptId: params.deptId }) |
| | | |
| | |
| | | |
| | | // 获取标绘箭头列表 |
| | | getSecurityPlotList (securityId) { |
| | | |
| | | getSecurityPlotList(securityId).then(res => { |
| | | // 要素资源 |
| | | this.$parent.normalPeopleList = res.data.data.filter(item => item.type == 6) |
| | |
| | | }, |
| | | |
| | | initLayersCoverage (type, color, params, position, altitude) { |
| | | if (altitude && altitude.length) position = position.split(';').map((item, index) => `${item},${altitude[index]}`).join(';') |
| | | let coverage = new global.DC[type](position) |
| | | |
| | | let positions |
| | | if (altitude && altitude.length) positions = position.split(';').map((item, index) => `${item},${altitude[index]}`).join(';') |
| | | let coverage = new global.DC[type](positions) |
| | | if (type == 'Polygon') { |
| | | coverage.setStyle({ |
| | | material: color.curColor, |
| | | extrudedHeight: null, |
| | | perPositionHeight: this.currentPlotType == 3 ? true : false, |
| | | closeTop: false, |
| | | closeBottom: false, |
| | | // classificationType: global.DC.Namespace.Cesium.ClassificationType.TERRAIN |
| | | outline: true, |
| | | outlineColor: color.outColor, |
| | | outlineWidth: 4.0, |
| | | }) |
| | | if (params.areaType == 1) { |
| | | coverage.setStyle({ |
| | | material: color.curColor, |
| | | extrudedHeight: null, |
| | | perPositionHeight: this.currentPlotType == 3 ? true : false, |
| | | closeTop: false, |
| | | closeBottom: false, |
| | | // classificationType: global.DC.Namespace.Cesium.ClassificationType.TERRAIN |
| | | outline: true, |
| | | outlineColor: color.outColor, |
| | | outlineWidth: 4.0, |
| | | }) |
| | | } else { |
| | | positions = position.split(';').map((item, index) => `${item},140`) |
| | | positions.push(positions[0]) |
| | | positions = positions.join(';') |
| | | |
| | | coverage = new global.DC.Wall(positions) |
| | | coverage.setStyle({ |
| | | material: new global.DC.WallImageTrailMaterialProperty({ |
| | | image: '/images/jjx.png', |
| | | color: color.curColor, |
| | | repeat: { |
| | | x: getLineSpeed(position.split(';').map(item => { |
| | | item.split(',') |
| | | |
| | | return [Number(item.split(',')[0]), Number(item.split(',')[1])] |
| | | })), y: 1 |
| | | }, |
| | | speed: 10 |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | coverage.customType = 'polygon' |
| | | } else if (type == 'Polyline') { |
| | |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-01-13 15:52:59 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-05-02 17:17:32 |
| | | * @LastEditTime: 2023-05-06 21:50:44 |
| | | * @FilePath: \srs-police-affairs\src\views\home\components\bottomContainer.vue |
| | | * @Description: |
| | | * |
| | |
| | | </div> |
| | | |
| | | <div class="timeSeclect" v-show="historytype"> |
| | | <el-date-picker |
| | | v-show="timetype == 0" |
| | | v-model="currentWeekTime" |
| | | @change="datePickerChange" |
| | | type="week" |
| | | align="center" |
| | | format="yyyy 第 WW 周" |
| | | placeholder="选择周" |
| | | popper-class="date-week-style" |
| | | ></el-date-picker> |
| | | |
| | | <el-date-picker |
| | | v-show="timetype == 1" |
| | | v-model="currentMonthTime" |
| | | @change="datePickerChange" |
| | | type="month" |
| | | align="center" |
| | | placeholder="选择月" |
| | | popper-class="date-mouth-style" |
| | | ></el-date-picker> |
| | | |
| | | <el-date-picker |
| | | v-show="timetype == 2" |
| | | :clearable="false" |
| | | v-model="currentTime" |
| | | type="daterange" |
| | | align="center" |
| | | unlink-panels |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | @change="datePickerChange" |
| | | :picker-options="pickerOptions" |
| | | popper-class="date-day-style" |
| | | ></el-date-picker> |
| | | <div v-show="timetype == 0"> |
| | | <el-date-picker |
| | | size="small" |
| | | v-model="currentWeekTime" |
| | | @change="datePickerChange" |
| | | type="week" |
| | | align="center" |
| | | format="yyyy 第 WW 周" |
| | | placeholder="选择周" |
| | | popper-class="date-week-style" |
| | | ></el-date-picker> |
| | | </div> |
| | | <div v-show="timetype == 1"> |
| | | <el-date-picker |
| | | size="small" |
| | | v-model="currentMonthTime" |
| | | @change="datePickerChange" |
| | | type="month" |
| | | align="center" |
| | | placeholder="选择月" |
| | | popper-class="date-mouth-style" |
| | | ></el-date-picker> |
| | | </div> |
| | | <div v-show="timetype == 2"> |
| | | <el-date-picker |
| | | size="small" |
| | | :clearable="false" |
| | | v-model="currentTime" |
| | | type="daterange" |
| | | align="center" |
| | | unlink-panels |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | @change="datePickerChange" |
| | | :picker-options="pickerOptions" |
| | | popper-class="date-day-style" |
| | | ></el-date-picker> |
| | | </div> |
| | | <div> |
| | | <el-select |
| | | style="flex: 1;" |
| | | size="small" |
| | | v-model="policeInforValue" |
| | | @change="policeTypeChange" |
| | | placeholder="请选择" |
| | | > |
| | | <el-option |
| | | v-for="item in policeInforOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="history-tab"> |
| | |
| | | currentPage: 1, |
| | | // table高度 |
| | | currentTableHeight: 0, |
| | | policeStaionID: '' |
| | | policeStaionID: '', |
| | | policeInforValue: '', |
| | | policeInforOptions: [ |
| | | { |
| | | value: '', |
| | | label: '全部' |
| | | }, |
| | | { |
| | | value: '盗窃', |
| | | label: '盗窃' |
| | | }, |
| | | { |
| | | value: '诈骗', |
| | | label: '诈骗' |
| | | }, |
| | | { |
| | | value: '纠纷', |
| | | label: '纠纷' |
| | | }, |
| | | { |
| | | value: '涉赌', |
| | | label: '涉赌' |
| | | }, |
| | | { |
| | | value: '涉毒', |
| | | label: '涉毒' |
| | | }, |
| | | { |
| | | value: '涉黄', |
| | | label: '涉黄' |
| | | }, |
| | | { |
| | | value: '求救', |
| | | label: '求救' |
| | | }, |
| | | { |
| | | value: '其他', |
| | | label: '其他' |
| | | } |
| | | ], |
| | | } |
| | | }, |
| | | |
| | |
| | | }) |
| | | }, |
| | | |
| | | |
| | | policeTypeChange () { |
| | | this.currentPage = 1 |
| | | |
| | | if (this.timetype == 0) { |
| | | |
| | | this.getAlarmList({ type: this.timetype, time: this.dateFormat(this.currentWeekTime), current: this.currentPage }) |
| | | |
| | | } else if (this.timetype == 1) { |
| | | |
| | | this.getAlarmList({ type: this.timetype, time: this.dateFormat(this.currentMonthTime), current: this.currentPage }) |
| | | |
| | | } else { |
| | | const date = this.currentTime.map(item => { |
| | | return this.dateFormat(item) |
| | | }) |
| | | |
| | | this.getAlarmList({ start: date[0], end: date[1], current: this.currentPage }) |
| | | } |
| | | }, |
| | | |
| | | // 获取历史接警记录 |
| | | getAlarmList (params) { |
| | | getAlarmList({ ...params, size: this.pagesize, jjdwbh: this.policeStaionID != '' ? this.policeStaionID : this.userInfo.dept_id }).then(res => { |
| | | getAlarmList({ ...params, size: this.pagesize, jjdwbh: this.policeStaionID != '' ? this.policeStaionID : this.userInfo.dept_id, bjlx: this.policeInforValue }).then(res => { |
| | | this.pagesCount = res.data.data.pages |
| | | |
| | | this.policeSituationHistoryArr = [] |
| | |
| | | .timeTab { |
| | | position: absolute; |
| | | top: 22px; |
| | | right: 400px; |
| | | right: 670px; |
| | | display: flex; |
| | | border-radius: 6px; |
| | | overflow: hidden; |
| | |
| | | } |
| | | |
| | | .timeSeclect { |
| | | width: 250px; |
| | | width: 520px; |
| | | height: 30px; |
| | | position: absolute; |
| | | top: 12px; |
| | | top: 20px; |
| | | right: 130px; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | & > div { |
| | | margin: 0 5px; |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | } |
| | | |
| | | .history-tab { |
| | |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-08-18 16:18:17 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-05-04 19:18:48 |
| | | * @LastEditTime: 2023-05-05 16:07:00 |
| | | * @FilePath: \srs-police-affairs\src\views\home\index.vue |
| | | * @Description: 小区-栋-层-房屋 |
| | | * |
| | |
| | | ...item, |
| | | lng: item.longitude, |
| | | lat: item.latitude, |
| | | url: '/img/icon/camera.png', |
| | | url: item.status == 1 ? '/img/icon/video.png' : '/img/icon/video-off.png', |
| | | channelId: item.channelId, |
| | | setStyle: { |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY |
| | | } |
| | | }, |
| | | incident: this.siteClick |
| | | incident: this.siteClick, |
| | | }) |
| | | } |
| | | }) |
| | |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-08-18 16:18:17 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-04-26 15:05:54 |
| | | * @LastEditTime: 2023-05-05 10:58:05 |
| | | * @FilePath: \srs-police-affairs\src\views\police\index.vue |
| | | * @Description: 辖区管理 |
| | | * |
| | |
| | | <template> |
| | | <div class="police-page container"> |
| | | <div v-show="boxShow" class="container-content"> |
| | | <el-main v-loading="equimentLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" |
| | | element-loading-background="rgba(0, 0, 0, 0.5)" style="overflow: hidden;padding: 0px;"> |
| | | <el-main |
| | | v-loading="equimentLoading" |
| | | element-loading-text="拼命加载中" |
| | | element-loading-spinner="el-icon-loading" |
| | | element-loading-background="rgba(0, 0, 0, 0.5)" |
| | | style="overflow: hidden;padding: 0px;" |
| | | > |
| | | <div class="switch-box" v-show="!detailFlag"> |
| | | 资源类别: |
| | | <el-select v-model="typeValue" @change="navClick" placeholder="请选择" class="type-select-css"> |
| | | <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" |
| | | class="option-css"></el-option> |
| | | <el-select |
| | | v-model="typeValue" |
| | | @change="navClick" |
| | | placeholder="请选择" |
| | | class="type-select-css" |
| | | > |
| | | <el-option |
| | | v-for="item in options" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | class="option-css" |
| | | ></el-option> |
| | | </el-select> |
| | | </div> |
| | | |
| | | <div class="list-show" v-if="!detailFlag"> |
| | | <div class="search-box"> |
| | | <span style="display: inline-block; white-space: nowrap;"> |
| | | 资源名称: |
| | | </span> |
| | | <el-input size="small" placeholder="请输入…" v-model="searchValue" @change="searchChange" clearable> |
| | | </el-input> |
| | | <span style="display: inline-block; white-space: nowrap;">资源名称:</span> |
| | | <el-input |
| | | size="small" |
| | | placeholder="请输入…" |
| | | v-model="searchValue" |
| | | @change="searchChange" |
| | | clearable |
| | | ></el-input> |
| | | </div> |
| | | |
| | | <div class="list" ref="tableBox"> |
| | | <el-table :data="equimentTableData" |
| | | <el-table |
| | | :data="equimentTableData" |
| | | :header-cell-style="{ 'text-align': 'center', 'background-color': '#203c60', borderColor: '#324e75' }" |
| | | :cell-style="{ 'text-align': 'center', borderColor: '#324e75', cursor: 'default' }" |
| | | :height="currentTableHeight"> |
| | | <el-table-column prop="newName" :show-overflow-tooltip="true" label="名称" |
| | | :min-width="typeValue == 0 || typeValue == 2 ? '56%' : '68%'"></el-table-column> |
| | | <el-table-column prop="status" label="状态" |
| | | :min-width="typeValue == 0 || typeValue == 2 ? '14%' : '14%'"> |
| | | :height="currentTableHeight" |
| | | > |
| | | <el-table-column |
| | | prop="newName" |
| | | :show-overflow-tooltip="true" |
| | | label="名称" |
| | | :min-width="typeValue == 0 || typeValue == 2 ? '56%' : '68%'" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="status" |
| | | label="状态" |
| | | :min-width="typeValue == 0 || typeValue == 2 ? '14%' : '14%'" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <div class="state-box" :class="{ online: scope.row.status == '1' }"></div> |
| | | <div |
| | | class="state-box" |
| | | :class="{ online: scope.row.status == '1' }" |
| | | ></div> |
| | | </template> |
| | | </el-table-column> |
| | | <div slot="empty" style="text-align: center;">{{ emptyText }}</div> |
| | | <el-table-column label="操作" align="center" |
| | | :min-width="typeValue == 0 || typeValue == 2 ? '30%' : '18%'"> |
| | | <el-table-column |
| | | label="操作" |
| | | align="center" |
| | | :min-width="typeValue == 0 || typeValue == 2 ? '30%' : '18%'" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button :disabled="whetherPosition(scope.row)" @click="rowClick(scope.row)" |
| | | type="text" size="small" title="定位"> |
| | | <i class="el-icon-location" :style="{ color: positionColor(scope.row) }"></i> |
| | | <el-button |
| | | :disabled="whetherPosition(scope.row)" |
| | | @click="rowClick(scope.row)" |
| | | type="text" |
| | | size="small" |
| | | title="定位" |
| | | > |
| | | <i |
| | | class="el-icon-location" |
| | | :style="{ color: positionColor(scope.row) }" |
| | | ></i> |
| | | </el-button> |
| | | <el-button v-show="navType == 0 || navType == 2" @click="equipmentTrack(scope.row)" |
| | | type="text" size="small" title="轨迹"> |
| | | <el-button |
| | | v-show="navType == 0 || navType == 2" |
| | | @click="equipmentTrack(scope.row)" |
| | | type="text" |
| | | size="small" |
| | | title="轨迹" |
| | | > |
| | | <i class="el-icon-police-track"></i> |
| | | </el-button> |
| | | <el-button @click="play(scope.row)" type="text" size="small" title="播放视频"> |
| | | <el-button |
| | | v-show="navType != 2" |
| | | @click="play(scope.row)" |
| | | type="text" |
| | | size="small" |
| | | title="播放视频" |
| | | > |
| | | <i class="el-icon-video-play"></i> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <div class="pages all-pagination-sty" ref="tablePagination" style="padding-top:-15px"> |
| | | <el-pagination background layout="prev, pager, next" :page-size="equimentPage.pageSize" |
| | | :total="equimentPage.total" :pager-count="4" :current-page="equimentPage.currentPage" |
| | | @current-change="handleCurrentChange"></el-pagination> |
| | | <div |
| | | class="pages all-pagination-sty" |
| | | ref="tablePagination" |
| | | style="padding-top:-15px" |
| | | > |
| | | <el-pagination |
| | | background |
| | | layout="prev, pager, next" |
| | | :page-size="equimentPage.pageSize" |
| | | :total="equimentPage.total" |
| | | :pager-count="4" |
| | | :current-page="equimentPage.currentPage" |
| | | @current-change="handleCurrentChange" |
| | | ></el-pagination> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | | </el-main> |
| | | |
| | | |
| | | <div class="track-box" v-show="detailFlag"> |
| | | <div class="track-box-info"> |
| | |
| | | <div>状态:</div> |
| | | <div> |
| | | {{ |
| | | currentSelectEquipment.status ? (currentSelectEquipment.status == 0 ? '离线' : '在线') : |
| | | '' |
| | | currentSelectEquipment.status ? (currentSelectEquipment.status == 0 ? '离线' : '在线') : |
| | | '' |
| | | }} |
| | | </div> |
| | | </li> |
| | |
| | | <li> |
| | | <div>选择时间:</div> |
| | | <div class="datetime"> |
| | | <el-date-picker v-model="trackTime" type="daterange" unlink-panels range-separator="至" |
| | | start-placeholder="开始日期" size="mini" :editable="false" |
| | | end-placeholder="结束日期"></el-date-picker> |
| | | <el-date-picker |
| | | v-model="trackTime" |
| | | type="daterange" |
| | | unlink-panels |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | size="mini" |
| | | :editable="false" |
| | | end-placeholder="结束日期" |
| | | ></el-date-picker> |
| | | </div> |
| | | </li> |
| | | |
| | |
| | | |
| | | <div v-show="searchExtensivelyValBoxShow" class="searchExtensively-val-box"> |
| | | <div> |
| | | <div @click="searchExtensivelyVlaClick(item)" v-for="(item, index) in searchExtensivelyArray" :key="index"> |
| | | {{ item.name }}</div> |
| | | <div |
| | | @click="searchExtensivelyVlaClick(item)" |
| | | v-for="(item, index) in searchExtensivelyArray" |
| | | :key="index" |
| | | >{{ item.name }}</div> |
| | | </div> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" :before-close="dialogBeforeClose" :modal="true" |
| | | :modal-append-to-body="false" :close-on-click-modal="false" class="car-video-box"> |
| | | <el-dialog |
| | | :title="dialogTitle" |
| | | :visible.sync="dialogVisible" |
| | | :before-close="dialogBeforeClose" |
| | | :modal="true" |
| | | :modal-append-to-body="false" |
| | | :close-on-click-modal="false" |
| | | class="car-video-box" |
| | | > |
| | | <video-loading v-show="videoPlayShow"></video-loading> |
| | | |
| | | <video autoplay controls width="100%" height="100%" ref="videoElement" id="videoElement" |
| | | style="object-fit: fill"></video> |
| | | <video |
| | | autoplay |
| | | controls |
| | | width="100%" |
| | | height="100%" |
| | | ref="videoElement" |
| | | id="videoElement" |
| | | style="object-fit: fill" |
| | | ></video> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | data () { |
| | | return { |
| | | emptyText: '', |
| | | navType: 0, |
| | | navType: 1, |
| | | equimentLoading: false, |
| | | dialogTitle: '', |
| | | dialogVisible: false, |
| | |
| | | // label: '执法记录仪' |
| | | // } |
| | | ], |
| | | typeValue: '0', |
| | | typeValue: '1', |
| | | boxShow: true, |
| | | searchExtensivelyValue: '', |
| | | searchExtensivelyValBoxShow: false, |
| | |
| | | align-items: center; |
| | | justify-content: space-around; |
| | | |
| | | &>div { |
| | | & > div { |
| | | flex: 1; |
| | | } |
| | | } |
| | |
| | | padding: 0; |
| | | width: 100%; |
| | | overflow: hidden !important; |
| | | ; |
| | | } |
| | | } |
| | | |
| | |
| | | color: #fff; |
| | | border-bottom: 1px solid #fff; |
| | | |
| | | &>div { |
| | | & > div { |
| | | text-align: center; |
| | | } |
| | | |
| | | &>div:first-child { |
| | | & > div:first-child { |
| | | flex: 2; |
| | | } |
| | | |
| | | &>div:last-child { |
| | | & > div:last-child { |
| | | flex: 6; |
| | | |
| | | &>div { |
| | | & > div { |
| | | width: 100% !important; |
| | | } |
| | | } |
| | |
| | | border-radius: 10px; |
| | | overflow: hidden; |
| | | |
| | | &>div { |
| | | & > div { |
| | | height: 100%; |
| | | overflow-y: auto; |
| | | |
| | |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-08-18 16:18:17 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-04-27 20:03:16 |
| | | * @LastEditTime: 2023-05-06 21:39:45 |
| | | * @FilePath: \srs-police-affairs\src\views\policeInfor\index.vue |
| | | * @Description: 辖区管理 |
| | | * |
| | |
| | | <template> |
| | | <div class="police-page container"> |
| | | <div v-show="boxShow" class="container-content" ref="containerContent"> |
| | | <div class="time-select" ref="timeSelect"> |
| | | <div class="search-item-box"> |
| | | <span>警情类型:</span> |
| | | |
| | | <div class="nav-tab" ref="navTabBox"> |
| | | <div class="nav" :class="navType == 0 ? 'choosed' : ''" @click="navClick(0)">实时警情</div> |
| | | <div class="nav" :class="navType == 1 ? 'choosed' : ''" @click="navClick(1)">历史警情</div> |
| | | <el-select |
| | | style="flex: 1;" |
| | | size="small" |
| | | v-model="policeInforValue" |
| | | @change="policeTypeChange" |
| | | placeholder="请选择" |
| | | > |
| | | <el-option |
| | | v-for="item in policeInforOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </div> |
| | | |
| | | <div class="search-item-box"> |
| | | <el-date-picker |
| | | size="mini" |
| | | :clearable="false" |
| | | v-model="currentTime" |
| | | type="daterange" |
| | | align="center" |
| | | unlink-panels |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | @change="datePickerChange" |
| | | :picker-options="pickerOptions" |
| | | ></el-date-picker> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="time-select" v-show="navType == 1" ref="timeSelect"> |
| | | <el-date-picker :clearable="false" v-model="currentTime" type="daterange" align="center" unlink-panels |
| | | range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" @change="datePickerChange" |
| | | popper-class="date-day-style"></el-date-picker> |
| | | </div> |
| | | |
| | | <div v-if="navType == 0" class="police-info"> |
| | | <el-table :data="realPoliceInforData" style="width: 100%" :height="currentTableHeight" |
| | | <div class="police-info"> |
| | | <el-table |
| | | :data="historyPoliceInforData" |
| | | style="width: 100%" |
| | | :height="currentTableHeight" |
| | | :header-cell-style="{ 'text-align': 'center', 'background-color': '#203c60', 'borderColor': '#324e75' }" |
| | | :cell-style="{ 'text-align': 'center', 'borderColor': '#324e75', 'cursor': 'default' }" |
| | | :row-class-name="tableRowClassName" class="police-infor-table" @cell-click="siteClick" |
| | | @cell-mouse-enter="tableEnter" @cell-mouse-leave="tabelLeave"> |
| | | <template slot="empty"> |
| | | <div>{{ realEmptyText }}</div> |
| | | </template> |
| | | |
| | | <el-table-column prop="JJDWMC" :show-overflow-tooltip="true" label="接警单位" |
| | | min-width="80%"></el-table-column> |
| | | <el-table-column prop="BJSJ" label="报警时间" min-width="50%"> |
| | | </el-table-column> |
| | | <el-table-column prop="BJLX" label="报警类型"> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" min-width="32%"> |
| | | <template slot-scope="scope"> |
| | | <el-button v-if="!whetherPosition(scope.row)" @click="clickData(scope.row)" type="text" |
| | | size="small" title="定位"> |
| | | <i class="el-icon-location" :style="{ color: positionColor(scope.row) }"></i> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <div v-else class="police-info"> |
| | | <el-table :data="historyPoliceInforData" style="width: 100%" :height="currentTableHeight" |
| | | :header-cell-style="{ 'text-align': 'center', 'background-color': '#203c60', 'borderColor': '#324e75' }" |
| | | :cell-style="{ 'text-align': 'center', 'borderColor': '#324e75', 'cursor': 'default' }" |
| | | :row-class-name="tableRowClassName" class="police-infor-table" @cell-mouse-enter="tableEnter" |
| | | @cell-mouse-leave="tabelLeave"> |
| | | :row-class-name="tableRowClassName" |
| | | class="police-infor-table" |
| | | @cell-mouse-enter="tableEnter" |
| | | @cell-mouse-leave="tabelLeave" |
| | | > |
| | | <template slot="empty"> |
| | | <div>{{ historyEmptyText }}</div> |
| | | </template> |
| | | <el-table-column prop="JJDWMC" :show-overflow-tooltip="true" label="接警单位" |
| | | min-width="80%"></el-table-column> |
| | | <el-table-column prop="BJSJ" label="报警时间" min-width="50%"> |
| | | </el-table-column> |
| | | <el-table-column prop="BJLX" label="报警类型"> |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="JJDWMC" |
| | | :show-overflow-tooltip="true" |
| | | label="接警单位" |
| | | min-width="80%" |
| | | ></el-table-column> |
| | | <el-table-column prop="BJSJ" label="报警时间" min-width="50%"></el-table-column> |
| | | <el-table-column prop="BJLX" label="报警类型"></el-table-column> |
| | | <el-table-column label="操作" align="center" min-width="32%"> |
| | | <template slot-scope="scope"> |
| | | <el-button v-if="!whetherPosition(scope.row)" @click="clickData(scope.row)" type="text" |
| | | size="small" title="定位"> |
| | | <i class="el-icon-location" :style="{ color: positionColor(scope.row) }"></i> |
| | | <el-button |
| | | v-if="!whetherPosition(scope.row)" |
| | | @click="clickData(scope.row)" |
| | | type="text" |
| | | size="small" |
| | | title="定位" |
| | | > |
| | | <i |
| | | class="el-icon-location" |
| | | :style="{ color: positionColor(scope.row) }" |
| | | ></i> |
| | | </el-button> |
| | | <el-buttonalign-justify @click="siteClick(scope.row)" type="text" size="small" title="详情"> |
| | | <el-buttonalign-justify |
| | | @click="siteClick(scope.row)" |
| | | type="text" |
| | | size="small" |
| | | title="详情" |
| | | > |
| | | <i class="el-icon-document"></i> |
| | | </el-buttonalign-justify> |
| | | </template> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <el-dialog title="警情信息" :visible.sync="policeSituationVisible" :modal-append-to-body="false" |
| | | :before-close="policeSituationBeforeClose" :modal="true" :close-on-click-modal="false" |
| | | class="policeSituation-details-box"> |
| | | <el-dialog |
| | | title="警情信息" |
| | | :visible.sync="policeSituationVisible" |
| | | :modal-append-to-body="false" |
| | | :before-close="policeSituationBeforeClose" |
| | | :modal="true" |
| | | :close-on-click-modal="false" |
| | | class="policeSituation-details-box" |
| | | > |
| | | <div class="btn-change"> |
| | | <div :class="{ on: policeInformationType == '接警信息' }" @click="alarmOrActAsPolice('接警信息')">接警信息</div> |
| | | <div :class="{ on: policeInformationType == '出警信息' }" @click="alarmOrActAsPolice('出警信息')">出警信息</div> |
| | | <div |
| | | :class="{ on: policeInformationType == '接警信息' }" |
| | | @click="alarmOrActAsPolice('接警信息')" |
| | | >接警信息</div> |
| | | <div |
| | | :class="{ on: policeInformationType == '出警信息' }" |
| | | @click="alarmOrActAsPolice('出警信息')" |
| | | >出警信息</div> |
| | | </div> |
| | | |
| | | <div v-show="policeInformationType == '接警信息'" class="box"> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-show="policeInformationType == '出警信息' && JSON.stringify(CJdata) != '{}'" class="box"> |
| | | <div |
| | | v-show="policeInformationType == '出警信息' && JSON.stringify(CJdata) != '{}'" |
| | | class="box" |
| | | > |
| | | <div class="item"> |
| | | <div>处警单位编号:</div> |
| | | <div>{{ CJdata.CJDWBH }}</div> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-show="policeInformationType == '出警信息' && JSON.stringify(CJdata) == '{}'" class="box no-data">暂无警情</div> |
| | | <div |
| | | v-show="policeInformationType == '出警信息' && JSON.stringify(CJdata) == '{}'" |
| | | class="box no-data" |
| | | >暂无警情</div> |
| | | </el-dialog> |
| | | |
| | | <div class="cur-tooltip" v-show="currentTooltip" |
| | | :style="{ top: currentPointerPosition.y + 'px', left: currentPointerPosition.x + 'px' }"> |
| | | <div class="type-name"> |
| | | 报警内容 |
| | | </div> |
| | | <div class="type-content"> |
| | | {{ currentBJNR }} |
| | | </div> |
| | | <div |
| | | class="cur-tooltip" |
| | | v-show="currentTooltip" |
| | | :style="{ top: currentPointerPosition.y + 'px', left: currentPointerPosition.x + 'px' }" |
| | | > |
| | | <div class="type-name">报警内容</div> |
| | | <div class="type-content">{{ currentBJNR }}</div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | import { getActAsPoliceList, getAnswerPolices, getAlarmList } from "@/api/home/index.js" |
| | | import { initMapPosition } from '@/utils/mapPositionInit' |
| | | import { BjlxData } from "@/assets/police" |
| | | import '@/utils/CesiumHeatmap.js' |
| | | |
| | | import { getMapBounds } from '@/utils/turfPolygon.js' |
| | | |
| | | let loading = null |
| | | |
| | |
| | | current: 1 |
| | | }, |
| | | |
| | | navType: 1, |
| | | currentTableHeight: 0, |
| | | currentTime: [], |
| | | |
| | |
| | | x: 0, |
| | | y: 0 |
| | | }, |
| | | |
| | | currentTooltip: false, |
| | | currentBJNR: '' |
| | | currentBJNR: '', |
| | | pickerOptions: { |
| | | shortcuts: [ |
| | | { |
| | | text: '最近一周', |
| | | onClick (picker) { |
| | | const end = new Date() |
| | | const start = new Date() |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 7) |
| | | picker.$emit('pick', [start, end]) |
| | | } |
| | | }, |
| | | { |
| | | text: '最近两周', |
| | | onClick (picker) { |
| | | const end = new Date() |
| | | const start = new Date() |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 14) |
| | | picker.$emit('pick', [start, end]) |
| | | } |
| | | }, |
| | | { |
| | | text: '最近一个月', |
| | | onClick (picker) { |
| | | const end = new Date() |
| | | const start = new Date() |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 30) |
| | | picker.$emit('pick', [start, end]) |
| | | } |
| | | }, |
| | | { |
| | | text: '最近三个月', |
| | | onClick (picker) { |
| | | const end = new Date() |
| | | const start = new Date() |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 90) |
| | | picker.$emit('pick', [start, end]) |
| | | } |
| | | }] |
| | | }, |
| | | |
| | | policeInforValue: '', |
| | | policeInforOptions: [ |
| | | { |
| | | value: '', |
| | | label: '全部' |
| | | }, |
| | | { |
| | | value: '盗窃', |
| | | label: '盗窃' |
| | | }, |
| | | { |
| | | value: '诈骗', |
| | | label: '诈骗' |
| | | }, |
| | | { |
| | | value: '纠纷', |
| | | label: '纠纷' |
| | | }, |
| | | { |
| | | value: '涉赌', |
| | | label: '涉赌' |
| | | }, |
| | | { |
| | | value: '涉毒', |
| | | label: '涉毒' |
| | | }, |
| | | { |
| | | value: '涉黄', |
| | | label: '涉黄' |
| | | }, |
| | | { |
| | | value: '求救', |
| | | label: '求救' |
| | | }, |
| | | { |
| | | value: '其他', |
| | | label: '其他' |
| | | } |
| | | ], |
| | | |
| | | heatMap: null |
| | | } |
| | | }, |
| | | |
| | |
| | | policeInforSiteLayer = new global.DC.PrimitiveLayer('policeInforSiteLayer') |
| | | global.viewer.addLayer(policeInforSiteLayer) |
| | | this.$EventBus.$emit('closeMxTileset') |
| | | this.navClick(0) |
| | | this.navClick() |
| | | this.setTableHeight() |
| | | }) |
| | | |
| | |
| | | } |
| | | }, |
| | | |
| | | policeTypeChange () { |
| | | this.navClick() |
| | | }, |
| | | |
| | | // 设置默认时间 |
| | | defaultDate () { |
| | | var current = new Date() |
| | | |
| | | var seven = new Date(current.getTime() - 1 * 24 * 60 * 60 * 1000) |
| | | var seven = new Date(current.getTime() - 7 * 24 * 60 * 60 * 1000) |
| | | |
| | | this.currentTime = [seven, current] //将值设置给插件绑定的数据 |
| | | }, |
| | |
| | | |
| | | return { ...item, index: index + 1, lng: item.ZDDWXZB, lat: item.ZDDWYZB, BJLX: bjlxText } |
| | | }) |
| | | this.addPoliceInforSiteLayer(this.realPoliceInforData) |
| | | } else { |
| | | this.realPoliceInforData = [] |
| | | this.realEmptyText = "暂无实时警情信息" |
| | |
| | | // return { ...item, index: index + 1, lng: item.ZDDWXZB, lat: item.ZDDWYZB } |
| | | // }) |
| | | |
| | | // this.addPoliceInforSiteLayer(this.realPoliceInforData) |
| | | |
| | | // setTimeout(() => { |
| | | // loading && loading.close() |
| | | // }, 500) |
| | | }, |
| | | |
| | | addHeatmap (data) { |
| | | let box = getMapBounds(data) |
| | | let bounds = { |
| | | west: Number(box[0]), |
| | | south: Number(box[1]), |
| | | east: Number(box[2]), |
| | | north: Number(box[3]) |
| | | } |
| | | |
| | | //初始化cesiumheatmap对象,传入相应的参数 |
| | | // eslint-disable-next-line no-undef |
| | | let heatMap = CesiumHeatmap.create( |
| | | global.viewer, // 视图层 |
| | | bounds, // 矩形坐标 |
| | | { |
| | | radius: 80, |
| | | maxOpacity: .5, |
| | | minOpacity: 0, |
| | | blur: .75 |
| | | } |
| | | ) |
| | | let valueMin = 0 |
| | | let valueMax = 100 |
| | | // add data to heatmap |
| | | //获取动态数据 |
| | | heatMap.setWGS84Data(valueMin, valueMax, data) |
| | | this.heatMap = heatMap |
| | | }, |
| | | |
| | | // 获取历史接警记录(不分页) |
| | |
| | | this.loading() |
| | | this.historyPoliceInforData = [] |
| | | this.historyEmptyText = "" |
| | | getAlarmList({ ...params, size: this.pages.size, jjdwbh: this.userInfo.dept_id, type: 3 }).then(res => { |
| | | |
| | | if (this.heatMap != null) { |
| | | this.heatMap.show(false) |
| | | } |
| | | |
| | | getAlarmList({ ...params, size: this.pages.size, jjdwbh: this.userInfo.dept_id, type: 3, bjlx: this.policeInforValue }).then(res => { |
| | | if (res.data.data.length > 0) { |
| | | let positions = [] |
| | | // this.pages.total = res.data.data.pages |
| | | this.historyPoliceInforData = res.data.data.map((item, index) => { |
| | | const bjlxText = BjlxData.filter(i => item.BJLX == i.BJLX)[0] ? BjlxData.filter(i => item.BJLX == i.BJLX)[0].VALUE : '' |
| | |
| | | if (item.JJDWMC.indexOf('信州区分局') != -1) item.JJDWMC = item.JJDWMC.replace(/信州区分局/, '') |
| | | if (item.JJDWMC.indexOf('信州') != -1) item.JJDWMC = item.JJDWMC.replace(/信州/, '') |
| | | |
| | | |
| | | if (item.ZDDWXZB && item.ZDDWXZB != '' && item.ZDDWXZB > 0) { |
| | | positions.push({ x: Number(item.ZDDWXZB), y: Number(item.ZDDWYZB), value: 23 }) |
| | | } |
| | | |
| | | return { ...item, index: index + 1, lng: item.ZDDWXZB, lat: item.ZDDWYZB, BJLX: bjlxText } |
| | | }) |
| | | |
| | | this.addHeatmap(positions) |
| | | } else { |
| | | // this.pages.total = 0 |
| | | this.historyPoliceInforData = [] |
| | | this.realEmptyText = "暂无历史警情信息" |
| | | } |
| | | |
| | | this.addPoliceInforSiteLayer(this.historyPoliceInforData) |
| | | setTimeout(() => { |
| | | loading && loading.close() |
| | | }, 500) |
| | |
| | | // this.historyPoliceInforData = this.historyPoliceInforData.map((item, index) => { |
| | | // return { ...item, index: index + 1, lng: item.ZDDWXZB, lat: item.ZDDWYZB } |
| | | // }) |
| | | |
| | | // this.addPoliceInforSiteLayer(this.historyPoliceInforData) |
| | | }, |
| | | |
| | | addPoliceInforSiteLayer (data) { |
| | | this.clearLayer() |
| | | let policeInfoPositionList = [] |
| | | |
| | | data.forEach((item, index) => { |
| | | if (item.lng && item.lng != undefined && item.lng != '') { |
| | | let center = new global.DC.Position(Number(item.lng), Number(item.lat)) |
| | | let point = new global.DC.PointPrimitive(center) |
| | | policeInfoPositionList.push(center) |
| | | let num = 0 |
| | | |
| | | timer[index] = setInterval(() => { |
| | | num++ |
| | | if (num >= 10) { |
| | | num = 0 |
| | | } |
| | | |
| | | point.setStyle({ |
| | | outlineColor: global.DC.Color.RED.withAlpha(0.5),//边框颜色 |
| | | outlineWidth: num,//边框大小, |
| | | color: global.DC.Color.RED |
| | | }) |
| | | }, 100) |
| | | |
| | | point.attrParams = item |
| | | point.on(global.DC.MouseEventType.CLICK, this.siteClick) |
| | | policeInforSiteLayer.addOverlay(point) |
| | | } |
| | | }) |
| | | this.$EventBus.$emit('layerPointAdd', { |
| | | layerName: 'policeInfoHeatLayer', |
| | | type: "HeatPoint", |
| | | layerType: 'HeatLayer', |
| | | params: { |
| | | positions: policeInfoPositionList |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | /** |
| | |
| | | }, |
| | | |
| | | setTableHeight () { |
| | | |
| | | if (this.navType == 0) { |
| | | this.currentTableHeight = this.$refs.containerContent.offsetHeight - this.$refs.navTabBox.offsetHeight |
| | | } else { |
| | | this.currentTableHeight = this.$refs.containerContent.offsetHeight - this.$refs.navTabBox.offsetHeight - this.$refs.timeSelect.offsetHeight |
| | | } |
| | | |
| | | this.currentTableHeight = this.$refs.containerContent.offsetHeight - this.$refs.timeSelect.offsetHeight |
| | | }, |
| | | |
| | | /** |
| | | * @description: 实时历史警情切换 |
| | | * @param {*} type |
| | | * @return {*} |
| | | */ |
| | | async navClick (type) { |
| | | this.navType = type |
| | | async navClick () { |
| | | |
| | | const date = this.currentTime.map(item => { |
| | | return this.dateFormat(item) |
| | | }) |
| | | |
| | | if (this.navType == 0) { |
| | | await this.getAnswerPolices() |
| | | } else { |
| | | this.pages.current = 1 |
| | | this.pages.current = 1 |
| | | |
| | | await this.getAlarmList({ |
| | | start: date[0], |
| | | end: date[1], |
| | | current: this.pages.current |
| | | }) |
| | | } |
| | | await this.getAlarmList({ |
| | | start: date[0], |
| | | end: date[1], |
| | | current: this.pages.current |
| | | }) |
| | | |
| | | this.$nextTick(() => { |
| | | this.setTableHeight() |
| | |
| | | destroyed () { |
| | | loading && loading.close() |
| | | |
| | | if (this.heatMap != null) { |
| | | this.heatMap.removeLayer() |
| | | } |
| | | |
| | | window.removeEventListener('resize', this.setTableHeight) |
| | | |
| | | policeInforSiteLayer != null && policeInforSiteLayer.remove() |
| | |
| | | showBox: false, |
| | | showBtn: false, |
| | | openMenu: '' |
| | | }) |
| | | |
| | | this.$EventBus.$emit("mapRemoveLayer", { |
| | | layerName: "policeInfoHeatLayer", |
| | | type: "HeatPoint", |
| | | }) |
| | | |
| | | for (let i = 0; i < timer.length; i++) { |
| | |
| | | height: 100%; |
| | | color: #fff; |
| | | background: $bg-color; |
| | | |
| | | .nav-tab { |
| | | height: 40px; |
| | | line-height: 40px; |
| | | display: flex; |
| | | justify-content: space-around; |
| | | |
| | | .nav { |
| | | flex: 1; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .choosed { |
| | | background-color: #3d5ad5; |
| | | } |
| | | } |
| | | |
| | | .time-select { |
| | | margin: 0; |
| | | padding: 5px; |
| | | } |
| | | } |
| | | |
| | | .cur-tooltip { |