Browse Source

[新增]黄海盒子配置文件

非煤矿业企业安全风险监测预警系统
邵佳豪 2 years ago
parent
commit
e6daa47a38
  1. 9
      src/app/system-management/analysis-of-the-host/analysis-of-the-host.component.html
  2. 29
      src/app/system-management/analysis-of-the-host/analysis-of-the-host.component.ts
  3. 7
      src/app/system-management/host-config/host-config.component.html
  4. 57
      src/app/system-management/host-config/host-config.component.ts
  5. 53
      src/app/system-management/image-label/image-label.component.html
  6. 79
      src/app/system-management/image-label/image-label.component.scss
  7. 860
      src/app/system-management/image-label/image-label.component.ts
  8. 49
      src/app/system-management/system-management.module.ts

9
src/app/system-management/analysis-of-the-host/analysis-of-the-host.component.html

@ -48,6 +48,15 @@
<td class="operation">
<!-- <a (click)="edit(data)" style="margin-right: 12px;">编辑</a> -->
<a (click)="config(data)" style="margin-right: 12px;">配置</a>
<nz-modal [(nzVisible)]="isVisible" [nzWidth]="300" nzTitle="请选择要配置的边缘主机" (nzOnCancel)="handleCancel()"
(nzOnOk)="handleOk()">
<ng-container *nzModalContent>
<nz-radio-group [(ngModel)]="radioValue">
<label nz-radio nzValue="交大">交大盒子</label>
<label nz-radio nzValue="黄海">黄海盒子</label>
</nz-radio-group>
</ng-container>
</nz-modal>
<a (click)="download(data)" style="margin-right: 12px;">下载设备编号</a>
<!-- <a class="red" (click)="delete(data)">删除</a> -->
</td>

29
src/app/system-management/analysis-of-the-host/analysis-of-the-host.component.ts

@ -37,11 +37,9 @@ export class AnalysisOfTheHostComponent implements OnInit {
router.events
.pipe(filter((e) => e instanceof NavigationEnd))
.subscribe((e) => {
if(this.selectedOilStation && this.selectedOilStation.id){
if (this.selectedOilStation && this.selectedOilStation.id) {
this.getHost();
}
});
}
ngOnInit(): void {
@ -204,12 +202,31 @@ export class AnalysisOfTheHostComponent implements OnInit {
});
}
isVisible = false;
radioValue = '交大';
configdata;
config(data) {
this.router.navigate([`/system/host/camera`], {
queryParams: { hostId: data.id, orId: this.selectedOilStation.id },
});
this.isVisible = true;
this.configdata = data;
}
handleOk(): void {
this.isVisible = false;
setTimeout(() => {
this.router.navigate([`/system/host/camera`], {
queryParams: {
hostId: this.configdata.id,
orId: this.selectedOilStation.id,
type: this.radioValue,
},
});
}, 0);
}
handleCancel(): void {
this.isVisible = false;
}
download(data) {
console.log(data);
let params = {

7
src/app/system-management/host-config/host-config.component.html

@ -53,12 +53,15 @@
</tr>
</tbody>
</nz-table>
<div class="footer">
<div class="footer" *ngIf="hostType === '交大'">
<button nz-button nzType="primary" (click)="sourceYaml()">下发source.yaml配置</button>
</div>
<div class="footer">
<div class="footer" *ngIf="hostType === '交大'">
<button [disabled]="isSourceYaml === false" nz-button nzType="primary" (click)="connect()">下发算法配置</button>
</div>
<div class="footer" *ngIf="hostType === '黄海'">
<button nz-button nzType="primary" (click)="config()">下发黄海config.json配置</button>
</div>
</div>
</div>
<div class="rightbox">

57
src/app/system-management/host-config/host-config.component.ts

@ -20,6 +20,7 @@ import { catchError, tap } from 'rxjs/operators';
import { ConfigFormDataService } from 'src/app/service/configFormData.service';
import { SendFileComponent } from './send-file/send-file.component';
import { ImageLabel2Component } from '../image-label2/image-label2.component';
import { ImageLabelComponent } from '../image-label/image-label.component';
interface Camera {
name: string;
user: string;
@ -50,9 +51,12 @@ export class HostConfigComponent implements OnInit {
hostId; //主机id
orId; //加油站id
hostType; //黄海还是交大的盒子
ngOnInit(): void {
this.hostId = this.route.snapshot.queryParams.hostId;
this.orId = this.route.snapshot.queryParams.orId;
this.hostType = this.route.snapshot.queryParams.type;
this.getCamera();
this.http.get(`/api/EdgeDevices/${this.hostId}`).subscribe({
@ -203,15 +207,46 @@ export class HostConfigComponent implements OnInit {
label(item) {
this.http.get(`/api/EdgeDevices/${this.hostId}`).subscribe({
next: (data: any) => {
if (data.configFiles) {
this.isSourceYaml = true;
if (this.hostType == '交大') {
if (data.configFiles) {
this.isSourceYaml = true;
const element = document.documentElement;
if (element.requestFullscreen) {
//进入全屏
element.requestFullscreen();
}
const modal = this.modal.create({
nzContent: ImageLabel2Component,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 1920,
nzClosable: false,
nzFooter: null,
nzWrapClassName: 'canvasContentBox',
nzBodyStyle: {
'border-radius': '0px',
padding: '0px',
margin: '0px',
},
nzComponentParams: {
data: item.id,
},
nzOnOk: async () => {},
});
modal.afterClose.subscribe((result) => {
this.ngOnInit();
});
} else {
this.isSourceYaml = false;
this.message.create('error', '请先下发source.yaml配置');
}
} else if (this.hostType == '黄海') {
const element = document.documentElement;
if (element.requestFullscreen) {
//进入全屏
element.requestFullscreen();
}
const modal = this.modal.create({
nzContent: ImageLabel2Component,
nzContent: ImageLabelComponent,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 1920,
nzClosable: false,
@ -223,24 +258,15 @@ export class HostConfigComponent implements OnInit {
margin: '0px',
},
nzComponentParams: {
data: item.id,
cameraId: item.id,
},
nzOnOk: async () => {},
});
const instance = modal.getContentComponent();
modal.afterClose.subscribe((result) => {
this.ngOnInit();
});
//this.router.navigate(['/system/host/camera/imageLabel'], { queryParams: { id: item.id } })
} else {
this.isSourceYaml = false;
this.message.create('error', '请先下发source.yaml配置');
}
},
error: (err) => {
// this.message.create('error', '请先下发source.yaml配置');
},
error: (err) => {},
});
}
@ -1110,4 +1136,7 @@ rule_threshold:
sessionStorage.setItem('config3', config3);
sessionStorage.setItem('config4', config4);
}
//黄海配置文件
config() {}
}

53
src/app/system-management/image-label/image-label.component.html

@ -1,12 +1,51 @@
<div class="box" id="canvasBox">
<div class="canvasBox">
<!-- <nz-page-header class="site-page-header" (nzBack)="goback()" nzBackIcon nzSubtitle="返回上一页"></nz-page-header> -->
<div class="btnbox">
<button nz-button [ngClass]="{selectBtn: markType}" (click)="markType = true;">标注监控区域</button>
<button nz-button [ngClass]="{selectBtn: !markType}" (click)="markType = false;">标注禁止区域</button>
<button nz-button nzType="primary" nzDanger (click)="clearCanvas()">清空</button>
<label class="leftTitle" style="color: red;">黄海盒子标记</label>
<label class="leftTitle" *ngIf="markType === 0">进出口</label>
<label class="leftTitle" *ngIf="markType === 1">加油区</label>
<label class="leftTitle" *ngIf="markType === 2">卸油区</label>
<label class="leftTitle" *ngIf="markType === 3">便利店</label>
<button *ngIf="markType === 0 || markType === 2 " nz-button [ngClass]="{selectBtn: selectedBtn === '停车区'}"
(click)="selectedBtn = '停车区'">停车区
<span class="deleteItem" (click)="clearCanvasItem($event,'isAllMonitoring')">删除</span>
</button>
<button *ngIf="markType === 3" nz-button [ngClass]="{selectBtn: selectedBtn === '收银区'}"
(click)="selectedBtn = '收银区'">收银区
<span class="deleteItem" (click)="clearCanvasItem($event,'isAllMonitoring')">删除</span>
</button>
<button *ngIf="markType === 2" nz-button [ngClass]="{selectBtn: selectedBtn === '闯入区'}"
(click)="selectedBtn = '闯入区'">闯入区
<span class="deleteItem" (click)="clearCanvasItem($event,'isAllMonitoring')">删除</span>
</button>
<!-- 矩形 -->
<button *ngIf="markType === 2" nz-button [ngClass]="{selectBtn: selectedBtn === '卸油区'}"
(click)="selectedBtn = '卸油区'">卸油区
<span class="deleteItem" (click)="clearCanvasItem($event,'isAllMonitoring')">删除</span>
</button>
<button nz-button nzType="primary" (click)="anewgetImg()">重新捕获摄像头图片</button>
<button nz-button nzType="primary" (click)="save()">保存</button>
<button nz-button nzType="primary" nzDanger nz-popconfirm nzPopconfirmTitle="您确定要清空吗?"
(nzOnConfirm)="clearCanvas()">清空</button>
<label *ngIf="camerasData" class="rightTitle">原始分辨率: {{camerasData.originalWeight}} ×
{{camerasData.originalHeight}}
</label>
</div>
<div class="imgbox" [style]="heightCount()">
<div class="imgbox">
<div class="content">
<div class="center" id="canvasCenter"><canvas id="canvas" [width]="canvasWidth" [height]="canvasHeight"></canvas></div>
<div class="center" id="canvasCenter"><canvas id="canvas" [width]="canvasWidth" [height]="canvasHeight"></canvas>
</div>
</div>
</div>
</div>
</div>

79
src/app/system-management/image-label/image-label.component.scss

@ -1,26 +1,77 @@
.box {
.canvasBox {
width: 100%;
height: 100%;
background: #fff;
font-size: 15px;
color: black;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
overflow: hidden;
.btnbox {
margin-bottom: 5px;
button {
margin-right: 15px;
.imgbox {
flex: 1;
overflow: hidden;
}
}
.selectBtn { background-color: #1890ff; color: #fff; }
.imgbox {
width: 100%;
height:500px;
overflow: hidden;
canvas{ overflow: hidden; }
.content,.center{
canvas {
overflow: hidden;
display: block;
}
.content,
.center {
width: 100%;
height: 100%;
overflow: hidden;
}
}
.btnbox {
display: flex;
position: fixed;
left: 1%;
top: 1%;
z-index: 10;
button {
margin-right: 6px;
display: flex;
}
.deleteItem {
display: none;
color: red;
cursor: pointer;
margin-left: 5px;
}
button:hover {
.deleteItem {
display: block;
}
}
.leftTitle {
line-height: 32px;
margin-right: 10px;
color: #fff;
}
.rightTitle {
line-height: 32px;
margin-left: 10px;
color: #fff;
}
}
.imgbox,
.btnbox {
box-sizing: border-box;
padding: 0;
}
.selectBtn {
background-color: #1890ff;
color: #fff;
}

860
src/app/system-management/image-label/image-label.component.ts

@ -1,216 +1,762 @@
import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Component, Input, OnInit } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal';
@Component({
selector: 'app-image-label',
templateUrl: './image-label.component.html',
styleUrls: ['./image-label.component.scss']
styleUrls: ['./image-label.component.scss'],
})
export class ImageLabelComponent implements OnInit {
constructor(
private http: HttpClient,
private message: NzMessageService,
private modal: NzModalService
) {}
constructor() { }
imgItem: any;
@Input() cameraId: any; //传递id
camerasData: any; //摄像头Data
imgItem: any; //图片 URL
canvasWidth: number = 0;
canvasHeight: number = 0;
copyCanvas: any;
markType: boolean = true; //标注type
copyCanvas: any; //拷贝 canvas底图
selectedBtn: string; //按钮选中
//返回上一步路由
goback() {
history.go(-1);
}
ngOnInit(): void {}
//获取 摄像头图片/标注点位
getImgMarkData() {
return new Promise((resolve, reject) => {
this.http.get(`/api/Cameras/${this.cameraId}`).subscribe((info: any) => {
info.dimensionedPoints
? (info.dimensionedPoints = JSON.parse(info.dimensionedPoints))
: null;
this.camerasData = info;
this.markType = info.type;
ngOnInit(): void {
this.markType === 3
? (this.selectedBtn = '收银区')
: (this.selectedBtn = '停车区');
const httpOptions = {
responseType: 'blob' as 'json',
params: { cameraId: this.cameraId },
};
this.http.get(`/api/Cameras/Images`, httpOptions).subscribe({
next: (data) => {
resolve(data);
},
error: (err) => {
reject('error');
},
});
});
});
}
anewgetImg() {
let params = {
cameraId: this.cameraId,
};
this.http
.put('/api/Cameras/Commands/CaptureImages', '', { params: params })
.subscribe({
next: (value: Object) => {
this.message.create(
'success',
'向边缘设备发送请求成功,请过一段时间手动刷新页面!'
);
},
error: (error: HttpErrorResponse) => {},
complete: () => {},
});
}
ngAfterContentInit(): void {
this.initBackgroundImg()
this.getImgMarkData()
.then((res: any) => {
this.imgItem = window.URL.createObjectURL(res);
window.setTimeout(() => {
this.initBackgroundImg();
}, 0);
})
.catch((err) => {
this.message.create('error', '获取图片失败!');
});
}
//初始化背景图
canvas;
ctx;
initBackgroundImg() {
let canvas = document.getElementById('canvas') as any;
canvas.oncontextmenu = () =>{ return false; };
let that = this
let ctx
this.canvas = document.getElementById('canvas') as any;
//取消鼠标右键事件
this.canvas.oncontextmenu = () => {
return false;
};
// 检测canvas支持性
if (canvas.getContext) {
ctx = canvas.getContext('2d'); // 返回一个对象,该对象提供了用在画布上绘图的方法和属性
if (this.canvas.getContext) {
this.ctx = this.canvas.getContext('2d'); // 返回一个对象,该对象提供了用在画布上绘图的方法和属性
} else {
document.write("你的浏览器不支持canvas,请升级你的浏览器!");
document.write('你的浏览器不支持canvas,请升级你的浏览器!');
return;
}
// 读取可视区域 宽高
let center = (document.getElementById('canvasCenter') as any).getBoundingClientRect();
// 图片加载完后,将其显示在canvas中
var img = new Image();
img.src = that.imgItem.url? that.imgItem.url : "../../../assets/images/bgImg.png";
img.src = this.imgItem ? this.imgItem : '../../../assets/images/bgImg.png';
img.onload = () => {
// 等比例缩放图片
var scale = 1;
if (img.width > center.width || img.height > center.height) {
if (img.width > img.height) {
scale = center.width / img.width;
}else {
scale = center.height / img.height;
this.canvasWidth = img.width;
this.canvasHeight = img.height;
window.setTimeout(() => {
// 加载图片
this.ctx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight);
this.copyCanvas = this.ctx.getImageData(
0,
0,
this.canvasWidth,
this.canvasHeight
);
//初始化标绘图形
this.initMark(this.canvas, this.ctx);
//监听canvas事件
this.initCanvasEvent(this.canvas);
}, 0);
};
}
//初始化标绘图形
initMark(canvas, context) {
this.camerasData.dimensionedPointsOfHH = sessionStorage.getItem('xxx');
if (!this.camerasData.dimensionedPointsOfHH) {
return;
} else {
this.camerasData.dimensionedPointsOfHH = JSON.parse(
this.camerasData.dimensionedPointsOfHH
);
}
console.log('原始标点数据', this.camerasData.dimensionedPointsOfHH);
return;
//绘制停车区多边形
this.camerasData.dimensionedPointsOfHH.carStopROI.forEach((element) => {
this.carStopROIDrawPolygon(element.x, element.y, canvas, context);
});
//绘制收银区多边形
this.camerasData.dimensionedPointsOfHH.cashierROI.forEach((element) => {
this.cashierROIDrawPolygon(element.x, element.y, canvas, context);
});
//绘制闯入区多边形
this.camerasData.dimensionedPointsOfHH.intrusionROI.forEach((element) => {
this.intrusionROIDrawPolygon(element.x, element.y, canvas, context);
});
//绘制卸油区矩形
this.unloadingROIDrawOblong(
this.camerasData.dimensionedPointsOfHH.unloadingROI,
context
);
}
markType: number = 0; //0=进出口,1=加油区,2=卸油区,3=便利店,
//记录鼠标点击位置
downx = 0;
downy = 0;
//初始化 canvas画布 监听事件
context;
initCanvasEvent(canvas) {
var context = canvas.getContext('2d');
this.context = context;
canvas.onmousedown = (e) => {
//鼠标按下事件
var clickX = e.pageX - canvas.offsetLeft;
var clickY = e.pageY - canvas.offsetTop;
this.downx = clickX;
this.downy = clickY;
if (this.markType === 0) {
//进出口
this.carStopROIDrawPolygon(clickX, clickY, canvas, context); //绘制停车区
} else if (this.markType === 1) {
//加油区(暂不需要标注)
} else if (this.markType === 2) {
//卸油区
if (this.selectedBtn === '停车区') {
this.carStopROIDrawPolygon(clickX, clickY, canvas, context); //绘制停车区
} else if (this.selectedBtn === '闯入区') {
this.intrusionROIDrawPolygon(clickX, clickY, canvas, context); //绘制闯入区
} else if (this.selectedBtn === '卸油区') {
if (this.unloadingROIOblongPoints.length === 1) {
//限制数量
this.message.create('warning', '卸油区只允许绘制1个!');
return;
}
//绘制矩形
context.beginPath();
context.moveTo(clickX, clickY);
context.strokeStyle = 'green';
context.lineWidth = 3;
canvas.onmousemove = (ev) => {
//鼠标移动事件
var moveX = ev.pageX - canvas.offsetLeft;
var moveY = ev.pageY - canvas.offsetTop;
this.unloadingROIDrawOblong(this.unloadingROIOblongPoints, context);
context.strokeStyle = 'orange';
let element = this.getOblongInfo(
this.downx,
this.downy,
moveX,
moveY
);
context.strokeRect(
element.x,
element.y,
element.width,
element.height
);
context.font = '22px Arial';
context.fillText(
'高度:' + element.height,
element.x + 3,
element.y + 22
);
};
}
//
} else if (this.markType === 3) {
//便利店
this.cashierROIDrawPolygon(clickX, clickY, canvas, context); //绘制停车区
}
that.canvasWidth = img.width * scale;
that.canvasHeight = img.height * scale; // 计算等比缩小后图片
window.setTimeout(()=>{ // 加载图片
ctx.drawImage(img, 0, 0, that.canvasWidth, that.canvasHeight);
this.copyCanvas = ctx.getImageData(0, 0, that.canvasWidth, that.canvasHeight)
that.initCanvasEvent(canvas)
}, 0)
}
}
//线段的点的集合
points = [];
points2 = [];
//可拖动圆圈的点的集合
circles = [];
circles2 = [];
//整体移动点位
allpoints = [];
allpoints2 = [];
isDragging = false
//是否在绘制区域内
isInOut = false
//记录鼠标点击位置
downx = 0
downy = 0
};
canvas.onmouseup = (e) => {
//鼠标松开事件
canvas.onmousemove = (ev) => {
//鼠标移动事件
return false;
};
if (this.markType !== 2) {
//因为只有卸油区需要画矩形
return;
}
if (this.markType === 2 && this.unloadingROIOblongPoints.length === 1) {
return;
}
if (this.markType === 2 && this.selectedBtn === '卸油区') {
var upX = e.pageX - canvas.offsetLeft;
var upY = e.pageY - canvas.offsetTop;
let point = this.getOblongInfo(this.downx, this.downy, upX, upY);
this.unloadingROIOblongPoints.push(point);
this.unloadingROIDrawOblong(this.unloadingROIOblongPoints, context);
}
};
}
//卸油区矩形
unloadingROIOblongPoints = []; //矩形的点的集合
unloadingROIDrawOblong(oblongList, context) {
context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
this.copyCanvas ? context.putImageData(this.copyCanvas, 0, 0) : null;
//重绘停车区
if (this.carStopROIPoints && this.carStopROIPoints.length != 0) {
this.redrawPolygon(
this.carStopROIPoints,
this.carStopROIAllpoints,
this.carStopROICircles,
context,
'green'
);
}
//重绘闯入区
if (this.carStopROIPoints && this.carStopROIPoints.length != 0) {
this.redrawPolygon(
this.intrusionROIPoints,
this.intrusionROIAllpoints,
this.intrusionROICircles,
context,
'red'
);
}
oblongList.forEach((element) => {
context.strokeStyle = 'orange';
context.lineWidth = 3;
context.strokeRect(element.x, element.y, element.width, element.height);
context.font = '22px Arial';
context.fontColor = 'orange';
context.fillText('高度:' + element.height, element.x + 3, element.y + 22);
});
}
/** 获取 矩形左上角点位/宽高 */
getOblongInfo(startX, startY, endX, endY) {
let point = {
x: 0,
y: 0,
width: 0,
height: 0,
};
if (startX > endX) {
point.x = endX;
point.width = startX - endX;
} else {
point.x = startX;
point.width = endX - startX;
}
if (startY > endY) {
point.y = endY;
point.height = startY - endY;
} else {
point.y = startY;
point.height = endY - startY;
}
return point;
}
//停车区多边形
carStopROIPoints = []; //线段的点的集合
carStopROICircles = []; //可拖动圆圈的点的集合
carStopROIAllpoints = []; //整体移动点位
carStopROIIsDragging = false; //是否可拖拽
carStopROIIsInOut = false; //是否在绘制区域内
carStopROIDrawPolygon(clickX, clickY, canvas, context) {
if (this.isInt(clickX, clickY, this.carStopROIPoints)) {
this.carStopROIIsInOut = true;
return;
} else {
this.carStopROIIsInOut = false;
}
let index;
//判断当前点击点是否在已经绘制的圆圈上,如果是执行相关操作,并return,不进入画线的代码
for (var i = 0; i < this.carStopROICircles.length; i++) {
let circle = this.carStopROICircles[i];
//使用勾股定理计算这个点与圆心之间的距离
var distanceFromCenter = Math.sqrt(
Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2)
);
// 如果是其他的点,则设置可以拖动
if (distanceFromCenter <= circle.radius) {
// 清除之前选择的圆圈
index = i;
this.carStopROIIsDragging = true;
//停止搜索
return;
}
}
//如果点击新的位置,则进入下面的代码,绘制点
context.clearRect(0, 0, canvas.width, canvas.height);
this.copyCanvas ? context.putImageData(this.copyCanvas, 0, 0) : null;
//重绘闯入区
if (this.carStopROIPoints && this.carStopROIPoints.length != 0) {
this.redrawPolygon(
this.intrusionROIPoints,
this.intrusionROIAllpoints,
this.intrusionROICircles,
context,
'red'
);
}
//重绘卸油区
if (
this.unloadingROIOblongPoints &&
this.unloadingROIOblongPoints.length != 0
) {
this.redrawRectangle(this.unloadingROIOblongPoints, context);
}
//遍历数组画圆
var circle = {
x: clickX,
y: clickY,
radius: 5,
color: 'white',
isSelected: false, //拖拽点的标记
};
this.carStopROICircles.push(circle);
this.carStopROIAllpoints = JSON.parse(
JSON.stringify(this.carStopROICircles)
);
this.carStopROICircles[0].color = 'white';
for (var i = 0; i < this.carStopROICircles.length; i++) {
let circle = this.carStopROICircles[i];
// 绘制圆圈
context.globalAlpha = 0.85;
context.beginPath();
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
context.fillStyle = circle.color;
context.strokeStyle = 'red';
context.fill();
context.stroke();
}
// 画线
var point = {
x: clickX,
y: clickY,
};
this.carStopROIPoints.push(point);
context.beginPath();
context.lineWidth = 3;
//从起始点开始绘制
context.moveTo(this.carStopROIPoints[0].x, this.carStopROIPoints[0].y);
for (var i = 0; i < this.carStopROIPoints.length; i++) {
context.lineTo(this.carStopROIPoints[i].x, this.carStopROIPoints[i].y);
}
context.closePath();
context.strokeStyle = 'green';
context.stroke();
}
//闯入区多边形
intrusionROIPoints = []; //线段的点的集合
intrusionROICircles = []; //可拖动圆圈的点的集合
intrusionROIAllpoints = []; //整体移动点位
intrusionROIIsDragging = false; //是否可拖拽
intrusionROIIsInOut = false; //是否在绘制区域内
intrusionROIDrawPolygon(clickX, clickY, canvas, context) {
if (this.isInt(clickX, clickY, this.intrusionROIPoints)) {
this.intrusionROIIsInOut = true;
return;
} else {
this.intrusionROIIsInOut = false;
}
let index;
//判断当前点击点是否在已经绘制的圆圈上,如果是执行相关操作,并return,不进入画线的代码
for (var i = 0; i < this.intrusionROICircles.length; i++) {
let circle = this.intrusionROICircles[i];
//使用勾股定理计算这个点与圆心之间的距离
var distanceFromCenter = Math.sqrt(
Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2)
);
// 如果是其他的点,则设置可以拖动
if (distanceFromCenter <= circle.radius) {
// 清除之前选择的圆圈
index = i;
this.intrusionROIIsDragging = true;
//停止搜索
return;
}
}
context.clearRect(0, 0, canvas.width, canvas.height);
this.copyCanvas ? context.putImageData(this.copyCanvas, 0, 0) : null;
//重绘停车区
if (this.carStopROIPoints && this.carStopROIPoints.length != 0) {
this.redrawPolygon(
this.carStopROIPoints,
this.carStopROIAllpoints,
this.carStopROICircles,
context,
'green'
);
}
//重绘卸油区
if (
this.unloadingROIOblongPoints &&
this.unloadingROIOblongPoints.length != 0
) {
this.redrawRectangle(this.unloadingROIOblongPoints, context);
}
//遍历数组画圆
var circle = {
x: clickX,
y: clickY,
radius: 5,
color: 'white',
isSelected: false, //拖拽点的标记
};
this.intrusionROICircles.push(circle);
this.intrusionROIAllpoints = JSON.parse(
JSON.stringify(this.intrusionROICircles)
);
this.intrusionROICircles[0].color = 'white';
for (var i = 0; i < this.intrusionROICircles.length; i++) {
let circle = this.intrusionROICircles[i];
// 绘制圆圈
context.globalAlpha = 0.85;
context.beginPath();
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
context.fillStyle = circle.color;
context.strokeStyle = 'red';
context.fill();
context.stroke();
}
// 画线
var point = {
x: clickX,
y: clickY,
};
this.intrusionROIPoints.push(point);
context.beginPath();
context.lineWidth = 3;
//从起始点开始绘制
context.moveTo(this.intrusionROIPoints[0].x, this.intrusionROIPoints[0].y);
for (var i = 0; i < this.intrusionROIPoints.length; i++) {
context.lineTo(
this.intrusionROIPoints[i].x,
this.intrusionROIPoints[i].y
);
}
context.closePath();
context.strokeStyle = 'red';
context.stroke();
}
//收银区多边形
cashierROIPoints = []; //线段的点的集合
cashierROICircles = []; //可拖动圆圈的点的集合
cashierROIAllpoints = []; //整体移动点位
cashierROIIsDragging = false; //是否可拖拽
cashierROIIsInOut = false; //是否在绘制区域内
cashierROIDrawPolygon(clickX, clickY, canvas, context) {
if (this.isInt(clickX, clickY, this.cashierROIPoints)) {
this.cashierROIIsInOut = true;
return;
} else {
this.cashierROIIsInOut = false;
}
let index;
//判断当前点击点是否在已经绘制的圆圈上,如果是执行相关操作,并return,不进入画线的代码
for (var i = 0; i < this.cashierROICircles.length; i++) {
let circle = this.cashierROICircles[i];
//使用勾股定理计算这个点与圆心之间的距离
var distanceFromCenter = Math.sqrt(
Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2)
);
// 如果是其他的点,则设置可以拖动
if (distanceFromCenter <= circle.radius) {
// 清除之前选择的圆圈
index = i;
this.cashierROIIsDragging = true;
//停止搜索
return;
}
}
context.clearRect(0, 0, canvas.width, canvas.height);
this.copyCanvas ? context.putImageData(this.copyCanvas, 0, 0) : null;
//遍历数组画圆
var circle = {
x: clickX,
y: clickY,
radius: 5,
color: 'yellow',
isSelected: false, //拖拽点的标记
};
this.cashierROICircles.push(circle);
this.cashierROIAllpoints = JSON.parse(
JSON.stringify(this.cashierROICircles)
);
this.cashierROICircles[0].color = 'white';
for (var i = 0; i < this.cashierROICircles.length; i++) {
let circle = this.cashierROICircles[i];
// 绘制圆圈
context.globalAlpha = 0.85;
context.beginPath();
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
context.fillStyle = circle.color;
context.strokeStyle = 'red';
context.fill();
context.stroke();
}
// 画线
var point = {
x: clickX,
y: clickY,
};
this.cashierROIPoints.push(point);
context.beginPath();
context.lineWidth = 3;
//从起始点开始绘制
context.moveTo(this.cashierROIPoints[0].x, this.cashierROIPoints[0].y);
for (var i = 0; i < this.cashierROIPoints.length; i++) {
context.lineTo(this.cashierROIPoints[i].x, this.cashierROIPoints[i].y);
}
context.closePath();
context.strokeStyle = 'blue';
context.stroke();
}
//判断点位是否在图形区域内
isInt(x, y, points) {
if (!points[2]) {
return;
}
var pt = {
x: x,
y: y,
};
return this.PointInPoly(pt, points);
}
//射线法判断点位
PointInPoly(pt, poly) {
for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i].y <= pt.y && pt.y < poly[j].y) ||
(poly[j].y <= pt.y && pt.y < poly[i].y)) &&
pt.x <
((poly[j].x - poly[i].x) * (pt.y - poly[i].y)) /
(poly[j].y - poly[i].y) +
poly[i].x &&
(c = !c);
return c;
}
//清空画布
clearCanvas() {
this.points = [];
this.points2 = [];
this.circles = [];
this.circles2 = [];
this.allpoints = [];
this.allpoints2 = [];
let canvas = document.getElementById('canvas') as any;
let context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
this.copyCanvas?context.putImageData(this.copyCanvas, 0, 0) : null;
context.clearRect(0, 0, canvas.width, canvas.height);
this.copyCanvas ? context.putImageData(this.copyCanvas, 0, 0) : null;
}
//初始化 canvas画布 点击事件
initCanvasEvent(canvas) {
let context = canvas.getContext('2d');
let html = document.documentElement
let boxDiv = document.getElementsByClassName("canvasDialog")[0]
canvas.onmousedown = (e)=>{
var clickX = e.pageX - canvas.offsetLeft - ((html.clientWidth - boxDiv.clientWidth) / 2);
var clickY = e.pageY - canvas.offsetTop - ((html.clientHeight - boxDiv.clientHeight) / 2);
this.downx = clickX
this.downy = clickY
if (this.isInt(clickX, clickY)) {
this.isInOut = true
return
} else {
this.isInOut = false
}
//清除某个标绘
clearCanvasItem(e, type) {
e.stopPropagation();
this.modal.confirm({
nzTitle: '确认要清除此标绘吗?',
nzOkText: '确定',
nzOkType: 'primary',
nzOkDanger: true,
nzOnOk: () => {
// if (type == 'isAllMonitoring') {
// //全局的多边形
// this.pointsOfmonitor = [];
// this.circlesOfmonitor = [];
// this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
// this.copyCanvas
// ? this.context.putImageData(this.copyCanvas, 0, 0)
// : null;
// }
// this.initMark2(this.canvas, this.ctx); //初始化标绘图形
},
nzCancelText: '取消',
});
}
let index
let beforeCircles = this.markType? this.circles: this.circles2
//判断当前点击点是否在已经绘制的圆圈上,如果是执行相关操作,并return,不进入画线的代码
for (var i = 0; i < beforeCircles.length; i++) {
let circle = beforeCircles[i];
//使用勾股定理计算这个点与圆心之间的距离
var distanceFromCenter = Math.sqrt(Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2));
// 如果是其他的点,则设置可以拖动
if (distanceFromCenter <= circle.radius) {
// 清除之前选择的圆圈
index = i;
this.isDragging = true;
//停止搜索
return;
}
}
//如果点击新的位置,则进入下面的代码,绘制点
//context.clearRect(0, 0, canvas.width, canvas.height);
//根据已有数据重绘多边形
redrawPolygon(data, points, circles, context, color) {
data.forEach((element) => {
//遍历数组画圆
var circle = {
x: clickX,
y: clickY,
radius: 10,
color: "blue",
isSelected: false, //拖拽点的标记
};
if (this.markType) {
this.circles.push(circle);
this.allpoints = JSON.parse(JSON.stringify(this.circles))
this.circles[0].color = "green";
} else {
this.circles2.push(circle);
this.allpoints2 = JSON.parse(JSON.stringify(this.circles2))
this.circles2[0].color = "red";
}
for (var i = 0; i < beforeCircles.length; i++) {
let circle = beforeCircles[i];
points = JSON.parse(JSON.stringify(circles));
circles[0].color = 'white';
for (var i = 0; i < circles.length; i++) {
let circle = circles[i];
// 绘制圆圈
context.globalAlpha = 0.85;
context.beginPath();
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
context.fillStyle = circle.color;
context.strokeStyle = "black";
context.strokeStyle = 'red';
context.fill();
context.stroke();
}
// 画线
var point = {
x: clickX,
y: clickY,
};
this.markType? this.points.push(point) : this.points2.push(point)
context.beginPath();
context.lineWidth = 3;
//从起始点开始绘制
let beforePoint = this.markType? this.points: this.points2
context.moveTo(beforePoint[0].x, beforePoint[0].y);
for (var i = 0; i < beforePoint.length; i++) {
context.lineTo(beforePoint[i].x, beforePoint[i].y);
context.moveTo(data[0].x, data[0].y);
for (var i = 0; i < data.length; i++) {
context.lineTo(data[i].x, data[i].y);
}
context.closePath()
context.fillStyle = "rgb(2,100,30)";
context.fill();
context.strokeStyle = "#9d4dca";
context.closePath();
context.strokeStyle = color;
context.stroke();
}
});
}
//判断点位是否在图形区域内
isInt(x, y) {
if (this.markType && !this.points[2]) {
return
}
if (!this.markType && !this.points2[2]) {
return
//根据已有数据重绘矩形
redrawRectangle(oblongList, context) {
oblongList.forEach((element) => {
context.strokeStyle = 'orange';
context.lineWidth = 3;
context.strokeRect(element.x, element.y, element.width, element.height);
context.font = '22px Arial';
context.fontColor = 'orange';
context.fillText('高度:' + element.height, element.x + 3, element.y + 22);
});
}
//保存
save() {
console.log(this.camerasData.dimensionedPointsOfHH);
if (!this.camerasData.dimensionedPointsOfHH) {
this.camerasData.dimensionedPointsOfHH = {
carStopROI: [],
intrusionROI: [],
cashierROI: [],
unloadingROI: [],
};
}
var pt = {
x: x,
y: y
//进出口
if (this.markType === 0) {
if (this.carStopROIPoints.length === 0) {
this.message.create('warning', '绘制完整后可保存!');
return;
}
this.camerasData.dimensionedPointsOfHH.carStopROI = this.carStopROIPoints;
}
var poly = this.markType? this.points : this.points2;
return this.PointInPoly(pt, poly)
}
//卸油区
if (this.markType === 2) {
if (
this.carStopROIPoints.length === 0 ||
this.intrusionROIPoints.length === 0 ||
this.unloadingROIOblongPoints.length === 0
) {
this.message.create('warning', '绘制完整后可保存!');
return;
}
//射线法判断点位
PointInPoly(pt, poly) {
for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
&& (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
&& (c = !c);
return c;
}
this.camerasData.dimensionedPointsOfHH.carStopROI = this.carStopROIPoints;
this.camerasData.dimensionedPointsOfHH.intrusionROI =
this.intrusionROIPoints;
this.camerasData.dimensionedPointsOfHH.unloadingROI =
this.unloadingROIOblongPoints;
}
//便利店
if (this.markType === 3) {
if (this.cashierROIPoints.length === 0) {
this.message.create('warning', '绘制完整后可保存!');
return;
}
this.camerasData.dimensionedPointsOfHH.cashierROI = this.cashierROIPoints;
}
//cneter height
heightCount() {
let style: any = {}
let height = document.documentElement.clientHeight
style.height = (height - 180) + 'px';
return style
// let paramsData = JSON.parse(JSON.stringify(this.camerasData));
// paramsData.dimensionedPointsHH = JSON.stringify(
// paramsData.dimensionedPointsHH
// );
console.log('标点结果', this.camerasData.dimensionedPointsOfHH);
// this.http
// .put(`/api/Cameras/${this.camerasData.id}/DimensionedPoints`, paramsData)
// .subscribe((data) => {
// this.message.create('success', '保存成功!');
// const isFullScreen = document.fullscreenElement;
// if (document.exitFullscreen && isFullScreen) {
// //关闭全屏
// document.exitFullscreen();
// }
// this.modal.closeAll();
// });
}
}

49
src/app/system-management/system-management.module.ts

@ -45,8 +45,35 @@ import { FileComponent } from './condition-monitoring/file/file.component';
import { ScriptComponent } from './status-monitoring/script/script.component';
import { VideoStreamingComponent } from './video-streaming/video-streaming.component';
import { DetailsComponent } from './video-streaming/details/details.component';
import { NzRadioModule } from 'ng-zorro-antd/radio';
@NgModule({
declarations: [OrganizationComponent, NavigationComponent, AddorComponent, EditorComponent, AnalysisOfTheHostComponent, AddhostComponent, EdithostComponent, AddcameraComponent, EditcameraComponent, HostConfigComponent, ImageListComponent, ImageLabelComponent, PlottingImageComponent, cameraType, ImageLabel2Component, ConfigFormComponent, ConditionMonitoringComponent, SendFileComponent, ModelComponent, KafkaComponent, StatusMonitoringComponent, FileComponent, ScriptComponent, VideoStreamingComponent, DetailsComponent],
declarations: [
OrganizationComponent,
NavigationComponent,
AddorComponent,
EditorComponent,
AnalysisOfTheHostComponent,
AddhostComponent,
EdithostComponent,
AddcameraComponent,
EditcameraComponent,
HostConfigComponent,
ImageListComponent,
ImageLabelComponent,
PlottingImageComponent,
cameraType,
ImageLabel2Component,
ConfigFormComponent,
ConditionMonitoringComponent,
SendFileComponent,
ModelComponent,
KafkaComponent,
StatusMonitoringComponent,
FileComponent,
ScriptComponent,
VideoStreamingComponent,
DetailsComponent,
],
imports: [
CommonModule,
SystemRoutingModule,
@ -69,9 +96,21 @@ import { DetailsComponent } from './video-streaming/details/details.component';
NzCheckboxModule,
NzPageHeaderModule,
NzTabsModule,
NzPopconfirmModule
NzPopconfirmModule,
NzRadioModule,
],
entryComponents: [
AddorComponent,
EditorComponent,
AddhostComponent,
EdithostComponent,
AddcameraComponent,
EditcameraComponent,
SendFileComponent,
ModelComponent,
FileComponent,
ScriptComponent,
DetailsComponent,
],
entryComponents: [AddorComponent, EditorComponent, AddhostComponent, EdithostComponent, AddcameraComponent, EditcameraComponent, SendFileComponent, ModelComponent, FileComponent, ScriptComponent, DetailsComponent]
})
export class SystemManagementModule { }
export class SystemManagementModule {}

Loading…
Cancel
Save