1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666 |
- import { dataService } from "../Service/DataService.js";
- import { stateService } from "../Service/StateService.js";
- import { coordinate } from "../Coordinate.js";
- import Style from "@/graphic/CanvasStyle/index.js";
- import { mathUtil } from "../Util/MathUtil.js";
- import { elementService } from "../Service/ElementService.js";
- import UIEvents from "@/graphic/enum/UIEvents.js";
- import VectorCategory from "@/graphic/enum/VectorCategory.js";
- import Settings from "@/graphic/Settings.js";
- import SVGIcons from "../CanvasStyle/ImageLabels/SVGIcons";
- import VectorStyle from "@/graphic/enum/VectorStyle.js";
- import VectorWeight from "@/graphic/enum/VectorWeight.js";
- import router from "@/router/index";
- import VectorType from "../enum/VectorType.js";
- import { ui18n } from "@/lang/index.js";
- const isScreenStyle = () =>
- Settings.screenMode && router.currentRoute.value.params.mode === "0";
- const imgCache = {};
- export const help = {
- getVectorStyle(vector, geoType = vector.geoType) {
- const geoId = vector?.vectorId;
- if (!geoId || isScreenStyle()) {
- return [
- isScreenStyle() && Style["Screen"][geoType]
- ? Style["Screen"][geoType]
- : Style[geoType],
- undefined,
- ];
- }
- const itemsEntry = [
- [stateService.getSelectItem(), "Select"],
- [stateService.getDraggingItem(), "Dragging"],
- [stateService.getFocusItem(), "Focus"],
- ];
- let currentAttr;
- //console.log(itemsEntry)
- return [
- itemsEntry.reduce((prev, [item, attr]) => {
- if (!item) return prev;
- const selected =
- geoId === item.vectorId ||
- (item.parent && Object.keys(item.parent).some((id) => id === geoId));
- if (selected && Style[attr]) {
- const style = Style[attr][geoType] || Style[attr][vector.category];
- if (style) {
- currentAttr = attr;
- return style;
- }
- }
- return prev;
- }, Style[geoType]),
- currentAttr,
- ];
- },
- setStyle(ctx, styles) {
- for (const style in styles) {
- if (typeof styles[style] === "function") {
- styles[style](ctx, vector);
- } else {
- ctx[style] = styles[style];
- }
- }
- },
- setVectorStyle(ctx, vector, geoType = vector.geoType) {
- let styles, attr;
- if (Array.isArray(geoType)) {
- for (const type of geoType) {
- [styles, attr] = help.getVectorStyle(vector, type);
- if (styles) {
- break;
- }
- }
- } else {
- [styles, attr] = help.getVectorStyle(vector, geoType);
- }
- help.setStyle(ctx, styles);
- return [styles, attr];
- },
- transformCoves(lines) {
- return lines.map((line) =>
- line.map((line) => ({
- start: coordinate.getScreenXY(line.start),
- end: coordinate.getScreenXY(line.end),
- controls: line.controls.map(coordinate.getScreenXY.bind(coordinate)),
- }))
- );
- },
- drawCove(ctx, curve) {
- if (curve.controls.length === 1) {
- ctx.quadraticCurveTo(
- curve.controls[0].x,
- curve.controls[0].y,
- curve.end.x,
- curve.end.y
- );
- } else {
- ctx.bezierCurveTo(
- curve.controls[0].x,
- curve.controls[0].y,
- curve.controls[1].x,
- curve.controls[1].y,
- curve.end.x,
- curve.end.y
- );
- }
- },
- drawCoves(ctx, coves) {
- for (const curve of coves) {
- ctx.beginPath();
- ctx.moveTo(curve.start.x, curve.start.y);
- help.drawCove(ctx, curve);
- ctx.stroke();
- }
- },
- getReal(data) {
- return (data * coordinate.ratio * coordinate.zoom) / coordinate.defaultZoom;
- },
- getImage(src) {
- if (imgCache[src]) {
- return imgCache[src];
- }
- const img = new Image();
- img.src = src;
- return (imgCache[src] = new Promise((resolve) => {
- img.onload = () => {
- resolve(img);
- };
- }));
- },
- getTextCenter(ctx, txt) {
- const text = ctx.measureText(txt);
- const height = text.actualBoundingBoxAscent + text.actualBoundingBoxDescent;
- return {
- width: text.width,
- height,
- x: text.width / 2,
- y: -height / 2,
- };
- },
- // 绘制圆角矩形
- roundRect(ctx, x, y, width, height, radius) {
- ctx.beginPath();
- ctx.moveTo(x + radius, y);
- ctx.lineTo(x + width - radius, y);
- ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
- ctx.lineTo(x + width, y + height - radius);
- ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
- ctx.lineTo(x + radius, y + height);
- ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
- ctx.lineTo(x, y + radius);
- ctx.quadraticCurveTo(x, y, x + radius, y);
- ctx.closePath();
- },
- getRealDistance(p1, p2) {
- return Math.round(
- (mathUtil.getDistance(p1, p2) * coordinate.res * 1000) / coordinate.ratio
- );
- },
- getScreenDistance(dis) {
- return (dis * coordinate.ratio) / (coordinate.res * 1000);
- },
- getPerpendicularPoint(p1, p2, p3, d) {
- if (p1.x === p2.x) {
- return { x: p3.x + d, y: p3.y };
- } else if (p1.y === p2.y) {
- return { x: p3.x, y: p3.y + d };
- }
- // 计算通过 p1 和 p2 的直线的斜率和截距
- const slope = (p2.y - p1.y) / (p2.x - p1.x);
- const intercept = p1.y - slope * p1.x;
- // 计算垂直线的斜率和截距
- const perpendicularSlope = -1 / slope;
- const perpendicularIntercept = p3.y - perpendicularSlope * p3.x;
- // 计算垂足点 p0
- const x =
- (perpendicularIntercept - intercept) / (slope - perpendicularSlope);
- const y = slope * x + intercept;
- const p0 = { x, y };
- // 计算点 p4
- const distance = d; // 指定距离
- const dx = distance / Math.sqrt(1 + perpendicularSlope ** 2);
- const dy = perpendicularSlope * dx;
- return { x: p0.x + dx, y: p0.y + dy };
- },
- drawLineText(ctx, start, end, text, style) {
- if (start.x > end.x) {
- [start, end] = [end, start];
- }
- const at2 = Math.atan2(end.y - start.y, end.x - start.x) * 180;
- const angle = at2 / Math.PI;
- const fontSize = (style.fontSize || 10) * coordinate.ratio;
- const vline = mathUtil.getVerticalLineByDistance(start, end, fontSize);
- const center = mathUtil.lineCenter(vline[0], vline[1]);
- // console.log(center, start, end);
- ctx.save();
- ctx.translate(center.x, center.y);
- ctx.rotate((angle * Math.PI) / 180);
- ctx.font = `${fontSize}px Microsoft YaHei`;
- const textCenter = help.getTextCenter(ctx, text);
- if (!isScreenStyle()) {
- // ctx.fillStyle = style.backColor;
- // const padding = style.padding;
- // help.roundRect(
- // ctx,
- // -textCenter.x - padding,
- // textCenter.y - padding,
- // textCenter.width + 2 * padding,
- // textCenter.height + 2 * padding,
- // textCenter.height / 2 + padding
- // );
- // ctx.fill();
- }
- ctx.lineWidth = 8;
- if (!style.fillStyle) {
- ctx.strokeStyle = "#fff";
- ctx.strokeText(text, -textCenter.x, -textCenter.y);
- ctx.fillStyle = "#000";
- ctx.fillText(text, -textCenter.x, -textCenter.y);
- } else {
- ctx.fillStyle = style.fillColor;
- ctx.fillText(text, -textCenter.x, -textCenter.y);
- }
- ctx.restore();
- },
- isTriangleClockwise(p1, p2, p3) {
- const crossProduct =
- (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
- return crossProduct < 0;
- },
- drawStyleLine(
- ctx,
- line,
- style = VectorStyle.SingleSolidLine,
- weight = VectorStyle.Thinning
- ) {
- ctx.save();
- style = style || VectorStyle.SingleSolidLine;
- ctx.beginPath();
- const lineWidth =
- Settings.lineWidth *
- (ctx.lineWidth || 1) *
- (typeof weight === "string"
- ? weight === VectorWeight.Bold
- ? 2
- : 1
- : weight);
- const funStyle = [
- VectorStyle.PointDrawLine,
- VectorStyle.SingleDashedLine,
- VectorStyle.SingleSolidLine,
- VectorStyle.RoadSide,
- ];
- if (typeof line === "function" && !funStyle.includes(style)) {
- style = VectorStyle.SingleSolidLine;
- }
- switch (style) {
- case VectorStyle.PointDrawLine:
- case VectorStyle.SingleDashedLine:
- case VectorStyle.SingleSolidLine:
- ctx.lineWidth = lineWidth;
- if (style === VectorStyle.SingleDashedLine) {
- ctx.setLineDash([8 * coordinate.ratio, 8 * coordinate.ratio]);
- } else if (style === VectorStyle.PointDrawLine) {
- ctx.setLineDash([
- 6 * coordinate.ratio,
- 6 * coordinate.ratio,
- 2 * coordinate.ratio,
- ]);
- }
- if (typeof line === "function") {
- line();
- } else {
- ctx.moveTo(line[0].x, line[0].y);
- ctx.lineTo(line[1].x, line[1].y);
- }
- break;
- // 单实线
- case VectorStyle.DoubleDashedLine:
- case VectorStyle.DoubleSolidLine:
- ctx.lineWidth = lineWidth;
- if (style === VectorStyle.DoubleDashedLine) {
- ctx.setLineDash([8 * coordinate.ratio, 8 * coordinate.ratio]);
- }
- const pd1 = help.getPerpendicularPoint(
- line[0],
- line[1],
- line[0],
- 4 * coordinate.ratio
- );
- const pd2 = help.getPerpendicularPoint(
- line[0],
- line[1],
- line[1],
- 4 * coordinate.ratio
- );
- const pd3 = help.getPerpendicularPoint(
- line[0],
- line[1],
- line[0],
- -4 * coordinate.ratio
- );
- const pd4 = help.getPerpendicularPoint(
- line[0],
- line[1],
- line[1],
- -4 * coordinate.ratio
- );
- ctx.moveTo(pd1.x, pd1.y);
- ctx.lineTo(pd2.x, pd2.y);
- ctx.stroke();
- ctx.moveTo(pd3.x, pd3.y);
- ctx.lineTo(pd4.x, pd4.y);
- break;
- case VectorStyle.BrokenLine:
- const ldis = 5 * coordinate.ratio;
- if (mathUtil.getDistance(...line) < ldis * 2) {
- ctx.moveTo(line[0].x, line[0].y);
- ctx.lineTo(line[1].x, line[1].y);
- } else {
- const start = mathUtil.translate(line[0], line[1], line[0], ldis);
- const end = mathUtil.translate(line[0], line[1], line[1], -ldis);
- const lineDis = mathUtil.getDistance(start, end);
- const len = Math.ceil(lineDis / (6 * coordinate.ratio));
- const split = lineDis / len;
- const points = [start];
- let temp = start;
- for (let i = 0; i < len; i++) {
- temp = mathUtil.translate(temp, line[1], temp, split);
- points.push(temp);
- }
- ctx.moveTo(line[0].x, line[0].y);
- ctx.lineTo(start.x, start.y);
- for (let i = 0; i < points.length - 1; i++) {
- const vTop = help.getPerpendicularPoint(
- points[i],
- points[i + 1],
- mathUtil.lineCenter(points[i], points[i + 1]),
- (split * (i % 2 ? -1 : 1)) / 2
- );
- ctx.lineTo(vTop.x, vTop.y);
- }
- ctx.lineTo(end.x, end.y);
- ctx.lineTo(line[1].x, line[1].y);
- }
- ctx.lineWidth = lineWidth;
- break;
- case VectorStyle.Greenbelt:
- const dis = 4 * coordinate.ratio;
- const size = 8 * coordinate.ratio;
- const p1 = help.getPerpendicularPoint(line[0], line[1], line[0], dis);
- const p2 = help.getPerpendicularPoint(line[0], line[1], line[1], dis);
- const p3 = help.getPerpendicularPoint(p1, p2, p2, size);
- const p4 = help.getPerpendicularPoint(p1, p2, p1, size);
- ctx.beginPath();
- ctx.lineWidth = lineWidth;
- ctx.moveTo(line[0].x, line[0].y);
- ctx.lineTo(line[1].x, line[1].y);
- ctx.stroke();
- ctx.beginPath();
- ctx.moveTo(p4.x, p4.y);
- ctx.lineTo(p1.x, p1.y);
- ctx.lineTo(p2.x, p2.y);
- ctx.lineTo(p3.x, p3.y);
- ctx.stroke();
- const rdis = 6 * coordinate.ratio;
- const lineDis = mathUtil.getDistance(p3, p4);
- const len = Math.ceil(lineDis / rdis);
- const split = lineDis / len;
- const points = [p3];
- const geo = [p4, { ...p4, x: 999 }, p3];
- let angle = (mathUtil.Angle1(...geo) / 180) * Math.PI;
- const isClock = help.isTriangleClockwise(...geo) || angle === 0;
- angle = isClock ? -angle : angle;
- let temp = p3;
- for (let i = 0; i < len; i++) {
- temp = mathUtil.translate(temp, p4, temp, split);
- points.push(temp);
- }
- for (let i = 0; i < points.length - 1; i++) {
- const center = mathUtil.lineCenter(points[i], points[i + 1]);
- ctx.beginPath();
- ctx.arc(
- center.x,
- center.y,
- split / 2,
- angle,
- angle + Math.PI,
- !isClock
- );
- ctx.stroke();
- }
- ctx.lineWidth = lineWidth;
- break;
- case VectorStyle.RoadSide:
- ctx.save();
- ctx.beginPath();
- ctx.moveTo(line[0].x, line[0].y);
- ctx.lineTo(line[1].x, line[1].y);
- ctx.lineTo(line[2].x, line[2].y);
- ctx.lineTo(line[3].x, line[3].y);
- ctx.closePath();
- ctx.fill();
- ctx.stroke();
- ctx.restore();
- // line.forEach((point) => {
- // ctx.beginPath();
- // ctx.fillStyle = "#000";
- // ctx.arc(point.x, point.y, 10, 0, 2 * Math.PI);
- // ctx.fill();
- // ctx.closePath();
- // console.log(point);
- // });
- const width = mathUtil.getDistance(line[0], line[3]);
- const c1 = mathUtil.translate(line[0], line[3], line[0], width / 2);
- const c2 = mathUtil.translate(line[1], line[2], line[1], width / 2);
- ctx.beginPath();
- ctx.moveTo(c1.x, c1.y);
- ctx.lineTo(c2.x, c2.y);
- ctx.lineWidth = width;
- ctx.setLineDash([2 * coordinate.ratio, 40 * coordinate.ratio]);
- ctx.stroke();
- ctx.closePath();
- ctx.restore();
- return;
- }
- ctx.stroke();
- ctx.restore();
- },
- };
- export default class Draw {
- constructor() {
- this.canvas = null;
- this.context = null;
- }
- initContext(canvas) {
- if (canvas) {
- this.canvas = canvas;
- this.context = canvas.getContext("2d");
- const saveRaw = this.context.save.bind(this.context);
- const restoreRaw = this.context.restore.bind(this.context);
- let index = 0;
- this.context.save = saveRaw;
- // this.context.save = () => {
- // index++;
- // console.error("save", index);
- // saveRaw();
- // };
- this.context.restore = restoreRaw;
- // this.context.restore = () => {
- // index--;
- // console.log("restore", index);
- // restoreRaw();
- // };
- } else {
- this.context = null;
- this.canvas = null;
- }
- }
- clear() {
- this.context.clearRect(
- 0,
- 0,
- this.context.canvas.width,
- this.context.canvas.height
- );
- }
- drawBackGroundImg(vector) {
- if (!vector.display) {
- return;
- }
- const img = vector.imageData;
- const width = help.getReal(img.width);
- const height = help.getReal(img.height);
- const center = coordinate.getScreenXY(vector.center);
- this.context.save();
- if (vector.scale) {
- this.context.translate(center.x, center.y);
- this.context.scale(vector.scale, vector.scale);
- this.context.translate(-center.x, -center.y);
- }
- this.context.drawImage(
- img,
- center.x - width / 2,
- center.y - height / 2,
- width,
- height
- );
- this.context.restore();
- }
- drawGrid(startX, startY, w, h, step1, step2) {
- this.context.save();
- this.context.beginPath();
- for (var x = startX; x <= w; x += step1) {
- this.context.moveTo(x, 0);
- this.context.lineTo(x, h);
- }
- for (var y = startY; y <= h; y += step1) {
- this.context.moveTo(0, y);
- this.context.lineTo(w, y);
- }
- this.context.strokeStyle = "rgba(0,0,0,0.1)";
- this.context.lineWidth = 0.5 * coordinate.ratio;
- this.context.stroke();
- this.context.beginPath();
- for (var x = startX; x <= w; x += step2) {
- this.context.moveTo(x, 0);
- this.context.lineTo(x, h);
- }
- for (var y = startY; y <= h; y += step2) {
- this.context.moveTo(0, y);
- this.context.lineTo(w, y);
- }
- this.context.strokeStyle = "rgba(0,0,0,0.2)";
- this.context.lineWidth = 1 * coordinate.ratio;
- this.context.stroke();
- this.context.restore();
- }
- drawRoad(vector, isTemp) {
- const [styles, label] = help.getVectorStyle(vector);
- if (!isTemp && vector.display && vector.way !== "oneWay") {
- const ctx = this.context;
- const draw = (midDivide) => {
- const startScreen = coordinate.getScreenXY(midDivide.start);
- const endScreen = coordinate.getScreenXY(midDivide.end);
- ctx.beginPath();
- if (label) {
- help.setStyle(ctx, Style.Focus.Road);
- }
- ctx.moveTo(startScreen.x, startScreen.y);
- ctx.lineTo(endScreen.x, endScreen.y);
- ctx.stroke();
- };
- ctx.save();
- help.setStyle(ctx, styles);
- vector.midDivide.leftMidDivide && draw(vector.midDivide.leftMidDivide);
- vector.midDivide.rightMidDivide && draw(vector.midDivide.rightMidDivide);
- ctx.restore();
- }
- if (import.meta.env.DEV && !isTemp) {
- const startReal = isTemp
- ? vector.start
- : dataService.getRoadPoint(vector.startId);
- const endReal = isTemp
- ? vector.end
- : dataService.getRoadPoint(vector.endId);
- this.drawTextByInfo(
- { x: (startReal.x + endReal.x) / 2, y: (startReal.y + endReal.y) / 2 },
- vector.vectorId
- );
- }
- this.drawRoadEdge(vector, isTemp);
- if (vector.way === "oneWay") {
- vector.singleLanes &&
- vector.singleLanes.forEach((g) => this.drawLan(g, !!label));
- } else {
- vector.leftLanes &&
- vector.leftLanes.forEach((g) => this.drawLan(g, !!label));
- vector.rightLanes &&
- vector.rightLanes.forEach((g) => this.drawLan(g, !!label));
- }
- if (vector.roadWidthTipsPos) {
- this.drawRoadTip(vector);
- }
- }
- drawRoadTip(vector) {
- let width;
- if (vector.way === "twoWay") {
- width = vector.leftWidth / vector.leftDrivewayCount;
- } else {
- width = vector.singleRoadWidth / vector.singleRoadDrivewayCount;
- }
- // console.log(width);
- width = width.toFixed(0);
- vector.roadWidthTipsPos.forEach((line) => {
- const width = help.getRealDistance(line.start, line.end);
- const start = coordinate.getScreenXY(line.start);
- const end = coordinate.getScreenXY(line.end);
- const [style] = help.setVectorStyle(this.context, vector, ["NormalLine"]);
- help.drawStyleLine(this.context, [start, end]);
- help.drawLineText(this.context, start, end, Math.round(width * 0.1), {
- padding: 6,
- fontSize: 12,
- });
- this.drawLineArrow([start, end], true);
- });
- }
- drawLan(lan, focus) {
- const ctx = this.context;
- const start = coordinate.getScreenXY(lan.start);
- const end = coordinate.getScreenXY(lan.end);
- ctx.save();
- ctx.beginPath();
- help.setVectorStyle(ctx, null, "Lane");
- if (focus) {
- ctx.strokeStyle = "rgba(255, 143, 40, 1)";
- }
- ctx.lineWidth *= Settings.lineWidth;
- ctx.setLineDash(Style.Lane.dash);
- ctx.moveTo(start.x, start.y);
- ctx.lineTo(end.x, end.y);
- ctx.stroke();
- ctx.restore();
- if (import.meta.env.DEV) {
- // this.drawPoint(lan.start);
- // this.drawPoint(lan.end);
- }
- }
- drawRoadEdge(vector, isTemp) {
- //判断是否与road方向一致。角度足够小,路足够宽,有可能向量方向不一致
- const start = isTemp
- ? vector.start
- : dataService.getRoadPoint(vector.startId);
- const end = isTemp ? vector.end : dataService.getRoadPoint(vector.endId);
- const drawRoadEdgeChild = (edgeVector) => {
- const flag = mathUtil.isSameDirForVector(
- start,
- end,
- edgeVector.start,
- edgeVector.end
- );
- if (flag) {
- let points = [
- coordinate.getScreenXY(edgeVector.start),
- coordinate.getScreenXY(edgeVector.end),
- ];
- if (edgeVector.roadSide) {
- points.push(
- coordinate.getScreenXY(edgeVector.roadSide.end),
- coordinate.getScreenXY(edgeVector.roadSide.start)
- );
- }
- // console.log(edgeVector, vector);
- // edgeVector.style = VectorStyle.SingleSolidLine;
- help.drawStyleLine(
- ctx,
- points,
- edgeVector.roadSide ? VectorStyle.RoadSide : edgeVector.style,
- edgeVector.roadSide ? edgeVector.roadSide.width : edgeVector.weight
- );
- if (edgeVector.roadSide) {
- const checkLine = [edgeVector.start, edgeVector.end];
- const targetLine = [
- vector.roadWidthTipsPos[0].start,
- vector.roadWidthTipsPos[0].end,
- ];
- const join = mathUtil.getIntersectionPoint(
- mathUtil.createLine1(checkLine[0], checkLine[1]),
- mathUtil.createLine1(targetLine[0], targetLine[1])
- );
- const isStartMax =
- mathUtil.getDisForLineCoord(checkLine, targetLine[0]) >
- mathUtil.getDisForLineCoord(checkLine, targetLine[1]);
- // this.drawPoint(join);
- if (!isStartMax) {
- const temp = targetLine[0];
- targetLine[0] = targetLine[1];
- targetLine[1] = temp;
- }
- const tstart = mathUtil.translate(
- targetLine[0],
- targetLine[1],
- join,
- help.getScreenDistance(edgeVector.roadSide.width * 1000)
- );
- const tend = mathUtil.translate(
- targetLine[0],
- targetLine[1],
- join,
- help.getScreenDistance(edgeVector.roadSide.width * 1000) +
- 24 * coordinate.ratio
- );
- // this.drawPoint(tstart);
- // this.drawPoint(tend);
- help.drawLineText(
- ctx,
- coordinate.getScreenXY(tstart),
- coordinate.getScreenXY(tend),
- Math.round(edgeVector.roadSide.width * 1000 * 0.1),
- {
- padding: 6,
- fontSize: 12,
- }
- );
- }
- }
- if (import.meta.env.DEV) {
- this.drawTextByInfo(
- {
- x: (edgeVector.start.x + edgeVector.end.x) / 2,
- y: (edgeVector.start.y + edgeVector.end.y) / 2,
- },
- edgeVector.vectorId
- );
- }
- };
- const leftEdge = isTemp
- ? vector.leftEdge
- : dataService.getRoadEdge(vector.leftEdgeId);
- const rightEdge = isTemp
- ? vector.rightEdge
- : dataService.getRoadEdge(vector.rightEdgeId);
- const ctx = this.context;
- ctx.save();
- isTemp && (ctx.globalAlpha = 0.3);
- help.setVectorStyle(ctx, leftEdge);
- let [style, fo] = help.getVectorStyle(vector);
- if (fo) {
- help.setStyle(ctx, Style.Focus.RoadEdge);
- }
- drawRoadEdgeChild(leftEdge);
- help.setVectorStyle(ctx, rightEdge);
- if (fo) {
- help.setStyle(ctx, Style.Focus.RoadEdge);
- }
- drawRoadEdgeChild(rightEdge);
- ctx.restore();
- if (fo) {
- ctx.save();
- const p1 = coordinate.getScreenXY(leftEdge.start);
- const p2 = coordinate.getScreenXY(rightEdge.start);
- const p3 = coordinate.getScreenXY(leftEdge.end);
- const p4 = coordinate.getScreenXY(rightEdge.end);
- ctx.lineWidth = 1 * coordinate.ratio;
- ctx.setLineDash([5 * coordinate.ratio, 5 * coordinate.ratio]);
- ctx.strokeStyle = Style.Road.strokeStyle;
- // ctx.beginPath();
- // ctx.moveTo(p1.x, p1.y);
- // ctx.lineTo(p2.x, p2.y);
- // ctx.stroke();
- // ctx.beginPath();
- // ctx.moveTo(p3.x, p3.y);
- // ctx.lineTo(p4.x, p4.y);
- // ctx.stroke();
- ctx.fillStyle = "rgba(255, 153, 0, 0.30)";
- ctx.moveTo(p1.x, p1.y);
- ctx.lineTo(p2.x, p2.y);
- ctx.lineTo(p4.x, p4.y);
- ctx.lineTo(p3.x, p3.y);
- ctx.fill();
- ctx.restore();
- }
- if (import.meta.env.DEV) {
- // this.drawPoint(leftEdge.start);
- // this.drawPoint(leftEdge.end);
- // this.drawPoint(rightEdge.start);
- // this.drawPoint(rightEdge.end);
- }
- }
- drawCrossPoint(vector) {
- const start = coordinate.getScreenXY(
- dataService
- .getRoadEdge(vector.edgeInfo1.id)
- .getPosition(vector.edgeInfo1.dir)
- );
- const end = coordinate.getScreenXY(
- dataService
- .getRoadEdge(vector.edgeInfo2.id)
- .getPosition(vector.edgeInfo2.dir)
- );
- const pt2 = mathUtil.twoOrderBezier(
- 0.5,
- start,
- coordinate.getScreenXY({ x: vector.x, y: vector.y }),
- end
- );
- const pt = mathUtil.twoOrderBezier2(0.5, start, pt2, end);
- const extremePoint = coordinate.getScreenXY(vector.extremePoint);
- const ctx = this.context;
- ctx.save();
- help.setVectorStyle(ctx, vector);
- ctx.beginPath();
- if (!Settings.screenMode) {
- ctx.arc(
- extremePoint.x,
- extremePoint.y,
- Style.CrossPoint.radius * coordinate.ratio,
- 0,
- Math.PI * 2,
- true
- );
- }
- ctx.stroke();
- ctx.fill();
- ctx.restore();
- ctx.save();
- ctx.beginPath();
- help.setVectorStyle(ctx, null, "RoadEdge");
- //曲线
- // ctx.moveTo(start.x, start.y);
- // ctx.quadraticCurveTo(pt.x, pt.y, end.x, end.y);
- help.drawStyleLine(
- ctx,
- () => {
- const [coves] = help.transformCoves([vector.curves]);
- help.drawCoves(ctx, coves);
- },
- vector.style,
- vector.weight
- );
- ctx.restore();
- }
- drawCurveRoad(vector) {
- const ctx = this.context;
- ctx.save();
- let midCovesArray;
- const [_, foo] = help.setVectorStyle(ctx, vector);
- if (vector.display && vector.midDivide) {
- midCovesArray = help.transformCoves([
- vector.midDivide.leftMidDivideCurves,
- // vector.midDivide.rightMidDivideCurves,
- ]);
- ctx.setLineDash([8 * coordinate.ratio, 8 * coordinate.ratio]);
- ctx.lineWidth *= Settings.lineWidth;
- for (let coves of midCovesArray) {
- help.drawCoves(ctx, coves);
- }
- // midCovesArray = help.transformCoves([
- // vector.curves,
- // ]);
- // ctx.strokeStyle = 'red'
- // for (let coves of midCovesArray) {
- // help.drawCoves(ctx, coves);
- // }
- }
- ctx.restore();
- this.drawCurveRoadEdge(
- dataService.getCurveRoadEdge(vector.rightEdgeId),
- vector
- );
- this.drawCurveRoadEdge(
- dataService.getCurveRoadEdge(vector.leftEdgeId),
- vector
- );
- vector.leftLanesCurves &&
- vector.leftLanesCurves.forEach((data) => this.drawCurveLan(data, foo));
- vector.rightLanesCurves &&
- vector.rightLanesCurves.forEach((data) => this.drawCurveLan(data, foo));
- if (foo) {
- const leftEdge = dataService.getCurveRoadEdge(vector.leftEdgeId);
- const rightEdge = dataService.getCurveRoadEdge(vector.rightEdgeId);
- // const p1 = coordinate.getScreenXY(leftEdge.start);
- // const p2 = coordinate.getScreenXY(rightEdge.start);
- // const p3 = coordinate.getScreenXY(leftEdge.end);
- // const p4 = coordinate.getScreenXY(rightEdge.end);
- // ctx.save();
- // ctx.setLineDash([5 * coordinate.ratio, 5 * coordinate.ratio]);
- // ctx.lineWidth = 1 * coordinate.ratio;
- // ctx.strokeStyle = Style.Lane.strokeStyle;
- // ctx.beginPath();
- // ctx.moveTo(p1.x, p1.y);
- // ctx.lineTo(p2.x, p2.y);
- // ctx.stroke();
- // ctx.beginPath();
- // ctx.moveTo(p3.x, p3.y);
- // ctx.lineTo(p4.x, p4.y);
- // ctx.stroke();
- if (midCovesArray) {
- const edgeCurves = help.transformCoves([
- leftEdge.curves,
- rightEdge.curves,
- ]);
- edgeCurves[1] = edgeCurves[1].reverse().map((curve) => ({
- start: curve.end,
- end: curve.start,
- controls: curve.controls.reverse(),
- }));
- ctx.beginPath();
- ctx.setLineDash([]);
- ctx.moveTo(edgeCurves[0][0].start.x, edgeCurves[0][0].start.y);
- edgeCurves[0].forEach((cuve) => help.drawCove(ctx, cuve));
- ctx.lineTo(edgeCurves[1][0].start.x, edgeCurves[1][0].start.y);
- edgeCurves[1].forEach((cuve) => help.drawCove(ctx, cuve));
- ctx.closePath();
- ctx.fillStyle = "rgba(255, 153, 0, 0.30)";
- ctx.fill();
- }
- ctx.restore();
- }
- // if (import.meta.env.DEV) {
- vector.points.forEach(this.drawPoint.bind(this));
- // }
- }
- drawCurveRoadEdge(vector, roadVector) {
- const [coves] = help.transformCoves([vector.curves]);
- const ctx = this.context;
- const [style, select] = help.getVectorStyle(roadVector);
- ctx.save();
- help.setVectorStyle(ctx, vector);
- select && help.setStyle(ctx, style);
- // ctx.lineWidth *= Settings.lineWidth;
- help.drawStyleLine(
- this.context,
- () => {
- help.drawCoves(ctx, coves);
- },
- vector.style,
- vector.weight
- );
- // help.drawCoves(ctx, coves);
- ctx.restore();
- if (import.meta.env.DEV) {
- // vector.points.forEach(this.drawPoint.bind(this));
- }
- }
- drawCurveLan(lines, focus) {
- const [coves] = help.transformCoves([lines]);
- const ctx = this.context;
- ctx.save();
- help.setVectorStyle(ctx, null, "CurveLan");
- ctx.lineWidth *= Settings.lineWidth;
- if (focus) {
- ctx.strokeStyle = "rgba(255, 153, 0, 1)";
- ctx.lineWidth *= 2;
- }
- ctx.setLineDash(Style.Lane.dash);
- help.drawCoves(ctx, coves);
- ctx.restore();
- // if (import.meta.env.DEV) {
- // lines.map((line) => {
- // this.drawPoint(line.start);
- // this.drawPoint(line.end);
- // });
- // }
- }
- drawRoadPoint(vector) {
- this.drawPoint(vector);
- }
- drawLineArrow(line, doubleArrow = false, len = 20) {
- const ctx = this.context;
- const [start, end] = line;
- const dires = doubleArrow
- ? [
- [start, end],
- [end, start],
- ]
- : [[start, end]];
- ctx.save();
- for (let [start, end] of dires) {
- const lines = mathUtil.getArrow(start, end, 30, len);
- ctx.moveTo(lines[0].x, lines[0].y);
- ctx.lineTo(lines[1].x, lines[1].y);
- ctx.lineTo(lines[2].x, lines[2].y);
- }
- ctx.stroke();
- ctx.restore();
- }
- drawArrow(vector) {
- const startReal = dataService.getPoint(vector.startId);
- const start = coordinate.getScreenXY(startReal);
- const endReal = dataService.getPoint(vector.endId);
- const end = coordinate.getScreenXY(endReal);
- const ctx = this.context;
- ctx.save();
- help.setVectorStyle(this.context, vector);
- if (vector.color) {
- ctx.strokeStyle = vector.color;
- }
- this.drawLineArrow(
- [start, end],
- vector.category === UIEvents.DoubleArrow,
- 40
- );
- }
- drawMagnifier(vector) {
- const ctx = this.context;
- ctx.save();
- const [style] = help.setVectorStyle(ctx, vector);
- const radius = vector.radius || style.radius;
- this.drawPoint({
- ...vector,
- ...vector.position,
- radius,
- });
- const pt = coordinate.getScreenXY(vector.position);
- // vector.setPopPosition();
- const target = {
- x: vector.popPosition.x,
- y: vector.popPosition.y,
- };
- const offset = radius / 2;
- const targetPts = [mathUtil.translate(pt, target, pt, radius), target];
- ctx.beginPath();
- ctx.moveTo(pt.x - offset, pt.y);
- ctx.lineTo(pt.x + offset, pt.y);
- ctx.stroke();
- ctx.beginPath();
- ctx.moveTo(pt.x, pt.y - offset);
- ctx.lineTo(pt.x, pt.y + offset);
- ctx.stroke();
- if (targetPts) {
- ctx.beginPath();
- ctx.moveTo(targetPts[0].x, targetPts[0].y);
- ctx.lineTo(targetPts[1].x, targetPts[1].y);
- ctx.stroke();
- let img, imgBound;
- if (vector.photoImage) {
- img = vector.photoImage;
- let top = 0,
- left = 0,
- size = 0;
- if (img.width > img.height) {
- size = img.height;
- left = (img.width - size) / 2;
- } else {
- size = img.width;
- top = (img.height - size) / 2;
- }
- imgBound = [left, top, size, size];
- } else {
- const backImg = dataService.getBackgroundImg();
- const size = help.getReal(style.target.realRadius);
- img = backImg.imageData;
- const imgCenter = coordinate.getScreenXY(backImg.center);
- const width = img.width * backImg.scale;
- const height = img.height * backImg.scale;
- const start = {
- x: imgCenter.x - help.getReal(width) / 2,
- y: imgCenter.y - help.getReal(height) / 2,
- };
- const pts = pt;
- const ro = width / help.getReal(width);
- imgBound = [
- ((pts.x - start.x - size) * ro) / backImg.scale,
- ((pts.y - start.y - size) * ro) / backImg.scale,
- (size * 2 * ro) / backImg.scale,
- (size * 2 * ro) / backImg.scale,
- ];
- }
- const size = style.target.radius;
- ctx.beginPath();
- ctx.arc(target.x, target.y, size, 0, 2 * Math.PI);
- ctx.clip();
- ctx.drawImage(
- img,
- ...imgBound,
- target.x - size,
- target.y - size,
- size * 2,
- size * 2
- );
- ctx.strokeStyle = style.target.strokeStyle;
- ctx.lineWidth = style.target.lineWidth;
- ctx.stroke();
- }
- ctx.restore();
- }
- drawElliptic(element, radiusX = element.radiusX, radiusY = element.radiusY) {
- function drawEllipse(context, x, y, a, b) {
- const step = a > b ? 1 / a : 1 / b;
- context.beginPath();
- context.moveTo(x + a, y);
- for (let i = 0; i < 2 * Math.PI; i += step) {
- context.lineTo(x + a * Math.cos(i), y + b * Math.sin(i));
- }
- context.closePath();
- }
- const pt = coordinate.getScreenXY({
- x: element.center.x,
- y: element.center.y,
- });
- const ctx = this.context;
- ctx.save();
- const [_, label] = help.setVectorStyle(ctx, element);
- ctx.strokeStyle = element.color;
- drawEllipse(
- ctx,
- pt.x,
- pt.y,
- (radiusX * coordinate.zoom) / coordinate.defaultZoom,
- (radiusY * coordinate.zoom) / coordinate.defaultZoom
- );
- ctx.stroke();
- ctx.fill();
- ctx.restore();
- }
- drawCircle(element) {
- this.context.save();
- const geo = [
- element.center,
- element.points[1],
- { ...element.center, x: 999 },
- ];
- let angle = mathUtil.Angle(...geo);
- angle = help.isTriangleClockwise(...geo) ? -angle : angle;
- const center = coordinate.getScreenXY(element.center);
- this.context.translate(center.x, center.y);
- this.context.rotate((angle / 180) * Math.PI);
- this.context.translate(-center.x, -center.y);
- this.drawElliptic(element, element.radiusX, element.radiusY);
- this.context.restore();
- const [_, label] = help.getVectorStyle(element);
- label && element.points.forEach((point) => this.drawPoint(point));
- }
- drawPoint(vector, screenSave) {
- const screenNotDrawTypes = [VectorCategory.Point.NormalPoint];
- if (!screenSave) {
- if (
- (Settings.screenMode &&
- (!vector.category || screenNotDrawTypes.includes(vector.category))) ||
- vector.category === VectorCategory.Point.TestBasePoint
- ) {
- return;
- }
- }
- const pt = coordinate.getScreenXY({ x: vector.x, y: vector.y });
- const ctx = this.context;
- ctx.save();
- let [style, attr] = help.setVectorStyle(ctx, vector, [
- vector.category,
- vector.geoType,
- "Point",
- ]);
- if (vector.category === VectorCategory.Point.NormalPoint) {
- const lineid = Object.keys(vector.parent)[0];
- let line;
- if (!(lineid && (line = dataService.getLine(lineid)))) {
- ctx.restore();
- return;
- }
- // console.log(line);
- if (line.category !== "ZebraCrossing") {
- const [stylea, attr] = help.getVectorStyle(line, line.category);
- style = {
- ...style,
- ...stylea,
- fillStyle: attr ? "#fff" : stylea.strokeStyle,
- };
- }
- if (
- line &&
- [VectorType.SingleArrowLine, VectorType.DoubleArrowLine].includes(
- line.category
- ) &&
- line.color
- ) {
- style = {
- ...style,
- fillStyle: line.color,
- strokeStyle: line.color,
- };
- }
- if (line && ["MeasureLine", "FreeMeasureLine"].includes(line.category)) {
- return;
- }
- } else if (vector.category === VectorCategory.Point.FixPoint) {
- const text = dataService.getText(vector?.linkedTextId);
- if (text) {
- style = {
- ...style,
- fillStyle: isScreenStyle() ? "#000" : text.color,
- strokeStyle: isScreenStyle() ? "#000" : text.color,
- };
- }
- }
- if (vector.color) {
- ctx.strokeStyle = vector.color;
- style = {
- ...style,
- strokeStyle: vector.color,
- };
- }
- if (vector.fillColor) {
- style = {
- ...style,
- fillStyle: vector.fillColor,
- };
- }
- const draw = (style) => {
- const radius = vector.radius || style.radius;
- ctx.save();
- ctx.beginPath();
- ctx.arc(pt.x, pt.y, radius, 0, Math.PI * 2, true);
- help.setStyle(ctx, style);
- ctx.stroke();
- ctx.fill();
- ctx.restore();
- };
- if (Settings.selectBasePointId === vector.vectorId && !isScreenStyle()) {
- style = {
- ...style,
- fillStyle: "rgba(255, 143, 40, 1)",
- strokeStyle: "rgba(255,255,255,1)",
- out: style.out && {
- ...style.out,
- strokeStyle: "rgba(255, 143, 40, 1)",
- },
- };
- }
- //console.log(vector, style, Settings.selectBasePointId)
- draw(style);
- if (style.out) {
- draw(style.out);
- }
- if (vector.category === "BasePoint") {
- ctx.font = `${12 * coordinate.ratio}px Microsoft YaHei`;
- const bound = help.getTextCenter(ctx, ui18n.t("tl.basep"));
- const screen = coordinate.getScreenXY(vector);
- const textPt = coordinate.getXYFromScreenNotRatio({
- y: screen.y + bound.height + style.radius + 4 * coordinate.ratio,
- x: screen.x - bound.width / 2,
- });
- ctx.fillStyle = style.fillStyle;
- this.drawTextByInfo(textPt, ui18n.t("tl.basep"), 0, false);
- } else {
- if (import.meta.env.DEV) {
- if (vector.vectorId) {
- // this.drawTextByInfo(vector, vector.vectorId);
- }
- }
- }
- if (vector.category === VectorCategory.Point.FixPoint) {
- let select = false;
- const geo = stateService.getFocusItem();
- if (geo) {
- const realVector = dataService.getGeo(geo.type, geo.vectorId);
- select = realVector && realVector.linkedPointId === vector.vectorId;
- }
- if (attr || select) {
- this.context.beginPath();
- const padding = style.radius * coordinate.ratio;
- this.context.moveTo(pt.x - padding, pt.y - padding);
- this.context.lineTo(pt.x + padding, pt.y - padding);
- this.context.lineTo(pt.x + padding, pt.y + padding);
- this.context.lineTo(pt.x - padding, pt.y + padding);
- this.context.strokeStyle = "rgba(255, 153, 0, 1)";
- this.context.fillStyle = "rgba(255, 153, 0, 0.30)";
- this.context.lineWidth = 2 * coordinate.ratio;
- this.context.setLineDash([6 * coordinate.ratio, 2 * coordinate.ratio]);
- this.context.closePath();
- this.context.stroke();
- this.context.fill();
- }
- }
- ctx.restore();
- }
- drawTextByInfo(position, txt, angle, setStyle = true) {
- const ctx = this.context;
- ctx.save();
- setStyle && help.setVectorStyle(ctx, null, "Text");
- const pt = coordinate.getScreenXY(position);
- const textCenter = help.getTextCenter(ctx, txt);
- // pt.x -= textCenter.x;
- // pt.y -= textCenter.y;
- if (angle) {
- ctx.translate(pt.x, pt.y);
- ctx.rotate(angle);
- ctx.translate(-textCenter.x, -textCenter.y);
- ctx.fillText(txt, 0, 0);
- } else {
- ctx.fillText(txt, pt.x, pt.y);
- }
- ctx.restore();
- }
- // 文字
- drawText(vector) {
- if (!vector.value) {
- return;
- }
- this.context.save();
- const [_, foo] = help.setVectorStyle(this.context, vector);
- const color = isScreenStyle() ? "#000" : vector.color;
- this.context.fillStyle = color;
- this.context.textBaseline = "bottom";
- this.context.font = `${
- vector.fontSize * coordinate.ratio
- }px Microsoft YaHei`;
- const bound = vector
- .getBound(this.context)
- .map(coordinate.getScreenXY.bind(coordinate));
- this.context.fillText(vector.value, bound[3].x, bound[3].y);
- let select = false;
- const geo = stateService.getFocusItem();
- if (geo) {
- const realVector = dataService.getGeo(geo.type, geo.vectorId);
- select = realVector && realVector.linkedTextId === vector.vectorId;
- }
- if (select || foo === "Focus") {
- this.context.beginPath();
- const padding = 2 * coordinate.ratio;
- this.context.moveTo(bound[0].x - padding, bound[0].y - padding);
- this.context.lineTo(bound[1].x + padding, bound[1].y - padding);
- this.context.lineTo(bound[2].x + padding, bound[2].y + padding);
- this.context.lineTo(bound[3].x - padding, bound[3].y + padding);
- this.context.strokeStyle = "rgba(255, 153, 0, 1)";
- this.context.fillStyle = "rgba(255, 153, 0, 0.30)";
- this.context.lineWidth = 2 * coordinate.ratio;
- this.context.setLineDash([6 * coordinate.ratio, 2 * coordinate.ratio]);
- this.context.closePath();
- this.context.stroke();
- this.context.fill();
- }
- this.context.restore();
- vector.displayPoint &&
- this.drawPoint(
- {
- ...vector.center,
- color: color,
- fillColor: color,
- },
- true
- );
- // const bound = help.getTextCenter(this.context, vector.value);
- // // console.log(vector)
- // const screen = coordinate.getScreenXY(vector.center);
- // this.drawTextByInfo(
- // // vector.center,
- // coordinate.getXYFromScreenNotRatio({
- // // y: screen.y + (bound.height + Style.Point.radius),
- // y: screen.y + (bound.height + Style.Point.radius),
- // x: screen.x - bound.width / 2,
- // }),
- // vector.value,
- // -(vector.angle || 0),
- // false
- // );
- // this.context.restore();
- // vector.displayPoint &&
- // this.drawPoint({ ...vector.center, color: vector.color }, true);
- // vector.getBound(this.context).forEach(this.drawPoint.bind(this));
- }
- drawSVG(vector) {
- const points = vector.points.map(coordinate.getScreenXY.bind(coordinate));
- const svgWidth = 64;
- const svgHidth = 64;
- const width = mathUtil.getDistance(points[0], points[1]);
- const height = mathUtil.getDistance(points[0], points[3]);
- const dires = [points[0], { ...points[0], x: 10000 }, points[1]];
- let angle = mathUtil.Angle(...dires) * (Math.PI / 180);
- angle = mathUtil.isClockwise(dires) ? angle : -angle;
- this.context.save();
- this.context.translate(points[0].x, points[0].y);
- this.context.rotate(angle);
- this.context.scale(width / svgWidth, height / svgHidth);
- console.log(width, height);
- const [style, label] = help.getVectorStyle(vector);
- this.context.lineWidth = style.lineWidth / (width / svgWidth);
- this.context.fillStyle = "rgba(0,0,0,0)";
- this.context.strokeStyle = "rgba(0,0,0,0)";
- SVGIcons[vector.type].draw(
- this.context,
- style.fillStyle || "rgba(0,0,0,0)",
- style.strokeStyle || "rgba(0,0,0,0)"
- );
- this.context.restore();
- if (label) {
- this.context.save();
- this.context.beginPath();
- this.context.moveTo(points[0].x, points[0].y);
- this.context.lineTo(points[1].x, points[1].y);
- this.context.lineTo(points[2].x, points[2].y);
- this.context.lineTo(points[3].x, points[3].y);
- this.context.strokeStyle = style.strokeStyle;
- this.context.fillStyle = "rgba(255, 153, 0, 0.30)";
- this.context.lineWidth = 2 * coordinate.ratio;
- this.context.setLineDash([6 * coordinate.ratio, 2 * coordinate.ratio]);
- this.context.closePath();
- this.context.stroke();
- this.context.fill();
- this.context.restore();
- vector.points.forEach((point) =>
- this.drawPoint({
- ...point,
- fillColor: "#fff",
- color: style.strokeStyle,
- radius: 5,
- })
- );
- }
- }
- drawLineText(vector, style) {
- const startReal = dataService.getPoint(vector.startId);
- const endReal = dataService.getPoint(vector.endId);
- help.drawLineText(
- this.context,
- coordinate.getScreenXY(startReal),
- coordinate.getScreenXY(endReal),
- vector.value
- ? Math.round(vector.value * 1000 * 0.1)
- : Math.round(help.getRealDistance(startReal, endReal) * 0.1),
- style
- );
- }
- drawBaseLineLabel(vector) {
- const startReal = dataService.getPoint(vector.startId);
- const start = coordinate.getScreenXY(startReal);
- const endReal = dataService.getPoint(vector.endId);
- const end = coordinate.getScreenXY(endReal);
- const point = mathUtil.translate(
- end,
- start,
- end,
- mathUtil.getDistance(start, end) / 3
- );
- const p4 = help.getPerpendicularPoint(
- start,
- end,
- point,
- 30 * coordinate.ratio
- );
- const ctx = this.context;
- ctx.save();
- ctx.beginPath();
- const [style] = help.setVectorStyle(
- this.context,
- vector,
- vector.category || vector.geoType
- );
- ctx.moveTo(point.x, point.y);
- ctx.lineTo(p4.x, p4.y);
- ctx.stroke();
- const p5 = help.getPerpendicularPoint(
- start,
- end,
- point,
- 35 * coordinate.ratio
- );
- this.context.font = `${12 * coordinate.ratio}px Microsoft YaHei`;
- help.drawLineText(
- this.context,
- help.getPerpendicularPoint(point, p5, p5, 10 * coordinate.ratio),
- help.getPerpendicularPoint(point, p5, p5, -10 * coordinate.ratio),
- ui18n.t("tl.basel"),
- {
- padding: 6 * coordinate.ratio,
- backColor: "rgba(0,0,0,0)",
- fillColor: style.strokeStyle,
- }
- );
- ctx.restore();
- }
- drawCurveLine(vector) {
- // points CurveLine
- const ctx = this.context;
- ctx.save();
- help.setVectorStyle(ctx, vector);
- help.drawStyleLine(
- this.context,
- () => {
- help.transformCoves([vector.curves]).forEach((coves) => {
- help.drawCoves(ctx, coves);
- });
- },
- vector.style,
- vector.weight
- );
- ctx.restore();
- // if (import.meta.env.DEV) {
- vector.points.forEach(this.drawPoint.bind(this));
- // }
- }
- drawLine(vector) {
- const startReal = dataService.getPoint(vector.startId);
- const start = coordinate.getScreenXY(startReal);
- const endReal = dataService.getPoint(vector.endId);
- const end = coordinate.getScreenXY(endReal);
- this.context.save();
- const [style, attr] = help.setVectorStyle(this.context, vector, [
- vector.category,
- vector.geoType,
- "BaseLine",
- ]);
- if (style.dash) {
- this.context.setLineDash(style.dash);
- }
- if (
- [VectorType.SingleArrowLine, VectorType.DoubleArrowLine].includes(
- vector.category
- ) &&
- vector.color
- ) {
- this.context.strokeStyle = vector.color;
- }
- console.log(vector.style);
- help.drawStyleLine(this.context, [start, end], vector.style, vector.weight);
- // vector.category = VectorCategory.Line.LocationLineByFixPoint;
- switch (vector.category) {
- case VectorCategory.Line.SingleArrowLine:
- this.drawArrow(vector);
- break;
- case VectorCategory.Line.DoubleArrowLine:
- this.drawArrow(vector);
- break;
- case VectorCategory.Line.BaseLine:
- this.drawBaseLineLabel(vector);
- break;
- case VectorCategory.Line.LocationLineByFixPoint:
- case VectorCategory.Line.LocationLineByBasePoint:
- case VectorCategory.Line.FreeMeasureLine:
- case VectorCategory.Line.MeasureLine:
- case VectorCategory.Line.PositionLine:
- this.drawLineText(vector, style.text);
- if (
- [
- VectorCategory.Line.FreeMeasureLine,
- VectorCategory.Line.MeasureLine,
- VectorCategory.Line.LocationLineByFixPoint,
- VectorCategory.Line.LocationLineByBasePoint,
- ].includes(vector.category)
- ) {
- this.drawLineArrow([start, end], true, 20);
- }
- break;
- }
- this.context.restore();
- }
- drawElementLine(element) {
- let start = elementService.getPoint(element.startId);
- start = coordinate.getScreenXY(start);
- let end = elementService.getPoint(element.endId);
- end = coordinate.getScreenXY(end);
- this.context.save();
- const [style] = help.setVectorStyle(
- this.context,
- element,
- element.category || element.geoType
- );
- if (style.dash) {
- this.context.setLineDash(style.dash);
- }
- this.context.beginPath();
- this.context.moveTo(start.x, start.y);
- this.context.lineTo(end.x, end.y);
- this.context.stroke();
- this.context.restore();
- }
- }
- const draw = new Draw();
- export { draw };
|