Skip to content

Commit

Permalink
feat: PolygonTool add combining operation
Browse files Browse the repository at this point in the history
  • Loading branch information
lihqi committed Jun 8, 2022
1 parent 368a59f commit 56bb126
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 18 deletions.
116 changes: 115 additions & 1 deletion packages/lb-annotation/src/core/toolOperation/polygonOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import StyleUtils from '../../utils/tool/StyleUtils';
import uuid from '../../utils/uuid';
import { BasicToolOperation, IBasicToolOperationProps } from './basicToolOperation';
import TextAttributeClass from './textAttributeClass';
import { i18n } from '@labelbee/lb-utils';

const TEXT_MAX_WIDTH = 164;

Expand All @@ -49,6 +50,8 @@ class PolygonOperation extends BasicToolOperation {

public pattern: EPolygonPattern; // 当前多边形标注形式

public isCombined: boolean; // 是否开启合并操作

private dragInfo?: {
dragStartCoord: ICoordinate;
initPointList: IPolygonPoint[];
Expand All @@ -75,6 +78,7 @@ class PolygonOperation extends BasicToolOperation {
this.drawingHistory = new ActionsHistory();
this.isCtrl = false;
this.isAlt = false;
this.isCombined = false;
this.pattern = EPolygonPattern.Normal;

this.getCurrentSelectedData = this.getCurrentSelectedData.bind(this);
Expand Down Expand Up @@ -711,6 +715,11 @@ class PolygonOperation extends BasicToolOperation {
break;

case EKeyCode.Z:
if (e.altKey) {
this.onCombinedExecute();
return;
}

this.setIsHidden(!this.isHidden);
this.render();
break;
Expand Down Expand Up @@ -980,9 +989,63 @@ class PolygonOperation extends BasicToolOperation {
newPolygonList = newPolygonList.filter((v) => v.id !== this.selectedID);
}
this.setPolygonList(newPolygonList);
this.history.pushHistory(newPolygonList);
this.render();
}

public onCombinedExecute() {
if (!this.selectedID) {
this.emit('messageInfo', i18n.t('PolygonsToBeCombinedNeedToBeSelected'));
return;
}
this.isCombined = !this.isCombined;
}

public combine(e: MouseEvent) {
// 没有选中和 hover 都退出
const hoverID = this.getHoverID(e);
if (!hoverID || !this.selectedID || this.selectedID === hoverID) {
return;
}

if (this.config?.lineType !== ELineTypes.Line) {
this.emit('messageInfo', i18n.t('CurveModeDoesNotSupportCutting'));
return;
}

const selectedPolygon = this.polygonList.find((v) => v.id === this.selectedID);
const combinedPolygon = this.currentShowList.find((v) => v.id === hoverID);
if (!combinedPolygon || !selectedPolygon) {
return;
}

const composeData = PolygonUtils.combinePolygonWithPolygon(selectedPolygon, combinedPolygon);

if (!composeData) {
return;
}

const { newPolygon, unionList } = composeData;
if (unionList.length === 1 && newPolygon) {
const newPolygonList = this.polygonList
.filter((v) => !unionList.includes(v.id))
.map((v) => {
if (v.id === this.selectedID) {
return newPolygon;
}

return v;
});
this.setPolygonList(newPolygonList);
this.history.pushHistory(newPolygonList);
this.render();

this.emit('messageInfo', i18n.t('CombineSuccess'));
} else {
this.emit('messageInfo', i18n.t('CombiningFailedNotify'));
}
this.isCombined = false;
}
/**
* 判断是否在边界外
* @param selectedPointList
Expand Down Expand Up @@ -1202,6 +1265,20 @@ class PolygonOperation extends BasicToolOperation {
}

public onMouseUp(e: MouseEvent) {
if (this.isCombined) {
switch (e.button) {
case 0:
this.combine(e);
break;

case 2:
this.isCombined = false;
break;
}

return;
}

if (super.onMouseUp(e) || this.forbidMouseOperation || !this.imgInfo) {
return undefined;
}
Expand Down Expand Up @@ -1531,10 +1608,47 @@ class PolygonOperation extends BasicToolOperation {
}

super.render();
this.renderCursorLine(this.getLineColor(this.defaultAttribute));
this.renderPolygon();
this.renderCursorLine(this.getLineColor(this.defaultAttribute));
}

public renderCursorLine(lineColor: string) {
super.renderCursorLine(lineColor);
if (this.isCombined) {
const { x, y } = this.coord;
const padding = 10; // 框的边界
const rectWidth = 186; // 框的宽度
const rectHeight = 32; // 框的高度
DrawUtils.drawRectWithFill(
this.canvas,
{
x: x + padding,
y: y - padding * 4 - 1,
width: rectWidth,
height: rectHeight,
} as IRect,
{ color: 'black' },
);

DrawUtils.drawText(this.canvas, { x, y }, i18n.t('ClickAnotherPolygon'), {
textAlign: 'center',
color: 'white',
offsetX: rectWidth / 2 + padding,
offsetY: -(rectHeight / 2 + padding / 2),
});

DrawUtils.drawRect(
this.canvas,
{
x: x - padding,
y: y - padding,
width: padding * 2,
height: padding * 2,
} as IRect,
{ lineDash: [6], color: 'white' },
);
}
}
/** 撤销 */
public undo() {
if (this.drawingPointList.length > 0) {
Expand Down
56 changes: 49 additions & 7 deletions packages/lb-annotation/src/utils/tool/PolygonUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ import { ELineTypes, SEGMENT_NUMBER } from '../../constant/tool';
import AxisUtils from './AxisUtils';
import MathUtils from '../MathUtils';
import LineToolUtils from './LineToolUtils';
import { difference, polygon } from '@turf/turf';

declare interface IAxis {
x: number;
y: number;
}
import { difference, polygon, union } from '@turf/turf';

export default class PolygonUtils {
static getHoverPolygonID(
Expand Down Expand Up @@ -649,7 +644,7 @@ export default class PolygonUtils {
/**
* 获取当前点与多边形点集最近的点,并返回 Index
*/
public static getClosePointDistanceFromPolygon(point: IAxis, pointList: IPolygonPoint[]) {
public static getClosePointDistanceFromPolygon(point: ICoordinate, pointList: IPolygonPoint[]) {
let minLen = Number.MAX_SAFE_INTEGER;
let index = -1;

Expand All @@ -663,4 +658,51 @@ export default class PolygonUtils {

return index;
}

/**
* 多边形合成多边形
* @param selectedPolygon
* @param combinedPolygon
*/
public static combinePolygonWithPolygon(
selectedPolygon: IPolygonData,
combinedPolygon: IPolygonData,
):
| {
newPolygon: IPolygonData;
unionList: string[];
}
| undefined {
try {
let turfSelectedPolygon = polygon([
[...PolygonUtils.concatBeginAndEnd(selectedPolygon.pointList.map((v) => [v.x, v.y]))],
]);
const turfCombinedPolygon = polygon([
[...PolygonUtils.concatBeginAndEnd(combinedPolygon.pointList.map((v) => [v.x, v.y]))],
]);
const unionPolygon = union(turfSelectedPolygon, turfCombinedPolygon);
const unionList: string[] = [];
let newPolygon = selectedPolygon;
if (unionPolygon?.geometry?.coordinates?.length === 1) {
unionList.push(combinedPolygon.id);
const pointList = unionPolygon?.geometry.coordinates.map((polygon) => {
// 多边形需要另外判断
if (unionPolygon?.geometry?.type === 'MultiPolygon') {
//@ts-ignore
return polygon[0].reduce(PolygonUtils.deletePolygonLastPoint, []);
}
//@ts-ignore
return polygon.reduce(PolygonUtils.deletePolygonLastPoint, []);
})[0];
newPolygon.pointList = pointList;
}

return {
newPolygon,
unionList,
};
} catch (e) {
console.error(e);
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import DrawPolygonSvg from '@/assets/annotation/toolHotKeyIcon/icon_line_kj.svg'
import DrawInvalidPolygonSvg from '@/assets/annotation/toolHotKeyIcon/icon_polygonNull_kj.svg'
import SelectedPolygonSvg from '@/assets/annotation/toolHotKeyIcon/icon_polygonActive_kj.svg'
import ChangePolygonAttribute from '@/assets/annotation/toolHotKeyIcon/icon_polygonChange_kj.svg'
import DeletePolygonSvg from '@/assets/annotation/toolHotKeyIcon/icon_polygonDel_kj.svg'
import MouseLeftSvg from '@/assets/annotation/toolHotKeyIcon/icon_mouse_left_kj.svg'
import DrawPolygonSvg from '@/assets/annotation/toolHotKeyIcon/icon_line_kj.svg';
import DrawInvalidPolygonSvg from '@/assets/annotation/toolHotKeyIcon/icon_polygonNull_kj.svg';
import SelectedPolygonSvg from '@/assets/annotation/toolHotKeyIcon/icon_polygonActive_kj.svg';
import ChangePolygonAttribute from '@/assets/annotation/toolHotKeyIcon/icon_polygonChange_kj.svg';
import DeletePolygonSvg from '@/assets/annotation/toolHotKeyIcon/icon_polygonDel_kj.svg';
import MouseLeftSvg from '@/assets/annotation/toolHotKeyIcon/icon_mouse_left_kj.svg';
import MouseRightSvg from '@/assets/annotation/toolHotKeyIcon/icon_mouse_right_kj.svg';

import IconLineContKj from '@/assets/annotation/toolHotKeyIcon/icon_lineCont_kj.svg';
import IconPolygonInsertKj from '@/assets/annotation/toolHotKeyIcon/icon_polygonInsert_kj.svg';
import IconUnGripKj from '@/assets/annotation/toolHotKeyIcon/icon_unGrip_kj.svg';
import IconPointSpecialKj from '@/assets/annotation/toolHotKeyIcon/icon_pointSpecial_kj.svg';
import IconSegment from '@/assets/annotation/toolHotKeyIcon/icon_segment.svg';
import IconPolygonMerge from '@/assets/annotation/toolHotKeyIcon/icon_polygonMerge_kj.svg';
import IconAI from '@/assets/annotation/toolHotKeyIcon/icon_AI.svg';
import IconSwapOutlined from '@/assets/annotation/toolHotKeyIcon/icon_swap_outlined.svg';

Expand All @@ -32,7 +33,7 @@ import {
// hidden,
// changeSpecialLine,
// saveResult,
dargWithLeftClick
dargWithLeftClick,
} from '../common';

export const polygon = {
Expand Down Expand Up @@ -107,6 +108,13 @@ export const splitPolygon = {
shortCut: ['ALT', 'X'],
};

export const combinePolygon = {
name: 'CombineOverlapArea',
icon: IconPolygonMerge,
noticeInfo: '',
shortCut: ['Alt', 'Z'],
};

export const segmentByAlgorithm = {
name: 'SegmentationRecognition',
icon: IconAI,
Expand Down Expand Up @@ -152,6 +160,7 @@ const pointToolShortCutTable = [
tabChangeSelected,
tabReverseChangeSelected,
// changeRenderPattern,
combinePolygon,
splitPolygon,
];
export default pointToolShortCutTable;
18 changes: 15 additions & 3 deletions packages/lb-utils/src/i18n/resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,13 @@
"imageInvalidAndSkip": "Image invalid, please skip",
"videoErrorAndReload": "Failed to load video, please reload",
"imageErrorAndReload": "Failed to load image, please reload",
"orMaskAsInvalid": " or mask it as invalid"
"orMaskAsInvalid": " or mask it as invalid",
"ClickAnotherPolygon": "Click another polygon",
"PolygonsToBeCombinedNeedToBeSelected": "Polygons to be combined need to be selected",
"CurveModeDoesNotSupportCutting": "Curve mode does not support cutting",
"CombineSuccess": "Combine success",
"CombiningFailedNotify": "Combining failed. Please check whether two polygons intersect or whether polygon combining forms a leak",
"CombineOverlapArea": "Combine Overlap Area"
},
"cn": {
"TextInput": "文本输入",
Expand Down Expand Up @@ -229,6 +235,12 @@
"imageInvalidAndSkip": "无效图片,请跳过",
"videoErrorAndReload": "视频加载失败, 请重新加载",
"imageErrorAndReload": "图片加载失败, 请重新加载",
"orMaskAsInvalid": " 或 将其标为无效"
"orMaskAsInvalid": " 或 将其标为无效",
"ClickAnotherPolygon": "请点击希望合并的多边形",
"PolygonsToBeCombinedNeedToBeSelected": "需要选中需要合并的多边形",
"CurveModeDoesNotSupportCutting": "曲线模式暂不支持裁剪",
"CombineSuccess": "合并成功",
"CombiningFailedNotify": "合并失败,请检查是否两个多边形是否有相交,或多边形合并是否形成漏空",
"CombineOverlapArea": "合并重叠区域"
}
}
}

0 comments on commit 56bb126

Please sign in to comment.