字典配置轨迹文件格式
This commit is contained in:
parent
d76271da24
commit
50462faaff
@ -4,14 +4,10 @@
|
|||||||
<button class="fullscreen-btn" @click="toggleFullscreen">
|
<button class="fullscreen-btn" @click="toggleFullscreen">
|
||||||
{{ isFullscreen ? '退出全屏' : '全屏' }}
|
{{ isFullscreen ? '退出全屏' : '全屏' }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<svg ref="svgRef" class="trajectory-svg" :width="svgWidth" :height="svgHeight">
|
<svg ref="svgRef" class="trajectory-svg" :width="svgWidth" :height="svgHeight">
|
||||||
<g class="zoom-container">
|
<g class="zoom-container">
|
||||||
<image
|
<image :xlink:href="imageUrl" :width="svgWidth" :height="svgHeight" />
|
||||||
:xlink:href="imageUrl"
|
|
||||||
:width="svgWidth"
|
|
||||||
:height="svgHeight"
|
|
||||||
/>
|
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
@ -24,17 +20,17 @@ import * as d3 from 'd3'
|
|||||||
// === Props 定义 ===
|
// === Props 定义 ===
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
imageUrl: { type: String, required: true },
|
imageUrl: { type: String, required: true },
|
||||||
bounds: {
|
bounds: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true,
|
required: true,
|
||||||
default: () => [0, 0, 1, 1] // [minLng, minLat, maxLng, maxLat]
|
default: () => [0, 0, 1, 1] // [minLng, minLat, maxLng, maxLat]
|
||||||
},
|
},
|
||||||
trajectory: {
|
trajectory: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true,
|
required: true,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
qvehuan: {
|
qvehuan: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
@ -64,13 +60,13 @@ const initMap = () => {
|
|||||||
svgWidth.value = container.clientWidth
|
svgWidth.value = container.clientWidth
|
||||||
svgHeight.value = container.clientHeight
|
svgHeight.value = container.clientHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
const [minLng, minLat, maxLng, maxLat] = props.bounds
|
const [minLng, minLat, maxLng, maxLat] = props.bounds
|
||||||
|
|
||||||
xScale.value = d3.scaleLinear()
|
xScale.value = d3.scaleLinear()
|
||||||
.domain([minLng, maxLng])
|
.domain([minLng, maxLng])
|
||||||
.range([0, svgWidth.value])
|
.range([0, svgWidth.value])
|
||||||
|
|
||||||
yScale.value = d3.scaleLinear()
|
yScale.value = d3.scaleLinear()
|
||||||
.domain([minLat, maxLat])
|
.domain([minLat, maxLat])
|
||||||
.range([svgHeight.value, 0])
|
.range([svgHeight.value, 0])
|
||||||
@ -83,7 +79,7 @@ const initMap = () => {
|
|||||||
const initZoom = () => {
|
const initZoom = () => {
|
||||||
const mapZoom = d3.zoom()
|
const mapZoom = d3.zoom()
|
||||||
.scaleExtent([0.5, 3]) // 缩放范围
|
.scaleExtent([0.5, 3]) // 缩放范围
|
||||||
.translateExtent([[-svgWidth.value, -svgHeight.value], [2*svgWidth.value, 2*svgHeight.value]])
|
.translateExtent([[-svgWidth.value, -svgHeight.value], [2 * svgWidth.value, 2 * svgHeight.value]])
|
||||||
.on("zoom", (event) => {
|
.on("zoom", (event) => {
|
||||||
d3.select(svgRef.value).select('.zoom-container')
|
d3.select(svgRef.value).select('.zoom-container')
|
||||||
.attr("transform", event.transform)
|
.attr("transform", event.transform)
|
||||||
@ -131,10 +127,10 @@ const renderTrajectoryPath = () => {
|
|||||||
.attr('stroke', '#1890FF')
|
.attr('stroke', '#1890FF')
|
||||||
.attr('stroke-width', 2.5)
|
.attr('stroke-width', 2.5)
|
||||||
.attr('fill', 'none')
|
.attr('fill', 'none')
|
||||||
.attr('stroke-dasharray', function() {
|
.attr('stroke-dasharray', function () {
|
||||||
return this.getTotalLength()
|
return this.getTotalLength()
|
||||||
})
|
})
|
||||||
.attr('stroke-dashoffset', function() {
|
.attr('stroke-dashoffset', function () {
|
||||||
return this.getTotalLength()
|
return this.getTotalLength()
|
||||||
})
|
})
|
||||||
.transition()
|
.transition()
|
||||||
@ -152,7 +148,7 @@ const renderTrajectoryMarkers = () => {
|
|||||||
props.trajectory.forEach(([lng, lat], index) => {
|
props.trajectory.forEach(([lng, lat], index) => {
|
||||||
const x = xScale.value(lng)
|
const x = xScale.value(lng)
|
||||||
const y = yScale.value(lat)
|
const y = yScale.value(lat)
|
||||||
|
|
||||||
d3.select(svgRef.value).select('.zoom-container')
|
d3.select(svgRef.value).select('.zoom-container')
|
||||||
.append('circle')
|
.append('circle')
|
||||||
.attr('class', `marker-circle marker-${index}`)
|
.attr('class', `marker-circle marker-${index}`)
|
||||||
@ -162,12 +158,12 @@ const renderTrajectoryMarkers = () => {
|
|||||||
.attr('fill', '#FF4D4F')
|
.attr('fill', '#FF4D4F')
|
||||||
.attr('stroke', '#fff')
|
.attr('stroke', '#fff')
|
||||||
.attr('stroke-width', 0.8)
|
.attr('stroke-width', 0.8)
|
||||||
.on('mouseover', function() {
|
.on('mouseover', function () {
|
||||||
d3.select(this)
|
d3.select(this)
|
||||||
.attr('r', 4)
|
.attr('r', 4)
|
||||||
.attr('stroke-width', 1.2)
|
.attr('stroke-width', 1.2)
|
||||||
})
|
})
|
||||||
.on('mouseout', function() {
|
.on('mouseout', function () {
|
||||||
d3.select(this)
|
d3.select(this)
|
||||||
.attr('r', 2.5)
|
.attr('r', 2.5)
|
||||||
.attr('stroke-width', 0.8)
|
.attr('stroke-width', 0.8)
|
||||||
@ -216,24 +212,26 @@ const toggleFullscreen = () => {
|
|||||||
// === 全屏状态更新处理 ===
|
// === 全屏状态更新处理 ===
|
||||||
const handleFullscreenChange = () => {
|
const handleFullscreenChange = () => {
|
||||||
isFullscreen.value = !!document.fullscreenElement
|
isFullscreen.value = !!document.fullscreenElement
|
||||||
|
|
||||||
// 全屏切换时主动清除原有轨迹
|
// 全屏切换时主动清除原有轨迹
|
||||||
clearOldElements()
|
clearOldElements()
|
||||||
|
requestAnimationFrame(() => {
|
||||||
// 延迟执行以确保DOM更新
|
// 延迟执行以确保DOM更新
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
initMap()
|
initMap()
|
||||||
updateTrajectory()
|
updateTrajectory()
|
||||||
}, 500)
|
}, 500)
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// === 窗口大小变化处理 ===
|
// === 窗口大小变化处理 ===
|
||||||
const handleResize = () => {
|
const handleResize = () => {
|
||||||
if (resizeTimeout) clearTimeout(resizeTimeout)
|
if (resizeTimeout) clearTimeout(resizeTimeout)
|
||||||
resizeTimeout = setTimeout(() => {
|
resizeTimeout = setTimeout(() => {
|
||||||
|
clearOldElements()
|
||||||
initMap()
|
initMap()
|
||||||
updateTrajectory()
|
updateTrajectory()
|
||||||
}, 300)
|
},500)
|
||||||
}
|
}
|
||||||
|
|
||||||
// === 响应式监听与生命周期 ===
|
// === 响应式监听与生命周期 ===
|
||||||
@ -253,14 +251,14 @@ onMounted(() => {
|
|||||||
// 添加全屏变化监听
|
// 添加全屏变化监听
|
||||||
document.addEventListener('fullscreenchange', handleFullscreenChange)
|
document.addEventListener('fullscreenchange', handleFullscreenChange)
|
||||||
window.addEventListener('resize', handleResize)
|
window.addEventListener('resize', handleResize)
|
||||||
|
|
||||||
// 初始化SVG尺寸
|
// 初始化SVG尺寸
|
||||||
const container = d3.select(svgRef.value).node()
|
const container = d3.select(svgRef.value).node()
|
||||||
if (container) {
|
if (container) {
|
||||||
svgWidth.value = container.clientWidth
|
svgWidth.value = container.clientWidth
|
||||||
svgHeight.value = container.clientHeight
|
svgHeight.value = container.clientHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载图片
|
// 加载图片
|
||||||
const imageElement = d3.select(svgRef.value).select('image')
|
const imageElement = d3.select(svgRef.value).select('image')
|
||||||
if (imageElement) {
|
if (imageElement) {
|
||||||
|
20
web/src/views/testdata/datamanagement/index.vue
vendored
20
web/src/views/testdata/datamanagement/index.vue
vendored
@ -44,6 +44,7 @@ import VideoPlayerAsyncLoading from "@/components/file/preview/VideoPlayerAsyncL
|
|||||||
import TextViewerAsyncLoading from "@/components/file/preview/TextViewerAsyncLoading.vue";
|
import TextViewerAsyncLoading from "@/components/file/preview/TextViewerAsyncLoading.vue";
|
||||||
import MarkdownViewerDialogAsyncLoading from "@/components/file/preview/MarkdownViewerDialogAsyncLoading.vue";
|
import MarkdownViewerDialogAsyncLoading from "@/components/file/preview/MarkdownViewerDialogAsyncLoading.vue";
|
||||||
import { display } from "html2canvas/dist/types/css/property-descriptors/display";
|
import { display } from "html2canvas/dist/types/css/property-descriptors/display";
|
||||||
|
import { getDict } from '@/api/dict'
|
||||||
const { dialogVideoVisible, dialogTextVisible, dialogPdfVisible, dialogOfficeVisible, dialog3dVisible } = useFilePreview();
|
const { dialogVideoVisible, dialogTextVisible, dialogPdfVisible, dialogOfficeVisible, dialog3dVisible } = useFilePreview();
|
||||||
const { clearALlFinishedUploadFile } = useFileUpload();
|
const { clearALlFinishedUploadFile } = useFileUpload();
|
||||||
const { currentStorageKey } = useHeaderStorageList();
|
const { currentStorageKey } = useHeaderStorageList();
|
||||||
@ -51,6 +52,7 @@ const { openRow } = useFileData();
|
|||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getProject()
|
getProject()
|
||||||
|
getDictOne()
|
||||||
|
|
||||||
});
|
});
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
@ -63,6 +65,15 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
const trackFileType = ref([])
|
||||||
|
function getDictOne() {
|
||||||
|
getDict({ dictcode: 'Trajectory_File_Key' }).then((res: any) => {
|
||||||
|
trackFileType.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function iftrackFile(name: string): boolean {
|
||||||
|
return trackFileType.value.some((item: any) => name.includes(item.dictname));
|
||||||
|
}
|
||||||
//拖动条
|
//拖动条
|
||||||
const vMove = {
|
const vMove = {
|
||||||
mounted(el: any) {
|
mounted(el: any) {
|
||||||
@ -1769,6 +1780,10 @@ function getSSELink() {
|
|||||||
try {
|
try {
|
||||||
const data = JSON.parse(e.data)
|
const data = JSON.parse(e.data)
|
||||||
console.log('SSE消息:', data)
|
console.log('SSE消息:', data)
|
||||||
|
if(data.message == '配置文件选择错误,请重新选择!'){
|
||||||
|
ElMessage.warning(data.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
if (data) {
|
if (data) {
|
||||||
dynamicCoordinates.value.push([data.lon, data.lat])
|
dynamicCoordinates.value.push([data.lon, data.lat])
|
||||||
if (dynamicCoordinates.value.length > 2) {
|
if (dynamicCoordinates.value.length > 2) {
|
||||||
@ -1960,7 +1975,8 @@ const configradio: any = ref(null)
|
|||||||
style="cursor: pointer;"> -->
|
style="cursor: pointer;"> -->
|
||||||
<img src="@/assets/project/chong.png" alt="" title="重命名" @click="editfile(scope.row, false)"
|
<img src="@/assets/project/chong.png" alt="" title="重命名" @click="editfile(scope.row, false)"
|
||||||
style="cursor: pointer;">
|
style="cursor: pointer;">
|
||||||
<img v-if="scope.row.fileName.includes('ins_img') || scope.row.fileName == 'VINS.csv'"
|
|
||||||
|
<img v-if="iftrackFile(scope.row.fileName)"
|
||||||
src="@/assets/MenuIcon/guiji.png" alt="" @click="openMap(scope.row)" title="轨迹预览图"
|
src="@/assets/MenuIcon/guiji.png" alt="" @click="openMap(scope.row)" title="轨迹预览图"
|
||||||
style="cursor: pointer;">
|
style="cursor: pointer;">
|
||||||
<img src="@/assets/MenuIcon/lbcz_xg.png" alt="" @click="editfile(scope.row, true)"
|
<img src="@/assets/MenuIcon/lbcz_xg.png" alt="" @click="editfile(scope.row, true)"
|
||||||
@ -2281,7 +2297,7 @@ const configradio: any = ref(null)
|
|||||||
<el-button @click="">取消</el-button>
|
<el-button @click="">取消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 800px;height:600px;overflow: hidden;margin: auto;" v-else>
|
<div style="width: 800px;height:600px;margin: auto;" v-else>
|
||||||
<Imggui :imageUrl="pngobj.pngurl" :bounds="pngobj.textcontent" :trajectory="imgarrdata"
|
<Imggui :imageUrl="pngobj.pngurl" :bounds="pngobj.textcontent" :trajectory="imgarrdata"
|
||||||
:qvehuan="qvehuan" @qvehuan1="handleCustomEvent" />
|
:qvehuan="qvehuan" @qvehuan1="handleCustomEvent" />
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user