Compare commits
8 Commits
338933940e
...
168e68d3f0
| Author | SHA1 | Date | |
|---|---|---|---|
| 168e68d3f0 | |||
| afef45c1c1 | |||
| 6c8b424afd | |||
| 3d69966e15 | |||
| 99d06f67b8 | |||
|
|
67e62ee905 | ||
| c593f007c8 | |||
| d43d18088a |
@ -35,7 +35,12 @@ export default function Join() {
|
||||
const joinValidation = (formData) => {
|
||||
|
||||
// 전화번호/FAX 정규식 (일본 형식: 0으로 시작, 하이픈 포함)
|
||||
const telRegex = /^0\d{1,4}-\d{1,4}-\d{4}$/
|
||||
const telRegex = /^0\d{1,4}-\d{1,4}-\d{3,4}$/
|
||||
const isValidTel = (value) => {
|
||||
if (!telRegex.test(value)) return false
|
||||
const digitCount = value.replace(/-/g, '').length
|
||||
return digitCount >= 10 && digitCount <= 11
|
||||
}
|
||||
|
||||
|
||||
// 판매대리점 정보 - 판매대리점명
|
||||
@ -77,7 +82,7 @@ export default function Join() {
|
||||
alert(getMessage('common.message.required.data', [getMessage('join.sub1.telNo')]))
|
||||
telNoRef.current.focus()
|
||||
return false
|
||||
} else if (!telRegex.test(telNo)) {
|
||||
} else if (!isValidTel(telNo)) {
|
||||
alert(getMessage('join.validation.check1', [getMessage('join.sub1.telNo')]))
|
||||
telNoRef.current.focus()
|
||||
return false
|
||||
@ -98,7 +103,7 @@ export default function Join() {
|
||||
alert(getMessage('common.message.required.data', [getMessage('join.sub1.fax')]))
|
||||
faxRef.current.focus()
|
||||
return false
|
||||
}else if (!telRegex.test(fax)) {
|
||||
}else if (!isValidTel(fax)) {
|
||||
alert(getMessage('join.validation.check1', [getMessage('join.sub1.fax')]))
|
||||
faxRef.current.focus()
|
||||
return false
|
||||
@ -173,7 +178,7 @@ export default function Join() {
|
||||
alert(getMessage('common.message.required.data', [getMessage('join.sub1.telNo')]))
|
||||
userTelNoRef.current.focus()
|
||||
return false
|
||||
} else if (!telRegex.test(userTelNo)) {
|
||||
} else if (!isValidTel(userTelNo)) {
|
||||
alert(getMessage('join.validation.check1', [getMessage('join.sub1.telNo')]))
|
||||
userTelNoRef.current.focus()
|
||||
return false
|
||||
@ -185,7 +190,7 @@ export default function Join() {
|
||||
alert(getMessage('common.message.required.data', [getMessage('join.sub2.fax')]))
|
||||
userFaxRef.current.focus()
|
||||
return false
|
||||
} else if (!telRegex.test(userFax)) {
|
||||
} else if (!isValidTel(userFax)) {
|
||||
alert(getMessage('join.validation.check1', [getMessage('join.sub2.fax')]))
|
||||
userFaxRef.current.focus()
|
||||
return false
|
||||
|
||||
@ -683,7 +683,7 @@
|
||||
"join.sub1.addr": "住所",
|
||||
"join.sub1.addr_placeholder": "全角50文字以内",
|
||||
"join.sub1.telNo": "電話番号",
|
||||
"join.sub1.telNo_placeholder": "00-0000-0000",
|
||||
"join.sub1.telNo_placeholder": "000-0000-0000 / 0000-000-000",
|
||||
"join.sub1.fax": "FAX番号",
|
||||
"join.sub1.fax_placeholder": "00-0000-0000",
|
||||
"join.sub1.bizNo": "法人番号",
|
||||
@ -702,7 +702,7 @@
|
||||
"join.complete.title": "HANASYS設計ログインID発行申請完了",
|
||||
"join.complete.contents": "※申請したIDが承認されると、担当者情報に入力したEメールアドレスにログイン関連案内メールが送信されます。",
|
||||
"join.complete.email_comment": "担当者のメールアドレス",
|
||||
"join.validation.check1": "{0}形式を確認してください。",
|
||||
"join.validation.check1": "{0}形式(000-0000-0000 / 0000-000-000)を確認してください。",
|
||||
"join.complete.save.confirm": "ID申請を完了後は申請情報の修正が出来ません。申請しますか?",
|
||||
"stuff.gridHeader.lastEditDatetime": "更新日時",
|
||||
"stuff.gridHeader.objectNo": "物件番号",
|
||||
|
||||
@ -683,7 +683,7 @@
|
||||
"join.sub1.addr": "주소",
|
||||
"join.sub1.addr_placeholder": "전각50자이내",
|
||||
"join.sub1.telNo": "전화번호",
|
||||
"join.sub1.telNo_placeholder": "000-0000-0000",
|
||||
"join.sub1.telNo_placeholder": "000-0000-0000 또는 0000-000-000",
|
||||
"join.sub1.fax": "FAX 번호",
|
||||
"join.sub1.fax_placeholder": "00 0000 0000",
|
||||
"join.sub1.bizNo": "법인번호",
|
||||
@ -702,7 +702,7 @@
|
||||
"join.complete.title": "Q.CAST3 로그인ID 발행신청 완료",
|
||||
"join.complete.contents": "※ 신청한 ID가 승인되면 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.",
|
||||
"join.complete.email_comment": "담당자 이메일 주소",
|
||||
"join.validation.check1": "{0} 형식을 확인해주세요.",
|
||||
"join.validation.check1": "{0} 형식(000-0000-0000 또는 0000-000-000)을 확인해주세요.",
|
||||
"join.complete.save.confirm": "Hanwha Japan 담당자에게 ID승인이 요청되면 더 이상 정보를 수정할 수 없습니다. 정말로 요청하시겠습니까?",
|
||||
"stuff.gridHeader.lastEditDatetime": "갱신일시",
|
||||
"stuff.gridHeader.objectNo": "물건번호",
|
||||
|
||||
@ -94,14 +94,14 @@ export const inputNumberCheck = (e) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 영문, 숫자, 특수문자(ASCII)만 입력 체크
|
||||
// 영문, 숫자, 특수문자(_ . # ! & + - @)만 입력 체크
|
||||
export const inputUserIdCheck = (e) => {
|
||||
const input = e.target
|
||||
const allowedRegex = /^[A-Za-z0-9!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?`~]*$/g
|
||||
const allowedRegex = /^[A-Za-z0-9_.#!&+\-@]*$/g
|
||||
if (allowedRegex.test(input.value)) {
|
||||
input.value = input.value
|
||||
} else {
|
||||
input.value = input.value.replace(/[^A-Za-z0-9!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?`~]/g, '')
|
||||
input.value = input.value.replace(/[^A-Za-z0-9_.#!&+\-@]/g, '')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -608,39 +608,53 @@ export const drawGableRoof = (roofId, canvas, textMode) => {
|
||||
}
|
||||
}
|
||||
|
||||
const findEdge = { vertex1: { x: midX, y: midY }, vertex2: { x: midX + roofVector.x * offset, y: midY + roofVector.y * offset } }
|
||||
const edgeDx =
|
||||
Big(findEdge.vertex2.x).minus(Big(findEdge.vertex1.x)).abs().toNumber() < 0.1
|
||||
? 0
|
||||
: Big(findEdge.vertex2.x).minus(Big(findEdge.vertex1.x)).toNumber()
|
||||
const edgeDy =
|
||||
Big(findEdge.vertex2.y).minus(Big(findEdge.vertex1.y)).abs().toNumber() < 0.1
|
||||
? 0
|
||||
: Big(findEdge.vertex2.y).minus(Big(findEdge.vertex1.y)).toNumber()
|
||||
const edgeLength = Math.sqrt(edgeDx * edgeDx + edgeDy * edgeDy)
|
||||
const edgeVector = { x: edgeDx / edgeLength, y: edgeDy / edgeLength }
|
||||
|
||||
const intersectRoofLines = []
|
||||
checkRoofLines.forEach((roofLine) => {
|
||||
const lineEdge = { vertex1: { x: roofLine.x1, y: roofLine.y1 }, vertex2: { x: roofLine.x2, y: roofLine.y2 } }
|
||||
const intersect = edgesIntersection(lineEdge, findEdge)
|
||||
if (intersect) {
|
||||
const intersectDx =
|
||||
Big(intersect.x).minus(Big(findEdge.vertex1.x)).abs().toNumber() < 0.1 ? 0 : Big(intersect.x).minus(Big(findEdge.vertex1.x)).toNumber()
|
||||
const intersectDy =
|
||||
Big(intersect.y).minus(Big(findEdge.vertex1.y)).abs().toNumber() < 0.1 ? 0 : Big(intersect.y).minus(Big(findEdge.vertex1.y)).toNumber()
|
||||
const intersectLength = Math.sqrt(intersectDx * intersectDx + intersectDy * intersectDy)
|
||||
const intersectVector = { x: intersectDx / intersectLength, y: intersectDy / intersectLength }
|
||||
if (edgeVector.x === intersectVector.x && edgeVector.y === intersectVector.y) {
|
||||
intersectRoofLines.push({ roofLine, intersect, length: intersectLength })
|
||||
let currentRoof
|
||||
if (line.attributes.offset === 0) {
|
||||
checkRoofLines.forEach((roofLine) => {
|
||||
const isVerticalSame = line.y1 === roofLine.y1 && line.y2 === roofLine.y2
|
||||
const isHorizontalSame = line.x1 === roofLine.x1 && line.x2 === roofLine.x2
|
||||
if (
|
||||
(isVerticalSame || isHorizontalSame) &&
|
||||
(isPointOnLineNew(roofLine, { x: line.x1, y: line.y1 }) || isPointOnLineNew(roofLine, { x: line.x2, y: line.y2 }))
|
||||
) {
|
||||
currentRoof = { roofLine }
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
const findEdge = { vertex1: { x: midX, y: midY }, vertex2: { x: midX + roofVector.x * offset, y: midY + roofVector.y * offset } }
|
||||
const edgeDx =
|
||||
Big(findEdge.vertex2.x).minus(Big(findEdge.vertex1.x)).abs().toNumber() < 0.1
|
||||
? 0
|
||||
: Big(findEdge.vertex2.x).minus(Big(findEdge.vertex1.x)).toNumber()
|
||||
const edgeDy =
|
||||
Big(findEdge.vertex2.y).minus(Big(findEdge.vertex1.y)).abs().toNumber() < 0.1
|
||||
? 0
|
||||
: Big(findEdge.vertex2.y).minus(Big(findEdge.vertex1.y)).toNumber()
|
||||
const edgeLength = Math.sqrt(edgeDx * edgeDx + edgeDy * edgeDy)
|
||||
const edgeVector = { x: edgeDx / edgeLength, y: edgeDy / edgeLength }
|
||||
|
||||
intersectRoofLines.sort((a, b) => a.length - b.length)
|
||||
let currentRoof = intersectRoofLines.find((roof) => isPointOnLineNew(roof.roofLine, roof.intersect) && roof.length - offset < 0.1)
|
||||
if (!currentRoof) {
|
||||
currentRoof = intersectRoofLines[0]
|
||||
const intersectRoofLines = []
|
||||
checkRoofLines.forEach((roofLine) => {
|
||||
const lineEdge = { vertex1: { x: roofLine.x1, y: roofLine.y1 }, vertex2: { x: roofLine.x2, y: roofLine.y2 } }
|
||||
const intersect = edgesIntersection(lineEdge, findEdge)
|
||||
if (intersect) {
|
||||
const intersectDx =
|
||||
Big(intersect.x).minus(Big(findEdge.vertex1.x)).abs().toNumber() < 0.1 ? 0 : Big(intersect.x).minus(Big(findEdge.vertex1.x)).toNumber()
|
||||
const intersectDy =
|
||||
Big(intersect.y).minus(Big(findEdge.vertex1.y)).abs().toNumber() < 0.1 ? 0 : Big(intersect.y).minus(Big(findEdge.vertex1.y)).toNumber()
|
||||
const intersectLength = Math.sqrt(intersectDx * intersectDx + intersectDy * intersectDy)
|
||||
const intersectVector = { x: intersectDx / intersectLength, y: intersectDy / intersectLength }
|
||||
if (edgeVector.x === intersectVector.x && edgeVector.y === intersectVector.y) {
|
||||
intersectRoofLines.push({ roofLine, intersect, length: intersectLength })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
intersectRoofLines.sort((a, b) => a.length - b.length)
|
||||
currentRoof = intersectRoofLines.find((roof) => isPointOnLineNew(roof.roofLine, roof.intersect) && roof.length - offset < 0.1)
|
||||
if (!currentRoof) {
|
||||
currentRoof = intersectRoofLines[0]
|
||||
}
|
||||
}
|
||||
|
||||
let startPoint, endPoint
|
||||
@ -924,11 +938,16 @@ export const drawGableRoof = (roofId, canvas, textMode) => {
|
||||
const y2 = analyze.endPoint.y
|
||||
|
||||
const lineVector = { x: 0, y: 0 }
|
||||
if (analyze.isHorizontal) {
|
||||
lineVector.x = Math.sign(analyze.roofLine.y1 - currentLine.attributes.originPoint.y1)
|
||||
}
|
||||
if (analyze.isVertical) {
|
||||
lineVector.y = Math.sign(analyze.roofLine.x1 - currentLine.attributes.originPoint.x1)
|
||||
if (currentLine.attributes.offset === 0) {
|
||||
lineVector.x = analyze.roofVector.y
|
||||
lineVector.y = analyze.roofVector.x
|
||||
} else {
|
||||
if (analyze.isHorizontal) {
|
||||
lineVector.x = Math.sign(analyze.roofLine.y1 - currentLine.attributes.originPoint.y1)
|
||||
}
|
||||
if (analyze.isVertical) {
|
||||
lineVector.y = Math.sign(analyze.roofLine.x1 - currentLine.attributes.originPoint.x1)
|
||||
}
|
||||
}
|
||||
|
||||
const overlapLines = []
|
||||
@ -1904,40 +1923,53 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
roofVector = { x: 1, y: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
const findEdge = { vertex1: { x: midX, y: midY }, vertex2: { x: midX + roofVector.x * offset, y: midY + roofVector.y * offset } }
|
||||
const edgeDx =
|
||||
Big(findEdge.vertex2.x).minus(Big(findEdge.vertex1.x)).abs().toNumber() < 0.1
|
||||
? 0
|
||||
: Big(findEdge.vertex2.x).minus(Big(findEdge.vertex1.x)).toNumber()
|
||||
const edgeDy =
|
||||
Big(findEdge.vertex2.y).minus(Big(findEdge.vertex1.y)).abs().toNumber() < 0.1
|
||||
? 0
|
||||
: Big(findEdge.vertex2.y).minus(Big(findEdge.vertex1.y)).toNumber()
|
||||
const edgeLength = Math.sqrt(edgeDx * edgeDx + edgeDy * edgeDy)
|
||||
const edgeVector = { x: edgeDx / edgeLength, y: edgeDy / edgeLength }
|
||||
|
||||
const intersectRoofLines = []
|
||||
checkRoofLines.forEach((roofLine) => {
|
||||
const lineEdge = { vertex1: { x: roofLine.x1, y: roofLine.y1 }, vertex2: { x: roofLine.x2, y: roofLine.y2 } }
|
||||
const intersect = edgesIntersection(lineEdge, findEdge)
|
||||
if (intersect) {
|
||||
const intersectDx =
|
||||
Big(intersect.x).minus(Big(findEdge.vertex1.x)).abs().toNumber() < 0.1 ? 0 : Big(intersect.x).minus(Big(findEdge.vertex1.x)).toNumber()
|
||||
const intersectDy =
|
||||
Big(intersect.y).minus(Big(findEdge.vertex1.y)).abs().toNumber() < 0.1 ? 0 : Big(intersect.y).minus(Big(findEdge.vertex1.y)).toNumber()
|
||||
const intersectLength = Math.sqrt(intersectDx * intersectDx + intersectDy * intersectDy)
|
||||
const intersectVector = { x: intersectDx / intersectLength, y: intersectDy / intersectLength }
|
||||
if (edgeVector.x === intersectVector.x && edgeVector.y === intersectVector.y) {
|
||||
intersectRoofLines.push({ roofLine, intersect, length: intersectLength })
|
||||
let currentRoof
|
||||
if (line.attributes.offset === 0) {
|
||||
checkRoofLines.forEach((roofLine) => {
|
||||
const isVerticalSame = line.y1 === roofLine.y1 && line.y2 === roofLine.y2
|
||||
const isHorizontalSame = line.x1 === roofLine.x1 && line.x2 === roofLine.x2
|
||||
if (
|
||||
(isVerticalSame || isHorizontalSame) &&
|
||||
(isPointOnLineNew(roofLine, { x: line.x1, y: line.y1 }) || isPointOnLineNew(roofLine, { x: line.x2, y: line.y2 }))
|
||||
) {
|
||||
currentRoof = { roofLine }
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
const findEdge = { vertex1: { x: midX, y: midY }, vertex2: { x: midX + roofVector.x * offset, y: midY + roofVector.y * offset } }
|
||||
const edgeDx =
|
||||
Big(findEdge.vertex2.x).minus(Big(findEdge.vertex1.x)).abs().toNumber() < 0.1
|
||||
? 0
|
||||
: Big(findEdge.vertex2.x).minus(Big(findEdge.vertex1.x)).toNumber()
|
||||
const edgeDy =
|
||||
Big(findEdge.vertex2.y).minus(Big(findEdge.vertex1.y)).abs().toNumber() < 0.1
|
||||
? 0
|
||||
: Big(findEdge.vertex2.y).minus(Big(findEdge.vertex1.y)).toNumber()
|
||||
const edgeLength = Math.sqrt(edgeDx * edgeDx + edgeDy * edgeDy)
|
||||
const edgeVector = { x: edgeDx / edgeLength, y: edgeDy / edgeLength }
|
||||
|
||||
intersectRoofLines.sort((a, b) => a.length - b.length)
|
||||
let currentRoof = intersectRoofLines.find((roof) => isPointOnLineNew(roof.roofLine, roof.intersect) && roof.length - offset < 0.1)
|
||||
if (!currentRoof) {
|
||||
currentRoof = intersectRoofLines[0]
|
||||
const intersectRoofLines = []
|
||||
checkRoofLines.forEach((roofLine) => {
|
||||
const lineEdge = { vertex1: { x: roofLine.x1, y: roofLine.y1 }, vertex2: { x: roofLine.x2, y: roofLine.y2 } }
|
||||
const intersect = edgesIntersection(lineEdge, findEdge)
|
||||
if (intersect) {
|
||||
const intersectDx =
|
||||
Big(intersect.x).minus(Big(findEdge.vertex1.x)).abs().toNumber() < 0.1 ? 0 : Big(intersect.x).minus(Big(findEdge.vertex1.x)).toNumber()
|
||||
const intersectDy =
|
||||
Big(intersect.y).minus(Big(findEdge.vertex1.y)).abs().toNumber() < 0.1 ? 0 : Big(intersect.y).minus(Big(findEdge.vertex1.y)).toNumber()
|
||||
const intersectLength = Math.sqrt(intersectDx * intersectDx + intersectDy * intersectDy)
|
||||
const intersectVector = { x: intersectDx / intersectLength, y: intersectDy / intersectLength }
|
||||
if (edgeVector.x === intersectVector.x && edgeVector.y === intersectVector.y) {
|
||||
intersectRoofLines.push({ roofLine, intersect, length: intersectLength })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
intersectRoofLines.sort((a, b) => a.length - b.length)
|
||||
currentRoof = intersectRoofLines.find((roof) => isPointOnLineNew(roof.roofLine, roof.intersect) && roof.length - offset < 0.1)
|
||||
if (!currentRoof) {
|
||||
currentRoof = intersectRoofLines[0]
|
||||
}
|
||||
}
|
||||
|
||||
let startPoint, endPoint
|
||||
@ -3289,6 +3321,8 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
prevLine = baseLines[(index - 1 + baseLines.length) % baseLines.length]
|
||||
}
|
||||
})
|
||||
const prevIndex = baseLines.findIndex((line) => line === prevLine)
|
||||
const nextIndex = baseLines.findIndex((line) => line === nextLine)
|
||||
|
||||
//양옆이 처마가 아닐때 패스
|
||||
if (prevLine.attributes.type !== LINE_TYPE.WALLLINE.EAVES || nextLine.attributes.type !== LINE_TYPE.WALLLINE.EAVES) {
|
||||
@ -3377,14 +3411,24 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
ridgePoint[2] += ridgeVector.x * offset
|
||||
ridgePoint[3] += ridgeVector.y * offset
|
||||
|
||||
linesAnalysis.push({
|
||||
start: { x: ridgePoint[0], y: ridgePoint[1] },
|
||||
end: { x: ridgePoint[2], y: ridgePoint[3] },
|
||||
left: baseLines.findIndex((line) => line === prevLine),
|
||||
right: baseLines.findIndex((line) => line === nextLine),
|
||||
type: TYPES.RIDGE,
|
||||
degree: 0,
|
||||
})
|
||||
const alreadyRidge = linesAnalysis.find(
|
||||
(line) =>
|
||||
line.type === TYPES.RIDGE &&
|
||||
line.start.x === ridgePoint[0] &&
|
||||
line.start.y === ridgePoint[1] &&
|
||||
line.end.x === ridgePoint[2] &&
|
||||
line.end.y === ridgePoint[3],
|
||||
)
|
||||
if (!alreadyRidge) {
|
||||
linesAnalysis.push({
|
||||
start: { x: ridgePoint[0], y: ridgePoint[1] },
|
||||
end: { x: ridgePoint[2], y: ridgePoint[3] },
|
||||
left: prevIndex,
|
||||
right: nextIndex,
|
||||
type: TYPES.RIDGE,
|
||||
degree: 0,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (beforePrevLine.attributes.type === LINE_TYPE.WALLLINE.GABLE) {
|
||||
const beforeVector = {
|
||||
@ -3983,14 +4027,24 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
endPoint = { x: point[0], y: point[1] }
|
||||
}
|
||||
}
|
||||
linesAnalysis.push({
|
||||
start: startPoint,
|
||||
end: endPoint,
|
||||
left: baseLines.findIndex((line) => line === r.left),
|
||||
right: baseLines.findIndex((line) => line === r.right),
|
||||
type: TYPES.RIDGE,
|
||||
degree: 0,
|
||||
})
|
||||
const alreadyRidge = linesAnalysis.find(
|
||||
(line) =>
|
||||
line.type === TYPES.RIDGE &&
|
||||
line.start.x === startPoint.x &&
|
||||
line.start.y === startPoint.y &&
|
||||
line.end.x === endPoint.x &&
|
||||
line.end.y === endPoint.y,
|
||||
)
|
||||
if (!alreadyRidge) {
|
||||
linesAnalysis.push({
|
||||
start: startPoint,
|
||||
end: endPoint,
|
||||
left: prevIndex,
|
||||
right: nextIndex,
|
||||
type: TYPES.RIDGE,
|
||||
degree: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -4036,8 +4090,8 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
linesAnalysis.push({
|
||||
start: startPoint,
|
||||
end: { x: correctPoint.x, y: correctPoint.y },
|
||||
left: baseLines.findIndex((line) => line === prevLine),
|
||||
right: baseLines.findIndex((line) => line === nextLine),
|
||||
left: prevIndex,
|
||||
right: nextIndex,
|
||||
type: TYPES.GABLE_LINE,
|
||||
degree: getDegreeByChon(prevLine.attributes.pitch),
|
||||
gableId: baseLines.findIndex((line) => line === currentLine),
|
||||
@ -4464,14 +4518,13 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
if (isOpposite) {
|
||||
const points = [currentLine.start.x, currentLine.start.y, partnerLine.start.x, partnerLine.start.y]
|
||||
const length = Math.sqrt((points[0] - points[2]) ** 2 + (points[1] - points[3]) ** 2)
|
||||
|
||||
if (length > 0) {
|
||||
const isDiagonal = Math.abs(points[0] - points[2]) >= 1 && Math.abs(points[1] - points[3]) >= 1
|
||||
if (length > EPSILON) {
|
||||
if (currentLine.type === TYPES.HIP) {
|
||||
innerLines.push(drawHipLine(points, canvas, roof, textMode, currentDegree, currentDegree))
|
||||
} else if (currentLine.type === TYPES.RIDGE) {
|
||||
} else if (currentLine.type === TYPES.RIDGE && !isDiagonal) {
|
||||
innerLines.push(drawRidgeLine(points, canvas, roof, textMode))
|
||||
} else if (currentLine.type === TYPES.NEW) {
|
||||
const isDiagonal = Math.abs(points[0] - points[2]) >= 1 && Math.abs(points[1] - points[3]) >= 1
|
||||
if (isDiagonal && almostEqual(Math.abs(points[0] - points[2]), Math.abs(points[1] - points[3]))) {
|
||||
innerLines.push(drawHipLine(points, canvas, roof, textMode, currentDegree, currentDegree))
|
||||
}
|
||||
@ -4496,11 +4549,12 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
const length = Math.sqrt((points[0].x - points[1].x) ** 2 + (points[0].y - points[1].y) ** 2)
|
||||
if (length < EPSILON) return
|
||||
const isDiagonal = Math.abs(points[0].x - points[1].x) >= 1 && Math.abs(points[0].y - points[1].y) >= 1
|
||||
if (isDiagonal) {
|
||||
if (isDiagonal && almostEqual(Math.abs(points[0] - points[2]), Math.abs(points[1] - points[3]))) {
|
||||
innerLines.push(
|
||||
drawHipLine([points[0].x, points[0].y, points[1].x, points[1].y], canvas, roof, textMode, currentDegree, currentDegree),
|
||||
)
|
||||
} else {
|
||||
}
|
||||
if (!isDiagonal) {
|
||||
innerLines.push(drawRidgeLine([points[0].x, points[0].y, points[1].x, points[1].y], canvas, roof, textMode))
|
||||
}
|
||||
proceedAnalysis.push(currentLine, partnerLine)
|
||||
@ -4545,7 +4599,6 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//케라바에서 파생된 하단 지붕 라인처리
|
||||
const downRoofGable = []
|
||||
//처마에서 파생된 하단 지붕 라인 처리
|
||||
|
||||
@ -401,26 +401,70 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
|
||||
console.log('baseLinePoints:', orderedBaseLinePoints)
|
||||
|
||||
// baseLinePoint에서 roofLinePoint 방향으로 45도 대각선 확장 후 가장 가까운 접점 계산
|
||||
let roofLineContactPoints = orderedBaseLinePoints.map((point, index) => {
|
||||
// 각 포인트의 dx, dy, sign 정보 수집
|
||||
const contactData = orderedBaseLinePoints.map((point, index) => {
|
||||
const roofPoint = roofLinePoints[index]
|
||||
if (!roofPoint) return point
|
||||
if (!roofPoint) return { dx: 0, dy: 0, signDx: 0, signDy: 0 }
|
||||
|
||||
const dx = roofPoint.x - point.x
|
||||
const dy = roofPoint.y - point.y
|
||||
const absDx = Math.abs(dx)
|
||||
const absDy = Math.abs(dy)
|
||||
return { dx, dy, signDx: Math.sign(dx), signDy: Math.sign(dy) }
|
||||
})
|
||||
|
||||
// maxStep: 모든 포인트 중 가장 큰 45도 step
|
||||
const maxStep = contactData.reduce((max, data) => {
|
||||
return Math.max(max, Math.min(Math.abs(data.dx), Math.abs(data.dy)))
|
||||
}, 0)
|
||||
|
||||
// baseLine 폴리곤의 중심 계산 (확장 방향 결정용)
|
||||
const centroid = orderedBaseLinePoints.reduce((acc, p) => {
|
||||
acc.x += p.x / orderedBaseLinePoints.length
|
||||
acc.y += p.y / orderedBaseLinePoints.length
|
||||
return acc
|
||||
}, { x: 0, y: 0 })
|
||||
|
||||
// 모든 포인트를 동일한 maxStep으로 45도 확장
|
||||
let roofLineContactPoints = orderedBaseLinePoints.map((point, index) => {
|
||||
const data = contactData[index]
|
||||
const { dx, dy } = data
|
||||
|
||||
// dx 또는 dy가 0인 경우 중심에서 바깥쪽 방향으로 확장
|
||||
let signDx = data.signDx
|
||||
let signDy = data.signDy
|
||||
if (signDx === 0) {
|
||||
signDx = point.x >= centroid.x ? 1 : -1
|
||||
}
|
||||
if (signDy === 0) {
|
||||
signDy = point.y >= centroid.y ? 1 : -1
|
||||
}
|
||||
|
||||
return {
|
||||
x: point.x + signDx * maxStep,
|
||||
y: point.y + signDy * maxStep
|
||||
}
|
||||
})
|
||||
|
||||
const maxContactDistance = Math.hypot(maxStep, maxStep)
|
||||
|
||||
let changRoofLinePoints = orderedBaseLinePoints.map((point, index) => {
|
||||
const contactPoint = roofLineContactPoints[index]
|
||||
if (!contactPoint) return point
|
||||
|
||||
const dx = contactPoint.x - point.x
|
||||
const dy = contactPoint.y - point.y
|
||||
const len = Math.hypot(dx, dy)
|
||||
|
||||
// 거리가 0이면 이미 같은 위치
|
||||
if (absDx === 0 && absDy === 0) return point
|
||||
if (len === 0) return point
|
||||
|
||||
const step = Math.min(absDx, absDy)
|
||||
const step = maxContactDistance
|
||||
if (step === 0) return point
|
||||
|
||||
const nextX = point.x + Math.sign(dx) * step
|
||||
const nextY = point.y + Math.sign(dy) * step
|
||||
const nextX = point.x + (dx / len) * step
|
||||
const nextY = point.y + (dy / len) * step
|
||||
return {
|
||||
x: Number(nextX.toFixed(1)),
|
||||
y: Number(nextY.toFixed(1))
|
||||
x: nextX,
|
||||
y: nextY
|
||||
}
|
||||
})
|
||||
|
||||
@ -429,8 +473,11 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
|
||||
roofLineContactPoints = movingLineFromSkeleton(roofId, canvas)
|
||||
}
|
||||
|
||||
console.log('points:', roofLineContactPoints)
|
||||
const geoJSONPolygon = toGeoJSON(roofLineContactPoints)
|
||||
// changRoofLinePoints 좌표를 roof.skeletonPoints에 저장 (원본 roof.points는 유지)
|
||||
roof.skeletonPoints = changRoofLinePoints.map(p => ({ x: p.x, y: p.y }))
|
||||
|
||||
console.log('points:', changRoofLinePoints)
|
||||
const geoJSONPolygon = toGeoJSON(changRoofLinePoints)
|
||||
|
||||
try {
|
||||
// SkeletonBuilder는 닫히지 않은 폴리곤을 기대하므로 마지막 점 제거
|
||||
@ -440,7 +487,7 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
|
||||
// 스켈레톤 데이터를 기반으로 내부선 생성
|
||||
roof.innerLines = roof.innerLines || []
|
||||
roof.innerLines = createInnerLinesFromSkeleton(roofId, canvas, skeleton, textMode)
|
||||
|
||||
console.log("roofInnerLines:::", roof.innerLines);
|
||||
// 캔버스에 스켈레톤 상태 저장
|
||||
if (!canvas.skeletonStates) {
|
||||
canvas.skeletonStates = {}
|
||||
@ -1722,10 +1769,28 @@ function processEavesEdge(roofId, canvas, skeleton, edgeResult, skeletonLines) {
|
||||
}
|
||||
|
||||
let eavesLines = []
|
||||
// 확장된 외곽선 판별용
|
||||
const skPts = roof.skeletonPoints || []
|
||||
const isSkeletonOuterEdge = (p1, p2, tolerance = 0.5) => {
|
||||
for (let si = 0; si < skPts.length; si++) {
|
||||
const sp1 = skPts[si]
|
||||
const sp2 = skPts[(si + 1) % skPts.length]
|
||||
if ((Math.abs(p1.x - sp1.x) < tolerance && Math.abs(p1.y - sp1.y) < tolerance &&
|
||||
Math.abs(p2.x - sp2.x) < tolerance && Math.abs(p2.y - sp2.y) < tolerance) ||
|
||||
(Math.abs(p1.x - sp2.x) < tolerance && Math.abs(p1.y - sp2.y) < tolerance &&
|
||||
Math.abs(p2.x - sp1.x) < tolerance && Math.abs(p2.y - sp1.y) < tolerance)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for (let i = 0; i < polygonPoints.length; i++) {
|
||||
const p1 = polygonPoints[i];
|
||||
const p2 = polygonPoints[(i + 1) % polygonPoints.length];
|
||||
|
||||
// 확장된 외곽선에 해당하는 edge는 스킵
|
||||
if (skPts.length > 0 && isSkeletonOuterEdge(p1, p2)) continue
|
||||
|
||||
// 지붕 경계선과 교차 확인 및 클리핑
|
||||
const clippedLine = clipLineToRoofBoundary(p1, p2, roof.lines, roof.moveSelectLine);
|
||||
@ -1900,7 +1965,7 @@ function addRawLine(id, skeletonLines, p1, p2, lineType, color, width, pitch, is
|
||||
};
|
||||
|
||||
skeletonLines.push(newLine);
|
||||
console.log('skeletonLines', skeletonLines);
|
||||
//console.log('skeletonLines', skeletonLines);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user