bx-865-apps #1

Merged
ksenia_mikhailova merged 140 commits from bx-865-apps into main 2024-06-27 15:03:27 +03:00
4 changed files with 150 additions and 110 deletions
Showing only changes of commit 9d666c349b - Show all commits

View File

@ -3,6 +3,9 @@ const menu = [{
label: 'Создать план помещения',
to: '/plan'
}]
const point_array = useState('point_array', () => [[]])
point_array.value = [[]]
</script>
<template>
<div class="grid grid-cols-12 gap-4">

View File

@ -0,0 +1,42 @@
<script setup lang="ts">
const point_array = useState<number[][] | undefined>('point_array', () => undefined)
const canvasElement: Ref<HTMLCanvasElement | undefined> = ref();
const context: Ref<CanvasRenderingContext2D | undefined> = ref();
const props = defineProps(['cw', 'ch'])
const nextFrame = () => new Promise(resolve => requestAnimationFrame(resolve));
const newDraw = async () => {
context.value = canvasElement.value?.getContext('2d') || undefined;
const lines = point_array.value
if (!lines) return;
context.value?.clearRect(0, 0, props.cw, props.ch)
await nextFrame()
for (let indexY = 0; indexY < lines.length; indexY++) {
const line = lines[indexY];
const drawLine = () => {
line.forEach((point, indexX) => {
if (canvasElement.value && context.value && point > 0) {
context.value.fillStyle = 'rgba(70, 0, 70, 0.5)'
context.value.fillRect(indexX, indexY, 1, 1)
}
})
}
drawLine()
if (indexY % 10 == 0) await nextFrame()
}
}
watch(point_array, (newStatus) => {
newDraw()
})
onMounted(() => {
newDraw()
})
</script>
<template>
<canvas :width="props.cw" :height="props.ch" ref="canvasElement" style="position: absolute; z-index: -1;"></canvas>
</template>

View File

@ -0,0 +1,86 @@
<script setup lang="ts">
import { chunks } from '~/helpers';
const point_array = useState<number[][] | undefined>('point_array', () => undefined)
const chunk_size = useState<number>('chunk_size', () => 8)
const threshold = useState<number>('chunk_size', () => 20)
const paths_array = ref<{ path: string, unwalkable: boolean, x: number, y: number }[]>()
const props = defineProps(['cw', 'ch'])
const sampling_data = () => {
const points = point_array.value
const chunk = chunk_size.value
if (!points) return
const prepared_array = [...chunks(points, chunk)].map(line => {
const line_data = [] as any[][]
line.map((item: any) => [...chunks(item, chunk)]).map((item) => {
item.map((one_line, k) => {
if (!line_data[k]) line_data[k] = []
line_data[k].push(...one_line)
})
})
return line_data.map(el => {
return el.filter(e => e > 0).length > threshold.value ? 1 : 0
})
});
const res: any[] = []
prepared_array.forEach((line, indexY) => {
line.forEach((point, indexX) => {
const targetX = indexX * chunk
const targetY = indexY * chunk
res.push({
path: `M${targetX} ${targetY} ${targetX + chunk} ${targetY} ${targetX + chunk} ${targetY + chunk} ${targetX} ${targetY + chunk}Z`,
unwalkable: !!point,
x: indexX,
y: indexY,
})
})
})
paths_array.value = res
}
watch(point_array, (newStatus) => {
sampling_data()
})
onMounted(() => {
sampling_data()
})
</script>
<template>
<svg ref="svgElement" :width="props.cw" :height="props.ch">
<path v-for="item in paths_array" :d="item.path" :class="[
{ 'unwalkable': item.unwalkable },
// { 'endPoint': (endPoint && item.x == endPoint.x && item.y == endPoint.y) },
// { 'startPoint': (startPoint && item.x == startPoint.x && item.y == startPoint.y) },
// { 'pathPoint': (startToEndPath && startToEndPath.find((el: number[]) => el[0] == item.x && el[1] == item.y)) },
]">
</path>
</svg>
</template>
<style scoped>
svg path {
fill: transparent
}
svg path:hover {
fill: red
}
svg path.unwalkable {
fill: rgba(70, 70, 0, 0.5);
}
svg path.endPoint {
fill: blue;
}
svg path.startPoint {
fill: lawngreen;
}
svg path.pathPoint {
fill: gold;
}
</style>

View File

@ -4,7 +4,10 @@ import PF, { Grid } from 'pathfinding'
import { chunks } from '~/helpers';
const config = useRuntimeConfig()
const point_array = ref<number[][]>()
const point_array = useState('point_array', () => [[]])
const chunk_size = useState('chunk_size', () => 8)
const threshold = useState('chunk_size', () => 20)
const paths_array = ref<{ path: string, unwalkable: boolean, x: number, y: number }[]>()
const loading = ref<boolean>(false)
@ -33,9 +36,6 @@ const onUpload = (event: FileUploadUploadEvent) => {
try {
const data = JSON.parse(event.xhr.response)
point_array.value = data.response.np_field
paths_array.value = sampling_data(data.response.np_field, 8, 20)
newDraw()
} catch (error) {
console.log(error)
}
@ -46,73 +46,23 @@ const selectFileEvent = async () => {
const res = await fetch(`${config.public.apiBase}/api/floorplan/${selectFile.value}`)
const data = await res.json()
point_array.value = data.np_field
paths_array.value = sampling_data(data.np_field, 8, 20)
newDraw()
} catch (error) {
console.log(error)
}
loadingFile.value = false
}
const sampling_data = (np_field: number[][], chunkSize: number, threshold: number) => {
const prepared_array = [...chunks(np_field, chunkSize)].map(line => {
const line_data = [] as any[][]
line.map((item: any) => [...chunks(item, chunkSize)]).map((item) => {
item.map((one_line, k) => {
if (!line_data[k]) line_data[k] = []
line_data[k].push(...one_line)
})
})
return line_data.map(el => {
return el.filter(e => e > 0).length > threshold ? 1 : 0
})
});
const res: any[] = []
prepared_array.forEach((line, indexY) => {
line.forEach((point, indexX) => {
const targetX = indexX * chunkSize
const targetY = indexY * chunkSize
res.push({
path: `M${targetX} ${targetY} ${targetX + chunkSize} ${targetY} ${targetX + chunkSize} ${targetY + chunkSize} ${targetX} ${targetY + chunkSize}Z`,
unwalkable: !!point,
x: indexX,
y: indexY,
})
})
})
return res
}
const newDraw = async () => {
startPoint.value = undefined
endPoint.value = undefined
startToEndPath.value = undefined
context.value = canvasElement.value?.getContext('2d') || undefined;
const lines = point_array.value
if (!lines) return;
context.value?.clearRect(0, 0, cw, ch)
await nextFrame()
for (let indexY = 0; indexY < lines.length; indexY++) {
const line = lines[indexY];
const drawLine = () => {
line.forEach((point, indexX) => {
if (canvasElement.value && context.value && point > 0) {
context.value.fillStyle = 'crimson'
context.value.fillRect(indexX, indexY, 1, 1)
}
})
}
drawLine()
await nextFrame()
const loadFiles = async () => {
try {
loadingFile.value = true
const res = await fetch(`${config.public.apiBase}/api/floorplan/`)
const data = await res.json()
files.value = data
} catch (error) {
console.log(error)
}
grid.value = new PF.Grid(lines.map(y => y.map(x => x > 0 ? 1 : 0)))
loadingFile.value = false
}
const toggleBlock = (name: string) => {
if (openBlocks.value.includes(name)) {
openBlocks.value.splice(openBlocks.value.indexOf(name), 1)
@ -131,17 +81,6 @@ const fileBtnClick = async () => {
}
toggleBlock('upload_file')
}
const loadFiles = async () => {
try {
loadingFile.value = true
const res = await fetch(`${config.public.apiBase}/api/floorplan/`)
const data = await res.json()
files.value = data
} catch (error) {
console.log(error)
}
loadingFile.value = false
}
onMounted(async () => {
await loadFiles()
})
@ -169,45 +108,15 @@ onMounted(async () => {
chooseLabel="Выберите файл" :disabled="loading" />
</Panel>
<Panel header="Данные для работы">
</Panel>
<Panel :header="loading ? `Идет отрисовка` : `Обработанный план здания`">
<div style=" max-width: 100%; overflow: auto; position: relative;">
<canvas ref="canvasElement" :width="cw" :height="ch" style="position: absolute; z-index: -1;"></canvas>
<svg ref="svgElement" :width="cw" :height="ch">
<path v-for="item in paths_array" :d="item.path" :class="[
{ 'unwalkable': item.unwalkable },
// { 'endPoint': (endPoint && item.x == endPoint.x && item.y == endPoint.y) },
// { 'startPoint': (startPoint && item.x == startPoint.x && item.y == startPoint.y) },
// { 'pathPoint': (startToEndPath && startToEndPath.find((el: number[]) => el[0] == item.x && el[1] == item.y)) },
]">
</path>
</svg>
<FloorplanCanvas :cw="cw" :ch="ch" />
<FloorplanSvg :cw="cw" :ch="ch" />
</div>
</Panel>
</div>
</template>
<style scoped>
svg path {
fill: transparent
}
svg path:hover {
fill: red
}
svg path.unwalkable {
fill: rgba(0, 0, 0, 0.5);
}
svg path.endPoint {
fill: blue;
}
svg path.startPoint {
fill: lawngreen;
}
svg path.pathPoint {
fill: gold;
}
</style>