|
|
|
@ -1,4 +1,7 @@
|
|
|
|
|
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', |
|
|
|
@ -6,194 +9,679 @@ import { Component, OnInit } from '@angular/core';
|
|
|
|
|
styleUrls: ['./image-label.component.scss'] |
|
|
|
|
}) |
|
|
|
|
export class ImageLabelComponent implements OnInit { |
|
|
|
|
constructor(private http: HttpClient, private message: NzMessageService, private modal: NzModalService) { } |
|
|
|
|
|
|
|
|
|
constructor() { } |
|
|
|
|
|
|
|
|
|
imgItem: any; |
|
|
|
|
@Input() data: any; //传递id
|
|
|
|
|
camerasData: any; //摄像头Data
|
|
|
|
|
imgItem: any; //图片 URL
|
|
|
|
|
canvasWidth: number = 0; |
|
|
|
|
canvasHeight: number = 0; |
|
|
|
|
copyCanvas: any; |
|
|
|
|
markType: boolean = true; //标注type
|
|
|
|
|
copyCanvas: any; //拷贝 canvas底图
|
|
|
|
|
|
|
|
|
|
//返回上一步路由
|
|
|
|
|
goback() { |
|
|
|
|
history.go(-1) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ngOnInit(): void { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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', '获取图片失败!'); |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
anewgetImg() { |
|
|
|
|
let params = { |
|
|
|
|
cameraId: this.data |
|
|
|
|
} |
|
|
|
|
this.http.put('/api/Cameras/Commands/CaptureImages', '', { params: params }).subscribe( |
|
|
|
|
{ |
|
|
|
|
next: (value: Object) => { |
|
|
|
|
this.message.create('success', '向边缘设备发送请求成功,请过一段时间手动刷新页面!'); |
|
|
|
|
}, |
|
|
|
|
error: (error: HttpErrorResponse) => { |
|
|
|
|
|
|
|
|
|
}, |
|
|
|
|
complete: () => { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//获取 摄像头图片/标注点位
|
|
|
|
|
getImgMarkData() { |
|
|
|
|
let that = this |
|
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
|
that.http.get(`/api/Cameras/${that.data}`).subscribe((info: any) => { |
|
|
|
|
info.dimensionedPoints ? info.dimensionedPoints = JSON.parse(info.dimensionedPoints) : null; |
|
|
|
|
that.camerasData = info; |
|
|
|
|
that.markType = info.type; |
|
|
|
|
console.log(that.camerasData, "摄像头数据") |
|
|
|
|
const httpOptions = { |
|
|
|
|
responseType: 'blob' as 'json', |
|
|
|
|
params: { cameraId: that.data } |
|
|
|
|
}; |
|
|
|
|
that.http.get(`/api/Cameras/Images`, httpOptions).subscribe({ |
|
|
|
|
next: (data) => { |
|
|
|
|
resolve(data) |
|
|
|
|
}, |
|
|
|
|
error: (err) => { |
|
|
|
|
reject('error') |
|
|
|
|
}, |
|
|
|
|
}) //get
|
|
|
|
|
}) //get
|
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//保存
|
|
|
|
|
save() { |
|
|
|
|
console.log(this.camerasData.dimensionedPoints) |
|
|
|
|
if (!this.camerasData.dimensionedPoints) { |
|
|
|
|
this.camerasData.dimensionedPoints = { |
|
|
|
|
polygon: [], |
|
|
|
|
arrow: [], |
|
|
|
|
arrowOfSouth: [], |
|
|
|
|
arrowOfWest: [], |
|
|
|
|
arrowOfEast: [], |
|
|
|
|
arrowOfNorth: [], |
|
|
|
|
rectangle: [], |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (this.markType === 0) { |
|
|
|
|
if (!this.points.length) { |
|
|
|
|
this.message.create('warning', '绘制完整后可保存!'); |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
this.camerasData.dimensionedPoints.polygon = this.points |
|
|
|
|
} else if (this.markType === 2) { |
|
|
|
|
|
|
|
|
|
console.log(this.arrowPoints) |
|
|
|
|
|
|
|
|
|
if (this.arrowPoints.length == 1) { |
|
|
|
|
this.message.create('warning', '请将箭头标绘完整!'); |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (this.oblongPoints.length != 2 || !this.oblongPoints.find(item => { return item.oilUnloadingArea }) || !this.oblongPoints.find(item => { return !item.oilUnloadingArea })) { |
|
|
|
|
this.message.create('warning', '绘制完整后可保存!'); |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
this.camerasData.dimensionedPoints.arrow = this.arrowPoints |
|
|
|
|
|
|
|
|
|
this.camerasData.dimensionedPoints.arrowOfSouth = this.arrowPointsOfSouth |
|
|
|
|
this.camerasData.dimensionedPoints.arrowOfWest = this.arrowPointsOfWest |
|
|
|
|
this.camerasData.dimensionedPoints.arrowOfEast = this.arrowPointsOfEast |
|
|
|
|
this.camerasData.dimensionedPoints.arrowOfNorth = this.arrowPointsOfNorth |
|
|
|
|
|
|
|
|
|
this.camerasData.dimensionedPoints.rectangle = this.oblongPoints |
|
|
|
|
} else if (this.markType === 3) { |
|
|
|
|
if (this.arrowPoints.length != 2) { |
|
|
|
|
this.message.create('warning', '绘制完整后可保存!'); |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
this.camerasData.dimensionedPoints.arrow = this.arrowPoints |
|
|
|
|
this.camerasData.dimensionedPoints.arrowOfSouth = this.arrowPointsOfSouth |
|
|
|
|
} |
|
|
|
|
let paramsData = JSON.parse(JSON.stringify(this.camerasData)) |
|
|
|
|
paramsData.dimensionedPoints = JSON.stringify(paramsData.dimensionedPoints) |
|
|
|
|
console.log('标点结果', this.camerasData.dimensionedPoints) |
|
|
|
|
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(); |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//初始化背景图
|
|
|
|
|
canvas |
|
|
|
|
ctx |
|
|
|
|
initBackgroundImg() { |
|
|
|
|
let canvas = document.getElementById('canvas') as any; |
|
|
|
|
canvas.oncontextmenu = () =>{ return false; }; |
|
|
|
|
this.canvas = document.getElementById('canvas') as any; |
|
|
|
|
this.canvas.oncontextmenu = () => { return false; }; |
|
|
|
|
let that = this |
|
|
|
|
let ctx |
|
|
|
|
// 检测canvas支持性
|
|
|
|
|
if (canvas.getContext) { |
|
|
|
|
ctx = canvas.getContext('2d'); // 返回一个对象,该对象提供了用在画布上绘图的方法和属性
|
|
|
|
|
if (this.canvas.getContext) { |
|
|
|
|
this.ctx = this.canvas.getContext('2d'); // 返回一个对象,该对象提供了用在画布上绘图的方法和属性
|
|
|
|
|
} else { |
|
|
|
|
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 = that.imgItem ? that.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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
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) |
|
|
|
|
that.canvasWidth = img.width; |
|
|
|
|
that.canvasHeight = img.height; |
|
|
|
|
console.log(img.width + "*" + img.height) |
|
|
|
|
window.setTimeout(() => { // 加载图片
|
|
|
|
|
this.ctx.drawImage(img, 0, 0, that.canvasWidth, that.canvasHeight); |
|
|
|
|
this.copyCanvas = this.ctx.getImageData(0, 0, that.canvasWidth, that.canvasHeight) |
|
|
|
|
that.initCanvasEvent(this.canvas) //监听canvas事件
|
|
|
|
|
that.initMark(this.canvas, this.ctx) //初始化标绘图形
|
|
|
|
|
}, 0) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//线段的点的集合
|
|
|
|
|
points = []; |
|
|
|
|
points2 = []; |
|
|
|
|
//可拖动圆圈的点的集合
|
|
|
|
|
circles = []; |
|
|
|
|
circles2 = []; |
|
|
|
|
//整体移动点位
|
|
|
|
|
allpoints = []; |
|
|
|
|
allpoints2 = []; |
|
|
|
|
isDragging = false |
|
|
|
|
//是否在绘制区域内
|
|
|
|
|
isInOut = false |
|
|
|
|
|
|
|
|
|
clearCanvasItem(e, type) { |
|
|
|
|
e.stopPropagation() |
|
|
|
|
this.modal.confirm({ |
|
|
|
|
nzTitle: '确认要清除此标绘吗?', |
|
|
|
|
nzOkText: '确定', |
|
|
|
|
nzOkType: 'primary', |
|
|
|
|
nzOkDanger: true, |
|
|
|
|
nzOnOk: () => { |
|
|
|
|
// this.clearCanvas()
|
|
|
|
|
if (type == 'arrow') { |
|
|
|
|
this.arrowPoints = [] |
|
|
|
|
} |
|
|
|
|
if (type == 'arrowOfWest') { |
|
|
|
|
this.arrowPointsOfWest = [] |
|
|
|
|
} |
|
|
|
|
if (type == 'oilUnloadingAreaTrue') { |
|
|
|
|
for (let index = 0; index < this.oblongPoints.length; index++) { |
|
|
|
|
const element = this.oblongPoints[index]; |
|
|
|
|
if (element.oilUnloadingArea) { |
|
|
|
|
this.oblongPoints.splice(index, 1); |
|
|
|
|
index--; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (type == 'oilUnloadingAreaFalse') { |
|
|
|
|
for (let index = 0; index < this.oblongPoints.length; index++) { |
|
|
|
|
const element = this.oblongPoints[index]; |
|
|
|
|
if (!element.oilUnloadingArea) { |
|
|
|
|
this.oblongPoints.splice(index, 1); |
|
|
|
|
index--; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
console.log(this.camerasData.dimensionedPoints) |
|
|
|
|
this.initMark2(this.canvas, this.ctx) //初始化标绘图形
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
|
nzCancelText: '取消', |
|
|
|
|
nzOnCancel: () => console.log('Cancel') |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//初始化标绘图形
|
|
|
|
|
initMark(canvas, context) { |
|
|
|
|
if (!this.camerasData.dimensionedPoints) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
if (this.markType === 0) { |
|
|
|
|
this.camerasData.dimensionedPoints.polygon.forEach(element => { |
|
|
|
|
this.drawPolygon(element.x, element.y, canvas, context); //绘制多边形
|
|
|
|
|
}); |
|
|
|
|
} else if (this.markType === 2) { |
|
|
|
|
this.arrowPoints = this.camerasData.dimensionedPoints.arrow |
|
|
|
|
if (this.camerasData.dimensionedPoints.arrowOfSouth && this.camerasData.dimensionedPoints.arrowOfSouth.length != 0) { |
|
|
|
|
this.arrowPointsOfSouth = this.camerasData.dimensionedPoints.arrowOfSouth |
|
|
|
|
} |
|
|
|
|
if (this.camerasData.dimensionedPoints.arrowOfWest && this.camerasData.dimensionedPoints.arrowOfWest.length != 0) { |
|
|
|
|
this.arrowPointsOfWest = this.camerasData.dimensionedPoints.arrowOfWest |
|
|
|
|
} |
|
|
|
|
if (this.camerasData.dimensionedPoints.arrowOfEast && this.camerasData.dimensionedPoints.arrowOfEast.length != 0) { |
|
|
|
|
this.arrowPointsOfEast = this.camerasData.dimensionedPoints.arrowOfEast |
|
|
|
|
} |
|
|
|
|
if (this.camerasData.dimensionedPoints.arrowOfNorth && this.camerasData.dimensionedPoints.arrowOfNorth.length != 0) { |
|
|
|
|
this.arrowPointsOfNorth = this.camerasData.dimensionedPoints.arrowOfNorth |
|
|
|
|
} |
|
|
|
|
this.oblongPoints = this.camerasData.dimensionedPoints.rectangle |
|
|
|
|
let arr = [this.arrowPoints, this.arrowPointsOfSouth, this.arrowPointsOfWest, this.arrowPointsOfEast, this.arrowPointsOfNorth] |
|
|
|
|
this.drawLine(arr, context) |
|
|
|
|
} else if (this.markType === 3) { |
|
|
|
|
this.arrowPoints = this.camerasData.dimensionedPoints.arrow |
|
|
|
|
if (this.camerasData.dimensionedPoints.arrowOfSouth && this.camerasData.dimensionedPoints.arrowOfSouth.length != 0) { |
|
|
|
|
this.arrowPointsOfSouth = this.camerasData.dimensionedPoints.arrowOfSouth |
|
|
|
|
} |
|
|
|
|
let arr = [this.arrowPoints, this.arrowPointsOfSouth] |
|
|
|
|
this.drawLine(arr, context) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//初始化标绘图形
|
|
|
|
|
initMark2(canvas, context) { |
|
|
|
|
if (this.markType === 2) { |
|
|
|
|
let arr = [this.arrowPoints, this.arrowPointsOfSouth, this.arrowPointsOfWest, this.arrowPointsOfEast, this.arrowPointsOfNorth] |
|
|
|
|
this.drawLine(arr, context) |
|
|
|
|
} else if (this.markType === 3) { |
|
|
|
|
let arr = [this.arrowPoints, this.arrowPointsOfSouth] |
|
|
|
|
this.drawLine(arr, context) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
markType: number = 0; //0=进出口,2=卸油区,3=便利店,
|
|
|
|
|
isDrawArrow: boolean = true; //绘制type 箭头/矩形
|
|
|
|
|
arrowDirection = null |
|
|
|
|
oilUnloadingArea: boolean = true; //卸油区type 泄油管区域/静电接地仪
|
|
|
|
|
//记录鼠标点击位置
|
|
|
|
|
downx = 0 |
|
|
|
|
downy = 0 |
|
|
|
|
downx = 0; |
|
|
|
|
downy = 0; |
|
|
|
|
|
|
|
|
|
//清空画布
|
|
|
|
|
clearCanvas() { |
|
|
|
|
// 清空标绘箭头
|
|
|
|
|
this.arrowPoints = []; |
|
|
|
|
this.arrowPointsOfSouth = []; //南 箭头的点的集合
|
|
|
|
|
this.arrowPointsOfWest = []; //西 箭头的点的集合
|
|
|
|
|
this.arrowPointsOfEast = []; //东 箭头的点的集合
|
|
|
|
|
this.arrowPointsOfNorth = []; //北 箭头的点的集合
|
|
|
|
|
// 清空标绘箭头
|
|
|
|
|
// 清空标绘矩形
|
|
|
|
|
this.oblongPoints = []; |
|
|
|
|
// 清空标绘矩形
|
|
|
|
|
// 清空标绘多边形
|
|
|
|
|
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画布 点击事件
|
|
|
|
|
//初始化 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); |
|
|
|
|
canvas.onmousedown = (e) => { //鼠标按下事件
|
|
|
|
|
var clickX = e.pageX - canvas.offsetLeft; |
|
|
|
|
var clickY = e.pageY - canvas.offsetTop; |
|
|
|
|
this.downx = clickX |
|
|
|
|
this.downy = clickY |
|
|
|
|
if (this.isInt(clickX, clickY)) { |
|
|
|
|
this.isInOut = true |
|
|
|
|
return |
|
|
|
|
} else { |
|
|
|
|
this.isInOut = false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
//遍历数组画圆
|
|
|
|
|
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]; |
|
|
|
|
// 绘制圆圈
|
|
|
|
|
context.globalAlpha = 0.85; |
|
|
|
|
|
|
|
|
|
if (this.markType === 0) { //进出口
|
|
|
|
|
this.drawPolygon(clickX, clickY, canvas, context); //绘制多边形
|
|
|
|
|
} else if (this.markType === 2 || this.markType === 3) { //卸油区/便利店
|
|
|
|
|
//开始绘制
|
|
|
|
|
context.beginPath(); |
|
|
|
|
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2); |
|
|
|
|
context.fillStyle = circle.color; |
|
|
|
|
context.strokeStyle = "black"; |
|
|
|
|
context.fill(); |
|
|
|
|
context.stroke(); |
|
|
|
|
} |
|
|
|
|
// 画线
|
|
|
|
|
var point = { |
|
|
|
|
x: clickX, |
|
|
|
|
y: clickY, |
|
|
|
|
}; |
|
|
|
|
this.markType? this.points.push(point) : this.points2.push(point) |
|
|
|
|
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; |
|
|
|
|
if (this.isDrawArrow && !this.arrowDirection) { //绘制 箭头
|
|
|
|
|
if (this.arrowPoints.length === 2) { //限制数量
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
context.lineTo(moveX, moveY); |
|
|
|
|
context.stroke(); |
|
|
|
|
} else if (this.isDrawArrow && this.arrowDirection == 'South') { |
|
|
|
|
if (this.arrowPointsOfSouth.length === 2) { //限制数量
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
context.lineTo(moveX, moveY); |
|
|
|
|
context.stroke(); |
|
|
|
|
} else if (this.isDrawArrow && this.arrowDirection == 'West') { |
|
|
|
|
if (this.arrowPointsOfWest.length === 2) { //限制数量
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
context.lineTo(moveX, moveY); |
|
|
|
|
context.stroke(); |
|
|
|
|
} else if (this.isDrawArrow && this.arrowDirection == 'East') { |
|
|
|
|
if (this.arrowPointsOfEast.length === 2) { //限制数量
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
context.lineTo(moveX, moveY); |
|
|
|
|
context.stroke(); |
|
|
|
|
} else if (this.isDrawArrow && this.arrowDirection == 'North') { |
|
|
|
|
if (this.arrowPointsOfNorth.length === 2) { //限制数量
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
context.lineTo(moveX, moveY); |
|
|
|
|
context.stroke(); |
|
|
|
|
} else { //绘制 矩形
|
|
|
|
|
if (this.oblongPoints.length === 2) { //限制数量
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
this.drawOblong(this.oblongPoints, context) |
|
|
|
|
context.strokeStyle = this.oilUnloadingArea ? "green" : "red"; |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
canvas.onmouseup = (e) => { //鼠标松开事件
|
|
|
|
|
canvas.onmousemove = (ev) => { //鼠标移动事件
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if (this.markType != 2 && this.markType != 3) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
var upX = e.pageX - canvas.offsetLeft; |
|
|
|
|
var upY = e.pageY - canvas.offsetTop; |
|
|
|
|
if (this.isDrawArrow && !this.arrowDirection) { //绘制 箭头
|
|
|
|
|
if (this.arrowPoints.length === 2) { //限制数量
|
|
|
|
|
this.message.create('warning', '绘制数量已达上限!'); |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
let point = { |
|
|
|
|
startX: this.downx, |
|
|
|
|
startY: this.downy, |
|
|
|
|
endX: upX, |
|
|
|
|
endY: upY, |
|
|
|
|
} |
|
|
|
|
this.arrowPoints.push(point); |
|
|
|
|
let arr = [this.arrowPoints, this.arrowPointsOfSouth, this.arrowPointsOfWest, this.arrowPointsOfEast, this.arrowPointsOfNorth] |
|
|
|
|
this.drawLine(arr, context) |
|
|
|
|
} else if (this.isDrawArrow && this.arrowDirection == 'South') { |
|
|
|
|
if (this.arrowPointsOfSouth.length === 2) { //限制数量
|
|
|
|
|
this.message.create('warning', '绘制数量已达上限!'); |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
let point = { |
|
|
|
|
startX: this.downx, |
|
|
|
|
startY: this.downy, |
|
|
|
|
endX: upX, |
|
|
|
|
endY: upY, |
|
|
|
|
} |
|
|
|
|
this.arrowPointsOfSouth.push(point); |
|
|
|
|
let arr = [this.arrowPoints, this.arrowPointsOfSouth, this.arrowPointsOfWest, this.arrowPointsOfEast, this.arrowPointsOfNorth] |
|
|
|
|
this.drawLine(arr, context) |
|
|
|
|
} else if (this.isDrawArrow && this.arrowDirection == 'West') { |
|
|
|
|
if (this.arrowPointsOfWest.length === 2) { //限制数量
|
|
|
|
|
this.message.create('warning', '绘制数量已达上限!'); |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
let point = { |
|
|
|
|
startX: this.downx, |
|
|
|
|
startY: this.downy, |
|
|
|
|
endX: upX, |
|
|
|
|
endY: upY, |
|
|
|
|
} |
|
|
|
|
this.arrowPointsOfWest.push(point); |
|
|
|
|
let arr = [this.arrowPoints, this.arrowPointsOfSouth, this.arrowPointsOfWest, this.arrowPointsOfEast, this.arrowPointsOfNorth] |
|
|
|
|
this.drawLine(arr, context) |
|
|
|
|
} else if (this.isDrawArrow && this.arrowDirection == 'East') { |
|
|
|
|
console.log('East') |
|
|
|
|
if (this.arrowPointsOfEast.length === 2) { //限制数量
|
|
|
|
|
this.message.create('warning', '绘制数量已达上限!'); |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
let point = { |
|
|
|
|
startX: this.downx, |
|
|
|
|
startY: this.downy, |
|
|
|
|
endX: upX, |
|
|
|
|
endY: upY, |
|
|
|
|
} |
|
|
|
|
this.arrowPointsOfEast.push(point); |
|
|
|
|
let arr = [this.arrowPoints, this.arrowPointsOfSouth, this.arrowPointsOfWest, this.arrowPointsOfEast, this.arrowPointsOfNorth] |
|
|
|
|
this.drawLine(arr, context) |
|
|
|
|
} else if (this.isDrawArrow && this.arrowDirection == 'North') { |
|
|
|
|
console.log('North') |
|
|
|
|
if (this.arrowPointsOfNorth.length === 2) { //限制数量
|
|
|
|
|
this.message.create('warning', '绘制数量已达上限!'); |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
let point = { |
|
|
|
|
startX: this.downx, |
|
|
|
|
startY: this.downy, |
|
|
|
|
endX: upX, |
|
|
|
|
endY: upY, |
|
|
|
|
} |
|
|
|
|
this.arrowPointsOfNorth.push(point); |
|
|
|
|
let arr = [this.arrowPoints, this.arrowPointsOfSouth, this.arrowPointsOfWest, this.arrowPointsOfEast, this.arrowPointsOfNorth] |
|
|
|
|
this.drawLine(arr, context) |
|
|
|
|
} else { //绘制 矩形
|
|
|
|
|
if (this.oblongPoints.length === 2) { //限制数量
|
|
|
|
|
this.message.create('warning', '绘制数量已达上限!'); |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
let point = this.getOblongInfo(this.downx, this.downy, upX, upY) |
|
|
|
|
this.oblongPoints.push(point) |
|
|
|
|
this.drawOblong(this.oblongPoints, context) |
|
|
|
|
} |
|
|
|
|
console.log(this.camerasData.dimensionedPoints) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
arrowPoints = []; //箭头的点的集合
|
|
|
|
|
|
|
|
|
|
arrowPointsOfSouth = []; //南 箭头的点的集合
|
|
|
|
|
arrowPointsOfWest = []; //西 箭头的点的集合
|
|
|
|
|
arrowPointsOfEast = []; //东 箭头的点的集合
|
|
|
|
|
arrowPointsOfNorth = []; //北 箭头的点的集合
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//canvas 绘制直线
|
|
|
|
|
drawLine(pointsList, context, isRepeat: boolean = false) { |
|
|
|
|
context.clearRect(0, 0, this.canvasWidth, this.canvasHeight); |
|
|
|
|
this.copyCanvas ? context.putImageData(this.copyCanvas, 0, 0) : null; |
|
|
|
|
if (this.markType === 2 && !isRepeat) { //同时绘制 矩形
|
|
|
|
|
this.oblongPoints.forEach(element => { |
|
|
|
|
context.strokeStyle = element.oilUnloadingArea ? "green" : "red"; |
|
|
|
|
context.lineWidth = 3; |
|
|
|
|
context.strokeRect(element.x, element.y, element.width, element.height); |
|
|
|
|
context.font = '22px Arial'; |
|
|
|
|
context.fillText('高度:' + element.height, element.x + 3, element.y + 22); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
// console.log(789, pointsList)
|
|
|
|
|
pointsList.forEach(element => { |
|
|
|
|
if (element.length != 0) { |
|
|
|
|
element.forEach((item, index) => { |
|
|
|
|
if ((index + 1) % 2 === 0) { |
|
|
|
|
this.drawArrow(item.startX, item.startY, item.endX, item.endY, 30, 10, 3, 'green', context) |
|
|
|
|
} else { |
|
|
|
|
context.beginPath(); |
|
|
|
|
context.moveTo(item.startX, item.startY); |
|
|
|
|
context.strokeStyle = "green"; |
|
|
|
|
context.lineWidth = 3; |
|
|
|
|
context.lineTo(item.endX, item.endY); |
|
|
|
|
context.stroke(); |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//canvas 绘制箭头
|
|
|
|
|
drawArrow(fromX, fromY, toX, toY, theta, headlen, width, color, ctx) { |
|
|
|
|
// fromX, fromY:起点坐标(也可以换成p1,只不过它是一个数组)
|
|
|
|
|
// toX, toY:终点坐标 (也可以换成p2,只不过它是一个数组)
|
|
|
|
|
// theta:三角斜边一直线夹角
|
|
|
|
|
// headlen:三角斜边长度
|
|
|
|
|
// width:箭头线宽度
|
|
|
|
|
// color:箭头颜色
|
|
|
|
|
|
|
|
|
|
theta = typeof (theta) != 'undefined' ? theta : 30; |
|
|
|
|
headlen = typeof (theta) != 'undefined' ? headlen : 10; |
|
|
|
|
width = typeof (width) != 'undefined' ? width : 1; |
|
|
|
|
color = typeof (color) != 'undefined' ? color : '#000'; |
|
|
|
|
|
|
|
|
|
// 计算各角度和对应的P2,P3坐标
|
|
|
|
|
var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI, |
|
|
|
|
angle1 = (angle + theta) * Math.PI / 180, |
|
|
|
|
angle2 = (angle - theta) * Math.PI / 180, |
|
|
|
|
topX = headlen * Math.cos(angle1), |
|
|
|
|
topY = headlen * Math.sin(angle1), |
|
|
|
|
botX = headlen * Math.cos(angle2), |
|
|
|
|
botY = headlen * Math.sin(angle2); |
|
|
|
|
ctx.save(); |
|
|
|
|
ctx.beginPath(); |
|
|
|
|
|
|
|
|
|
var arrowX = fromX - topX, |
|
|
|
|
arrowY = fromY - topY; |
|
|
|
|
|
|
|
|
|
ctx.moveTo(arrowX, arrowY); |
|
|
|
|
ctx.moveTo(fromX, fromY); |
|
|
|
|
ctx.lineTo(toX, toY); |
|
|
|
|
arrowX = toX + topX; |
|
|
|
|
arrowY = toY + topY; |
|
|
|
|
ctx.moveTo(arrowX, arrowY); |
|
|
|
|
ctx.lineTo(toX, toY); |
|
|
|
|
arrowX = toX + botX; |
|
|
|
|
arrowY = toY + botY; |
|
|
|
|
ctx.lineTo(arrowX, arrowY); |
|
|
|
|
ctx.strokeStyle = color; |
|
|
|
|
ctx.lineWidth = width; |
|
|
|
|
ctx.stroke(); |
|
|
|
|
ctx.restore(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
oblongPoints = []; //矩形的点的集合
|
|
|
|
|
|
|
|
|
|
//获取 矩形左上角点位/宽高
|
|
|
|
|
getOblongInfo(startX, startY, endX, endY) { |
|
|
|
|
let point = { |
|
|
|
|
x: 0, |
|
|
|
|
y: 0, |
|
|
|
|
width: 0, |
|
|
|
|
height: 0, |
|
|
|
|
oilUnloadingArea: this.oilUnloadingArea, |
|
|
|
|
} |
|
|
|
|
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 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//canvas 绘制矩形
|
|
|
|
|
drawOblong(oblongList, context) { |
|
|
|
|
context.clearRect(0, 0, this.canvasWidth, this.canvasHeight); |
|
|
|
|
this.copyCanvas ? context.putImageData(this.copyCanvas, 0, 0) : null; |
|
|
|
|
if (this.markType === 2) { //同时绘制 直线箭头
|
|
|
|
|
let arr = [this.arrowPoints, this.arrowPointsOfSouth, this.arrowPointsOfWest, this.arrowPointsOfEast, this.arrowPointsOfNorth] |
|
|
|
|
this.drawLine(arr, context, true) |
|
|
|
|
} |
|
|
|
|
oblongList.forEach(element => { |
|
|
|
|
context.strokeStyle = element.oilUnloadingArea ? "green" : "red"; |
|
|
|
|
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.closePath() |
|
|
|
|
context.fillStyle = "rgb(2,100,30)"; |
|
|
|
|
context.strokeRect(element.x, element.y, element.width, element.height); |
|
|
|
|
context.font = '22px Arial'; |
|
|
|
|
context.fillText('高度:' + element.height, element.x + 3, element.y + 22); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
points = []; //线段的点的集合
|
|
|
|
|
circles = []; //可拖动圆圈的点的集合
|
|
|
|
|
allpoints = []; //整体移动点位
|
|
|
|
|
isDragging = false; //是否可拖拽
|
|
|
|
|
isInOut = false; //是否在绘制区域内
|
|
|
|
|
|
|
|
|
|
//canvas 绘制多边形
|
|
|
|
|
drawPolygon(clickX, clickY, canvas, context) { |
|
|
|
|
if (this.isInt(clickX, clickY)) { |
|
|
|
|
this.isInOut = true |
|
|
|
|
return |
|
|
|
|
} else { |
|
|
|
|
this.isInOut = false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let index |
|
|
|
|
//判断当前点击点是否在已经绘制的圆圈上,如果是执行相关操作,并return,不进入画线的代码
|
|
|
|
|
for (var i = 0; i < this.circles.length; i++) { |
|
|
|
|
let circle = this.circles[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); |
|
|
|
|
this.copyCanvas ? context.putImageData(this.copyCanvas, 0, 0) : null; |
|
|
|
|
//遍历数组画圆
|
|
|
|
|
var circle = { |
|
|
|
|
x: clickX, |
|
|
|
|
y: clickY, |
|
|
|
|
radius: 5, |
|
|
|
|
color: "white", |
|
|
|
|
isSelected: false, //拖拽点的标记
|
|
|
|
|
}; |
|
|
|
|
this.circles.push(circle); |
|
|
|
|
this.allpoints = JSON.parse(JSON.stringify(this.circles)) |
|
|
|
|
this.circles[0].color = "white"; |
|
|
|
|
for (var i = 0; i < this.circles.length; i++) { |
|
|
|
|
let circle = this.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 = "red"; |
|
|
|
|
context.fill(); |
|
|
|
|
context.strokeStyle = "#9d4dca"; |
|
|
|
|
context.stroke(); |
|
|
|
|
} |
|
|
|
|
// 画线
|
|
|
|
|
var point = { |
|
|
|
|
x: clickX, |
|
|
|
|
y: clickY, |
|
|
|
|
}; |
|
|
|
|
this.points.push(point) |
|
|
|
|
context.beginPath(); |
|
|
|
|
context.lineWidth = 3; |
|
|
|
|
//从起始点开始绘制
|
|
|
|
|
context.moveTo(this.points[0].x, this.points[0].y); |
|
|
|
|
for (var i = 0; i < this.points.length; i++) { |
|
|
|
|
context.lineTo(this.points[i].x, this.points[i].y); |
|
|
|
|
} |
|
|
|
|
context.closePath() |
|
|
|
|
//ontext.fillStyle = "rgb(2,100,30)";
|
|
|
|
|
//context.fill();
|
|
|
|
|
context.strokeStyle = "green"; |
|
|
|
|
context.stroke(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//判断点位是否在图形区域内
|
|
|
|
|
isInt(x, y) { |
|
|
|
|
if (this.markType && !this.points[2]) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
if (!this.markType && !this.points2[2]) { |
|
|
|
|
if (!this.points[2]) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
var pt = { |
|
|
|
|
x: x, |
|
|
|
|
y: y |
|
|
|
|
} |
|
|
|
|
var poly = this.markType? this.points : this.points2; |
|
|
|
|
return this.PointInPoly(pt, poly) |
|
|
|
|
return this.PointInPoly(pt, this.points) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//射线法判断点位
|
|
|
|
@ -204,13 +692,4 @@ export class ImageLabelComponent implements OnInit {
|
|
|
|
|
&& (c = !c); |
|
|
|
|
return c; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//cneter height
|
|
|
|
|
heightCount() { |
|
|
|
|
let style: any = {} |
|
|
|
|
let height = document.documentElement.clientHeight |
|
|
|
|
style.height = (height - 180) + 'px'; |
|
|
|
|
return style |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|