모듈 api 연동
This commit is contained in:
parent
6c5968e8b2
commit
c880b0bf13
@ -17,7 +17,7 @@ import { useOnClickOutside } from 'usehooks-ts'
|
|||||||
*/
|
*/
|
||||||
export default function QSelectBox({
|
export default function QSelectBox({
|
||||||
title = '',
|
title = '',
|
||||||
options,
|
options = [],
|
||||||
onChange,
|
onChange,
|
||||||
value,
|
value,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
@ -39,7 +39,11 @@ export default function QSelectBox({
|
|||||||
|
|
||||||
//value가 없으면 showKey가 있으면 우선 보여준다
|
//value가 없으면 showKey가 있으면 우선 보여준다
|
||||||
if (showKey !== '' && !value) {
|
if (showKey !== '' && !value) {
|
||||||
return options[0][showKey]
|
if (options.length > 0) {
|
||||||
|
return title
|
||||||
|
} else {
|
||||||
|
return options[0][showKey]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//value가 있으면 sourceKey와 targetKey를 비교하여 보여준다
|
//value가 있으면 sourceKey와 targetKey를 비교하여 보여준다
|
||||||
@ -65,7 +69,7 @@ export default function QSelectBox({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// value && handleClickSelectOption(value)
|
// value && handleClickSelectOption(value)
|
||||||
setSelected(handleInitState())
|
setSelected(handleInitState())
|
||||||
}, [value, sourceKey, targetKey, showKey])
|
}, [options, value, sourceKey, targetKey, showKey])
|
||||||
|
|
||||||
useOnClickOutside(ref, handleClose)
|
useOnClickOutside(ref, handleClose)
|
||||||
|
|
||||||
@ -73,11 +77,12 @@ export default function QSelectBox({
|
|||||||
<div className={`sort-select ${openSelect ? 'active' : ''}`} ref={ref} onClick={disabled ? () => {} : () => setOpenSelect(!openSelect)}>
|
<div className={`sort-select ${openSelect ? 'active' : ''}`} ref={ref} onClick={disabled ? () => {} : () => setOpenSelect(!openSelect)}>
|
||||||
<p>{selected}</p>
|
<p>{selected}</p>
|
||||||
<ul className="select-item-wrap">
|
<ul className="select-item-wrap">
|
||||||
{options?.map((option, index) => (
|
{options?.length > 0 &&
|
||||||
<li key={option.id || index} className="select-item" onClick={() => handleClickSelectOption(option)}>
|
options?.map((option, index) => (
|
||||||
<button key={option.id + 'btn'}>{showKey !== '' ? option[showKey] : option.name}</button>
|
<li key={option.id || index} className="select-item" onClick={() => handleClickSelectOption(option)}>
|
||||||
</li>
|
<button key={option.id + 'btn'}>{showKey !== '' ? option[showKey] : option.name}</button>
|
||||||
))}
|
</li>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,9 +1,75 @@
|
|||||||
import QSelectBox from '@/components/common/select/QSelectBox'
|
import QSelectBox from '@/components/common/select/QSelectBox'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { canvasSettingState, selectedModuleState, checkedModuleState, pitchSelector } from '@/store/canvasAtom'
|
||||||
|
import { useEffect, useReducer, useState } from 'react'
|
||||||
|
import { useRecoilValue, useRecoilState } from 'recoil'
|
||||||
|
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||||
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||||
|
import { addedRoofsState } from '@/store/settingAtom'
|
||||||
|
|
||||||
export default function Module({}) {
|
export default function Module({}) {
|
||||||
|
const canvasSetting = useRecoilValue(canvasSettingState) //캔버스 기본 셋팅
|
||||||
|
const addedRoofs = useRecoilValue(addedRoofsState) //지붕재 선택
|
||||||
|
|
||||||
|
const [globalPitch, setGlobalPitch] = useRecoilState(pitchSelector)
|
||||||
|
|
||||||
|
const [roofTab, setRoofTab] = useState(0)
|
||||||
|
const [moduleList, setModuleList] = useState([{}])
|
||||||
|
const [roofMaterial, setRoofMaterial] = useState(addedRoofs[0])
|
||||||
|
const [raftCodes, setRaftCodes] = useState([])
|
||||||
|
|
||||||
|
const { getModuleTypeItemList, getTrestleList } = useMasterController()
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const SelectOption01 = [{ name: '0' }, { name: '0' }, { name: '0' }, { name: '0' }]
|
const { findCommonCode } = useCommonCode()
|
||||||
|
|
||||||
|
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈
|
||||||
|
const [selectedTrestle, setSelectedTrestle] = useState({}) //선택된 가대
|
||||||
|
const [selectedConstMthd, setSelectedConstMthd] = useState({}) //선택된 공법
|
||||||
|
const [selectedRoofBase, setSelectedRoofBase] = useState({}) //선택된 지붕밑바탕
|
||||||
|
|
||||||
|
const [selectedOptions, dispatchSelectedOptions] = useReducer(
|
||||||
|
(prevState, nextState) => {
|
||||||
|
return { ...prevState, ...nextState }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
module: {},
|
||||||
|
roofs: [],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const displayPitch = canvasSetting.roofAngleSet === 'slope' ? '寸' : '度'
|
||||||
|
|
||||||
|
const [trestleList, setTrestleList] = useState([])
|
||||||
|
const [constMthdList, setConstMthdList] = useState([])
|
||||||
|
const [roofBaseList, setRoofBaseList] = useState([])
|
||||||
|
|
||||||
|
let optionParams = {
|
||||||
|
moduleTpCd: '',
|
||||||
|
roofMatlCd: '',
|
||||||
|
raftBaseCd: '',
|
||||||
|
trestleMkrCd: '',
|
||||||
|
constMthdCd: '',
|
||||||
|
roofBaseCd: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
//서까래 코드
|
||||||
|
const raftCodeList = findCommonCode('203800')
|
||||||
|
|
||||||
|
raftCodeList.forEach((obj) => {
|
||||||
|
obj.name = obj.clCodeNm
|
||||||
|
obj.id = obj.clCode
|
||||||
|
})
|
||||||
|
setRaftCodes(raftCodeList)
|
||||||
|
|
||||||
|
//지붕재 선택
|
||||||
|
const roofsIds = addedRoofs.filter((obj) => obj.roofMatlCd).map((obj) => obj.roofMatlCd)
|
||||||
|
if (roofsIds.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getModuleData(roofsIds)
|
||||||
|
}, [])
|
||||||
|
|
||||||
const moduleData = {
|
const moduleData = {
|
||||||
header: [
|
header: [
|
||||||
{ name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' },
|
{ name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' },
|
||||||
@ -14,23 +80,7 @@ export default function Module({}) {
|
|||||||
{ name: `${getMessage('width')} (mm)`, prop: 'width' },
|
{ name: `${getMessage('width')} (mm)`, prop: 'width' },
|
||||||
{ name: `${getMessage('output')} (W)`, prop: 'output' },
|
{ name: `${getMessage('output')} (W)`, prop: 'output' },
|
||||||
],
|
],
|
||||||
rows: [
|
rows: [],
|
||||||
{
|
|
||||||
module: { name: 'Re.RISE-G3 440', color: '#AA6768' },
|
|
||||||
height: { name: '1134' },
|
|
||||||
width: { name: '1722' },
|
|
||||||
output: { name: '440' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
module: {
|
|
||||||
name: 'Re.RISE MS-G3 290',
|
|
||||||
color: '#67A2AA',
|
|
||||||
},
|
|
||||||
height: { name: '1134' },
|
|
||||||
width: { name: '1722' },
|
|
||||||
output: { name: '240' },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
const surfaceTypes = [
|
const surfaceTypes = [
|
||||||
{ id: 1, name: 'Ⅱ', value: 'Ⅱ' },
|
{ id: 1, name: 'Ⅱ', value: 'Ⅱ' },
|
||||||
@ -42,6 +92,109 @@ export default function Module({}) {
|
|||||||
const windSpeeds = Array.from({ length: 7 }).map((data, index) => {
|
const windSpeeds = Array.from({ length: 7 }).map((data, index) => {
|
||||||
return { id: index, name: index * 2 + 30, value: index * 2 + 30 }
|
return { id: index, name: index * 2 + 30, value: index * 2 + 30 }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const handleRoofTab = (tab) => {
|
||||||
|
setRoofMaterial(addedRoofs[tab])
|
||||||
|
setRoofTab(tab)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangeModule = (option) => {
|
||||||
|
setSelectedModules(option) //선택값 저장
|
||||||
|
|
||||||
|
optionParams = {
|
||||||
|
moduleTpCd: option.itemTp,
|
||||||
|
roofMatlCd: roofMaterial.roofMatlCd,
|
||||||
|
raftBaseCd: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
getModuleOptionsListData(optionParams, 'trestleList')
|
||||||
|
|
||||||
|
dispatchSelectedOptions({
|
||||||
|
module: option,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangeTrestle = (option) => {
|
||||||
|
setSelectedTrestle(option) //선택값 저장
|
||||||
|
|
||||||
|
optionParams = {
|
||||||
|
moduleTpCd: selectedModules.itemTp,
|
||||||
|
roofMatlCd: roofMaterial.roofMatlCd,
|
||||||
|
raftBaseCd: '',
|
||||||
|
trestleMkrCd: option.trestleMkrCd,
|
||||||
|
}
|
||||||
|
|
||||||
|
getModuleOptionsListData(optionParams, 'constMthdList')
|
||||||
|
|
||||||
|
selectedOptions.roofs.map((roof) => {
|
||||||
|
if (roof.id === tab) {
|
||||||
|
roof.trestle = option
|
||||||
|
} else {
|
||||||
|
roof.trestle = {
|
||||||
|
id: tab,
|
||||||
|
trestle: option,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
dispatchSelectedOptions({
|
||||||
|
roofs: selectedOptions.roofs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangeConstMthd = (option) => {
|
||||||
|
setSelectedConstMthd(option) //선택된값 저장
|
||||||
|
|
||||||
|
optionParams = {
|
||||||
|
moduleTpCd: selectedModules.itemTp,
|
||||||
|
roofMatlCd: roofMaterial.roofMatlCd,
|
||||||
|
raftBaseCd: '',
|
||||||
|
trestleMkrCd: selectedTrestle.trestleMkrCd,
|
||||||
|
constMthdCd: option.constMthdCd,
|
||||||
|
}
|
||||||
|
|
||||||
|
getModuleOptionsListData(optionParams, 'roofBaseList')
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('roofMaterial', roofMaterial)
|
||||||
|
}, [roofMaterial])
|
||||||
|
|
||||||
|
const getModuleData = async (roofsIds) => {
|
||||||
|
const list = await getModuleTypeItemList(roofsIds)
|
||||||
|
//selectbox에 이름을 넣는다
|
||||||
|
list.data.forEach((item) => {
|
||||||
|
item.name = item.itemNm
|
||||||
|
})
|
||||||
|
//셀렉트박스 데이터 초기화
|
||||||
|
setModuleList(list.data)
|
||||||
|
setTrestleList([])
|
||||||
|
setConstMthdList([])
|
||||||
|
setRoofBaseList([])
|
||||||
|
}
|
||||||
|
|
||||||
|
const getModuleOptionsListData = async (params, optionsName) => {
|
||||||
|
const optionsList = await getTrestleList(params)
|
||||||
|
|
||||||
|
if (optionsName === 'trestleList') {
|
||||||
|
setTrestleList(optionsList.data)
|
||||||
|
setConstMthdList([])
|
||||||
|
setRoofBaseList([])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optionsName === 'constMthdList') {
|
||||||
|
setConstMthdList(optionsList.data)
|
||||||
|
setRoofBaseList([])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optionsName === 'roofBaseList') {
|
||||||
|
setRoofBaseList(optionsList.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('selectedOptions', selectedOptions)
|
||||||
|
}, [selectedOptions])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="module-table-flex-wrap mb10">
|
<div className="module-table-flex-wrap mb10">
|
||||||
@ -50,7 +203,7 @@ export default function Module({}) {
|
|||||||
<div className="outline-form mb10">
|
<div className="outline-form mb10">
|
||||||
<span className="mr10">{getMessage('modal.module.basic.setting.module.setting')}</span>
|
<span className="mr10">{getMessage('modal.module.basic.setting.module.setting')}</span>
|
||||||
<div className="grid-select">
|
<div className="grid-select">
|
||||||
<QSelectBox title={'Search'} option={SelectOption01} />
|
<QSelectBox title={'모듈 선택'} options={moduleList} value={moduleList} onChange={handleChangeModule} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="roof-module-table">
|
<div className="roof-module-table">
|
||||||
@ -67,34 +220,22 @@ export default function Module({}) {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{moduleData.rows.map((row) => (
|
{selectedModules.itemList &&
|
||||||
<>
|
selectedModules.itemList.map((row) => (
|
||||||
<tr>
|
<>
|
||||||
{moduleData.header.map((header) => (
|
<tr>
|
||||||
<>
|
<td>
|
||||||
{header.type === 'color-box' && (
|
<div className="color-wrap">
|
||||||
<td>
|
<span className="color-box" style={{ backgroundColor: row.color }}></span>
|
||||||
<div className="color-wrap">
|
<span className="name">{row.itemNm}</span>
|
||||||
<span className="color-box" style={{ backgroundColor: row[header.prop].color }}></span>
|
</div>
|
||||||
<span className="name">{row[header.prop].name}</span>
|
</td>
|
||||||
</div>
|
<td className="al-r">{Number(row.shortAxis).toFixed(0)}</td>
|
||||||
</td>
|
<td className="al-r">{Number(row.longAxis).toFixed(0)}</td>
|
||||||
)}
|
<td className="al-r">{Number(row.wpOut).toFixed(0)}</td>
|
||||||
{!header.type && header.type !== 'color-box' && <td className="al-r">{row[header.prop].name}</td>}
|
</tr>
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
</tr>
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
|
|
||||||
{Array.from({ length: 3 - moduleData.rows.length }).map((_, i) => (
|
|
||||||
<tr key={i}>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -153,37 +294,72 @@ export default function Module({}) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="module-table-box mb10">
|
<div className="module-table-box mb10">
|
||||||
<div className="module-box-tab">
|
<div className="module-box-tab">
|
||||||
<button className="module-btn act">屋根材1</button>
|
{addedRoofs.map((roof, index) => (
|
||||||
<button className="module-btn">屋根材2</button>
|
<button key={index} className={`module-btn ${roofTab === index ? 'act' : ''}`} onClick={() => (roof ? handleRoofTab(index) : null)}>
|
||||||
<button className="module-btn">屋根材3</button>
|
{roof !== undefined ? `屋根材${index + 1}` : '-'}
|
||||||
<button className="module-btn">屋根材4</button>
|
</button>
|
||||||
|
))}
|
||||||
|
{/* <button className={`module-btn ${roofTab === 0 ? 'act' : ''}`} onClick={() => handleRoofTab(0)}>
|
||||||
|
{canvasSetting.roofs[0] !== undefined ? '屋根材1' : '-'}
|
||||||
|
</button>
|
||||||
|
<button className={`module-btn ${roofTab === 1 ? 'act' : ''}`} onClick={() => (canvasSetting.roofs[1] ? handleRoofTab(1) : null)}>
|
||||||
|
{canvasSetting.roofs[1] !== undefined ? '屋根材2' : '-'}
|
||||||
|
</button>
|
||||||
|
<button className={`module-btn ${roofTab === 2 ? 'act' : ''}`} onClick={() => (canvasSetting.roofs[2] ? handleRoofTab(2) : null)}>
|
||||||
|
{canvasSetting.roofs[2] !== undefined ? '屋根材3' : '-'}{' '}
|
||||||
|
</button>
|
||||||
|
<button className={`module-btn ${roofTab === 3 ? 'act' : ''}`} onClick={() => (canvasSetting.roofs[3] ? handleRoofTab(3) : null)}>
|
||||||
|
{canvasSetting.roofs[3] !== undefined ? '屋根材4' : '-'}
|
||||||
|
</button> */}
|
||||||
</div>
|
</div>
|
||||||
<div className="module-table-inner">
|
<div className="module-table-inner">
|
||||||
<div className="module-table-flex-wrap tab2">
|
<div className="module-table-flex-wrap tab2">
|
||||||
<div className="module-flex-item">
|
<div className="module-flex-item">
|
||||||
<div className="module-flex-item-tit">{getMessage('modal.module.basic.setting.module.roof.material')}:スレーツ(4寸)</div>
|
<div className="module-flex-item-tit">
|
||||||
|
{getMessage('modal.module.basic.setting.module.roof.material')}:{roofMaterial.nameJp}({globalPitch}
|
||||||
|
{displayPitch})
|
||||||
|
</div>
|
||||||
<div className="eaves-keraba-table">
|
<div className="eaves-keraba-table">
|
||||||
<div className="eaves-keraba-item">
|
<div className="eaves-keraba-item">
|
||||||
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.rafter.margin')}</div>
|
{roofMaterial && ['C', 'R'].includes(roofMaterial.raftAuth) && (
|
||||||
<div className="eaves-keraba-td">
|
<>
|
||||||
<div className="keraba-flex">
|
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.rafter.margin')}</div>
|
||||||
<div className="grid-select">
|
<div className="eaves-keraba-td">
|
||||||
<QSelectBox title={'455'} option={SelectOption01} />
|
<div className="keraba-flex">
|
||||||
</div>
|
<div className="grid-select">
|
||||||
<div className="outline-form">
|
{raftCodes.length > 0 && (
|
||||||
<span>垂木の間隔</span>
|
<>
|
||||||
<div className="grid-select">
|
<QSelectBox
|
||||||
<QSelectBox title={'455'} option={SelectOption01} />
|
options={raftCodes}
|
||||||
|
value={roofMaterial.raftBaseCd}
|
||||||
|
showKey={'clCodeNm'}
|
||||||
|
disabled={roofMaterial.raftAuth === 'R' ? true : false}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="outline-form">
|
||||||
|
<span>垂木の間隔</span>
|
||||||
|
<div className="grid-select">
|
||||||
|
<input type="text" className="input-origin block" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</div>
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="eaves-keraba-item">
|
<div className="eaves-keraba-item">
|
||||||
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.trestle.maker')}</div>
|
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.trestle.maker')}</div>
|
||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="grid-select">
|
<div className="grid-select">
|
||||||
<QSelectBox title={'屋根技術研究所'} option={SelectOption01} />
|
<QSelectBox
|
||||||
|
title={'선택하세요.'}
|
||||||
|
options={trestleList}
|
||||||
|
value={trestleList?.trestleMkrCd}
|
||||||
|
showKey={'trestleMkrCdNm'}
|
||||||
|
onChange={handleChangeTrestle}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -191,7 +367,13 @@ export default function Module({}) {
|
|||||||
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.construction.method')}</div>
|
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.construction.method')}</div>
|
||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="grid-select">
|
<div className="grid-select">
|
||||||
<QSelectBox title={'スレート金具4'} option={SelectOption01} />
|
<QSelectBox
|
||||||
|
title={'선택하세요'}
|
||||||
|
options={constMthdList}
|
||||||
|
value={constMthdList.constMthdCd}
|
||||||
|
showKey={'constMthdCdNm'}
|
||||||
|
onChange={handleChangeConstMthd}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -199,7 +381,7 @@ export default function Module({}) {
|
|||||||
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.under.roof')}</div>
|
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.under.roof')}</div>
|
||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="grid-select">
|
<div className="grid-select">
|
||||||
<QSelectBox title={'構造用合板12mm以上 又はOSB12mm以上'} option={SelectOption01} />
|
<QSelectBox title={'선택하세요'} options={roofBaseList} value={roofBaseList.roofBaseCd} showKey={'roofBaseCdNm'} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,40 +1,40 @@
|
|||||||
import { forwardRef, useEffect, useState } from 'react'
|
import { forwardRef, useEffect, useState } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
||||||
|
import { selectedModuleState, checkedModuleState } from '@/store/canvasAtom'
|
||||||
|
import { useRecoilValue, useRecoilState, useSetRecoilState } from 'recoil'
|
||||||
|
|
||||||
const Placement = forwardRef((props, refs) => {
|
const Placement = forwardRef((props, refs) => {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const selectedModules = useRecoilValue(selectedModuleState)
|
||||||
const [isChidori, setIsChidori] = useState('false')
|
const [isChidori, setIsChidori] = useState('false')
|
||||||
const [setupLocation, setSetupLocation] = useState('center')
|
const [setupLocation, setSetupLocation] = useState('center')
|
||||||
const [isMaxSetup, setIsMaxSetup] = useState('false')
|
const [isMaxSetup, setIsMaxSetup] = useState('false')
|
||||||
|
|
||||||
const { makeModuleInstArea } = useModuleBasicSetting()
|
const { makeModuleInstArea } = useModuleBasicSetting()
|
||||||
|
const [selectedItems, setSelectedItems] = useState({})
|
||||||
|
const setCheckedModules = useSetRecoilState(checkedModuleState)
|
||||||
|
|
||||||
|
//모듈 배치면 생성
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
makeModuleInstArea()
|
makeModuleInstArea()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
//체크된 모듈 데이터
|
||||||
|
useEffect(() => {
|
||||||
|
const checkedModuleIds = Object.keys(selectedItems).filter((key) => selectedItems[key])
|
||||||
|
const moduleArray = selectedModules.itemList.filter((item) => {
|
||||||
|
return checkedModuleIds.includes(item.itemId)
|
||||||
|
})
|
||||||
|
setCheckedModules(moduleArray)
|
||||||
|
}, [selectedItems])
|
||||||
|
|
||||||
const moduleData = {
|
const moduleData = {
|
||||||
header: [
|
header: [
|
||||||
{ type: 'check', name: '', prop: 'check', width: 70 },
|
{ type: 'check', name: '', prop: 'check', width: 70 },
|
||||||
{ type: 'color-box', name: getMessage('module'), prop: 'module' },
|
{ type: 'color-box', name: getMessage('module'), prop: 'module' },
|
||||||
{ type: 'text', name: `${getMessage('output')} (W)`, prop: 'output', width: 70 },
|
{ type: 'text', name: `${getMessage('output')} (W)`, prop: 'output', width: 70 },
|
||||||
],
|
],
|
||||||
rows: [
|
rows: [],
|
||||||
{
|
|
||||||
check: false,
|
|
||||||
module: { name: 'Re.RISE-G3 440', color: '#AA6768' },
|
|
||||||
output: { name: '440' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
check: false,
|
|
||||||
module: {
|
|
||||||
name: 'Re.RISE MS-G3 290',
|
|
||||||
color: '#67A2AA',
|
|
||||||
},
|
|
||||||
output: { name: '240' },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChangeChidori = (e) => {
|
const handleChangeChidori = (e) => {
|
||||||
@ -48,8 +48,6 @@ const Placement = forwardRef((props, refs) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleMaxSetup = (e) => {
|
const handleMaxSetup = (e) => {
|
||||||
console.log(e.target.checked)
|
|
||||||
|
|
||||||
if (e.target.checked) {
|
if (e.target.checked) {
|
||||||
setIsMaxSetup('true')
|
setIsMaxSetup('true')
|
||||||
refs.isMaxSetup.current = 'true'
|
refs.isMaxSetup.current = 'true'
|
||||||
@ -59,6 +57,11 @@ const Placement = forwardRef((props, refs) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//체크된 모듈 아이디 추출
|
||||||
|
const handleSelectedItem = (e) => {
|
||||||
|
setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked })
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="module-table-flex-wrap mb10">
|
<div className="module-table-flex-wrap mb10">
|
||||||
@ -83,40 +86,26 @@ const Placement = forwardRef((props, refs) => {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{moduleData.rows.map((row) => (
|
{selectedModules.itemList &&
|
||||||
<>
|
selectedModules.itemList.map((item) => (
|
||||||
<tr>
|
<>
|
||||||
{moduleData.header.map((header) => (
|
<tr>
|
||||||
<>
|
<td className="al-c">
|
||||||
{header.type === 'color-box' && (
|
<div className="d-check-box no-text pop">
|
||||||
<td>
|
<input type="checkbox" id={item.itemId} name={item.itemId} onChange={handleSelectedItem} />
|
||||||
<div className="color-wrap">
|
<label htmlFor={item.itemId}></label>
|
||||||
<span className="color-box" style={{ backgroundColor: row[header.prop].color }}></span>
|
</div>
|
||||||
<span className="name">{row[header.prop].name}</span>
|
</td>
|
||||||
</div>
|
<td>
|
||||||
</td>
|
<div className="color-wrap">
|
||||||
)}
|
<span className="color-box" style={{ backgroundColor: item.color }}></span>
|
||||||
{header.type === 'check' && (
|
<span className="name">{item.itemNm}</span>
|
||||||
<td className="al-c">
|
</div>
|
||||||
<div className="d-check-box no-text pop">
|
</td>
|
||||||
<input type="checkbox" id="ch02" />
|
<td className="al-r">{item.wpOut}</td>
|
||||||
<label htmlFor="ch02"></label>
|
</tr>
|
||||||
</div>
|
</>
|
||||||
</td>
|
))}
|
||||||
)}
|
|
||||||
{header.type && header.type !== 'color-box' && header.type !== 'check' && (
|
|
||||||
<td className="al-r">{row[header.prop].name}</td>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
</tr>
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -33,10 +33,6 @@ export default function PanelEdit(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const contextModuleMove = (length, direction) => {
|
const contextModuleMove = (length, direction) => {
|
||||||
const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => {
|
|
||||||
return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
|
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
|
||||||
const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출
|
const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출
|
||||||
|
|
||||||
@ -51,7 +47,7 @@ export default function PanelEdit(props) {
|
|||||||
const isInSurfaceArray = []
|
const isInSurfaceArray = []
|
||||||
|
|
||||||
if (selectedModules) {
|
if (selectedModules) {
|
||||||
canvas.remove(...selectedModules)
|
canvas.remove(...selectedModules) //지워야 겹치는지 확인 가능
|
||||||
|
|
||||||
selectedModules.forEach((module) => {
|
selectedModules.forEach((module) => {
|
||||||
module.set({
|
module.set({
|
||||||
@ -79,10 +75,9 @@ export default function PanelEdit(props) {
|
|||||||
)
|
)
|
||||||
isOverlapArray.push(isOverlap)
|
isOverlapArray.push(isOverlap)
|
||||||
|
|
||||||
|
//나갔는지 확인하는 로직
|
||||||
const turfModuleSetupSurface = polygonToTurfPolygon(setupSurface, true)
|
const turfModuleSetupSurface = polygonToTurfPolygon(setupSurface, true)
|
||||||
const turfModule = polygonToTurfPolygon(module, true)
|
const turfModule = polygonToTurfPolygon(module, true)
|
||||||
|
|
||||||
//나갔는지 확인하는 로직
|
|
||||||
const isInSurface = turf.booleanContains(turfModuleSetupSurface, turfModule) || turf.booleanWithin(turfModule, turfModuleSetupSurface)
|
const isInSurface = turf.booleanContains(turfModuleSetupSurface, turfModule) || turf.booleanWithin(turfModule, turfModuleSetupSurface)
|
||||||
isInSurfaceArray.push(isInSurface)
|
isInSurfaceArray.push(isInSurface)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState, checkedModuleState, selectedModuleState } from '@/store/canvasAtom'
|
||||||
import { rectToPolygon, setSurfaceShapePattern, polygonToTurfPolygon } from '@/util/canvas-util'
|
import { rectToPolygon, setSurfaceShapePattern, polygonToTurfPolygon } from '@/util/canvas-util'
|
||||||
import { basicSettingState, roofDisplaySelector } from '@/store/settingAtom'
|
import { basicSettingState, roofDisplaySelector } from '@/store/settingAtom'
|
||||||
import offsetPolygon, { calculateAngle } from '@/util/qpolygon-utils'
|
import offsetPolygon, { calculateAngle } from '@/util/qpolygon-utils'
|
||||||
@ -27,6 +27,7 @@ export function useModuleBasicSetting() {
|
|||||||
const compasDeg = useRecoilValue(compasDegAtom)
|
const compasDeg = useRecoilValue(compasDegAtom)
|
||||||
const { setSurfaceShapePattern } = useRoofFn()
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState)
|
const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState)
|
||||||
|
const checkedModule = useRecoilValue(checkedModuleState)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// console.log('basicSetting', basicSetting)
|
// console.log('basicSetting', basicSetting)
|
||||||
@ -42,21 +43,6 @@ export function useModuleBasicSetting() {
|
|||||||
// const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext)
|
// const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext)
|
||||||
let selectedModuleInstSurfaceArray = []
|
let selectedModuleInstSurfaceArray = []
|
||||||
|
|
||||||
const moduleOptions = {
|
|
||||||
fill: '#BFFD9F',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 0.1,
|
|
||||||
selectable: true, // 선택 가능하게 설정
|
|
||||||
lockMovementX: true, // X 축 이동 잠금
|
|
||||||
lockMovementY: true, // Y 축 이동 잠금
|
|
||||||
lockRotation: true, // 회전 잠금
|
|
||||||
lockScalingX: true, // X 축 크기 조정 잠금
|
|
||||||
lockScalingY: true, // Y 축 크기 조정 잠금
|
|
||||||
parentId: moduleSetupSurface.parentId,
|
|
||||||
surfaceId: moduleSetupSurface.id,
|
|
||||||
name: 'module',
|
|
||||||
}
|
|
||||||
|
|
||||||
//모듈,회로에서 다른메뉴 -> 배치면으로 갈 경수 초기화
|
//모듈,회로에서 다른메뉴 -> 배치면으로 갈 경수 초기화
|
||||||
const restoreModuleInstArea = () => {
|
const restoreModuleInstArea = () => {
|
||||||
//설치면 삭제
|
//설치면 삭제
|
||||||
@ -127,18 +113,6 @@ export function useModuleBasicSetting() {
|
|||||||
setupSurface.setViewLengthText(false)
|
setupSurface.setViewLengthText(false)
|
||||||
canvas.add(setupSurface) //모듈설치면 만들기
|
canvas.add(setupSurface) //모듈설치면 만들기
|
||||||
|
|
||||||
//육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음
|
|
||||||
if (canvasSetting.roofSizeSet !== 3) {
|
|
||||||
const flowLines = {
|
|
||||||
bottom: bottomTopFlowLine(setupSurface).find((obj) => obj.target === 'bottom'),
|
|
||||||
top: bottomTopFlowLine(setupSurface).find((obj) => obj.target === 'top'),
|
|
||||||
left: leftRightFlowLine(setupSurface).find((obj) => obj.target === 'left'),
|
|
||||||
right: leftRightFlowLine(setupSurface).find((obj) => obj.target === 'right'),
|
|
||||||
}
|
|
||||||
|
|
||||||
setupSurface.set({ flowLines: flowLines })
|
|
||||||
}
|
|
||||||
|
|
||||||
//지붕면 선택 금지
|
//지붕면 선택 금지
|
||||||
roof.set({
|
roof.set({
|
||||||
selectable: false,
|
selectable: false,
|
||||||
@ -193,6 +167,16 @@ export function useModuleBasicSetting() {
|
|||||||
* 확인 후 셀을 이동시킴
|
* 확인 후 셀을 이동시킴
|
||||||
*/
|
*/
|
||||||
const manualModuleSetup = () => {
|
const manualModuleSetup = () => {
|
||||||
|
if (checkedModule.length === 0) {
|
||||||
|
swalFire({ text: '모듈을 선택해주세요.' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkedModule.length > 1) {
|
||||||
|
swalFire({ text: '모듈은 하나만 선택해주세요.' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴
|
const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴
|
||||||
const batchObjects = canvas
|
const batchObjects = canvas
|
||||||
?.getObjects()
|
?.getObjects()
|
||||||
@ -204,6 +188,19 @@ export function useModuleBasicSetting() {
|
|||||||
obj.name === BATCH_TYPE.SHADOW,
|
obj.name === BATCH_TYPE.SHADOW,
|
||||||
) //도머s 객체
|
) //도머s 객체
|
||||||
|
|
||||||
|
const moduleOptions = {
|
||||||
|
fill: checkedModule[0].color,
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 0.1,
|
||||||
|
selectable: true, // 선택 가능하게 설정
|
||||||
|
lockMovementX: true, // X 축 이동 잠금
|
||||||
|
lockMovementY: true, // Y 축 이동 잠금
|
||||||
|
lockRotation: true, // 회전 잠금
|
||||||
|
lockScalingX: true, // X 축 크기 조정 잠금
|
||||||
|
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||||
|
name: 'module',
|
||||||
|
}
|
||||||
|
|
||||||
if (moduleSetupSurfaces.length !== 0) {
|
if (moduleSetupSurfaces.length !== 0) {
|
||||||
let tempModule
|
let tempModule
|
||||||
let manualDrawModules = []
|
let manualDrawModules = []
|
||||||
@ -221,8 +218,10 @@ export function useModuleBasicSetting() {
|
|||||||
trestlePolygon = moduleSetupSurfaces[i]
|
trestlePolygon = moduleSetupSurfaces[i]
|
||||||
manualDrawModules = moduleSetupSurfaces[i].modules // 앞에서 자동으로 했을때 추가됨
|
manualDrawModules = moduleSetupSurfaces[i].modules // 앞에서 자동으로 했을때 추가됨
|
||||||
flowDirection = moduleSetupSurfaces[i].flowDirection //도형의 방향
|
flowDirection = moduleSetupSurfaces[i].flowDirection //도형의 방향
|
||||||
let width = flowDirection === 'south' || flowDirection === 'north' ? 172 : 113
|
const moduleWidth = Number(checkedModule[0].longAxis) / 10
|
||||||
let height = flowDirection === 'south' || flowDirection === 'north' ? 113 : 172
|
const moduleHeight = Number(checkedModule[0].shortAxis) / 10
|
||||||
|
let width = flowDirection === 'south' || flowDirection === 'north' ? moduleWidth : moduleHeight
|
||||||
|
let height = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth
|
||||||
|
|
||||||
const points = [
|
const points = [
|
||||||
{ x: mousePoint.x - width / 2, y: mousePoint.y - height / 2 },
|
{ x: mousePoint.x - width / 2, y: mousePoint.y - height / 2 },
|
||||||
@ -470,12 +469,17 @@ export function useModuleBasicSetting() {
|
|||||||
//자동 모듈 설치(그리드 방식)
|
//자동 모듈 설치(그리드 방식)
|
||||||
const autoModuleSetup = (placementRef) => {
|
const autoModuleSetup = (placementRef) => {
|
||||||
initEvent() //마우스 이벤트 초기화
|
initEvent() //마우스 이벤트 초기화
|
||||||
|
|
||||||
|
if (checkedModule.length === 0) {
|
||||||
|
swalFire({ text: '모듈을 선택해주세요.' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const isChidori = placementRef.isChidori.current === 'true' ? true : false
|
const isChidori = placementRef.isChidori.current === 'true' ? true : false
|
||||||
const setupLocation = placementRef.setupLocation.current
|
const setupLocation = placementRef.setupLocation.current
|
||||||
const isMaxSetup = placementRef.isMaxSetup.current === 'true' ? true : false
|
const isMaxSetup = placementRef.isMaxSetup.current === 'true' ? true : false
|
||||||
|
|
||||||
const moduleSetupSurfaces = moduleSetupSurface //선택 설치면
|
const moduleSetupSurfaces = moduleSetupSurface //선택 설치면
|
||||||
|
|
||||||
const notSelectedTrestlePolygons = canvas
|
const notSelectedTrestlePolygons = canvas
|
||||||
?.getObjects()
|
?.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && !moduleSetupSurfaces.includes(obj)) //설치면이 아닌것
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && !moduleSetupSurfaces.includes(obj)) //설치면이 아닌것
|
||||||
@ -526,8 +530,7 @@ export function useModuleBasicSetting() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const moduleOptions = {
|
let moduleOptions = {
|
||||||
fill: '#BFFD9F',
|
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
strokeWidth: 0.3,
|
strokeWidth: 0.3,
|
||||||
selectable: true, // 선택 가능하게 설정
|
selectable: true, // 선택 가능하게 설정
|
||||||
@ -536,8 +539,6 @@ export function useModuleBasicSetting() {
|
|||||||
lockRotation: true, // 회전 잠금
|
lockRotation: true, // 회전 잠금
|
||||||
lockScalingX: true, // X 축 크기 조정 잠금
|
lockScalingX: true, // X 축 크기 조정 잠금
|
||||||
lockScalingY: true, // Y 축 크기 조정 잠금
|
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||||
parentId: moduleSetupSurface.parentId,
|
|
||||||
surfaceId: moduleSetupSurface.id,
|
|
||||||
name: 'module',
|
name: 'module',
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -606,377 +607,519 @@ export function useModuleBasicSetting() {
|
|||||||
return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
||||||
}
|
}
|
||||||
|
|
||||||
const downFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, isCenter = false) => {
|
/**
|
||||||
const flowModuleLine = moduleSetupSurface.flowLines
|
* 모듈의 너비와 높이를 계산하는 함수
|
||||||
let startPoint = flowModuleLine.bottom
|
* @param {object} maxLengthLine 최대 길이 라인
|
||||||
|
* @param {object} moduleSetupSurface 모듈 설치면
|
||||||
|
* @param {object} module 모듈
|
||||||
|
* @returns {object} 모듈의 너비와 높이
|
||||||
|
*/
|
||||||
|
const getModuleWidthHeight = (maxLengthLine, moduleSetupSurface, module) => {
|
||||||
|
let width =
|
||||||
|
(maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? Number(module.longAxis) : Number(module.shortAxis)) / 10
|
||||||
|
let height =
|
||||||
|
(maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? Number(module.shortAxis) : Number(module.longAxis)) / 10
|
||||||
|
|
||||||
if (isCenter) {
|
//배치면때는 방향쪽으로 패널이 넓게 누워져야함
|
||||||
//중앙배치일 경우에는 계산한다
|
if (moduleSetupSurface.flowDirection !== undefined) {
|
||||||
|
width =
|
||||||
|
(moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north'
|
||||||
|
? Number(module.longAxis)
|
||||||
|
: Number(module.shortAxis)) / 10
|
||||||
|
height =
|
||||||
|
(moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north'
|
||||||
|
? Number(module.shortAxis)
|
||||||
|
: Number(module.longAxis)) / 10
|
||||||
|
}
|
||||||
|
return { width, height }
|
||||||
|
}
|
||||||
|
|
||||||
if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') {
|
const getFlowLines = (moduleSetupSurface, module) => {
|
||||||
//하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
let flowLines = {}
|
||||||
const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다
|
if (canvasSetting.roofSizeSet !== 3) {
|
||||||
const halfModuleWidthLength = width / 2
|
flowLines = {
|
||||||
startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength }
|
bottom: bottomTopFlowLine(moduleSetupSurface, module).find((obj) => obj.target === 'bottom'),
|
||||||
|
top: bottomTopFlowLine(moduleSetupSurface, module).find((obj) => obj.target === 'top'),
|
||||||
if (flowModuleLine.top.type === 'flat') {
|
left: leftRightFlowLine(moduleSetupSurface, module).find((obj) => obj.target === 'left'),
|
||||||
//상단까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산
|
right: leftRightFlowLine(moduleSetupSurface, module).find((obj) => obj.target === 'right'),
|
||||||
const heightLength = Math.abs(flowModuleLine.left.y1 - flowModuleLine.left.y2) //옆에에 길이에서 반을 가른다
|
|
||||||
const heightMargin = Math.abs(heightLength - height * Math.floor(heightLength / height)) / 2
|
|
||||||
startPoint = { ...startPoint, y1: startPoint.y1 - heightMargin }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else {
|
|
||||||
// //중앙배치가 아닐때도 흐름 방향 기준면으로 양면이 직선이면 가운데 배치
|
|
||||||
// if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') {
|
|
||||||
// //하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
|
||||||
// const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다
|
|
||||||
// const halfModuleWidthLength = width / 2
|
|
||||||
// startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
|
console.log('flowLines', flowLines)
|
||||||
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
|
|
||||||
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
|
|
||||||
|
|
||||||
let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
|
return flowLines
|
||||||
let totalTopEndPoint = maxTopEndPoint - startPoint.y1
|
}
|
||||||
let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width)
|
|
||||||
let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
|
const downFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, isCenter = false) => {
|
||||||
let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
|
let setupModule = []
|
||||||
let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
|
|
||||||
let tempMaxWidth = isMaxSetup ? width / 2 : width //최대배치인지 확인하려고 넣음
|
checkedModule.forEach((module, index) => {
|
||||||
if (isMaxSetup) totalWidth = totalWidth * 2 //최대배치시 2배로 늘려서 반씩 검사하기위함
|
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
|
||||||
|
const flowLines = getFlowLines(moduleSetupSurface, module)
|
||||||
|
//육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음
|
||||||
|
let startPoint = flowLines.bottom
|
||||||
|
const moduleArray = []
|
||||||
|
|
||||||
|
if (isCenter) {
|
||||||
|
//중앙배치일 경우에는 계산한다
|
||||||
|
if (flowLines.bottom.type === 'flat' && flowLines.left.type === 'flat' && flowLines.right.type === 'flat') {
|
||||||
|
//하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
||||||
|
const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다
|
||||||
|
const halfModuleWidthLength = width / 2
|
||||||
|
startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength }
|
||||||
|
|
||||||
|
if (flowLines.top.type === 'flat') {
|
||||||
|
//상단까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산
|
||||||
|
const heightLength = Math.abs(flowLines.left.y1 - flowLines.left.y2) //옆에에 길이에서 반을 가른다
|
||||||
|
const heightMargin = Math.abs(heightLength - height * Math.floor(heightLength / height)) / 2
|
||||||
|
startPoint = { ...startPoint, y1: startPoint.y1 - heightMargin }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else {
|
||||||
|
// //중앙배치가 아닐때도 흐름 방향 기준면으로 양면이 직선이면 가운데 배치
|
||||||
|
// if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') {
|
||||||
|
// //하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
||||||
|
// const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다
|
||||||
|
// const halfModuleWidthLength = width / 2
|
||||||
|
// startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
|
||||||
|
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
|
||||||
|
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
|
||||||
|
|
||||||
|
let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
|
||||||
|
let totalTopEndPoint = maxTopEndPoint - startPoint.y1
|
||||||
|
let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width)
|
||||||
|
let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
|
||||||
|
let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
|
||||||
|
let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
|
||||||
|
let tempMaxWidth = isMaxSetup ? width / 2 : width //최대배치인지 확인하려고 넣음
|
||||||
|
if (isMaxSetup) totalWidth = totalWidth * 2 //최대배치시 2배로 늘려서 반씩 검사하기위함
|
||||||
|
|
||||||
|
for (let j = 0; j < diffTopEndPoint; j++) {
|
||||||
|
bottomMargin = 0
|
||||||
|
for (let i = 0; i <= totalWidth; i++) {
|
||||||
|
leftMargin = 0
|
||||||
|
chidoriLength = 0
|
||||||
|
if (isChidori) {
|
||||||
|
chidoriLength = j % 2 === 0 ? 0 : width / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
square = [
|
||||||
|
[startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
||||||
|
[startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
||||||
|
[startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
|
||||||
|
[startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
|
||||||
|
[startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
||||||
|
]
|
||||||
|
|
||||||
|
let squarePolygon = turf.polygon([square])
|
||||||
|
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
||||||
|
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
||||||
|
|
||||||
|
moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id }
|
||||||
|
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
||||||
|
|
||||||
|
let disjointFromTrestle = checkModuleDisjointSurface(squarePolygon, polygonToTurfPolygon(moduleSetupSurface, true))
|
||||||
|
let isDisjoint = checkModuleDisjointObjects(squarePolygon, containsBatchObjects)
|
||||||
|
|
||||||
|
if (disjointFromTrestle && isDisjoint) {
|
||||||
|
if (index > 0) {
|
||||||
|
setupModule.forEach((item) => {
|
||||||
|
const isOverlap = item.some((item2) => turf.booleanOverlap(squarePolygon, polygonToTurfPolygon(item2, true)))
|
||||||
|
if (!isOverlap) {
|
||||||
|
canvas?.add(tempModule)
|
||||||
|
moduleSetupArray.push(tempModule)
|
||||||
|
moduleArray.push(tempModule)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
//최초 한번은 그냥 그린다
|
||||||
|
//겹치는지 확인해서 포함된 모듈만 그린다
|
||||||
|
canvas?.add(tempModule)
|
||||||
|
moduleSetupArray.push(tempModule)
|
||||||
|
moduleArray.push(tempModule)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setupModule.push(moduleArray)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const leftFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, isCenter = false) => {
|
||||||
|
let setupModule = []
|
||||||
|
|
||||||
|
checkedModule.forEach((module, index) => {
|
||||||
|
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
|
||||||
|
const flowLines = getFlowLines(moduleSetupSurface, module)
|
||||||
|
//육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음
|
||||||
|
let startPoint = flowLines.left
|
||||||
|
const moduleArray = []
|
||||||
|
|
||||||
|
//중앙배치일 경우에는 계산한다
|
||||||
|
if (isCenter) {
|
||||||
|
if (flowLines.left.type === 'flat' && flowLines.bottom.type === 'flat' && flowLines.top.type === 'flat') {
|
||||||
|
//좌측 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
||||||
|
const halfWidthLength = Math.abs(startPoint.y1 + startPoint.y2) / 2 //밑에 길이에서 반을 가른다
|
||||||
|
const halfModuleWidthLength = height / 2
|
||||||
|
startPoint = { ...startPoint, y1: halfWidthLength - halfModuleWidthLength }
|
||||||
|
if (flowLines.right.type === 'flat') {
|
||||||
|
//우측까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산
|
||||||
|
const widthLength = Math.abs(flowLines.top.x1 - flowLines.top.x2) //옆에에 길이에서 반을 가른다
|
||||||
|
const widthMargin = Math.abs(widthLength - width * Math.floor(widthLength / width)) / 2
|
||||||
|
startPoint = { ...startPoint, x1: startPoint.x1 + widthMargin }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
|
||||||
|
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
|
||||||
|
const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
|
||||||
|
|
||||||
|
let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌
|
||||||
|
let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
|
||||||
|
let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height)
|
||||||
|
let totalWidth = Math.abs(startPoint.x1 - maxRightEndPoint) / width
|
||||||
|
let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint)
|
||||||
|
|
||||||
|
let tempMaxHeight = isMaxSetup ? height / 2 : height //최대배치인지 확인하려고 넣음
|
||||||
|
if (isMaxSetup) totalHeight = totalHeight * 2 //최대배치시 2배로 늘려서 반씩 검사
|
||||||
|
|
||||||
for (let j = 0; j < diffTopEndPoint; j++) {
|
|
||||||
bottomMargin = 1 * j
|
|
||||||
for (let i = 0; i <= totalWidth; i++) {
|
for (let i = 0; i <= totalWidth; i++) {
|
||||||
leftMargin = 1 * i
|
bottomMargin = 0
|
||||||
chidoriLength = 0
|
for (let j = 0; j < totalHeight; j++) {
|
||||||
if (isChidori) {
|
leftMargin = 0
|
||||||
chidoriLength = j % 2 === 0 ? 0 : width / 2
|
chidoriLength = 0
|
||||||
|
if (isChidori) {
|
||||||
|
chidoriLength = i % 2 === 0 ? 0 : height / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
square = [
|
||||||
|
[startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength],
|
||||||
|
[startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength],
|
||||||
|
[startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin - chidoriLength],
|
||||||
|
[startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin - chidoriLength],
|
||||||
|
[startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength],
|
||||||
|
]
|
||||||
|
|
||||||
|
let squarePolygon = turf.polygon([square])
|
||||||
|
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
||||||
|
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
||||||
|
|
||||||
|
// if (disjointFromTrestle && isDisjoint) {
|
||||||
|
moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id }
|
||||||
|
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
||||||
|
let disjointFromTrestle = checkModuleDisjointSurface(squarePolygon, polygonToTurfPolygon(moduleSetupSurface, true))
|
||||||
|
let isDisjoint = checkModuleDisjointObjects(squarePolygon, containsBatchObjects)
|
||||||
|
|
||||||
|
if (disjointFromTrestle && isDisjoint) {
|
||||||
|
if (index > 0) {
|
||||||
|
setupModule.forEach((item) => {
|
||||||
|
const isOverlap = item.some((item2) => turf.booleanOverlap(squarePolygon, polygonToTurfPolygon(item2, true)))
|
||||||
|
if (!isOverlap) {
|
||||||
|
canvas?.add(tempModule)
|
||||||
|
moduleSetupArray.push(tempModule)
|
||||||
|
moduleArray.push(tempModule)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
//최초 한번은 그냥 그린다
|
||||||
|
//겹치는지 확인해서 포함된 모듈만 그린다
|
||||||
|
canvas?.add(tempModule)
|
||||||
|
moduleSetupArray.push(tempModule)
|
||||||
|
moduleArray.push(tempModule)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
square = [
|
|
||||||
[startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
|
||||||
[startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
|
||||||
[startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
|
|
||||||
[startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
|
|
||||||
[startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
|
||||||
]
|
|
||||||
|
|
||||||
let squarePolygon = turf.polygon([square])
|
|
||||||
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
|
||||||
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
|
||||||
|
|
||||||
moduleOptions.surfaceId = moduleSetupSurface.id
|
|
||||||
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
|
||||||
canvas?.add(tempModule)
|
|
||||||
moduleSetupArray.push(tempModule)
|
|
||||||
}
|
}
|
||||||
}
|
setupModule.push(moduleArray)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const leftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, isCenter = false) => {
|
const topFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, isCenter = false) => {
|
||||||
const flowModuleLine = moduleSetupSurface.flowLines
|
let setupModule = []
|
||||||
let startPoint = flowModuleLine.left
|
|
||||||
|
|
||||||
//중앙배치일 경우에는 계산한다
|
checkedModule.forEach((module, index) => {
|
||||||
if (isCenter) {
|
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
|
||||||
if (flowModuleLine.left.type === 'flat' && flowModuleLine.bottom.type === 'flat' && flowModuleLine.top.type === 'flat') {
|
const flowLines = getFlowLines(moduleSetupSurface, module)
|
||||||
//좌측 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
let startPoint = flowLines.top
|
||||||
const halfWidthLength = Math.abs(startPoint.y1 + startPoint.y2) / 2 //밑에 길이에서 반을 가른다
|
const moduleArray = []
|
||||||
const halfModuleWidthLength = height / 2
|
|
||||||
startPoint = { ...startPoint, y1: halfWidthLength - halfModuleWidthLength }
|
if (isCenter) {
|
||||||
if (flowModuleLine.right.type === 'flat') {
|
//중앙배치일 경우에는 계산한다
|
||||||
//우측까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산
|
if (flowLines.top.type === 'flat' && flowLines.left.type === 'flat' && flowLines.right.type === 'flat') {
|
||||||
const widthLength = Math.abs(flowModuleLine.top.x1 - flowModuleLine.top.x2) //옆에에 길이에서 반을 가른다
|
//하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
||||||
const widthMargin = Math.abs(widthLength - width * Math.floor(widthLength / width)) / 2
|
const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다
|
||||||
startPoint = { ...startPoint, x1: startPoint.x1 + widthMargin }
|
const halfModuleWidthLength = width / 2
|
||||||
|
startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength }
|
||||||
|
|
||||||
|
if (flowLines.bottom.type === 'flat') {
|
||||||
|
//상단까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산
|
||||||
|
const heightLength = Math.abs(flowLines.left.y1 - flowLines.left.y2) //옆에에 길이에서 반을 가른다
|
||||||
|
const heightMargin = Math.abs(heightLength - height * Math.floor(heightLength / height)) / 2
|
||||||
|
startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength, y1: startPoint.y1 - heightMargin }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// else {
|
||||||
|
// //중앙배치가 아닐때도 흐름 방향 기준면으로 양면이 직선이면 가운데 배치
|
||||||
|
// if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') {
|
||||||
|
// //하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
||||||
|
// const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다
|
||||||
|
// const halfModuleWidthLength = width / 2
|
||||||
|
// startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
|
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
|
||||||
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
|
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
|
||||||
const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
|
const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
|
||||||
|
|
||||||
let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌
|
let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
|
||||||
let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
|
let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint
|
||||||
let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height)
|
let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1
|
||||||
let totalWidth = Math.abs(startPoint.x1 - maxRightEndPoint) / width
|
let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
|
||||||
let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint)
|
let diffRightEndPoint = Math.ceil(Math.abs(totalRightEndPoint / width))
|
||||||
|
let diffBottomEndPoint = Math.ceil(Math.abs(totalBottomEndPoint / height))
|
||||||
|
let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
|
||||||
|
let tempMaxWidth = isMaxSetup ? width / 2 : width //최대배치인지 확인하려고 넣음
|
||||||
|
if (isMaxSetup) diffRightEndPoint = diffRightEndPoint * 2 //최대배치시 2배로 늘려서 반씩 검사하기위함
|
||||||
|
|
||||||
let tempMaxHeight = isMaxSetup ? height / 2 : height //최대배치인지 확인하려고 넣음
|
for (let j = 0; j < diffBottomEndPoint; j++) {
|
||||||
if (isMaxSetup) totalHeight = totalHeight * 2 //최대배치시 2배로 늘려서 반씩 검사
|
bottomMargin = 0
|
||||||
|
for (let i = 0; i < diffRightEndPoint; i++) {
|
||||||
|
leftMargin = 0
|
||||||
|
chidoriLength = 0
|
||||||
|
if (isChidori) {
|
||||||
|
chidoriLength = j % 2 === 0 ? 0 : width / 2
|
||||||
|
}
|
||||||
|
square = [
|
||||||
|
[startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin],
|
||||||
|
[startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + height + bottomMargin],
|
||||||
|
[startColPoint + tempMaxWidth * i + width + chidoriLength + leftMargin, startPoint.y1 + height * j + height + bottomMargin],
|
||||||
|
[startColPoint + tempMaxWidth * i + width + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin],
|
||||||
|
[startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin],
|
||||||
|
]
|
||||||
|
|
||||||
for (let i = 0; i <= totalWidth; i++) {
|
let squarePolygon = turf.polygon([square])
|
||||||
bottomMargin = i === 0 ? 1 : 2
|
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
||||||
for (let j = 0; j < totalHeight; j++) {
|
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
||||||
leftMargin = i === 0 ? 1 : 2
|
|
||||||
chidoriLength = 0
|
// if (disjointFromTrestle && isDisjoint) {
|
||||||
if (isChidori) {
|
moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id }
|
||||||
chidoriLength = i % 2 === 0 ? 0 : height / 2
|
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
||||||
|
|
||||||
|
let disjointFromTrestle = checkModuleDisjointSurface(squarePolygon, polygonToTurfPolygon(moduleSetupSurface, true))
|
||||||
|
let isDisjoint = checkModuleDisjointObjects(squarePolygon, containsBatchObjects)
|
||||||
|
|
||||||
|
if (disjointFromTrestle && isDisjoint) {
|
||||||
|
if (index > 0) {
|
||||||
|
setupModule.forEach((item) => {
|
||||||
|
const isOverlap = item.some((item2) => turf.booleanOverlap(squarePolygon, polygonToTurfPolygon(item2, true)))
|
||||||
|
if (!isOverlap) {
|
||||||
|
canvas?.add(tempModule)
|
||||||
|
moduleSetupArray.push(tempModule)
|
||||||
|
moduleArray.push(tempModule)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
//최초 한번은 그냥 그린다
|
||||||
|
//겹치는지 확인해서 포함된 모듈만 그린다
|
||||||
|
canvas?.add(tempModule)
|
||||||
|
moduleSetupArray.push(tempModule)
|
||||||
|
moduleArray.push(tempModule)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
square = [
|
|
||||||
[startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength],
|
|
||||||
[startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength],
|
|
||||||
[startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin - chidoriLength],
|
|
||||||
[startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin - chidoriLength],
|
|
||||||
[startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength],
|
|
||||||
]
|
|
||||||
|
|
||||||
let squarePolygon = turf.polygon([square])
|
|
||||||
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
|
||||||
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
|
||||||
|
|
||||||
// if (disjointFromTrestle && isDisjoint) {
|
|
||||||
moduleOptions.surfaceId = moduleSetupSurface.id
|
|
||||||
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
|
||||||
canvas?.add(tempModule)
|
|
||||||
moduleSetupArray.push(tempModule)
|
|
||||||
}
|
}
|
||||||
}
|
setupModule.push(moduleArray)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const topFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, isCenter = false) => {
|
const rightFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, isCenter = false) => {
|
||||||
const flowModuleLine = moduleSetupSurface.flowLines
|
let setupModule = []
|
||||||
let startPoint = flowModuleLine.top
|
|
||||||
|
|
||||||
if (isCenter) {
|
checkedModule.forEach((module, index) => {
|
||||||
//중앙배치일 경우에는 계산한다
|
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
|
||||||
if (flowModuleLine.top.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') {
|
const flowLines = getFlowLines(moduleSetupSurface, module)
|
||||||
//하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
let startPoint = flowLines.right
|
||||||
const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다
|
const moduleArray = []
|
||||||
const halfModuleWidthLength = width / 2
|
|
||||||
startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength }
|
|
||||||
|
|
||||||
if (flowModuleLine.bottom.type === 'flat') {
|
if (isCenter) {
|
||||||
//상단까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산
|
if (flowLines.left.type === 'flat' && flowLines.bottom.type === 'flat' && flowLines.top.type === 'flat') {
|
||||||
const heightLength = Math.abs(flowModuleLine.left.y1 - flowModuleLine.left.y2) //옆에에 길이에서 반을 가른다
|
//좌측 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
||||||
const heightMargin = Math.abs(heightLength - height * Math.floor(heightLength / height)) / 2
|
const halfWidthLength = Math.abs(startPoint.y1 + startPoint.y2) / 2 //밑에 길이에서 반을 가른다
|
||||||
startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength, y1: startPoint.y1 - heightMargin }
|
const halfModuleWidthLength = height / 2
|
||||||
|
startPoint = { ...startPoint, y1: halfWidthLength + halfModuleWidthLength }
|
||||||
|
|
||||||
|
if (flowLines.right.type === 'flat') {
|
||||||
|
//우측까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산
|
||||||
|
const widthLength = Math.abs(flowLines.top.x1 - flowLines.top.x2) //옆에에 길이에서 반을 가른다
|
||||||
|
const widthMargin = Math.abs(widthLength - width * Math.floor(widthLength / width)) / 2
|
||||||
|
startPoint = { ...startPoint, x1: startPoint.x1 - widthMargin }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// else {
|
|
||||||
// //중앙배치가 아닐때도 흐름 방향 기준면으로 양면이 직선이면 가운데 배치
|
|
||||||
// if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') {
|
|
||||||
// //하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
|
||||||
// const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다
|
|
||||||
// const halfModuleWidthLength = width / 2
|
|
||||||
// startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
|
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
|
||||||
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
|
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
|
||||||
const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
|
const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
|
||||||
|
|
||||||
let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
|
let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌
|
||||||
let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint
|
let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
|
||||||
let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1
|
let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height)
|
||||||
let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
|
let totalWidth = Math.abs(startPoint.x1 - maxLeftEndPoint) / width
|
||||||
let diffRightEndPoint = Math.ceil(Math.abs(totalRightEndPoint / width))
|
let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) - 3 // -3으로 위치살짝 보정
|
||||||
let diffBottomEndPoint = Math.ceil(Math.abs(totalBottomEndPoint / height))
|
|
||||||
let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
|
|
||||||
let tempMaxWidth = isMaxSetup ? width / 2 : width //최대배치인지 확인하려고 넣음
|
|
||||||
if (isMaxSetup) diffRightEndPoint = diffRightEndPoint * 2 //최대배치시 2배로 늘려서 반씩 검사하기위함
|
|
||||||
|
|
||||||
for (let j = 0; j < diffBottomEndPoint; j++) {
|
let tempMaxHeight = isMaxSetup ? height / 2 : height //최대배치인지 확인하려고 넣음
|
||||||
bottomMargin = j === 0 ? 1 : 2
|
if (isMaxSetup) totalHeight = totalHeight * 2 //최대배치시 2배로 늘려서 반씩 검사
|
||||||
for (let i = 0; i < diffRightEndPoint; i++) {
|
|
||||||
leftMargin = i === 0 ? 1 : 2
|
|
||||||
chidoriLength = 0
|
|
||||||
if (isChidori) {
|
|
||||||
chidoriLength = j % 2 === 0 ? 0 : width / 2
|
|
||||||
}
|
|
||||||
square = [
|
|
||||||
[startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin],
|
|
||||||
[startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + height + bottomMargin],
|
|
||||||
[startColPoint + tempMaxWidth * i + width + chidoriLength + leftMargin, startPoint.y1 + height * j + height + bottomMargin],
|
|
||||||
[startColPoint + tempMaxWidth * i + width + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin],
|
|
||||||
[startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin],
|
|
||||||
]
|
|
||||||
|
|
||||||
let squarePolygon = turf.polygon([square])
|
for (let i = 0; i <= totalWidth; i++) {
|
||||||
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
bottomMargin = 0
|
||||||
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
for (let j = 0; j < totalHeight; j++) {
|
||||||
|
leftMargin = 0
|
||||||
|
chidoriLength = 0
|
||||||
|
if (isChidori) {
|
||||||
|
chidoriLength = i % 2 === 0 ? 0 : height / 2
|
||||||
|
}
|
||||||
|
|
||||||
// if (disjointFromTrestle && isDisjoint) {
|
square = [
|
||||||
moduleOptions.surfaceId = moduleSetupSurface.id
|
[startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength],
|
||||||
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
[startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength],
|
||||||
canvas?.add(tempModule)
|
[startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin + chidoriLength],
|
||||||
moduleSetupArray.push(tempModule)
|
[startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin + chidoriLength],
|
||||||
}
|
[startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength],
|
||||||
}
|
]
|
||||||
}
|
|
||||||
|
|
||||||
const rightFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, isCenter = false) => {
|
let squarePolygon = turf.polygon([square])
|
||||||
const flowModuleLine = moduleSetupSurface.flowLines
|
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
||||||
let startPoint = flowModuleLine.right
|
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
||||||
|
|
||||||
if (isCenter) {
|
// if (disjointFromTrestle && isDisjoint) {
|
||||||
if (flowModuleLine.left.type === 'flat' && flowModuleLine.bottom.type === 'flat' && flowModuleLine.top.type === 'flat') {
|
moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id }
|
||||||
//좌측 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
|
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
||||||
const halfWidthLength = Math.abs(startPoint.y1 + startPoint.y2) / 2 //밑에 길이에서 반을 가른다
|
let disjointFromTrestle = checkModuleDisjointSurface(squarePolygon, polygonToTurfPolygon(moduleSetupSurface, true))
|
||||||
const halfModuleWidthLength = height / 2
|
let isDisjoint = checkModuleDisjointObjects(squarePolygon, containsBatchObjects)
|
||||||
startPoint = { ...startPoint, y1: halfWidthLength + halfModuleWidthLength }
|
|
||||||
|
|
||||||
if (flowModuleLine.right.type === 'flat') {
|
if (disjointFromTrestle && isDisjoint) {
|
||||||
//우측까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산
|
if (index > 0) {
|
||||||
const widthLength = Math.abs(flowModuleLine.top.x1 - flowModuleLine.top.x2) //옆에에 길이에서 반을 가른다
|
setupModule.forEach((item) => {
|
||||||
const widthMargin = Math.abs(widthLength - width * Math.floor(widthLength / width)) / 2
|
const isOverlap = item.some((item2) => turf.booleanOverlap(squarePolygon, polygonToTurfPolygon(item2, true)))
|
||||||
startPoint = { ...startPoint, x1: startPoint.x1 - widthMargin }
|
if (!isOverlap) {
|
||||||
|
canvas?.add(tempModule)
|
||||||
|
moduleSetupArray.push(tempModule)
|
||||||
|
moduleArray.push(tempModule)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
//최초 한번은 그냥 그린다
|
||||||
|
//겹치는지 확인해서 포함된 모듈만 그린다
|
||||||
|
canvas?.add(tempModule)
|
||||||
|
moduleSetupArray.push(tempModule)
|
||||||
|
moduleArray.push(tempModule)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
setupModule.push(moduleArray)
|
||||||
|
})
|
||||||
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
|
|
||||||
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
|
|
||||||
const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
|
|
||||||
|
|
||||||
let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌
|
|
||||||
let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
|
|
||||||
let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height)
|
|
||||||
let totalWidth = Math.abs(startPoint.x1 - maxLeftEndPoint) / width
|
|
||||||
let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) - 3 // -3으로 위치살짝 보정
|
|
||||||
|
|
||||||
let tempMaxHeight = isMaxSetup ? height / 2 : height //최대배치인지 확인하려고 넣음
|
|
||||||
if (isMaxSetup) totalHeight = totalHeight * 2 //최대배치시 2배로 늘려서 반씩 검사
|
|
||||||
|
|
||||||
for (let i = 0; i <= totalWidth; i++) {
|
|
||||||
bottomMargin = i === 0 ? 1 : 2
|
|
||||||
for (let j = 0; j < totalHeight; j++) {
|
|
||||||
leftMargin = j === 0 ? 1 : 2
|
|
||||||
chidoriLength = 0
|
|
||||||
if (isChidori) {
|
|
||||||
chidoriLength = i % 2 === 0 ? 0 : height / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
square = [
|
|
||||||
[startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength],
|
|
||||||
[startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength],
|
|
||||||
[startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin + chidoriLength],
|
|
||||||
[startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin + chidoriLength],
|
|
||||||
[startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength],
|
|
||||||
]
|
|
||||||
|
|
||||||
let squarePolygon = turf.polygon([square])
|
|
||||||
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
|
||||||
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
|
||||||
|
|
||||||
// if (disjointFromTrestle && isDisjoint) {
|
|
||||||
moduleOptions.surfaceId = moduleSetupSurface.id
|
|
||||||
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
|
||||||
canvas?.add(tempModule)
|
|
||||||
moduleSetupArray.push(tempModule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleSetupSurfaces.forEach((moduleSetupSurface, index) => {
|
moduleSetupSurfaces.forEach((moduleSetupSurface, index) => {
|
||||||
moduleSetupSurface.fire('mousedown')
|
moduleSetupSurface.fire('mousedown')
|
||||||
const moduleSetupArray = []
|
const moduleSetupArray = []
|
||||||
|
|
||||||
|
const turfModuleSetupSurface = polygonToTurfPolygon(moduleSetupSurface) //폴리곤을 turf 객체로 변환
|
||||||
|
const containsBatchObjects = objectsIncludeSurface(turfModuleSetupSurface) //배치면에 오브젝트(도머, 개구등)이 있는지 확인하는 로직
|
||||||
|
const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface)
|
||||||
|
|
||||||
let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => {
|
let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => {
|
||||||
return acc.length > cur.length ? acc : cur
|
return acc.length > cur.length ? acc : cur
|
||||||
})
|
})
|
||||||
|
|
||||||
const turfModuleSetupSurface = polygonToTurfPolygon(moduleSetupSurface) //폴리곤을 turf 객체로 변환
|
|
||||||
const containsBatchObjects = objectsIncludeSurface(turfModuleSetupSurface) //배치면에 오브젝트(도머, 개구등)이 있는지 확인하는 로직
|
|
||||||
|
|
||||||
let width = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 172.2 : 113.4
|
|
||||||
let height = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 113.4 : 172.2
|
|
||||||
|
|
||||||
//배치면때는 방향쪽으로 패널이 넓게 누워져야함
|
|
||||||
if (moduleSetupSurface.flowDirection !== undefined) {
|
|
||||||
width = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 172.2 : 113.4
|
|
||||||
height = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 113.4 : 172.2
|
|
||||||
}
|
|
||||||
|
|
||||||
const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface)
|
|
||||||
|
|
||||||
//처마면 배치
|
//처마면 배치
|
||||||
if (setupLocation === 'eaves') {
|
if (setupLocation === 'eaves') {
|
||||||
// 흐름방향이 남쪽일때
|
// 흐름방향이 남쪽일때
|
||||||
if (moduleSetupSurface.flowDirection === 'south') {
|
if (moduleSetupSurface.flowDirection === 'south') {
|
||||||
downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface)
|
downFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects)
|
||||||
}
|
}
|
||||||
if (moduleSetupSurface.flowDirection === 'west') {
|
if (moduleSetupSurface.flowDirection === 'west') {
|
||||||
leftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface)
|
leftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects)
|
||||||
}
|
}
|
||||||
if (moduleSetupSurface.flowDirection === 'east') {
|
if (moduleSetupSurface.flowDirection === 'east') {
|
||||||
rightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface)
|
rightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects)
|
||||||
}
|
}
|
||||||
if (moduleSetupSurface.flowDirection === 'north') {
|
if (moduleSetupSurface.flowDirection === 'north') {
|
||||||
topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface)
|
topFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects)
|
||||||
}
|
}
|
||||||
} else if (setupLocation === 'ridge') {
|
} else if (setupLocation === 'ridge') {
|
||||||
//용마루
|
//용마루
|
||||||
if (moduleSetupSurface.flowDirection === 'south') {
|
if (moduleSetupSurface.flowDirection === 'south') {
|
||||||
topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface)
|
topFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects)
|
||||||
}
|
}
|
||||||
if (moduleSetupSurface.flowDirection === 'west') {
|
if (moduleSetupSurface.flowDirection === 'west') {
|
||||||
rightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface)
|
rightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects)
|
||||||
}
|
}
|
||||||
if (moduleSetupSurface.flowDirection === 'east') {
|
if (moduleSetupSurface.flowDirection === 'east') {
|
||||||
leftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface)
|
leftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects)
|
||||||
}
|
}
|
||||||
if (moduleSetupSurface.flowDirection === 'north') {
|
if (moduleSetupSurface.flowDirection === 'north') {
|
||||||
downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface)
|
downFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects)
|
||||||
}
|
}
|
||||||
} else if (setupLocation === 'center') {
|
} else if (setupLocation === 'center') {
|
||||||
//중가면
|
//중가면
|
||||||
if (moduleSetupSurface.flowDirection === 'south') {
|
if (moduleSetupSurface.flowDirection === 'south') {
|
||||||
downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, true)
|
downFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, true)
|
||||||
}
|
}
|
||||||
if (moduleSetupSurface.flowDirection === 'west') {
|
if (moduleSetupSurface.flowDirection === 'west') {
|
||||||
leftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, true)
|
leftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, true)
|
||||||
}
|
}
|
||||||
if (moduleSetupSurface.flowDirection === 'east') {
|
if (moduleSetupSurface.flowDirection === 'east') {
|
||||||
rightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, true)
|
rightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, true)
|
||||||
}
|
}
|
||||||
if (moduleSetupSurface.flowDirection === 'north') {
|
if (moduleSetupSurface.flowDirection === 'north') {
|
||||||
topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, true)
|
topFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const setupedModules = moduleSetupArray.filter((module, index) => {
|
// const setupedModules = moduleSetupArray.filter((module, index) => {
|
||||||
let disjointFromTrestle = checkModuleDisjointSurface(module.turfPoints, turfModuleSetupSurface)
|
// let disjointFromTrestle = checkModuleDisjointSurface(module.turfPoints, turfModuleSetupSurface)
|
||||||
let isDisjoint = checkModuleDisjointObjects(module.turfPoints, containsBatchObjects)
|
// let isDisjoint = checkModuleDisjointObjects(module.turfPoints, containsBatchObjects)
|
||||||
|
|
||||||
if (!(disjointFromTrestle && isDisjoint)) {
|
// if (!(disjointFromTrestle && isDisjoint)) {
|
||||||
canvas?.remove(module)
|
// canvas?.remove(module)
|
||||||
// module.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 })
|
// // module.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 })
|
||||||
return false
|
// return false
|
||||||
} else {
|
// } else {
|
||||||
return module
|
// return module
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
|
||||||
canvas?.renderAll()
|
// canvas?.renderAll()
|
||||||
|
|
||||||
//나간애들 제외하고 설치된 애들로 겹친애들 삭제 하기
|
//나간애들 제외하고 설치된 애들로 겹친애들 삭제 하기
|
||||||
setupedModules.forEach((module, index) => {
|
moduleSetupArray.forEach((module, index) => {
|
||||||
if (isMaxSetup && index > 0) {
|
if (isMaxSetup && index > 0) {
|
||||||
const isOverlap = turf.booleanOverlap(polygonToTurfPolygon(setupedModules[index - 1]), polygonToTurfPolygon(module))
|
const isOverlap = turf.booleanOverlap(polygonToTurfPolygon(moduleSetupArray[index - 1]), polygonToTurfPolygon(module))
|
||||||
//겹치는지 확인
|
//겹치는지 확인
|
||||||
if (isOverlap) {
|
if (isOverlap) {
|
||||||
//겹쳐있으면 삭제
|
//겹쳐있으면 삭제
|
||||||
canvas?.remove(module)
|
canvas?.remove(module)
|
||||||
// module.set({ fill: 'rgba(72, 161, 250, 0.4)', stroke: 'black', strokeWidth: 0.1 })
|
// module.set({ fill: 'rgba(72, 161, 250, 0.4)', stroke: 'black', strokeWidth: 0.1 })
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
setupedModules.splice(index, 1)
|
moduleSetupArray.splice(index, 1)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
moduleSetupSurface.set({ modules: setupedModules })
|
// moduleSetupSurface.set({ modules: moduleSetupArray })
|
||||||
|
|
||||||
// const moduleArray = [...moduleIsSetup]
|
// const moduleArray = [...moduleIsSetup]
|
||||||
// moduleArray.push({
|
// moduleArray.push({
|
||||||
@ -985,7 +1128,7 @@ export function useModuleBasicSetting() {
|
|||||||
// })
|
// })
|
||||||
// setModuleIsSetup(moduleArray)
|
// setModuleIsSetup(moduleArray)
|
||||||
})
|
})
|
||||||
calculateForApi()
|
// calculateForApi()
|
||||||
}
|
}
|
||||||
|
|
||||||
const calculateForApi = () => {
|
const calculateForApi = () => {
|
||||||
@ -1247,8 +1390,9 @@ export function useModuleBasicSetting() {
|
|||||||
return hull
|
return hull
|
||||||
}
|
}
|
||||||
|
|
||||||
const bottomTopFlowLine = (surface) => {
|
const bottomTopFlowLine = (surface, module) => {
|
||||||
const flowArray = []
|
const flowArray = []
|
||||||
|
|
||||||
const bottomFlow = surface.lines.reduce(
|
const bottomFlow = surface.lines.reduce(
|
||||||
(acc, line, index) => {
|
(acc, line, index) => {
|
||||||
if (line.y1 > acc.y1 || (line.y1 === acc.y1 && line.x1 > acc.x1)) {
|
if (line.y1 > acc.y1 || (line.y1 === acc.y1 && line.x1 > acc.x1)) {
|
||||||
@ -1305,7 +1449,7 @@ export function useModuleBasicSetting() {
|
|||||||
const angle2 = Math.abs(Math.round(Math.atan(height2 / adjust2) * (180 / Math.PI) * 1000) / 1000)
|
const angle2 = Math.abs(Math.round(Math.atan(height2 / adjust2) * (180 / Math.PI) * 1000) / 1000)
|
||||||
const angle3 = 180 - (angle1 + angle2)
|
const angle3 = 180 - (angle1 + angle2)
|
||||||
|
|
||||||
const charlie = 173.3 // 평행선길이 약간 여유를 줌
|
const charlie = Number(module.longAxis) / 10 + 3 // 평행선길이 약간 여유를 줌
|
||||||
const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180)
|
const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180)
|
||||||
const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180))
|
const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180))
|
||||||
const h = beta * Math.sin((angle1 * Math.PI) / 180) // 높이
|
const h = beta * Math.sin((angle1 * Math.PI) / 180) // 높이
|
||||||
@ -1322,8 +1466,8 @@ export function useModuleBasicSetting() {
|
|||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
})
|
})
|
||||||
// canvas?.add(finalLine)
|
canvas?.add(finalLine)
|
||||||
// canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
|
|
||||||
let rtnObj
|
let rtnObj
|
||||||
//평평하면
|
//평평하면
|
||||||
@ -1364,7 +1508,7 @@ export function useModuleBasicSetting() {
|
|||||||
return rtnObjArray
|
return rtnObjArray
|
||||||
}
|
}
|
||||||
|
|
||||||
const leftRightFlowLine = (surface) => {
|
const leftRightFlowLine = (surface, module) => {
|
||||||
const flowArray = []
|
const flowArray = []
|
||||||
const leftFlow = surface.lines.reduce(
|
const leftFlow = surface.lines.reduce(
|
||||||
(acc, line, index) => {
|
(acc, line, index) => {
|
||||||
@ -1420,7 +1564,7 @@ export function useModuleBasicSetting() {
|
|||||||
const angle2 = Math.abs(Math.round(Math.atan(adjust2 / height2) * (180 / Math.PI) * 1000) / 1000)
|
const angle2 = Math.abs(Math.round(Math.atan(adjust2 / height2) * (180 / Math.PI) * 1000) / 1000)
|
||||||
const angle3 = 180 - (angle1 + angle2)
|
const angle3 = 180 - (angle1 + angle2)
|
||||||
|
|
||||||
const charlie = 173.3 // 평행선길이 약간 여유를줌
|
const charlie = Number(module.shortAxis) / 10 + 3 // 평행선길이 약간 여유를 줌
|
||||||
const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180)
|
const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180)
|
||||||
const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180))
|
const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180))
|
||||||
|
|
||||||
@ -1445,8 +1589,8 @@ export function useModuleBasicSetting() {
|
|||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
})
|
})
|
||||||
// canvas?.add(finalLine)
|
canvas?.add(finalLine)
|
||||||
// canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
|
|
||||||
let rtnObj
|
let rtnObj
|
||||||
//평평하면
|
//평평하면
|
||||||
|
|||||||
@ -373,3 +373,15 @@ export const moduleIsSetupState = atom({
|
|||||||
default: [],
|
default: [],
|
||||||
dangerouslyAllowMutability: true,
|
dangerouslyAllowMutability: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const selectedModuleState = atom({
|
||||||
|
key: 'selectedModuleState',
|
||||||
|
default: [],
|
||||||
|
dangerouslyAllowMutability: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const checkedModuleState = atom({
|
||||||
|
key: 'checkedModuleState',
|
||||||
|
default: [],
|
||||||
|
dangerouslyAllowMutability: true,
|
||||||
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user