Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
|
3c255deb03 | 2 years ago |
68 changed files with 1858 additions and 16879 deletions
@ -1,64 +1,58 @@ |
|||||||
import { |
import { RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router'; |
||||||
RouteReuseStrategy, |
|
||||||
ActivatedRouteSnapshot, |
|
||||||
DetachedRouteHandle, |
|
||||||
} from '@angular/router'; |
|
||||||
|
|
||||||
export class CustomReuseStrategy implements RouteReuseStrategy { |
export class CustomReuseStrategy implements RouteReuseStrategy { |
||||||
public static handlers: { [key: string]: DetachedRouteHandle } = {}; |
|
||||||
|
|
||||||
/** 删除缓存路由快照的方法 */ |
public static handlers: { [key: string]: DetachedRouteHandle } = {}; |
||||||
public static deleteRouteSnapshot(path: string): void { |
|
||||||
const name = path.replace(/\//g, '_'); |
/** 删除缓存路由快照的方法 */ |
||||||
if (CustomReuseStrategy.handlers[name]) { |
public static deleteRouteSnapshot(path: string): void { |
||||||
delete CustomReuseStrategy.handlers[name]; |
const name = path.replace(/\//g, '_'); |
||||||
|
if (CustomReuseStrategy.handlers[name]) { |
||||||
|
delete CustomReuseStrategy.handlers[name]; |
||||||
|
} |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
/** 进入路由触发,判断是否同一路由 */ |
/** 表示对所有路由允许复用 如果你有路由不想利用可以在这加一些业务逻辑判断 */ |
||||||
shouldReuseRoute( |
shouldDetach(route: ActivatedRouteSnapshot): boolean { |
||||||
future: ActivatedRouteSnapshot, |
console.log('shouldDetach======>', route); |
||||||
curr: ActivatedRouteSnapshot |
return true; |
||||||
): boolean { |
} |
||||||
// console.debug('shouldReuseRoute======>', future, curr);
|
|
||||||
return ( |
|
||||||
future.routeConfig === curr.routeConfig && |
|
||||||
JSON.stringify(future.params) === JSON.stringify(curr.params) |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
/** 表示对所有路由允许复用 如果你有路由不想利用可以在这加一些业务逻辑判断 */ |
/** 当路由离开时会触发。按path作为key存储路由快照&组件当前实例对象 */ |
||||||
shouldDetach(route: ActivatedRouteSnapshot): boolean { |
store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { |
||||||
console.log('shouldDetach======>', route); |
console.log('store======>', route, handle); |
||||||
return true; |
if(route.routeConfig.path == 'host'){ |
||||||
} |
CustomReuseStrategy.handlers[this.getRouteUrl(route)] = handle; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
/** 当路由离开时会触发。按path作为key存储路由快照&组件当前实例对象 */ |
/** 若 path 在缓存中有的都认为允许还原路由 */ |
||||||
store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { |
shouldAttach(route: ActivatedRouteSnapshot): boolean { |
||||||
console.log('store======>', route, handle); |
// console.debug('shouldAttach======>', route);
|
||||||
if (route.routeConfig.path == 'host') { |
return !!CustomReuseStrategy.handlers[this.getRouteUrl(route)]; |
||||||
CustomReuseStrategy.handlers[this.getRouteUrl(route)] = handle; |
|
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
/** 若 path 在缓存中有的都认为允许还原路由 */ |
/** 从缓存中获取快照,若无则返回nul */ |
||||||
shouldAttach(route: ActivatedRouteSnapshot): boolean { |
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { |
||||||
// console.debug('shouldAttach======>', route);
|
// console.debug('retrieve======>', route);
|
||||||
return !!CustomReuseStrategy.handlers[this.getRouteUrl(route)]; |
if (!CustomReuseStrategy.handlers[this.getRouteUrl(route)]) { |
||||||
} |
return null; |
||||||
|
} |
||||||
|
|
||||||
|
return CustomReuseStrategy.handlers[this.getRouteUrl(route)]; |
||||||
|
} |
||||||
|
|
||||||
|
/** 进入路由触发,判断是否同一路由 */ |
||||||
|
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { |
||||||
|
// console.debug('shouldReuseRoute======>', future, curr);
|
||||||
|
return future.routeConfig === curr.routeConfig && |
||||||
|
JSON.stringify(future.params) === JSON.stringify(curr.params); |
||||||
|
} |
||||||
|
|
||||||
/** 从缓存中获取快照,若无则返回nul */ |
/** 使用route的path作为快照的key */ |
||||||
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { |
getRouteUrl(route: ActivatedRouteSnapshot) { |
||||||
// console.debug('retrieve======>', route);
|
const path = route['_routerState'].url.replace(/\//g, '_'); |
||||||
if (!CustomReuseStrategy.handlers[this.getRouteUrl(route)]) { |
return path; |
||||||
return null; |
|
||||||
} |
} |
||||||
return CustomReuseStrategy.handlers[this.getRouteUrl(route)]; |
|
||||||
} |
|
||||||
|
|
||||||
/** 使用route的path作为快照的key */ |
|
||||||
getRouteUrl(route: ActivatedRouteSnapshot) { |
|
||||||
const path = route['_routerState'].url.replace(/\//g, '_'); |
|
||||||
return path; |
|
||||||
} |
|
||||||
} |
} |
@ -1,114 +0,0 @@ |
|||||||
import { HttpClient } from '@angular/common/http'; |
|
||||||
import { Injectable } from '@angular/core'; |
|
||||||
import { Observable } from 'rxjs'; |
|
||||||
|
|
||||||
@Injectable({ |
|
||||||
providedIn: 'root', |
|
||||||
}) |
|
||||||
export class ObjectsSimpleService { |
|
||||||
static readonly c_apiRoot = '/api/'; //普通上传的API根路径
|
|
||||||
static readonly c_apiRoot_Multipart = '/api/'; //分块上传的API根路径
|
|
||||||
constructor(private http: HttpClient) {} |
|
||||||
|
|
||||||
static getBucketName() { |
|
||||||
let bucket = '/test/'; |
|
||||||
return bucket; |
|
||||||
} |
|
||||||
|
|
||||||
//普通上传,单个文件上限5M
|
|
||||||
static baseUrl = |
|
||||||
ObjectsSimpleService.c_apiRoot + |
|
||||||
'Objects' + |
|
||||||
ObjectsSimpleService.getBucketName(); |
|
||||||
postFile(extensionPath: string, file: File): Observable<Object> { |
|
||||||
let formData = new FormData(); |
|
||||||
formData.append('file', file, file.name); |
|
||||||
let data = { keepOriginalName: 'true' }; |
|
||||||
return this.http.post( |
|
||||||
ObjectsSimpleService.baseUrl + extensionPath, |
|
||||||
formData, |
|
||||||
{ params: data } |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
//分块上传
|
|
||||||
static baseUrl_MultipartUpload = |
|
||||||
ObjectsSimpleService.c_apiRoot_Multipart + |
|
||||||
'NewMultipartUpload' + |
|
||||||
ObjectsSimpleService.getBucketName(); |
|
||||||
postFile_MultipartUpload(extensionPath: string, file: File): Promise<Object> { |
|
||||||
// let formData = new FormData()
|
|
||||||
// formData.append("file", file, file.name)
|
|
||||||
// return this.http.post(ObjectsSimpleService.baseUrl + extensionPath, formData);
|
|
||||||
let data = { keepOriginalName: 'true', filename: file.name }; |
|
||||||
return new Promise((resolve, reject) => { |
|
||||||
this.http |
|
||||||
.post( |
|
||||||
ObjectsSimpleService.baseUrl_MultipartUpload + extensionPath, |
|
||||||
{}, |
|
||||||
{ params: data } |
|
||||||
) |
|
||||||
.subscribe(async (data: any) => { |
|
||||||
//初始化分段上传
|
|
||||||
let objectName = data.objectName; |
|
||||||
let uploadId = data.uploadId; |
|
||||||
let PartNumberETag = []; //每次返回需要保存的信息
|
|
||||||
//分块 处理
|
|
||||||
let fileSize = file.size || null; //上传文件的总大小
|
|
||||||
let shardSize = 5 * 1024 * 1024; //5MB一个分片
|
|
||||||
let allSlice = Math.ceil(fileSize / shardSize); //总文件/5MB===共分多少段
|
|
||||||
console.log('共分多少段' + allSlice); |
|
||||||
for (let i = 0; i < allSlice; i++) { |
|
||||||
//循环分段上传
|
|
||||||
let start = i * shardSize; //切割文件开始位置
|
|
||||||
let end = Math.min(fileSize, start + shardSize); //切割文件结束位置
|
|
||||||
let formData = new FormData(); |
|
||||||
formData.append('file', file.slice(start, end)); |
|
||||||
|
|
||||||
//同步写法实现异步调用
|
|
||||||
let result = await new Promise((resolve, reject) => { |
|
||||||
// await 需要后面返回一个 promise 对象
|
|
||||||
this.http |
|
||||||
.post( |
|
||||||
ObjectsSimpleService.c_apiRoot_Multipart + |
|
||||||
`MultipartUpload` + |
|
||||||
+ObjectsSimpleService.getBucketName() + |
|
||||||
`${objectName}?uploadId=${uploadId}&partNumber=${i + 1}`, |
|
||||||
formData |
|
||||||
) |
|
||||||
.subscribe((data: any) => { |
|
||||||
let msg = { |
|
||||||
partNumber: data.partNumber || null, |
|
||||||
eTag: data.eTag || null, |
|
||||||
}; |
|
||||||
resolve(msg); // 调用 promise 内置方法处理成功
|
|
||||||
}); |
|
||||||
}); |
|
||||||
PartNumberETag.push(result); |
|
||||||
|
|
||||||
if (PartNumberETag.length === allSlice) { |
|
||||||
//分块上传完成
|
|
||||||
|
|
||||||
let data = PartNumberETag; |
|
||||||
let paramsData = { uploadId: uploadId }; |
|
||||||
let path = |
|
||||||
ObjectsSimpleService.c_apiRoot_Multipart + |
|
||||||
'CompleteMultipartUpload' + |
|
||||||
ObjectsSimpleService.getBucketName() + |
|
||||||
objectName; |
|
||||||
this.http |
|
||||||
.post(path, data, { params: paramsData }) |
|
||||||
.subscribe((data) => { |
|
||||||
let objData: any = new Object(); |
|
||||||
objData.fileName = file.name; |
|
||||||
objData.filePath = ObjectsSimpleService.baseUrl + objectName; |
|
||||||
resolve(objData); |
|
||||||
}); |
|
||||||
} |
|
||||||
} //for循环
|
|
||||||
|
|
||||||
//分块 处理
|
|
||||||
}); |
|
||||||
}); |
|
||||||
} |
|
||||||
} |
|
@ -1,22 +1,11 @@ |
|||||||
<div class="box"> |
<div class="box"> |
||||||
<form nz-form [formGroup]="validateForm"> |
<form nz-form [formGroup]="validateForm"> |
||||||
<nz-form-item> |
<nz-form-item> |
||||||
<nz-form-label [nzSpan]="5">ip</nz-form-label> |
|
||||||
<nz-form-control> |
<nz-form-control> |
||||||
<nz-input-group> |
<nz-input-group> |
||||||
<input nz-input type="text" formControlName="ip" placeholder="请输入ip" /> |
<input nz-input type="text" formControlName="ip" placeholder="请输入ip" /> |
||||||
</nz-input-group> |
</nz-input-group> |
||||||
</nz-form-control> |
</nz-form-control> |
||||||
</nz-form-item> |
</nz-form-item> |
||||||
<nz-form-item> |
|
||||||
<nz-form-label [nzSpan]="5">类型</nz-form-label> |
|
||||||
<nz-form-control> |
|
||||||
<nz-select formControlName="type" name="select-validate" nzPlaceHolder="设备类型"> |
|
||||||
<nz-option [nzValue]="0" nzLabel="警旗1"></nz-option> |
|
||||||
<nz-option [nzValue]="1" nzLabel="警旗2"></nz-option> |
|
||||||
<nz-option [nzValue]="2" nzLabel="警旗3"></nz-option> |
|
||||||
</nz-select> |
|
||||||
</nz-form-control> |
|
||||||
</nz-form-item> |
|
||||||
</form> |
</form> |
||||||
</div> |
</div> |
@ -1,3 +1,3 @@ |
|||||||
.ant-form-item { |
.ant-form-item{ |
||||||
margin-bottom: 12px; |
margin-bottom: 0; |
||||||
} |
} |
@ -1,22 +1,11 @@ |
|||||||
<div class="box"> |
<div class="box"> |
||||||
<form nz-form [formGroup]="validateForm"> |
<form nz-form [formGroup]="validateForm"> |
||||||
<nz-form-item> |
<nz-form-item> |
||||||
<nz-form-label [nzSpan]="5">ip</nz-form-label> |
|
||||||
<nz-form-control> |
<nz-form-control> |
||||||
<nz-input-group> |
<nz-input-group> |
||||||
<input [(ngModel)]="ip" nz-input type="text" formControlName="ip" placeholder="请输入ip" /> |
<input [(ngModel)]="ip" nz-input type="text" formControlName="ip" placeholder="请输入ip" /> |
||||||
</nz-input-group> |
</nz-input-group> |
||||||
</nz-form-control> |
</nz-form-control> |
||||||
</nz-form-item> |
</nz-form-item> |
||||||
<nz-form-item> |
|
||||||
<nz-form-label [nzSpan]="5">类型</nz-form-label> |
|
||||||
<nz-form-control> |
|
||||||
<nz-select formControlName="type" name="select-validate" [(ngModel)]="type" nzPlaceHolder="设备类型"> |
|
||||||
<nz-option [nzValue]="0" nzLabel="警旗1"></nz-option> |
|
||||||
<nz-option [nzValue]="1" nzLabel="警旗2"></nz-option> |
|
||||||
<nz-option [nzValue]="2" nzLabel="警旗3"></nz-option> |
|
||||||
</nz-select> |
|
||||||
</nz-form-control> |
|
||||||
</nz-form-item> |
|
||||||
</form> |
</form> |
||||||
</div> |
</div> |
@ -1,23 +0,0 @@ |
|||||||
<div class="tagbox"> |
|
||||||
<div class="content"> |
|
||||||
<nz-tree [hidden]="!(step === 1)" #nzTreeComponent [nzData]="nodes" nzCheckable |
|
||||||
[nzCheckedKeys]="defaultCheckedKeys" [nzExpandedKeys]="defaultExpandedKeys"></nz-tree> |
|
||||||
<div class="inputbox" [hidden]="!(step === 2)"> |
|
||||||
<div *ngIf="type==1"> |
|
||||||
<button (click)="addInput()" nz-button>增加一行</button> |
|
||||||
<div class="inputItem" *ngFor="let item of inputList;let key =index"> |
|
||||||
<input nz-input [(ngModel)]="item.value" [name]="key.toString()" /> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<div *ngIf="type==2"> |
|
||||||
<input nz-input [(ngModel)]="oldValue" type="number" placeholder="老值" /> |
|
||||||
<input nz-input [(ngModel)]="newValue" type="number" placeholder="新值" /> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<div class="btnbox"> |
|
||||||
<button nz-button nzType="primary" (click)="nextStep()" *ngIf="step === 1">下一步</button> |
|
||||||
<button nz-button nzType="primary" (click)="back()" *ngIf="step === 2">上一步</button> |
|
||||||
<button nz-button nzType="primary" (click)="ok()" *ngIf="step === 2">确定</button> |
|
||||||
</div> |
|
||||||
</div> |
|
@ -1,28 +0,0 @@ |
|||||||
.tagbox { |
|
||||||
max-height: 600px; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
} |
|
||||||
|
|
||||||
.content { |
|
||||||
flex: 1; |
|
||||||
overflow-y: auto; |
|
||||||
|
|
||||||
.inputbox { |
|
||||||
.inputItem { |
|
||||||
display: flex; |
|
||||||
margin:6px 0px; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
.btnbox { |
|
||||||
display: flex; |
|
||||||
justify-content: flex-end; |
|
||||||
align-items: center; |
|
||||||
margin-top: 16px; |
|
||||||
button{ |
|
||||||
margin-left: 6px; |
|
||||||
} |
|
||||||
} |
|
@ -1,25 +0,0 @@ |
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|
||||||
|
|
||||||
import { WorkerTagComponent } from './worker-tag.component'; |
|
||||||
|
|
||||||
describe('WorkerTagComponent', () => { |
|
||||||
let component: WorkerTagComponent; |
|
||||||
let fixture: ComponentFixture<WorkerTagComponent>; |
|
||||||
|
|
||||||
beforeEach(async () => { |
|
||||||
await TestBed.configureTestingModule({ |
|
||||||
declarations: [ WorkerTagComponent ] |
|
||||||
}) |
|
||||||
.compileComponents(); |
|
||||||
}); |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
fixture = TestBed.createComponent(WorkerTagComponent); |
|
||||||
component = fixture.componentInstance; |
|
||||||
fixture.detectChanges(); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should create', () => { |
|
||||||
expect(component).toBeTruthy(); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,179 +0,0 @@ |
|||||||
import { HttpClient } from '@angular/common/http'; |
|
||||||
import { Component, Input, OnInit, ViewChild } from '@angular/core'; |
|
||||||
import { NzMessageService } from 'ng-zorro-antd/message'; |
|
||||||
import { NzTreeComponent } from 'ng-zorro-antd/tree'; |
|
||||||
import { TreeService } from 'src/app/service/tree.service'; |
|
||||||
|
|
||||||
@Component({ |
|
||||||
selector: 'app-worker-tag', |
|
||||||
templateUrl: './worker-tag.component.html', |
|
||||||
styleUrls: ['./worker-tag.component.scss'], |
|
||||||
}) |
|
||||||
export class WorkerTagComponent implements OnInit { |
|
||||||
@Input() tree: any; |
|
||||||
@Input() type: number; |
|
||||||
@ViewChild('nzTreeComponent', { static: false }) |
|
||||||
nzTreeComponent!: NzTreeComponent; |
|
||||||
defaultCheckedKeys = []; |
|
||||||
defaultExpandedKeys = []; |
|
||||||
constructor( |
|
||||||
private http: HttpClient, |
|
||||||
private message: NzMessageService, |
|
||||||
private toTree: TreeService |
|
||||||
) {} |
|
||||||
|
|
||||||
nodes = []; |
|
||||||
|
|
||||||
inputList = [{ value: '' }]; |
|
||||||
|
|
||||||
step = 1; |
|
||||||
ngOnInit(): void { |
|
||||||
this.getAllOrganization(); |
|
||||||
} |
|
||||||
|
|
||||||
getAllOrganization() { |
|
||||||
let params = { |
|
||||||
ContainsChildren: true, |
|
||||||
PageSize: 9999, |
|
||||||
}; |
|
||||||
this.http |
|
||||||
.get('/api/Organizations', { |
|
||||||
params: params, |
|
||||||
}) |
|
||||||
.subscribe((data: any) => { |
|
||||||
data.items.forEach((element) => { |
|
||||||
element.key = element.id; |
|
||||||
element.title = element.name; |
|
||||||
element.selectable = false; |
|
||||||
if (element.isGasStation) { |
|
||||||
element.isLeaf = true; |
|
||||||
element.disableCheckbox = false; |
|
||||||
} else { |
|
||||||
element.disableCheckbox = true; |
|
||||||
} |
|
||||||
}); |
|
||||||
this.nodes = [...this.toTree.toTree(data.items)]; |
|
||||||
// this.defaultExpandedKeys = [this.nodes[0].id];
|
|
||||||
// this.defaultExpandedKeys = [...this.defaultExpandedKeys];
|
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
nextStep() { |
|
||||||
this.step = 2; |
|
||||||
} |
|
||||||
back() { |
|
||||||
this.step = 1; |
|
||||||
} |
|
||||||
addInput() { |
|
||||||
this.inputList.push({ value: '' }); |
|
||||||
} |
|
||||||
|
|
||||||
oldValue: string; |
|
||||||
newValue: string; |
|
||||||
ok() { |
|
||||||
let ids = |
|
||||||
this.nzTreeComponent.getCheckedNodeList().map((item) => { |
|
||||||
return item.key; |
|
||||||
}) || []; |
|
||||||
|
|
||||||
let workerTags = |
|
||||||
this.inputList.map((item) => { |
|
||||||
return item.value; |
|
||||||
}) || []; |
|
||||||
if (ids.length === 0) { |
|
||||||
this.message.create('info', '请至少选择一个加油站'); |
|
||||||
return; |
|
||||||
} |
|
||||||
if (this.type == 1) { |
|
||||||
if (this.inputList.find((v) => !v.value)) { |
|
||||||
this.message.create('info', '请将所有输入框填写完整'); |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
if (this.type == 2) { |
|
||||||
if (!this.oldValue || !this.newValue) { |
|
||||||
this.message.create('info', '请将所有输入框填写完整'); |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
let _this = this; |
|
||||||
function BatchModifyWorkerTags() { |
|
||||||
var a = new Promise<void>((resolve, reject) => { |
|
||||||
_this.http |
|
||||||
.put('/api/EdgeDevices/BatchModifyWorkerTags', ids, { |
|
||||||
params: { workerTags: workerTags }, |
|
||||||
}) |
|
||||||
.subscribe({ |
|
||||||
next: (data: any) => { |
|
||||||
_this.message.create('success', '批量修改成功'); |
|
||||||
resolve(data); |
|
||||||
}, |
|
||||||
error: (err) => { |
|
||||||
// _this.message.create('error', '批量修改失败,请重试');
|
|
||||||
reject(err); |
|
||||||
}, |
|
||||||
}); |
|
||||||
}); |
|
||||||
return a; |
|
||||||
} |
|
||||||
|
|
||||||
function BatchModifyoi() { |
|
||||||
var a = new Promise<void>((resolve, reject) => { |
|
||||||
let obj = { |
|
||||||
replaceString: 'oilin_sleep_m: ' + _this.newValue, |
|
||||||
targetString: 'oilin_sleep_m: ' + _this.oldValue, |
|
||||||
}; |
|
||||||
_this.http |
|
||||||
.put('/api/EdgeDevices/BatchModifyConfig', ids, { |
|
||||||
params: obj, |
|
||||||
}) |
|
||||||
.subscribe({ |
|
||||||
next: (data: any) => { |
|
||||||
_this.message.create('success', '批量修改成功'); |
|
||||||
resolve(data); |
|
||||||
}, |
|
||||||
error: (err) => { |
|
||||||
// _this.message.create('error', '批量修改失败,请重试');
|
|
||||||
reject(err); |
|
||||||
}, |
|
||||||
}); |
|
||||||
}); |
|
||||||
return a; |
|
||||||
} |
|
||||||
|
|
||||||
function BatchPushFile() { |
|
||||||
let b = new Promise<void>((resolve, reject) => { |
|
||||||
_this.http |
|
||||||
.put('/api/EdgeDevices/Commands/BatchPushFile', ids, { |
|
||||||
params: { fileName: 'data.yaml' }, |
|
||||||
}) |
|
||||||
.subscribe({ |
|
||||||
next: (data: any) => { |
|
||||||
_this.message.create('success', '批量推送成功'); |
|
||||||
resolve(data); |
|
||||||
}, |
|
||||||
error: (err) => { |
|
||||||
// _this.message.create('error', '批量推送失败');
|
|
||||||
reject(err); |
|
||||||
}, |
|
||||||
}); |
|
||||||
}); |
|
||||||
return b; |
|
||||||
} |
|
||||||
|
|
||||||
if (this.type == 1) { |
|
||||||
BatchModifyWorkerTags() |
|
||||||
.then((data) => { |
|
||||||
BatchPushFile(); |
|
||||||
}) |
|
||||||
.catch((err) => {}); |
|
||||||
} |
|
||||||
if (this.type == 2) { |
|
||||||
BatchModifyoi() |
|
||||||
.then((data) => { |
|
||||||
BatchPushFile(); |
|
||||||
}) |
|
||||||
.catch((err) => {}); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,21 +1,20 @@ |
|||||||
<div class="box"> |
<div class="box"> |
||||||
<form nz-form [formGroup]="validateForm"> |
<form nz-form [formGroup]="validateForm"> |
||||||
<nz-form-item> |
<nz-form-item> |
||||||
<nz-form-control> |
<nz-form-control> |
||||||
<nz-select nzMode="multiple" formControlName="type" nzPlaceHolder="请选择类型"> |
<nz-select nzMode="multiple" formControlName="type" nzPlaceHolder="请选择类型"> |
||||||
<nz-option [nzValue]="'peoplenet'" nzLabel="peoplenet"></nz-option> |
<nz-option [nzValue]="'peoplenet'" nzLabel="peoplenet"></nz-option> |
||||||
<nz-option [nzValue]="'trafficcam'" nzLabel="trafficcam"></nz-option> |
<nz-option [nzValue]="'trafficcam'" nzLabel="trafficcam"></nz-option> |
||||||
<nz-option [nzValue]="'actionnet'" nzLabel="actionnet"></nz-option> |
<nz-option [nzValue]="'actionnet'" nzLabel="actionnet"></nz-option> |
||||||
<nz-option [nzValue]="'idnet'" nzLabel="idnet"></nz-option> |
<nz-option [nzValue]="'idnet'" nzLabel="idnet"></nz-option> |
||||||
<nz-option [nzValue]="'oilnet'" nzLabel="oilnet"></nz-option> |
<nz-option [nzValue]="'oilnet'" nzLabel="oilnet"></nz-option> |
||||||
<nz-option [nzValue]="'smoking_calling_net'" nzLabel="smoking_calling_net"></nz-option> |
<nz-option [nzValue]="'smoking_calling_net'" nzLabel="smoking_calling_net"></nz-option> |
||||||
<!-- <nz-option [nzValue]="'connet'" nzLabel="connet"></nz-option> --> |
<!-- <nz-option [nzValue]="'connet'" nzLabel="connet"></nz-option> --> |
||||||
<nz-option [nzValue]="'connet_oil'" nzLabel="connet_oil"></nz-option> |
<nz-option [nzValue]="'connet_oil'" nzLabel="connet_oil"></nz-option> |
||||||
<nz-option [nzValue]="'connet_grounder'" nzLabel="connet_grounder"></nz-option> |
<nz-option [nzValue]="'connet_grounder'" nzLabel="connet_grounder"></nz-option> |
||||||
<nz-option [nzValue]="'fire_smoke_net'" nzLabel="fire_smoke_net"></nz-option> |
<nz-option [nzValue]="'fire_smoke_net'" nzLabel="fire_smoke_net"></nz-option> |
||||||
<nz-option [nzValue]="'bulk_oil_net'" nzLabel="bulk_oil_net"></nz-option> |
</nz-select> |
||||||
</nz-select> |
</nz-form-control> |
||||||
</nz-form-control> |
</nz-form-item> |
||||||
</nz-form-item> |
</form> |
||||||
</form> |
|
||||||
</div> |
</div> |
@ -1,5 +0,0 @@ |
|||||||
<div class="box"> |
|
||||||
<div class="content"> |
|
||||||
<textarea name="config" id="config" [(ngModel)]="datacopy"></textarea> |
|
||||||
</div> |
|
||||||
</div> |
|
@ -1,21 +0,0 @@ |
|||||||
.box { |
|
||||||
width: 100%; |
|
||||||
height: 100%; |
|
||||||
background: #fff; |
|
||||||
font-size: 15px; |
|
||||||
color: black; |
|
||||||
box-sizing: border-box; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
overflow-y: auto; |
|
||||||
} |
|
||||||
|
|
||||||
.content { |
|
||||||
flex: 1; |
|
||||||
box-sizing: border-box; |
|
||||||
|
|
||||||
textarea { |
|
||||||
width: 100%; |
|
||||||
height: 400px; |
|
||||||
} |
|
||||||
} |
|
@ -1,25 +0,0 @@ |
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|
||||||
|
|
||||||
import { AnxinConfigComponent } from './anxin-config.component'; |
|
||||||
|
|
||||||
describe('AnxinConfigComponent', () => { |
|
||||||
let component: AnxinConfigComponent; |
|
||||||
let fixture: ComponentFixture<AnxinConfigComponent>; |
|
||||||
|
|
||||||
beforeEach(async () => { |
|
||||||
await TestBed.configureTestingModule({ |
|
||||||
declarations: [ AnxinConfigComponent ] |
|
||||||
}) |
|
||||||
.compileComponents(); |
|
||||||
}); |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
fixture = TestBed.createComponent(AnxinConfigComponent); |
|
||||||
component = fixture.componentInstance; |
|
||||||
fixture.detectChanges(); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should create', () => { |
|
||||||
expect(component).toBeTruthy(); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,19 +0,0 @@ |
|||||||
import { Component, OnInit, Input } from '@angular/core'; |
|
||||||
import { FormGroup } from '@angular/forms'; |
|
||||||
import yaml from 'js-yaml'; |
|
||||||
@Component({ |
|
||||||
selector: 'app-anxin-config', |
|
||||||
templateUrl: './anxin-config.component.html', |
|
||||||
styleUrls: ['./anxin-config.component.scss'], |
|
||||||
}) |
|
||||||
export class AnxinConfigComponent implements OnInit { |
|
||||||
@Input() data: any; |
|
||||||
validateForm!: FormGroup; |
|
||||||
constructor() {} |
|
||||||
datacopy; |
|
||||||
ngOnInit(): void { |
|
||||||
this.datacopy = yaml.dump(JSON.parse(JSON.stringify(this.data)), { |
|
||||||
lineWidth: -1, |
|
||||||
}); |
|
||||||
} |
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@ |
|||||||
<div class="box"> |
|
||||||
<div class="content"> |
|
||||||
<textarea name="config" id="config" [(ngModel)]="datacopy"></textarea> |
|
||||||
</div> |
|
||||||
</div> |
|
@ -1,21 +0,0 @@ |
|||||||
.box { |
|
||||||
width: 100%; |
|
||||||
height: 100%; |
|
||||||
background: #fff; |
|
||||||
font-size: 15px; |
|
||||||
color: black; |
|
||||||
box-sizing: border-box; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
overflow-y: auto; |
|
||||||
} |
|
||||||
|
|
||||||
.content { |
|
||||||
flex: 1; |
|
||||||
box-sizing: border-box; |
|
||||||
|
|
||||||
textarea { |
|
||||||
width: 100%; |
|
||||||
height: 400px; |
|
||||||
} |
|
||||||
} |
|
@ -1,25 +0,0 @@ |
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|
||||||
|
|
||||||
import { HuangHaiConfigComponent } from './huang-hai-config.component'; |
|
||||||
|
|
||||||
describe('HuangHaiConfigComponent', () => { |
|
||||||
let component: HuangHaiConfigComponent; |
|
||||||
let fixture: ComponentFixture<HuangHaiConfigComponent>; |
|
||||||
|
|
||||||
beforeEach(async () => { |
|
||||||
await TestBed.configureTestingModule({ |
|
||||||
declarations: [ HuangHaiConfigComponent ] |
|
||||||
}) |
|
||||||
.compileComponents(); |
|
||||||
}); |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
fixture = TestBed.createComponent(HuangHaiConfigComponent); |
|
||||||
component = fixture.componentInstance; |
|
||||||
fixture.detectChanges(); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should create', () => { |
|
||||||
expect(component).toBeTruthy(); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,16 +0,0 @@ |
|||||||
import { Component, OnInit, Input } from '@angular/core'; |
|
||||||
import { FormGroup } from '@angular/forms'; |
|
||||||
@Component({ |
|
||||||
selector: 'app-huang-hai-config', |
|
||||||
templateUrl: './huang-hai-config.component.html', |
|
||||||
styleUrls: ['./huang-hai-config.component.scss'], |
|
||||||
}) |
|
||||||
export class HuangHaiConfigComponent implements OnInit { |
|
||||||
@Input() data: any; |
|
||||||
validateForm!: FormGroup; |
|
||||||
constructor() {} |
|
||||||
datacopy; |
|
||||||
ngOnInit(): void { |
|
||||||
this.datacopy = JSON.stringify(JSON.parse(this.data), null, 2); |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +1,23 @@ |
|||||||
import { Component, OnInit, Input } from '@angular/core'; |
import { Component, OnInit, Input } from '@angular/core'; |
||||||
import { FormGroup } from '@angular/forms'; |
import { NzModalRef } from 'ng-zorro-antd/modal'; |
||||||
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; |
||||||
|
import { HttpClient } from '@angular/common/http'; |
||||||
@Component({ |
@Component({ |
||||||
selector: 'app-send-file', |
selector: 'app-send-file', |
||||||
templateUrl: './send-file.component.html', |
templateUrl: './send-file.component.html', |
||||||
styleUrls: ['./send-file.component.scss'], |
styleUrls: ['./send-file.component.scss'] |
||||||
}) |
}) |
||||||
export class SendFileComponent implements OnInit { |
export class SendFileComponent implements OnInit { |
||||||
@Input() data: any; |
|
||||||
|
@Input() data: any |
||||||
validateForm!: FormGroup; |
validateForm!: FormGroup; |
||||||
constructor() {} |
constructor(private modal: NzModalRef, private fb: FormBuilder, private http: HttpClient) { } |
||||||
datacopy; |
datacopy |
||||||
ngOnInit(): void { |
ngOnInit(): void { |
||||||
this.datacopy = JSON.parse(JSON.stringify(this.data)); |
this.datacopy = JSON.parse(JSON.stringify(this.data)) |
||||||
|
console.log(this.datacopy) |
||||||
|
} |
||||||
|
putConfig() { |
||||||
|
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,82 +0,0 @@ |
|||||||
<div class="box"> |
|
||||||
<form nz-form [formGroup]="validateForm" [nzLayout]="'inline'"> |
|
||||||
<nz-form-item> |
|
||||||
<nz-form-label nzRequired nzFor="HostIPAddress">主机地址</nz-form-label> |
|
||||||
<nz-form-control> |
|
||||||
<nz-input-group> |
|
||||||
<input nz-input type="text" formControlName="HostIPAddress" placeholder="请输入主机地址" /> |
|
||||||
</nz-input-group> |
|
||||||
</nz-form-control> |
|
||||||
</nz-form-item> |
|
||||||
<nz-form-item> |
|
||||||
<nz-form-label nzRequired nzFor="EventSystemName">预警事件</nz-form-label> |
|
||||||
<nz-form-control> |
|
||||||
<nz-select formControlName="EventSystemName" nzPlaceHolder="请选择预警事件"> |
|
||||||
<nz-option *ngFor="let item of eventList" [nzValue]="item" [nzLabel]="item"></nz-option> |
|
||||||
</nz-select> |
|
||||||
</nz-form-control> |
|
||||||
</nz-form-item> |
|
||||||
<nz-form-item> |
|
||||||
<nz-form-label nzRequired nzFor="ViolateArea">预警区域</nz-form-label> |
|
||||||
<nz-form-control> |
|
||||||
<nz-select formControlName="ViolateArea" nzPlaceHolder="请选择预警区域"> |
|
||||||
<nz-option *ngFor="let item of areaList" [nzValue]="item" [nzLabel]="item"></nz-option> |
|
||||||
</nz-select> |
|
||||||
</nz-form-control> |
|
||||||
</nz-form-item> |
|
||||||
<nz-form-item> |
|
||||||
<nz-form-label nzRequired nzFor="CameraNo">摄像头编号</nz-form-label> |
|
||||||
<nz-form-control> |
|
||||||
<nz-input-group> |
|
||||||
<input nz-input type="text" formControlName="CameraNo" placeholder="请输入摄像头编号" /> |
|
||||||
</nz-input-group> |
|
||||||
</nz-form-control> |
|
||||||
</nz-form-item> |
|
||||||
<nz-form-item> |
|
||||||
<nz-form-label nzRequired nzFor="ViolateTime">选择日期</nz-form-label> |
|
||||||
<nz-form-control> |
|
||||||
<nz-date-picker nzShowTime formControlName="ViolateTime"></nz-date-picker> |
|
||||||
</nz-form-control> |
|
||||||
</nz-form-item> |
|
||||||
<nz-form-item> |
|
||||||
<nz-form-label nzRequired nzFor="ViolateImage">图片地址</nz-form-label> |
|
||||||
<nz-form-control> |
|
||||||
<nz-input-group> |
|
||||||
<input nz-input type="text" formControlName="ViolateImage" placeholder="请输入图片地址" /> |
|
||||||
</nz-input-group> |
|
||||||
</nz-form-control> |
|
||||||
</nz-form-item> |
|
||||||
<nz-form-item> |
|
||||||
<nz-form-label nzRequired nzFor="violateVideo">视频地址</nz-form-label> |
|
||||||
<nz-form-control> |
|
||||||
<nz-input-group> |
|
||||||
<input nz-input type="text" formControlName="violateVideo" placeholder="请输入图片地址" /> |
|
||||||
</nz-input-group> |
|
||||||
</nz-form-control> |
|
||||||
</nz-form-item> |
|
||||||
<nz-form-item> |
|
||||||
<nz-form-label>第一步</nz-form-label> |
|
||||||
<button nz-button (click)="getImg()">捕获图片</button> |
|
||||||
</nz-form-item> |
|
||||||
<nz-form-item> |
|
||||||
<button nz-button (click)="getVideo()">捕获视频</button> |
|
||||||
</nz-form-item> |
|
||||||
<nz-form-item> |
|
||||||
<nz-form-label>第二步</nz-form-label> |
|
||||||
<button nz-button (click)="updateImg()">更新底图</button> |
|
||||||
</nz-form-item> |
|
||||||
<nz-form-item> |
|
||||||
<button nz-button (click)="updateVideo()">更新视频</button> |
|
||||||
</nz-form-item> |
|
||||||
</form> |
|
||||||
<div class="img_box"> |
|
||||||
<canvas #canvas (mousedown)="onMouseDown($event)" (mousemove)="onMouseMove($event)" (mouseup)="onMouseUp()" |
|
||||||
style="border: 1px solid #ccc;"></canvas> |
|
||||||
<video style="width: 500px;height: auto;" [src]="videoUrl" controls></video> |
|
||||||
<div> |
|
||||||
<button style="margin-bottom: 10px;" nz-button nzType="primary" (click)="uploadImg()">上传预警图片</button> |
|
||||||
<button nz-button nzType="primary" (click)="uploadVideo()">上传预警视频</button> |
|
||||||
</div> |
|
||||||
|
|
||||||
</div> |
|
||||||
</div> |
|
@ -1,16 +0,0 @@ |
|||||||
.ant-form-item { |
|
||||||
margin-bottom: 10px; |
|
||||||
} |
|
||||||
.img_box { |
|
||||||
height: auto; |
|
||||||
display: flex; |
|
||||||
canvas { |
|
||||||
max-width: 1000px; |
|
||||||
height: auto; |
|
||||||
} |
|
||||||
button { |
|
||||||
margin: 0; |
|
||||||
margin-left: 10px; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,25 +0,0 @@ |
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|
||||||
|
|
||||||
import { SimulateDataComponent } from './simulate-data.component'; |
|
||||||
|
|
||||||
describe('SimulateDataComponent', () => { |
|
||||||
let component: SimulateDataComponent; |
|
||||||
let fixture: ComponentFixture<SimulateDataComponent>; |
|
||||||
|
|
||||||
beforeEach(async () => { |
|
||||||
await TestBed.configureTestingModule({ |
|
||||||
declarations: [ SimulateDataComponent ] |
|
||||||
}) |
|
||||||
.compileComponents(); |
|
||||||
}); |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
fixture = TestBed.createComponent(SimulateDataComponent); |
|
||||||
component = fixture.componentInstance; |
|
||||||
fixture.detectChanges(); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should create', () => { |
|
||||||
expect(component).toBeTruthy(); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,327 +0,0 @@ |
|||||||
import { Component, OnInit, Input, ViewChild, ElementRef } from '@angular/core'; |
|
||||||
import { NzModalRef } from 'ng-zorro-antd/modal'; |
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; |
|
||||||
import { HttpClient } from '@angular/common/http'; |
|
||||||
import { DomSanitizer } from '@angular/platform-browser'; |
|
||||||
import { ObjectsSimpleService } from 'src/app/service/objectsSimple.service'; |
|
||||||
import { NzMessageService } from 'ng-zorro-antd/message'; |
|
||||||
@Component({ |
|
||||||
selector: 'app-simulate-data', |
|
||||||
templateUrl: './simulate-data.component.html', |
|
||||||
styleUrls: ['./simulate-data.component.scss'], |
|
||||||
}) |
|
||||||
export class SimulateDataComponent implements OnInit { |
|
||||||
@Input() data: any; |
|
||||||
validateForm!: FormGroup; |
|
||||||
constructor( |
|
||||||
private fb: FormBuilder, |
|
||||||
private http: HttpClient, |
|
||||||
private objectsSrv: ObjectsSimpleService, |
|
||||||
private message: NzMessageService, |
|
||||||
private sanitizer: DomSanitizer |
|
||||||
) {} |
|
||||||
|
|
||||||
currentTime = null; |
|
||||||
arr = ['进出口', '加油区', '卸油区', '便利店']; |
|
||||||
ngOnInit(): void { |
|
||||||
this.currentTime = new Date().getTime(); |
|
||||||
|
|
||||||
let datacopy = JSON.parse(JSON.stringify(this.data)); |
|
||||||
let HostIPAddress = sessionStorage.getItem('hostIPAddress'); |
|
||||||
this.validateForm = this.fb.group({ |
|
||||||
HostIPAddress: [HostIPAddress, [Validators.required]], |
|
||||||
EventSystemName: [null, [Validators.required]], |
|
||||||
ViolateArea: [this.arr[datacopy.type], [Validators.required]], |
|
||||||
CameraNo: [datacopy.name, [Validators.required]], |
|
||||||
ViolateTime: [null, [Validators.required]], |
|
||||||
ViolateImage: [ |
|
||||||
`/api/Objects/test/${this.currentTime}/image.png`, |
|
||||||
[Validators.required], |
|
||||||
], |
|
||||||
violateVideo: [ |
|
||||||
`/api/Objects/test/${this.currentTime}/video.mp4`, |
|
||||||
[Validators.required], |
|
||||||
], |
|
||||||
}); |
|
||||||
this.getImgMarkData(); |
|
||||||
this.updateVideo(); |
|
||||||
} |
|
||||||
|
|
||||||
@ViewChild('canvas') canvasRef: ElementRef<HTMLCanvasElement>; |
|
||||||
private ctx: CanvasRenderingContext2D; |
|
||||||
imgUrl: string; |
|
||||||
isDrawing = false; |
|
||||||
startX: number; |
|
||||||
startY: number; |
|
||||||
endX: number; |
|
||||||
endY: number; |
|
||||||
img: HTMLImageElement; |
|
||||||
|
|
||||||
//获取 摄像头图片/标注点位
|
|
||||||
getImgMarkData() { |
|
||||||
const httpOptions = { |
|
||||||
responseType: 'blob' as 'json', |
|
||||||
params: { cameraId: this.data.id }, |
|
||||||
}; |
|
||||||
let date = new Date().getTime(); |
|
||||||
this.http.get(`/api/Cameras/Images?v=${date}`, httpOptions).subscribe({ |
|
||||||
next: (data: any) => { |
|
||||||
setTimeout(() => { |
|
||||||
this.initCanvas(data); |
|
||||||
}, 0); |
|
||||||
}, |
|
||||||
error: (error) => { |
|
||||||
console.error('获取图片数据失败', error); |
|
||||||
setTimeout(() => { |
|
||||||
this.initCanvas(null); |
|
||||||
}, 0); |
|
||||||
}, |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
canvasObj = null; |
|
||||||
initCanvas(data) { |
|
||||||
if (!data) { |
|
||||||
// 如果没有获取到图片数据,使用本地默认图片
|
|
||||||
this.message.warning('未获取到照片数据,使用默认图片'); |
|
||||||
this.imgUrl = '../../../../assets/images/bgImg.png'; // 请确保这个路径下有默认图片
|
|
||||||
} else { |
|
||||||
this.imgUrl = window.URL.createObjectURL(data); |
|
||||||
} |
|
||||||
|
|
||||||
this.img = new Image(); |
|
||||||
this.img.src = this.imgUrl; |
|
||||||
this.img.onerror = () => { |
|
||||||
// 如果图片加载失败,也使用默认图片
|
|
||||||
this.message.warning('图片加载失败,使用默认图片'); |
|
||||||
this.img.src = '../../../../assets/images/bgImg.png'; |
|
||||||
}; |
|
||||||
|
|
||||||
this.img.onload = () => { |
|
||||||
this.canvasObj = this.canvasRef.nativeElement; |
|
||||||
this.ctx = this.canvasObj.getContext('2d'); |
|
||||||
|
|
||||||
// 设置 canvas 宽度为 1000px,保持图片的宽高比
|
|
||||||
const targetWidth = 1000; |
|
||||||
this.canvasObj.width = targetWidth; |
|
||||||
this.canvasObj.height = (this.img.height / this.img.width) * targetWidth; |
|
||||||
|
|
||||||
// 在 canvas 上绘制图片
|
|
||||||
this.ctx.drawImage( |
|
||||||
this.img, |
|
||||||
0, |
|
||||||
0, |
|
||||||
this.canvasObj.width, |
|
||||||
this.canvasObj.height |
|
||||||
); |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
// 开始绘制红框
|
|
||||||
onMouseDown(event: MouseEvent): void { |
|
||||||
this.isDrawing = true; |
|
||||||
this.startX = event.offsetX; |
|
||||||
this.startY = event.offsetY; |
|
||||||
} |
|
||||||
|
|
||||||
// 实时绘制红框
|
|
||||||
onMouseMove(event: MouseEvent): void { |
|
||||||
if (!this.isDrawing) return; |
|
||||||
|
|
||||||
this.endX = event.offsetX; |
|
||||||
this.endY = event.offsetY; |
|
||||||
|
|
||||||
const canvas = this.canvasRef.nativeElement; |
|
||||||
this.ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除 canvas
|
|
||||||
this.ctx.drawImage(this.img, 0, 0, canvas.width, canvas.height); // 重新绘制图片
|
|
||||||
this.ctx.strokeStyle = 'red'; |
|
||||||
this.ctx.lineWidth = 2; |
|
||||||
this.ctx.strokeRect( |
|
||||||
this.startX, |
|
||||||
this.startY, |
|
||||||
this.endX - this.startX, |
|
||||||
this.endY - this.startY |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
// 停止绘制红框
|
|
||||||
onMouseUp(): void { |
|
||||||
this.isDrawing = false; |
|
||||||
} |
|
||||||
|
|
||||||
async uploadImg() { |
|
||||||
const canvas = this.canvasRef.nativeElement; |
|
||||||
canvas.toBlob(async (blob: Blob) => { |
|
||||||
// 创建 File 对象,'image.png' 为文件名,'image/png' 为文件类型
|
|
||||||
const file = new File([blob], 'image.png', { type: 'image/png' }); |
|
||||||
console.log(file); |
|
||||||
let url = await this.postFile(file); |
|
||||||
console.log(url); |
|
||||||
this.validateForm.patchValue({ |
|
||||||
ViolateImage: url, // 替换为你想要的 ViolateImage 值
|
|
||||||
}); |
|
||||||
}, 'image/png'); |
|
||||||
} |
|
||||||
|
|
||||||
async uploadVideo() { |
|
||||||
// 创建 File 对象,'image.png' 为文件名,'image/png' 为文件类型
|
|
||||||
const file = new File([this.videoBlob], 'video.mp4', { type: 'video/mp4' }); |
|
||||||
console.log(file); |
|
||||||
let url = await this.postFile(file); |
|
||||||
console.log(url); |
|
||||||
this.validateForm.patchValue({ |
|
||||||
ViolateImage: url, // 替换为你想要的 ViolateImage 值
|
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
//上传文件
|
|
||||||
async postFile(file: File) { |
|
||||||
return new Promise((resolve, reject) => { |
|
||||||
this.objectsSrv |
|
||||||
.postFile(`${this.currentTime}/`, file) |
|
||||||
.subscribe((data) => { |
|
||||||
let dataObj = data as any; |
|
||||||
let filePath: string = |
|
||||||
ObjectsSimpleService.baseUrl + dataObj.objectName; |
|
||||||
this.message.create('success', '上传成功'); |
|
||||||
resolve(filePath); |
|
||||||
}); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
getImg() { |
|
||||||
let params = { |
|
||||||
cameraId: this.data.id, |
|
||||||
provider: 1, |
|
||||||
}; |
|
||||||
this.http |
|
||||||
.put('/api/Cameras/Commands/CaptureImages', '', { params: params }) |
|
||||||
.subscribe({ |
|
||||||
next: (value: Object) => { |
|
||||||
this.message.create( |
|
||||||
'success', |
|
||||||
'发送指令: 捕获图片成功,请过一段时间手动更新底图!' |
|
||||||
); |
|
||||||
}, |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
getVideo() { |
|
||||||
let params = { |
|
||||||
cameraId: this.data.id, |
|
||||||
provider: 1, |
|
||||||
}; |
|
||||||
this.http |
|
||||||
.put('/api/Cameras/Commands/CaptureVideos', '', { params: params }) |
|
||||||
.subscribe({ |
|
||||||
next: (value: Object) => { |
|
||||||
this.message.create( |
|
||||||
'success', |
|
||||||
'发送指令: 捕获视频成功,请过一段时间手动更新视频!' |
|
||||||
); |
|
||||||
}, |
|
||||||
}); |
|
||||||
} |
|
||||||
updateImg() { |
|
||||||
const httpOptions = { |
|
||||||
responseType: 'blob' as 'json', |
|
||||||
params: { cameraId: this.data.id }, |
|
||||||
}; |
|
||||||
let date = new Date().getTime(); |
|
||||||
this.http.get(`/api/Cameras/Images?v=${date}`, httpOptions).subscribe({ |
|
||||||
next: (data: any) => { |
|
||||||
this.replaceBackground(data); |
|
||||||
}, |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
replaceBackground(newData: Blob) { |
|
||||||
console.log('newData', newData); |
|
||||||
const newImgUrl = window.URL.createObjectURL(newData); |
|
||||||
|
|
||||||
this.img = new Image(); |
|
||||||
this.img.src = newImgUrl; |
|
||||||
|
|
||||||
this.img.onload = () => { |
|
||||||
// 清空 canvas 内容
|
|
||||||
this.ctx.clearRect(0, 0, this.canvasObj.width, this.canvasObj.height); |
|
||||||
|
|
||||||
// 更新 canvas 大小和图片宽高比
|
|
||||||
const targetWidth = 1000; |
|
||||||
this.canvasObj.width = targetWidth; |
|
||||||
this.canvasObj.height = (this.img.height / this.img.width) * targetWidth; |
|
||||||
|
|
||||||
// 绘制新的图片
|
|
||||||
this.ctx.drawImage( |
|
||||||
this.img, |
|
||||||
0, |
|
||||||
0, |
|
||||||
this.canvasObj.width, |
|
||||||
this.canvasObj.height |
|
||||||
); |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
videoBlob = null; |
|
||||||
videoUrl = null; |
|
||||||
updateVideo() { |
|
||||||
const httpOptions = { |
|
||||||
responseType: 'blob' as 'json', |
|
||||||
params: { cameraId: this.data.id }, |
|
||||||
}; |
|
||||||
let date = new Date().getTime(); |
|
||||||
this.http.get(`/api/Cameras/Videos?v=${date}`, httpOptions).subscribe({ |
|
||||||
next: (data: any) => { |
|
||||||
console.log('视频数据', data); |
|
||||||
this.videoBlob = data; |
|
||||||
// 获取图片数据 (data 是 Blob 类型)
|
|
||||||
const unsafeUrl = window.URL.createObjectURL(data); |
|
||||||
|
|
||||||
// 使用 DomSanitizer 处理 URL
|
|
||||||
this.videoUrl = this.sanitizer.bypassSecurityTrustUrl(unsafeUrl); |
|
||||||
}, |
|
||||||
}); |
|
||||||
} |
|
||||||
eventList = [ |
|
||||||
'油罐区入侵', |
|
||||||
'进出口停车', |
|
||||||
'站内吸烟', |
|
||||||
'前庭接打电话', |
|
||||||
'设置卸油隔离区', |
|
||||||
'拆除卸油管', |
|
||||||
'卸油连接静电接地', |
|
||||||
'卸油设置消防器材', |
|
||||||
'卸油现场清理', |
|
||||||
'油罐车无人卸油', |
|
||||||
'连接卸油管', |
|
||||||
'卸油中无人监卸', |
|
||||||
'证照年检逾期报警', |
|
||||||
'证照年检临期提醒', |
|
||||||
'证照年检办理提醒', |
|
||||||
'普通证照有效期逾期报警', |
|
||||||
'证照有效期办理提醒', |
|
||||||
'烟雾预警', |
|
||||||
'火灾报警', |
|
||||||
'设备报废逾期报警', |
|
||||||
'设备报废临期提醒', |
|
||||||
'收银员着装', |
|
||||||
'关键证照有效期逾期报警', |
|
||||||
'证照有效期临期提醒', |
|
||||||
'设备维保临期提醒', |
|
||||||
'设备维保逾期报警', |
|
||||||
]; |
|
||||||
|
|
||||||
areaList = [ |
|
||||||
'进出口', |
|
||||||
'卸油区', |
|
||||||
'加油区', |
|
||||||
'收银区', |
|
||||||
'发油区', |
|
||||||
'油库区', |
|
||||||
'监控区', |
|
||||||
'消防通道', |
|
||||||
'泵房区', |
|
||||||
'油罐区', |
|
||||||
'停车区', |
|
||||||
]; |
|
||||||
} |
|
@ -1,2 +0,0 @@ |
|||||||
<button (click)="xxx()">向子页面发送信息</button> |
|
||||||
<iframe id="iframe" src="http://192.168.1.86:25647/login" frameborder="0" width="100%" height="100%"></iframe> |
|
@ -1,25 +0,0 @@ |
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|
||||||
|
|
||||||
import { IframeComponent } from './iframe.component'; |
|
||||||
|
|
||||||
describe('IframeComponent', () => { |
|
||||||
let component: IframeComponent; |
|
||||||
let fixture: ComponentFixture<IframeComponent>; |
|
||||||
|
|
||||||
beforeEach(async () => { |
|
||||||
await TestBed.configureTestingModule({ |
|
||||||
declarations: [ IframeComponent ] |
|
||||||
}) |
|
||||||
.compileComponents(); |
|
||||||
}); |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
fixture = TestBed.createComponent(IframeComponent); |
|
||||||
component = fixture.componentInstance; |
|
||||||
fixture.detectChanges(); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should create', () => { |
|
||||||
expect(component).toBeTruthy(); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,27 +0,0 @@ |
|||||||
import { Component, OnInit } from '@angular/core'; |
|
||||||
import { Renderer2} from '@angular/core'; |
|
||||||
@Component({ |
|
||||||
selector: 'app-iframe', |
|
||||||
templateUrl: './iframe.component.html', |
|
||||||
styleUrls: ['./iframe.component.scss'] |
|
||||||
}) |
|
||||||
export class IframeComponent implements OnInit { |
|
||||||
|
|
||||||
constructor( private render2: Renderer2) { } |
|
||||||
|
|
||||||
ngOnInit(): void { |
|
||||||
} |
|
||||||
xxx(){ |
|
||||||
this.handleToIframe() |
|
||||||
} |
|
||||||
handleToIframe() { |
|
||||||
const child = this.render2.selectRootElement("#iframe"); |
|
||||||
console.log(child); |
|
||||||
let data = { |
|
||||||
from: 'parent page', |
|
||||||
code: 200, |
|
||||||
data: '来自父页面的数据!!!' |
|
||||||
}; |
|
||||||
child.contentWindow.postMessage(data, '*'); |
|
||||||
} |
|
||||||
} |
|
@ -1,55 +0,0 @@ |
|||||||
<div class="canvasBox" > |
|
||||||
<div class="btnbox" cdkDrag> |
|
||||||
<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 nz-button [ngClass]="{selectBtn: selectedBtn === '进出口'}" (click)="selectedBtn = '进出口'">进出口 |
|
||||||
<span class="colorBlock" style="background-color: red;"></span> |
|
||||||
<span class="deleteItem" (click)="clearCanvasItem($event,'进出口')">删除</span> |
|
||||||
</button> |
|
||||||
|
|
||||||
<button nz-button [ngClass]="{selectBtn: selectedBtn === '收银区'}" (click)="selectedBtn = '收银区'">收银区 |
|
||||||
<span class="colorBlock" style="background-color: yellow;"></span> |
|
||||||
<span class="deleteItem" (click)="clearCanvasItem($event,'收银区')">删除</span> |
|
||||||
</button> |
|
||||||
|
|
||||||
<button nz-button [ngClass]="{selectBtn: selectedBtn === '加油区'}" (click)="selectedBtn = '加油区'">加油区 |
|
||||||
<span class="colorBlock" style="background-color: green;"></span> |
|
||||||
<span class="deleteItem" (click)="clearCanvasItem($event,'加油区')">删除</span> |
|
||||||
</button> |
|
||||||
|
|
||||||
<button nz-button [ngClass]="{selectBtn: selectedBtn === '卸油区'}" (click)="selectedBtn = '卸油区'">卸油区 |
|
||||||
<span class="colorBlock" style="background-color: black;"></span> |
|
||||||
<span class="deleteItem" (click)="clearCanvasItem($event,'卸油区')">删除</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> |
|
||||||
<div class="changeImg"> |
|
||||||
<button nz-button nzType="primary">更换底图</button> |
|
||||||
<input type="file" class="inputfile" (change)="changeImg($event)"> |
|
||||||
</div> |
|
||||||
|
|
||||||
<label *ngIf="camerasData" class="rightTitle">原始分辨率: {{camerasData.originalWeight}} × |
|
||||||
{{camerasData.originalHeight}} |
|
||||||
</label> |
|
||||||
</div> |
|
||||||
|
|
||||||
|
|
||||||
<div class="imgbox"> |
|
||||||
<div class="content"> |
|
||||||
<div class="center" id="canvasCenter"><canvas id="canvas" [width]="canvasWidth" |
|
||||||
[height]="canvasHeight"></canvas> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
@ -1,103 +0,0 @@ |
|||||||
.canvasBox { |
|
||||||
width: 100%; |
|
||||||
height: 100%; |
|
||||||
background: #fff; |
|
||||||
font-size: 15px; |
|
||||||
color: black; |
|
||||||
box-sizing: border-box; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
overflow: hidden; |
|
||||||
|
|
||||||
.imgbox { |
|
||||||
flex: 1; |
|
||||||
overflow: hidden; |
|
||||||
} |
|
||||||
|
|
||||||
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; |
|
||||||
border: 1px solid red; |
|
||||||
box-sizing: border-box; |
|
||||||
cursor: move; |
|
||||||
|
|
||||||
button { |
|
||||||
margin-right: 6px; |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
.colorBlock { |
|
||||||
display: inline-block; |
|
||||||
width: 12px; |
|
||||||
height: 12px; |
|
||||||
margin-left: 3px; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.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; |
|
||||||
} |
|
||||||
|
|
||||||
.changeImg { |
|
||||||
position: relative; |
|
||||||
|
|
||||||
.inputfile { |
|
||||||
width: 88px; |
|
||||||
height: 32px; |
|
||||||
position: absolute; |
|
||||||
left: 0; |
|
||||||
top: 0; |
|
||||||
opacity: 0; |
|
||||||
} |
|
||||||
} |
|
@ -1,25 +0,0 @@ |
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|
||||||
|
|
||||||
import { ImageLabelAnxinComponent } from './image-label-anxin.component'; |
|
||||||
|
|
||||||
describe('ImageLabelAnxinComponent', () => { |
|
||||||
let component: ImageLabelAnxinComponent; |
|
||||||
let fixture: ComponentFixture<ImageLabelAnxinComponent>; |
|
||||||
|
|
||||||
beforeEach(async () => { |
|
||||||
await TestBed.configureTestingModule({ |
|
||||||
declarations: [ ImageLabelAnxinComponent ] |
|
||||||
}) |
|
||||||
.compileComponents(); |
|
||||||
}); |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
fixture = TestBed.createComponent(ImageLabelAnxinComponent); |
|
||||||
component = fixture.componentInstance; |
|
||||||
fixture.detectChanges(); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should create', () => { |
|
||||||
expect(component).toBeTruthy(); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,605 +0,0 @@ |
|||||||
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-anxin', |
|
||||||
templateUrl: './image-label-anxin.component.html', |
|
||||||
styleUrls: ['./image-label-anxin.component.scss'], |
|
||||||
}) |
|
||||||
export class ImageLabelAnxinComponent implements OnInit { |
|
||||||
constructor( |
|
||||||
private http: HttpClient, |
|
||||||
private message: NzMessageService, |
|
||||||
private modal: NzModalService |
|
||||||
) {} |
|
||||||
|
|
||||||
@Input() cameraId: any; //传递id
|
|
||||||
camerasData: any; //摄像头Data
|
|
||||||
imgItem: any; //图片 URL
|
|
||||||
canvasWidth: number = 0; |
|
||||||
canvasHeight: number = 0; |
|
||||||
copyCanvas: any; //拷贝 canvas底图
|
|
||||||
|
|
||||||
selectedBtn: string; //按钮选中
|
|
||||||
//返回上一步路由
|
|
||||||
goback() { |
|
||||||
history.go(-1); |
|
||||||
} |
|
||||||
|
|
||||||
ngOnInit(): void {} |
|
||||||
|
|
||||||
//获取 摄像头图片/标注点位
|
|
||||||
getImgMarkData() { |
|
||||||
console.log('获取照片', new Date().getTime()); |
|
||||||
return new Promise((resolve, reject) => { |
|
||||||
this.http.get(`/api/Cameras/${this.cameraId}`).subscribe((data: any) => { |
|
||||||
this.camerasData = data; |
|
||||||
// this.camerasData.dimensionedPointsAnxin = null
|
|
||||||
this.markType = data.type; |
|
||||||
const httpOptions = { |
|
||||||
responseType: 'blob' as 'json', |
|
||||||
params: { cameraId: this.cameraId }, |
|
||||||
}; |
|
||||||
let date = new Date().getTime(); |
|
||||||
this.http.get(`/api/Cameras/Images?v=${date}`, httpOptions).subscribe({ |
|
||||||
next: (data) => { |
|
||||||
resolve(data); |
|
||||||
}, |
|
||||||
error: (err) => { |
|
||||||
reject('error'); |
|
||||||
}, |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
anewgetImg() { |
|
||||||
let params = { |
|
||||||
cameraId: this.cameraId, |
|
||||||
provider: 1, |
|
||||||
}; |
|
||||||
this.http |
|
||||||
.put('/api/Cameras/Commands/CaptureImages', '', { params: params }) |
|
||||||
.subscribe({ |
|
||||||
next: (value: Object) => { |
|
||||||
this.message.create( |
|
||||||
'success', |
|
||||||
'向边缘设备发送请求成功,请过一段时间手动刷新页面!' |
|
||||||
); |
|
||||||
}, |
|
||||||
error: (error: HttpErrorResponse) => {}, |
|
||||||
complete: () => {}, |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
ngAfterContentInit(): void { |
|
||||||
this.getImgMarkData() |
|
||||||
.then((res: any) => { |
|
||||||
this.imgItem = window.URL.createObjectURL(res); |
|
||||||
window.setTimeout(() => { |
|
||||||
this.initBackgroundImg(); |
|
||||||
}, 0); |
|
||||||
}) |
|
||||||
.catch((err) => { |
|
||||||
this.message.create('error', '获取图片失败!'); |
|
||||||
window.setTimeout(() => { |
|
||||||
this.initBackgroundImg(); |
|
||||||
}, 0); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
//初始化背景图
|
|
||||||
canvas; |
|
||||||
ctx; |
|
||||||
|
|
||||||
initBackgroundImg() { |
|
||||||
this.canvas = document.getElementById('canvas') as any; |
|
||||||
//取消鼠标右键事件
|
|
||||||
this.canvas.oncontextmenu = () => { |
|
||||||
return false; |
|
||||||
}; |
|
||||||
// 检测canvas支持性
|
|
||||||
if (this.canvas.getContext) { |
|
||||||
this.ctx = this.canvas.getContext('2d'); // 返回一个对象,该对象提供了用在画布上绘图的方法和属性
|
|
||||||
} else { |
|
||||||
document.write('你的浏览器不支持canvas,请升级你的浏览器!'); |
|
||||||
return; |
|
||||||
} |
|
||||||
// 图片加载完后,将其显示在canvas中
|
|
||||||
var img = new Image(); |
|
||||||
img.src = this.imgItem ? this.imgItem : '../../../assets/images/noImg.png'; |
|
||||||
|
|
||||||
console.log('img', img); |
|
||||||
|
|
||||||
img.onload = () => { |
|
||||||
console.log('原始宽度', img.width); |
|
||||||
console.log('原始高度', img.height); |
|
||||||
if (img.width > 1920) { |
|
||||||
img.height = img.height * (1920 / img.width); |
|
||||||
img.width = 1920; |
|
||||||
} |
|
||||||
this.canvasWidth = img.width; |
|
||||||
this.canvasHeight = img.height; |
|
||||||
console.log('显示宽度', this.canvasWidth); |
|
||||||
console.log('显示高度', this.canvasHeight); |
|
||||||
// return;
|
|
||||||
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); |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
//初始化标绘图形
|
|
||||||
|
|
||||||
DrawPolygoning = ''; |
|
||||||
initMark(canvas, context) { |
|
||||||
// return
|
|
||||||
if (!this.camerasData.dimensionedPointsAnxin) { |
|
||||||
return; |
|
||||||
} else { |
|
||||||
this.camerasData.dimensionedPointsAnxin = JSON.parse( |
|
||||||
this.camerasData.dimensionedPointsAnxin |
|
||||||
); |
|
||||||
} |
|
||||||
console.log('原始标点数据', this.camerasData.dimensionedPointsAnxin); |
|
||||||
|
|
||||||
// for (const key in this.camerasData.dimensionedPointsAnxin.rawData) {
|
|
||||||
// const element = this.camerasData.dimensionedPointsAnxin.rawData[key];
|
|
||||||
// console.log(key, element);
|
|
||||||
// if (element.length !== 0) {
|
|
||||||
// for (let index = 0; index < element.length; index++) {
|
|
||||||
// const item = element[index];
|
|
||||||
// console.log(666, item);
|
|
||||||
// let obj = this.PolygonData[key];
|
|
||||||
// this.DrawPolygoning = key;
|
|
||||||
// this.DrawPolygon(
|
|
||||||
// item.x,
|
|
||||||
// item.y,
|
|
||||||
// canvas,
|
|
||||||
// context,
|
|
||||||
// obj.Points,
|
|
||||||
// obj.Circles,
|
|
||||||
// obj.Allpoints,
|
|
||||||
// obj.IsDragging,
|
|
||||||
// obj.IsInOut,
|
|
||||||
// obj.Color
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// this.DrawPolygoning = '';
|
|
||||||
// }
|
|
||||||
|
|
||||||
for ( |
|
||||||
let key = 0; |
|
||||||
key < this.camerasData.dimensionedPointsAnxin.yamlData.length; |
|
||||||
key++ |
|
||||||
) { |
|
||||||
const element = this.camerasData.dimensionedPointsAnxin.yamlData[key]; |
|
||||||
let name = enum_area[element.type]; |
|
||||||
let arr = this.handleArr(element.points); |
|
||||||
for (let index = 0; index < arr.length; index++) { |
|
||||||
const item = arr[index]; |
|
||||||
let obj = this.PolygonData[name]; |
|
||||||
this.DrawPolygoning = name; |
|
||||||
this.DrawPolygon( |
|
||||||
item.x, |
|
||||||
item.y, |
|
||||||
canvas, |
|
||||||
context, |
|
||||||
obj.Points, |
|
||||||
obj.Circles, |
|
||||||
obj.Allpoints, |
|
||||||
obj.IsDragging, |
|
||||||
obj.IsInOut, |
|
||||||
obj.Color |
|
||||||
); |
|
||||||
} |
|
||||||
this.DrawPolygoning = ''; |
|
||||||
} |
|
||||||
} |
|
||||||
handleArr(arr, n = 2) { |
|
||||||
const res = []; |
|
||||||
for (let i = 0; i < arr.length - 1; i += 2) { |
|
||||||
let index = Math.floor(i / n); |
|
||||||
const obj = { |
|
||||||
x: Number((arr[i] * this.canvasWidth).toFixed(0)), |
|
||||||
y: Number((arr[i + 1] * this.canvasHeight).toFixed(0)), |
|
||||||
}; |
|
||||||
res[index] = obj; |
|
||||||
} |
|
||||||
return res; |
|
||||||
} |
|
||||||
|
|
||||||
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) => { |
|
||||||
if (!this.selectedBtn) { |
|
||||||
this.message.create('warning', '请先选择要绘制的区域!'); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
//鼠标按下事件
|
|
||||||
var clickX = e.pageX - canvas.offsetLeft; |
|
||||||
var clickY = e.pageY - canvas.offsetTop; |
|
||||||
this.downx = clickX; |
|
||||||
this.downy = clickY; |
|
||||||
let obj; |
|
||||||
obj = this.PolygonData[this.selectedBtn]; |
|
||||||
this.DrawPolygon( |
|
||||||
clickX, |
|
||||||
clickY, |
|
||||||
canvas, |
|
||||||
context, |
|
||||||
obj.Points, |
|
||||||
obj.Circles, |
|
||||||
obj.Allpoints, |
|
||||||
obj.IsDragging, |
|
||||||
obj.IsInOut, |
|
||||||
obj.Color |
|
||||||
); |
|
||||||
}; |
|
||||||
|
|
||||||
canvas.onmouseup = (e) => { |
|
||||||
//鼠标松开事件
|
|
||||||
canvas.onmousemove = (ev) => { |
|
||||||
//鼠标移动事件
|
|
||||||
return false; |
|
||||||
}; |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
PolygonData = { |
|
||||||
进出口: { |
|
||||||
//进出口多边形
|
|
||||||
Points: [], //线段的点的集合
|
|
||||||
Circles: [], //可拖动圆圈的点的集合
|
|
||||||
Allpoints: [], //整体移动点位
|
|
||||||
IsDragging: false, //是否可拖拽
|
|
||||||
IsInOut: false, //是否在绘制区域内
|
|
||||||
Color: 'red', |
|
||||||
}, |
|
||||||
收银区: { |
|
||||||
//收银区多边形
|
|
||||||
Points: [], //线段的点的集合
|
|
||||||
Circles: [], //可拖动圆圈的点的集合
|
|
||||||
Allpoints: [], //整体移动点位
|
|
||||||
IsDragging: false, //是否可拖拽
|
|
||||||
IsInOut: false, //是否在绘制区域内
|
|
||||||
Color: 'yellow', |
|
||||||
}, |
|
||||||
加油区: { |
|
||||||
//加油区多边形
|
|
||||||
Points: [], //线段的点的集合
|
|
||||||
Circles: [], //可拖动圆圈的点的集合
|
|
||||||
Allpoints: [], //整体移动点位
|
|
||||||
IsDragging: false, //是否可拖拽
|
|
||||||
IsInOut: false, //是否在绘制区域内
|
|
||||||
Color: 'green', |
|
||||||
}, |
|
||||||
卸油区: { |
|
||||||
Points: [], //线段的点的集合
|
|
||||||
Circles: [], //可拖动圆圈的点的集合
|
|
||||||
Allpoints: [], //整体移动点位
|
|
||||||
IsDragging: false, //是否可拖拽
|
|
||||||
IsInOut: false, //是否在绘制区域内
|
|
||||||
Color: 'black', |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
//绘制多边形的方法
|
|
||||||
DrawPolygon( |
|
||||||
clickX, |
|
||||||
clickY, |
|
||||||
canvas, |
|
||||||
context, |
|
||||||
Points, |
|
||||||
Circles, |
|
||||||
Allpoints, |
|
||||||
IsDragging, |
|
||||||
IsInOut, |
|
||||||
Color |
|
||||||
) { |
|
||||||
if (this.isInt(clickX, clickY, Points)) { |
|
||||||
IsInOut = true; |
|
||||||
return; |
|
||||||
} else { |
|
||||||
IsInOut = false; |
|
||||||
} |
|
||||||
let index; |
|
||||||
//判断当前点击点是否在已经绘制的圆圈上,如果是执行相关操作,并return,不进入画线的代码
|
|
||||||
for (var i = 0; i < Circles.length; i++) { |
|
||||||
let circle = Circles[i]; |
|
||||||
//使用勾股定理计算这个点与圆心之间的距离
|
|
||||||
var distanceFromCenter = Math.sqrt( |
|
||||||
Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2) |
|
||||||
); |
|
||||||
// 如果是其他的点,则设置可以拖动
|
|
||||||
if (distanceFromCenter <= circle.radius) { |
|
||||||
// 清除之前选择的圆圈
|
|
||||||
index = i; |
|
||||||
IsDragging = true; |
|
||||||
//停止搜索
|
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
//如果点击新的位置,则进入下面的代码,绘制点
|
|
||||||
context.clearRect(0, 0, canvas.width, canvas.height); |
|
||||||
this.copyCanvas ? context.putImageData(this.copyCanvas, 0, 0) : null; |
|
||||||
|
|
||||||
//重绘除了自己的其他区域
|
|
||||||
for (const key in this.PolygonData) { |
|
||||||
const item = this.PolygonData[key]; |
|
||||||
if (key !== this.selectedBtn && key !== this.DrawPolygoning) { |
|
||||||
this.redrawPolygon( |
|
||||||
item.Points, |
|
||||||
item.Allpoints, |
|
||||||
item.Circles, |
|
||||||
context, |
|
||||||
item.Color |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
//遍历数组画圆
|
|
||||||
var circle = { |
|
||||||
x: clickX, |
|
||||||
y: clickY, |
|
||||||
radius: 5, |
|
||||||
color: Color, |
|
||||||
isSelected: false, //拖拽点的标记
|
|
||||||
}; |
|
||||||
Circles.push(circle); |
|
||||||
Allpoints = JSON.parse(JSON.stringify(Circles)); |
|
||||||
Circles[0].color = Color; |
|
||||||
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 = Color; |
|
||||||
context.fill(); |
|
||||||
context.stroke(); |
|
||||||
} |
|
||||||
// 画线
|
|
||||||
var point = { |
|
||||||
x: clickX, |
|
||||||
y: clickY, |
|
||||||
}; |
|
||||||
Points.push(point); |
|
||||||
context.beginPath(); |
|
||||||
context.lineWidth = 3; |
|
||||||
//从起始点开始绘制
|
|
||||||
context.moveTo(Points[0].x, Points[0].y); |
|
||||||
for (var i = 0; i < Points.length; i++) { |
|
||||||
context.lineTo(Points[i].x, Points[i].y); |
|
||||||
} |
|
||||||
context.closePath(); |
|
||||||
context.strokeStyle = Color; |
|
||||||
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; |
|
||||||
} |
|
||||||
|
|
||||||
//根据已有数据重绘多边形
|
|
||||||
redrawPolygon(data, points, circles, context, color) { |
|
||||||
data.forEach((element) => { |
|
||||||
//遍历数组画圆
|
|
||||||
points = JSON.parse(JSON.stringify(circles)); |
|
||||||
circles[0].color = color; |
|
||||||
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 = color; |
|
||||||
context.fill(); |
|
||||||
context.stroke(); |
|
||||||
} |
|
||||||
// 画线
|
|
||||||
context.beginPath(); |
|
||||||
context.lineWidth = 3; |
|
||||||
//从起始点开始绘制
|
|
||||||
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.strokeStyle = color; |
|
||||||
context.stroke(); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
//清空画布
|
|
||||||
clearCanvas() { |
|
||||||
let canvas = document.getElementById('canvas') as any; |
|
||||||
let context = canvas.getContext('2d'); |
|
||||||
for (const key in this.PolygonData) { |
|
||||||
const element = this.PolygonData[key]; |
|
||||||
element.Points = []; |
|
||||||
element.Circles = []; |
|
||||||
element.Allpoints = []; |
|
||||||
element.IsDragging = false; |
|
||||||
element.IsInOut = false; |
|
||||||
} |
|
||||||
context.clearRect(0, 0, canvas.width, canvas.height); |
|
||||||
this.copyCanvas ? context.putImageData(this.copyCanvas, 0, 0) : null; |
|
||||||
// console.log(this.PolygonData)
|
|
||||||
} |
|
||||||
|
|
||||||
//清除某个标绘
|
|
||||||
clearCanvasItem(e, type) { |
|
||||||
e.stopPropagation(); |
|
||||||
this.modal.confirm({ |
|
||||||
nzTitle: '确认要清除此标绘吗?', |
|
||||||
nzOkText: '确定', |
|
||||||
nzOkType: 'primary', |
|
||||||
nzOkDanger: true, |
|
||||||
nzOnOk: () => { |
|
||||||
this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight); |
|
||||||
this.copyCanvas |
|
||||||
? this.context.putImageData(this.copyCanvas, 0, 0) |
|
||||||
: null; |
|
||||||
this.PolygonData[type].Points = []; |
|
||||||
this.PolygonData[type].Circles = []; |
|
||||||
this.PolygonData[type].Allpoints = []; |
|
||||||
this.redrawAll(); |
|
||||||
}, |
|
||||||
nzCancelText: '取消', |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
redrawAll() { |
|
||||||
//重绘除了自己的其他区域
|
|
||||||
for (const key in this.PolygonData) { |
|
||||||
const item = this.PolygonData[key]; |
|
||||||
this.redrawPolygon( |
|
||||||
item.Points, |
|
||||||
item.Allpoints, |
|
||||||
item.Circles, |
|
||||||
this.context, |
|
||||||
item.Color |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
//保存
|
|
||||||
save() { |
|
||||||
console.log(this.camerasData.dimensionedPointsAnxin); |
|
||||||
console.log('标点数据', this.PolygonData); |
|
||||||
|
|
||||||
for (const key in this.PolygonData) { |
|
||||||
const element = this.PolygonData[key]; |
|
||||||
if (element.Points.length !== 0 && element.Points.length <= 2) { |
|
||||||
this.message.create('info', '标绘图形必须为封闭图形!'); |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
if (!this.camerasData.dimensionedPointsAnxin) { |
|
||||||
this.camerasData.dimensionedPointsAnxin = {}; |
|
||||||
this.camerasData.dimensionedPointsAnxin.rawData = { |
|
||||||
进出口: [], |
|
||||||
收银区: [], |
|
||||||
加油区: [], |
|
||||||
卸油区: [], |
|
||||||
}; |
|
||||||
this.camerasData.dimensionedPointsAnxin.yamlData = []; |
|
||||||
} |
|
||||||
|
|
||||||
let yamlData = []; |
|
||||||
for (const key in this.PolygonData) { |
|
||||||
const item = this.PolygonData[key]; |
|
||||||
this.camerasData.dimensionedPointsAnxin.rawData[key] = item.Points; |
|
||||||
if (item.Points.length !== 0) { |
|
||||||
let points = []; |
|
||||||
for (const key in item.Points) { |
|
||||||
const v = item.Points[key]; |
|
||||||
points.push(Number((v.x / this.canvasWidth).toFixed(4))); |
|
||||||
points.push(Number((v.y / this.canvasHeight).toFixed(4))); |
|
||||||
} |
|
||||||
let obj = { |
|
||||||
type: enum_area[key], |
|
||||||
points: points, |
|
||||||
}; |
|
||||||
yamlData.push(obj); |
|
||||||
} |
|
||||||
} |
|
||||||
this.camerasData.dimensionedPointsAnxin.yamlData = yamlData; |
|
||||||
let body = { |
|
||||||
dimensionedPointsAnxin: JSON.stringify( |
|
||||||
this.camerasData.dimensionedPointsAnxin |
|
||||||
), |
|
||||||
}; |
|
||||||
|
|
||||||
console.log('标点结果', this.camerasData.dimensionedPointsAnxin); |
|
||||||
// return;
|
|
||||||
this.http |
|
||||||
.put(`/api/Cameras/${this.camerasData.id}/DimensionedPoints`, body) |
|
||||||
.subscribe((data) => { |
|
||||||
this.message.create('success', '保存成功!'); |
|
||||||
const isFullScreen = document.fullscreenElement; |
|
||||||
if (document.exitFullscreen && isFullScreen) { |
|
||||||
//关闭全屏
|
|
||||||
document.exitFullscreen(); |
|
||||||
} |
|
||||||
this.modal.closeAll(); |
|
||||||
}); |
|
||||||
} |
|
||||||
//更换底图
|
|
||||||
changeImg(e) { |
|
||||||
this.clearCanvas(); |
|
||||||
let file = e.target.files[0] || null; //获取上传的文件
|
|
||||||
let fileUrl = URL.createObjectURL(file); |
|
||||||
console.log(fileUrl); |
|
||||||
var img = new Image(); |
|
||||||
img.src = fileUrl; |
|
||||||
img.onload = () => { |
|
||||||
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 |
|
||||||
); |
|
||||||
}, 0); |
|
||||||
}; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
enum enum_area { |
|
||||||
'加油区' = 2, |
|
||||||
'卸油区' = 3, |
|
||||||
'收银区' = 1, |
|
||||||
'进出口' = 0, |
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,4 +0,0 @@ |
|||||||
<div class="box"> |
|
||||||
<nz-tree #nzTreeComponent [nzSelectedKeys]="defaultSelectedKeys" [nzData]="nodes" |
|
||||||
[nzExpandedKeys]="defaultExpandedKeys"></nz-tree> |
|
||||||
</div> |
|
@ -1,4 +0,0 @@ |
|||||||
.box { |
|
||||||
max-height: 500px; |
|
||||||
overflow-y: auto; |
|
||||||
} |
|
@ -1,25 +0,0 @@ |
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|
||||||
|
|
||||||
import { ChangeOrComponent } from './change-or.component'; |
|
||||||
|
|
||||||
describe('ChangeOrComponent', () => { |
|
||||||
let component: ChangeOrComponent; |
|
||||||
let fixture: ComponentFixture<ChangeOrComponent>; |
|
||||||
|
|
||||||
beforeEach(async () => { |
|
||||||
await TestBed.configureTestingModule({ |
|
||||||
declarations: [ ChangeOrComponent ] |
|
||||||
}) |
|
||||||
.compileComponents(); |
|
||||||
}); |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
fixture = TestBed.createComponent(ChangeOrComponent); |
|
||||||
component = fixture.componentInstance; |
|
||||||
fixture.detectChanges(); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should create', () => { |
|
||||||
expect(component).toBeTruthy(); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,55 +0,0 @@ |
|||||||
import { Component, Input, OnInit, ViewChild } from '@angular/core'; |
|
||||||
import { NzModalRef } from 'ng-zorro-antd/modal'; |
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; |
|
||||||
import { HttpClient } from '@angular/common/http'; |
|
||||||
import { TreeService } from 'src/app/service/tree.service'; |
|
||||||
import { NzTreeComponent } from 'ng-zorro-antd/tree'; |
|
||||||
|
|
||||||
@Component({ |
|
||||||
selector: 'app-change-or', |
|
||||||
templateUrl: './change-or.component.html', |
|
||||||
styleUrls: ['./change-or.component.scss'], |
|
||||||
}) |
|
||||||
export class ChangeOrComponent implements OnInit { |
|
||||||
@Input() data?: any; |
|
||||||
@ViewChild('nzTreeComponent', { static: false }) |
|
||||||
nzTreeComponent!: NzTreeComponent; |
|
||||||
constructor( |
|
||||||
private modal: NzModalRef, |
|
||||||
private fb: FormBuilder, |
|
||||||
private http: HttpClient, |
|
||||||
private toTree: TreeService |
|
||||||
) {} |
|
||||||
|
|
||||||
defaultExpandedKeys = []; |
|
||||||
defaultSelectedKeys = []; |
|
||||||
ngOnInit(): void { |
|
||||||
this.getAllOrganization(); |
|
||||||
// this.nzTreeComponent.getCheckedNodeList()
|
|
||||||
} |
|
||||||
|
|
||||||
allOrList: any; |
|
||||||
nodes: any; |
|
||||||
getAllOrganization() { |
|
||||||
let params = { |
|
||||||
ContainsChildren: true, |
|
||||||
pageSize: 9999, |
|
||||||
}; |
|
||||||
this.http |
|
||||||
.get('/api/Organizations', { |
|
||||||
params: params, |
|
||||||
}) |
|
||||||
.subscribe((data: any) => { |
|
||||||
data.items.forEach((element) => { |
|
||||||
element.key = element.id; |
|
||||||
element.title = element.name; |
|
||||||
}); |
|
||||||
this.allOrList = data.items.filter((v) => !v.isGasStation); |
|
||||||
this.nodes = [...this.toTree.toTree(this.allOrList)]; |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
destroyModal(): void { |
|
||||||
this.modal.destroy({ data: 'this the result data' }); |
|
||||||
} |
|
||||||
} |
|
@ -1,148 +0,0 @@ |
|||||||
# The all in one config file. |
|
||||||
|
|
||||||
debug: false #when the debug is on, osd. |
|
||||||
video_record: 10 #time to record into the .ts video |
|
||||||
|
|
||||||
sources: |
|
||||||
config: 'config/source.yaml' |
|
||||||
|
|
||||||
tracker: |
|
||||||
config: 'config/dstest_tracker_config.txt' |
|
||||||
|
|
||||||
analytics: |
|
||||||
config: 'config/config_nvdsanalytics.txt' |
|
||||||
|
|
||||||
## 通用模型 ## |
|
||||||
|
|
||||||
# 1:人物检测 |
|
||||||
peoplenet: |
|
||||||
enable: true |
|
||||||
apply_on: -1 |
|
||||||
interval: 1 |
|
||||||
batch_size: 16 |
|
||||||
topk: 5 |
|
||||||
roi-top-offset: 0 |
|
||||||
roi-bottom-offset: 0 |
|
||||||
detected-min-w: 20 |
|
||||||
detected-min-h: 200 |
|
||||||
model_engine_file: '/opt/nvidia/deepstream/deepstream-6.0/sources/project/models/peoplenet/weights/resnet34_peoplenet_int8.etlt_b16_gpu0_int8.engine' |
|
||||||
threshold: 0.3 |
|
||||||
|
|
||||||
# 2:车辆检测 |
|
||||||
trafficcam: |
|
||||||
enable: true |
|
||||||
apply_on: 0 |
|
||||||
interval: 1 |
|
||||||
batch_size: 16 |
|
||||||
topk: 5 |
|
||||||
roi-top-offset: 0 |
|
||||||
roi-bottom-offset: 0 |
|
||||||
detected-min-w: 100 |
|
||||||
detected-min-h: 100 |
|
||||||
model_engine_file: '/opt/nvidia/deepstream/deepstream-6.0/sources/project/models/trafficcam/weights/resnet18_trafficcamnet_pruned.etlt_b16_gpu0_int8.engine' |
|
||||||
|
|
||||||
# 3:人物倚靠行为 |
|
||||||
actionnet: |
|
||||||
enable: false |
|
||||||
apply_on: 1 |
|
||||||
# roi: |
|
||||||
# - 'fuel_island-4': |
|
||||||
# - [200, 0, 450, 500] |
|
||||||
# - 'fuel_island-5': |
|
||||||
# - [930, 93, 940, 987] |
|
||||||
# - 'fuel_island-6': |
|
||||||
# - [1174, 151, 746, 929] |
|
||||||
# - 'fuel_island-7': |
|
||||||
# - [1450, 300, 460, 650] |
|
||||||
interval: 1 |
|
||||||
batch_size: 32 |
|
||||||
|
|
||||||
# 4:烟火检测 |
|
||||||
fire_smoke_net: |
|
||||||
enable: true |
|
||||||
apply_on: -1 |
|
||||||
interval: 1 |
|
||||||
batch_size: 16 |
|
||||||
model_engine_file: '/opt/nvidia/deepstream/deepstream-6.0/sources/project/models/fire_smoke_net/weights/yolov4_cspdarknet_tiny_fp16.etlt_b16_gpu0_fp16.engine' |
|
||||||
threshold: 0.95 |
|
||||||
|
|
||||||
# 5:抽烟打电话检测 |
|
||||||
smoking_calling_net: |
|
||||||
enable: true |
|
||||||
apply_on: -1 |
|
||||||
interval: 1 |
|
||||||
batch_size: 2 |
|
||||||
model_engine_file: '/opt/nvidia/deepstream/deepstream-6.0/sources/project/models/smoking_calling_net/weights/resnet50_smoking_calling_net_fp16.etlt_b2_gpu0_fp16.engine' |
|
||||||
|
|
||||||
## 油站专用模型 ## |
|
||||||
|
|
||||||
# 1:身份判别:工装、反光衣、便衣 |
|
||||||
idnet: |
|
||||||
enable: true |
|
||||||
apply_on: -1 |
|
||||||
interval: 1 |
|
||||||
batch_size: 2 |
|
||||||
model_engine_file: '/opt/nvidia/deepstream/deepstream-6.0/sources/project/models/idnet/weights/resnet50_idnet_fp16.etlt_b2_gpu0_fp16.engine' |
|
||||||
|
|
||||||
# 2:卸油区物体识别:油罐车、灭火器、手推车、三角木、取样桶、隔离锥、卸油管 |
|
||||||
oilnet: |
|
||||||
enable: false |
|
||||||
apply_on: 2 |
|
||||||
interval: 1 |
|
||||||
batch_size: 2 |
|
||||||
roi-top-offset: 0 |
|
||||||
roi-bottom-offset: 0 |
|
||||||
detected-min-w: 20 |
|
||||||
detected-min-h: 20 |
|
||||||
model_engine_file: '/opt/nvidia/deepstream/deepstream-6.0/sources/project/models/oilnet/weights/yolov4_cspdarknet_tiny_fp16.etlt_b2_gpu0_fp16.engine' |
|
||||||
threshold: 0.5 |
|
||||||
|
|
||||||
# 3:卸油管是否连接判定 |
|
||||||
connet_oil: |
|
||||||
enable: true |
|
||||||
apply_on: 2 |
|
||||||
roi: |
|
||||||
- 'oil_tube-0': |
|
||||||
# - [719,509,136,206] |
|
||||||
- [719,509,436,286] |
|
||||||
interval: 1 |
|
||||||
batch_size: 2 |
|
||||||
model_engine_file: '/opt/nvidia/deepstream/deepstream-6.0/sources/project/models/connet_oil/weights/resnet50_connet_oil_fp16.etlt_b2_gpu0_fp16.engine' |
|
||||||
|
|
||||||
# 4:静电接地仪器是否连接判定 |
|
||||||
connet_grounder: |
|
||||||
enable: true |
|
||||||
apply_on: 2 |
|
||||||
roi: |
|
||||||
- 'grounder-0': |
|
||||||
- [782,378,271,149] |
|
||||||
interval: 1 |
|
||||||
batch_size: 2 |
|
||||||
model_engine_file: '/opt/nvidia/deepstream/deepstream-6.0/sources/project/models/connet_grounder/weights/resnet50_connet_grounder_fp16.etlt_b2_gpu0_fp16.engine' |
|
||||||
|
|
||||||
# 5:散装桶加油 |
|
||||||
bulk_oil_net: |
|
||||||
enable: False |
|
||||||
apply_on: 2 |
|
||||||
interval: 1 |
|
||||||
batch_size: 2 |
|
||||||
model_engine_file: '/opt/nvidia/deepstream/deepstream-6.0/sources/project/models/bulk_oil_net/weights/yolov4_cspdarknet_tiny_fp16.etlt_b2_gpu0_fp16.engine' |
|
||||||
threshold: 0.2 |
|
||||||
|
|
||||||
# 模型阈值通用设定 |
|
||||||
rule_threshold: |
|
||||||
object_occurence_interval_second: 3 |
|
||||||
object_disappear_interval_second: 10 |
|
||||||
on_car_parking_interval_second: 1800 |
|
||||||
on_fire_smoke_interval_second: 5 |
|
||||||
on_helmet_interval_second: 5 |
|
||||||
threshold_relying_sitting: 0.4 #rolling mean confidence |
|
||||||
threshold_smoking_calling: 0.3 #rolling mean confidence |
|
||||||
threshold_connecting: 0.667 #rolling mean confidence |
|
||||||
threshold_identity: 0.1 #only to filter out people net error |
|
||||||
threshold_helmet: 0 #num of helmet detected on a person |
|
||||||
enable_seconday_model: False # secondary model (双模型) |
|
||||||
threshold_secondary_model: 0.5 |
|
||||||
secondary_model_window: 50 |
|
||||||
secondary_model_path: '/opt/app/xgboost' |
|
||||||
|
|
Before Width: | Height: | Size: 2.3 KiB |
Loading…
Reference in new issue