批量复制改为弧度和距离复制
图例增加曲线隐藏
This commit is contained in:
parent
24dde0807c
commit
b1fbcb09f2
@ -8,25 +8,27 @@
|
||||
@close="dialogClose"
|
||||
>
|
||||
<el-form :model="batchCopyingForm" label-width="120" ref="BatchCopyingFormRef" :rules="rules">
|
||||
<el-form-item label="X轴偏移量(实际点位)" prop="x" required>
|
||||
<el-form-item label="方向(弧度)" prop="radian" required>
|
||||
<el-input-number
|
||||
v-model="batchCopyingForm.x"
|
||||
placeholder="请输入"
|
||||
v-model="batchCopyingForm.radian"
|
||||
placeholder="请输入弧度"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
precision="2"
|
||||
:min="-Math.PI"
|
||||
:max="Math.PI"
|
||||
:step="0.01"
|
||||
precision="4"
|
||||
/>
|
||||
<el-text type="info" size="small">X轴往左为负值,往右为正值</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="Y轴偏移量(实际点位)" prop="y" required>
|
||||
<el-form-item label="偏移距离(米)" prop="distance" required>
|
||||
<el-input-number
|
||||
v-model="batchCopyingForm.y"
|
||||
placeholder="请输入"
|
||||
v-model="batchCopyingForm.distance"
|
||||
placeholder="请输入距离"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
:min="0"
|
||||
precision="2"
|
||||
/>
|
||||
<el-text type="info" size="small">Y轴往上为负值,往下为正值</el-text>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
@ -39,7 +41,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import * as MapApi from '@/api/map/map'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
|
||||
@ -52,6 +54,8 @@ const props = defineProps({
|
||||
})
|
||||
//新增
|
||||
const batchCopyingForm = ref({
|
||||
radian: 0,
|
||||
distance: 0,
|
||||
x: 0,
|
||||
y: 0
|
||||
})
|
||||
@ -59,44 +63,30 @@ const boundaryValue = ref()
|
||||
const BatchCopyingFormRef = ref()
|
||||
const dialogFormVisible = ref(false) //列表的
|
||||
|
||||
const validateXValue = (rule, value, callback) => {
|
||||
const { resolution, width } = props.imgBgObj
|
||||
const roundToThree = (num) => Math.round(Number(num) * 1000) / 1000
|
||||
|
||||
let maxLeft = -(Number(boundaryValue.value.left) / Number(resolution))
|
||||
let maxRight = (Number(width) - Number(boundaryValue.value.right)) / Number(resolution)
|
||||
if (value < maxLeft || value > maxRight) {
|
||||
callback(new Error(`不能超出地图宽度,可偏移范围为${maxLeft}至${maxRight}`))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const validateYValue = (rule, value, callback) => {
|
||||
const { resolution, height } = props.imgBgObj
|
||||
|
||||
let maxTop = -(Number(boundaryValue.value.top) / Number(resolution))
|
||||
let maxBottom = (Number(height) - Number(boundaryValue.value.bottom)) / Number(resolution)
|
||||
if (value < maxTop || value > maxBottom) {
|
||||
callback(new Error(`不能超出地图宽度,可偏移范围为${maxTop}至${maxBottom}`))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
watch(
|
||||
() => [batchCopyingForm.value.radian, batchCopyingForm.value.distance],
|
||||
([newRadian, newDistance]) => {
|
||||
// 根据三角函数计算x和y
|
||||
// Y轴在屏幕坐标系中是向下的(向上为负),所以sin的结果需要反转
|
||||
const x = newDistance * Math.cos(newRadian)
|
||||
const y = -1 * newDistance * Math.sin(newRadian)
|
||||
batchCopyingForm.value.x = roundToThree(x)
|
||||
batchCopyingForm.value.y = roundToThree(y)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
const rules = reactive({
|
||||
x: [
|
||||
{ required: true, message: '请输入X轴偏移量', trigger: 'blur' },
|
||||
{ validator: validateXValue, trigger: 'blur' }
|
||||
],
|
||||
y: [
|
||||
{ required: true, message: '请输入Y轴偏移量', trigger: 'blur' },
|
||||
{ validator: validateYValue, trigger: 'blur' }
|
||||
]
|
||||
radian: [{ required: true, message: '请输入方向弧度', trigger: 'blur' }],
|
||||
distance: [{ required: true, message: '请输入偏移距离', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
const open = (boundaryObj) => {
|
||||
boundaryValue.value = boundaryObj
|
||||
batchCopyingForm.value.x = 0
|
||||
batchCopyingForm.value.y = 0
|
||||
batchCopyingForm.value.radian = 0
|
||||
batchCopyingForm.value.distance = 0
|
||||
dialogFormVisible.value = true
|
||||
}
|
||||
|
||||
@ -115,6 +105,7 @@ const submitLineLibraryForm = async () => {
|
||||
const y = roundToThree(
|
||||
safeNumber(batchCopyingForm.value.y) / safeNumber(props.imgBgObj.resolution)
|
||||
)
|
||||
|
||||
emit('submitBatchCopyingFormSuccess', {
|
||||
x: x,
|
||||
y: y
|
||||
@ -124,7 +115,6 @@ const submitLineLibraryForm = async () => {
|
||||
}
|
||||
|
||||
const safeNumber = (value) => Number(value || 0)
|
||||
const roundToThree = (num) => Math.round(Number(num) * 1000) / 1000
|
||||
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
</script>
|
||||
|
@ -134,7 +134,7 @@
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="库位类型" required prop="locationTypeId">
|
||||
<el-form-item label="库位类型" required prop="locationTypeId" v-if="form.type === 2">
|
||||
<el-select
|
||||
class="!w-300px"
|
||||
v-model="form.locationTypeId"
|
||||
@ -474,6 +474,7 @@ const typeChange = (type) => {
|
||||
form.value.dataJson = null
|
||||
form.value.dataObj = {}
|
||||
form.value.dataList = []
|
||||
form.value.locationTypeId = null
|
||||
if (type === 1) {
|
||||
form.value.layersNumber = null
|
||||
form.value.direction = null
|
||||
|
@ -22,19 +22,28 @@ const emit = defineEmits(['layerSelectionSuccess'])
|
||||
|
||||
const list = ref([
|
||||
{
|
||||
category: 'node',
|
||||
type: 2,
|
||||
name: '库位点',
|
||||
isShow: true
|
||||
},
|
||||
{
|
||||
category: 'node',
|
||||
type: 1,
|
||||
name: '路径点',
|
||||
isShow: true
|
||||
},
|
||||
{
|
||||
category: 'node',
|
||||
type: 3,
|
||||
name: '设备点',
|
||||
isShow: true
|
||||
},
|
||||
{
|
||||
category: 'curve',
|
||||
type: 4,
|
||||
name: '曲线',
|
||||
isShow: true
|
||||
}
|
||||
])
|
||||
|
||||
@ -44,9 +53,13 @@ const changeUnfold = () => {
|
||||
isUnfold.value = !isUnfold.value
|
||||
}
|
||||
const changeSelectList = (item) => {
|
||||
if (item.category === 'node') {
|
||||
const types = list.value.filter((item) => !item.isShow).map((item) => item.type)
|
||||
emit('layerSelectionSuccess', types)
|
||||
} else {
|
||||
emit('isCurveDisplayChange')
|
||||
}
|
||||
item.isShow = !item.isShow
|
||||
const types = list.value.filter((item) => !item.isShow).map((item) => item.type)
|
||||
emit('layerSelectionSuccess', types)
|
||||
}
|
||||
|
||||
const open = (item) => {}
|
||||
@ -59,8 +72,8 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
z-index: 999;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
bottom: 22px;
|
||||
left: 18px;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
width: 144px;
|
||||
cursor: pointer;
|
||||
|
||||
|
@ -715,49 +715,51 @@
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<path
|
||||
id="curvePath"
|
||||
:d="getCurvePath(curve)"
|
||||
:stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
|
||||
:stroke-width="state.routeWidthForm.routeWidth"
|
||||
fill="none"
|
||||
@click="handleChooseRoute(curve, index)"
|
||||
/>
|
||||
<text
|
||||
style="user-select: none"
|
||||
:x="computedCurveTextX(curve)"
|
||||
:y="computedCurveTextY(curve)"
|
||||
font-size="11"
|
||||
text-anchor="middle"
|
||||
fill="black"
|
||||
v-if="curve.isSelected"
|
||||
@click="handleChooseRoute(curve, index)"
|
||||
>
|
||||
{{ calculateRouteLength(curve, 'curve') }}米
|
||||
</text>
|
||||
<template v-if="state.isCurveDisplay">
|
||||
<path
|
||||
id="curvePath"
|
||||
:d="getCurvePath(curve)"
|
||||
:stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
|
||||
:stroke-width="state.routeWidthForm.routeWidth"
|
||||
fill="none"
|
||||
@click="handleChooseRoute(curve, index)"
|
||||
/>
|
||||
<text
|
||||
style="user-select: none"
|
||||
:x="computedCurveTextX(curve)"
|
||||
:y="computedCurveTextY(curve)"
|
||||
font-size="11"
|
||||
text-anchor="middle"
|
||||
fill="black"
|
||||
v-if="curve.isSelected"
|
||||
@click="handleChooseRoute(curve, index)"
|
||||
>
|
||||
{{ calculateRouteLength(curve, 'curve') }}米
|
||||
</text>
|
||||
|
||||
<!-- 第一条控制线 -->
|
||||
<line
|
||||
v-if="state.currentDragTarget.index == index"
|
||||
:x1="Number(curve.startPointX)"
|
||||
:y1="Number(curve.startPointY)"
|
||||
:x2="curve.beginControlX"
|
||||
:y2="curve.beginControlY"
|
||||
:stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
|
||||
stroke-dasharray="4"
|
||||
stroke-width="2"
|
||||
/>
|
||||
<!-- 第二条控制线 -->
|
||||
<line
|
||||
v-if="state.currentDragTarget.index == index"
|
||||
:x1="Number(curve.endPointX)"
|
||||
:y1="Number(curve.endPointY)"
|
||||
:x2="curve.endControlX"
|
||||
:y2="curve.endControlY"
|
||||
:stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
|
||||
stroke-dasharray="4"
|
||||
stroke-width="2"
|
||||
/>
|
||||
<!-- 第一条控制线 -->
|
||||
<line
|
||||
v-if="state.currentDragTarget.index == index"
|
||||
:x1="Number(curve.startPointX)"
|
||||
:y1="Number(curve.startPointY)"
|
||||
:x2="curve.beginControlX"
|
||||
:y2="curve.beginControlY"
|
||||
:stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
|
||||
stroke-dasharray="4"
|
||||
stroke-width="2"
|
||||
/>
|
||||
<!-- 第二条控制线 -->
|
||||
<line
|
||||
v-if="state.currentDragTarget.index == index"
|
||||
:x1="Number(curve.endPointX)"
|
||||
:y1="Number(curve.endPointY)"
|
||||
:x2="curve.endControlX"
|
||||
:y2="curve.endControlY"
|
||||
:stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
|
||||
stroke-dasharray="4"
|
||||
stroke-width="2"
|
||||
/>
|
||||
</template>
|
||||
<!-- 控制点circle已移至SVG末尾 -->
|
||||
</template>
|
||||
</template>
|
||||
@ -898,6 +900,7 @@
|
||||
v-if="state.isShowLayer"
|
||||
ref="layerSelectionToolDialogRef"
|
||||
@layer-selection-success="layerSelectionSuccess"
|
||||
@is-curve-display-change="isCurveDisplayChange"
|
||||
/>
|
||||
<!-- 设备弹窗选择 -->
|
||||
<equipmentToolDialog
|
||||
@ -1712,7 +1715,8 @@ const state = reactive({
|
||||
routeDirection: 2, //1单2双
|
||||
vLine: [],
|
||||
hLine: [],
|
||||
svgRouteZIndex: 9
|
||||
svgRouteZIndex: 9,
|
||||
isCurveDisplay: true
|
||||
})
|
||||
|
||||
const getRefLineParams = (params) => {
|
||||
@ -3847,6 +3851,11 @@ const layerSelectionSuccess = (typeList) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
//路线的图层筛选
|
||||
const isCurveDisplayChange = () => {
|
||||
state.isCurveDisplay = !state.isCurveDisplay
|
||||
}
|
||||
|
||||
//处理数据 考虑滚动条,缩放等各种情况的的坐标数据
|
||||
const disposeEventPoints = (event) => {
|
||||
const rect = mapBackgroundRef.value.getBoundingClientRect()
|
||||
@ -4196,7 +4205,7 @@ const findClosestPoint = (x, y) => {
|
||||
padding: 0 0 0 4px;
|
||||
|
||||
.top-tool-list {
|
||||
max-width: calc(100vw - 260px);
|
||||
max-width: calc(100% - 200px);
|
||||
overflow-x: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -4352,6 +4361,7 @@ const findClosestPoint = (x, y) => {
|
||||
}
|
||||
|
||||
.search-select {
|
||||
padding-right: 20px;
|
||||
.search-icon {
|
||||
widows: 20px;
|
||||
height: 20px;
|
||||
|
Loading…
Reference in New Issue
Block a user