index.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <template>
  2. <pannel class="fence-location-container">
  3. <template v-slot:title>
  4. 围栏闯禁
  5. </template>
  6. <template v-slot:action>
  7. <el-button
  8. size="mini"
  9. type="text"
  10. icon="el-icon-plus"
  11. round
  12. @click="startDraw"
  13. style="margin-left: auto"
  14. :disabled="drawState"
  15. >
  16. {{ drawState ? '绘制中...' : '绘制围栏' }}
  17. </el-button>
  18. </template>
  19. <template v-slot:content>
  20. <div class="location-list">
  21. <template v-for="fence in fenceList">
  22. <div :key="`fence_${fence.id}`" class="list-item">
  23. <span class="over-flow-hidden" style="width: 40%">
  24. {{ fence.name }}
  25. </span>
  26. <span class="over-flow-hidden" style="width: 40%">
  27. {{ fence.updateTime }}
  28. </span>
  29. <span class="over-flow-hidden" style="width: 20%">
  30. <el-popconfirm
  31. confirm-button-text='好的'
  32. cancel-button-text='不用了'
  33. icon="el-icon-info"
  34. icon-color="red"
  35. :title="`是否删除围栏【${fence.name}】?`"
  36. @confirm="()=>delFence(fence)"
  37. >
  38. <i
  39. slot="reference"
  40. class="el-icon-delete"
  41. title="删除围栏"
  42. ></i>
  43. </el-popconfirm>
  44. <i
  45. class="el-icon-edit"
  46. title="编辑围栏"
  47. @click="()=>editFence(fence)"
  48. />
  49. </span>
  50. </div>
  51. </template>
  52. </div>
  53. <el-dialog
  54. width="20%"
  55. title="提示"
  56. :visible="dialogVisible"
  57. append-to-body>
  58. <div>
  59. <div style="margin-bottom: 14px">
  60. 检测到未保存的内容,是否保存修改?
  61. </div>
  62. <el-form ref="form" :model="form" label-width="80px" :rules="rules">
  63. <el-form-item label="围栏名称" prop="name">
  64. <el-input v-model="form.name"></el-input>
  65. </el-form-item>
  66. </el-form>
  67. </div>
  68. <div slot="footer" class="dialog-footer">
  69. <el-button @click="cancelEdit">放弃修改</el-button>
  70. <el-button type="primary" @click="saveEdit">保存</el-button>
  71. </div>
  72. </el-dialog>
  73. </template>
  74. </pannel>
  75. </template>
  76. <script>
  77. import { addFenceInfo, listFenceInfo, updateFenceInfo } from '@/api/bd/fenceInfo';
  78. import maphandle from '@/views/bd/map/maphandle';
  79. import Pannel from '@/views/bd/pannel/index.vue';
  80. // this.drawtool = new BDLayers.Lib.Tools.CBDrawTool('mytool', this.mapView, 'Rectangle', true); // 绘制矩形,参数1:id,参数2:地图,参数3:绘制类型,参数4:是否可拖拽编辑
  81. // this.drawtool.enable(); // 开始绘制
  82. // this.drawtool.disable(); // 结束绘制
  83. // this.drawtool.clear(); // 清除绘制内容
  84. // this.drawtool.setDrawMode(type); // 设置绘制类型
  85. // this.drawtool.on('drawend', (geom) => {}) // 绘制结束事件
  86. // this.drawtool.on('selectDraw', geom => {}) // 绘制完毕后选择绘制图形
  87. export default {
  88. name: 'fence',
  89. components: { Pannel },
  90. mixins: [maphandle],
  91. data() {
  92. return {
  93. playItem: {},
  94. editState: false,
  95. editPolyInfo: {},
  96. dialogVisible: false,
  97. editingDrawGeom: null,
  98. drawState: false,
  99. drawtool: null,
  100. form: {
  101. name: '',
  102. },
  103. rules: {
  104. name: [
  105. {
  106. required: true,
  107. message: '请输入围栏名称',
  108. trigger: 'blur',
  109. },
  110. ],
  111. },
  112. fenceList: [],
  113. };
  114. },
  115. // 组件卸载前清空图层信息
  116. beforeDestroy() {
  117. window.map.removeLayersById('drawLayer');
  118. window.map.removeLayersById('distanceLayer');
  119. this.drawtool?.disable();
  120. },
  121. created() {
  122. // 地图绘制工具
  123. this.drawtool = new BDLayers.Lib.Tools.CBDrawTool('myTool', window.map, 'Polygon', true);
  124. // 监听图形编辑
  125. this.drawtool.on('selectDraw', geom => {
  126. this.editingDrawGeom = geom.target.geometry ? geom.target.geometry : geom.target.geom
  127. ? geom.target.geom
  128. : geom.target;
  129. if (this.editingDrawGeom.isEditing && this.editingDrawGeom.isEditing()) {
  130. // 点击地图 图形取消编辑状态
  131. window.map.map.once('click', () => {
  132. this.editingDrawGeom.endEdit();
  133. this.dialogVisible = true;
  134. });
  135. } else {
  136. window.map.map.once('click', () => {
  137. this.editingDrawGeom = null;
  138. });
  139. }
  140. });
  141. this.drawtool.on('drawend', (geom) => {
  142. this.editingDrawGeom = geom.target.geometry ? geom.target.geometry : geom.target.geom
  143. ? geom.target.geom
  144. : geom.target;
  145. this.dialogVisible = true;
  146. this.drawState = false;
  147. });
  148. },
  149. mounted() {
  150. this.getFenceList();
  151. },
  152. methods: {
  153. async getFenceList() {
  154. const { rows } = await listFenceInfo({
  155. pageNum: 1,
  156. pageSize: 10,
  157. });
  158. if (!rows || rows.length < 1) {
  159. return;
  160. }
  161. const result = [];
  162. rows.forEach(item => {
  163. const {
  164. id,
  165. defenceName,
  166. poly,
  167. } = item;
  168. const polygon = this.custDrawPoly({
  169. name: defenceName,
  170. coordinates: this.polygonToCoordinates(poly),
  171. symbol: {
  172. lineColor: 'rgba(241,0,23,0.49)',
  173. lineWidth: 2,
  174. polygonFill: 'rgba(241,0,23,0.49)',
  175. polygonOpacity: 0.4,
  176. },
  177. bizAttr: {
  178. id,
  179. name: defenceName,
  180. },
  181. });
  182. result.push({
  183. id,
  184. name: defenceName,
  185. polygon,
  186. });
  187. });
  188. this.editingDrawGeom = null;
  189. this.fenceList = result;
  190. // window.map.flyToPoint([118.86318437, 31.52265586], {
  191. // zoom: 13,
  192. // pitch: 0,
  193. // bearing: 20,
  194. // duration: 5000,
  195. // });
  196. },
  197. cancelEdit() {
  198. this.drawtool.clear();
  199. this.dialogVisible = false;
  200. },
  201. saveEdit() {
  202. this.$refs.form.validate((valid) => {
  203. if (valid) {
  204. const resultCoor = [];
  205. const coordinates = [];
  206. this.editingDrawGeom._coordinates.forEach(coor => {
  207. const {
  208. x,
  209. y,
  210. } = coor;
  211. resultCoor.push(`${x} ${y}`);
  212. coordinates.push([x, y]);
  213. });
  214. resultCoor.push(resultCoor[0]);
  215. this.form.poly = `POLYGON((${resultCoor.join(',')}))`;
  216. if (!this.form.id) {
  217. addFenceInfo(this.formatParams(this.form)).then(response => {
  218. this.$message({
  219. type: 'success',
  220. message: '围栏保存成功',
  221. });
  222. });
  223. } else {
  224. updateFenceInfo(this.formatParams(this.form)).then(response => {
  225. this.$message({
  226. type: 'success',
  227. message: '围栏编辑成功',
  228. });
  229. });
  230. }
  231. this.dialogVisible = false;
  232. this.drawtool.clear();
  233. const polygon = this.drawPoly({
  234. coordinates: coordinates,
  235. symbol: {
  236. lineColor: 'rgba(241,0,23,0.49)',
  237. lineWidth: 2,
  238. polygonFill: 'rgba(241,0,23,0.49)',
  239. polygonOpacity: 0.4,
  240. },
  241. labelSymbol: {
  242. labelText: this.form.name,
  243. },
  244. bizAttr: this.form,
  245. });
  246. this.polyLayer.addGeometry(polygon);
  247. this.editingDrawGeom = null;
  248. this.editState = false;
  249. this.$refs.form.resetFields();
  250. } else {
  251. return false;
  252. }
  253. });
  254. },
  255. formatParams(form) {
  256. return {
  257. ...form,
  258. defenceName: this.form.name,
  259. poly: this.form.poly,
  260. };
  261. },
  262. startDraw() {
  263. this.editingDrawGeom = null;
  264. this.drawState = true;
  265. this.drawtool.enable();
  266. },
  267. /**
  268. *
  269. * @param coordinates
  270. * [
  271. * [
  272. * [118.86318437, 31.52265586],
  273. * [118.86620514, 31.52541921],
  274. * [118.86520697, 31.52406319],
  275. * [118.86318437, 31.52265586],
  276. * ],
  277. * ]
  278. * @param symbol
  279. * @param bizAttr
  280. * @param labelSymbol
  281. * @returns {BDLayers.Lib.Overlays.Polygon}
  282. */
  283. custDrawPoly({
  284. name = '多边形',
  285. coordinates,
  286. symbol = {},
  287. bizAttr = {},
  288. labelSymbol = {},
  289. }) {
  290. return this.drawPoly({
  291. name,
  292. coordinates,
  293. symbol,
  294. bizAttr,
  295. labelSymbol,
  296. polyOnClick: (data) => {
  297. console.log(data.target.options);
  298. if (this.editState) {
  299. return;
  300. }
  301. this.form.name = data.target.options.bizAttr.name;
  302. this.editingDrawGeom = data.target.geometry ? data.target.geometry : data.target.geom
  303. ? data.target.geom
  304. : data.target;
  305. this.$confirm('检测到选中了围栏,请选择操作类型?', '提示', {
  306. confirmButtonText: '编辑围栏',
  307. cancelButtonText: '删除围栏',
  308. type: 'warning',
  309. }).then(() => {
  310. // 开始编辑围栏
  311. this.editState = true;
  312. this.editingDrawGeom.startEdit();
  313. }).catch(() => {
  314. this.editingDrawGeom.remove();
  315. this.editState = false;
  316. this.editingDrawGeom = null;
  317. this.$message({
  318. type: 'info',
  319. message: '删除围栏',
  320. });
  321. });
  322. // 点击地图 图形取消编辑状态
  323. window.map.map.once('click', () => {
  324. this.editingDrawGeom.endEdit();
  325. this.dialogVisible = true;
  326. });
  327. },
  328. })
  329. },
  330. delFence(fence) {
  331. // polygon.geom.startEdit();
  332. fence.polygon.geom.remove();
  333. },
  334. editFence(fence) {
  335. },
  336. },
  337. };
  338. </script>
  339. <style lang="scss" src="./index.scss" />