<template>
|
<div class="tools">
|
<!-- 工具栏标题 -->
|
<div class="tools-title" @click="toggleCollapse">
|
工具栏
|
<div class="popup-menu" v-if="isPopupVisible">
|
<div
|
class="popup-item"
|
v-for="(option, idx) in currentToolOptions"
|
:key="idx"
|
@click="handleOptionClick(option)"
|
>
|
<img
|
class="popup-icon"
|
:src="
|
require(`../../assets/img/tools/tools_second/${option.icon}.png`)
|
"
|
:alt="option.name"
|
/>
|
{{ option.name }}
|
</div>
|
</div>
|
<LayerTree class="popup-menu" v-show="showLayerTree" />
|
<!-- 可视域分析 -->
|
<seeAnalyze
|
:option="option"
|
v-show="seeAnalyzeShow"
|
@update:showConeLine="handleUpdateShowConeLine"
|
@update-option="onUpdateOption"
|
@draw="onDraw"
|
@clear="onClear"
|
class="popup-menu-see"
|
/>
|
<!-- 剖面提取 -->
|
<TopographyDia
|
@draw="handleDraw"
|
@clear="handleClear"
|
class="popup-menu-see"
|
v-show="topographyShow"
|
/>
|
<!-- 剖面提取的echarts -->
|
<div v-show="echartsShow" id="sectionCharts" class="sectionChars">
|
<div id="echartsView1" style="width: 100%; height: 100%"></div>
|
</div>
|
<!-- 坡向分析 -->
|
<Aspect
|
v-show="showAspect"
|
@draw="SlopeArrow"
|
@clear="SlopeArrowClose"
|
class="popup-menu-see"
|
/>
|
<SlopeAnalysis
|
@draw="SlopeAnalysiss"
|
v-show="showSlope"
|
class="popup-menu-see"
|
@update-slope="onUpdateSlope"
|
/>
|
<!-- 雨 -->
|
<Rain
|
v-show="showRain"
|
class="popup-menu-see"
|
@update-rain="onUpdateRain"
|
/>
|
<Snow
|
v-show="showSnow"
|
class="popup-menu-see"
|
@update-snow="onUpdateSnow"
|
/>
|
</div>
|
|
<!-- 工具栏内容 -->
|
<transition name="fade">
|
<div v-if="!isCollapsed" class="tools-content">
|
<div
|
class="tools-item"
|
v-for="(item, index) in toolList"
|
:key="index"
|
@click.stop="handleClick(item)"
|
>
|
<img
|
class="icon"
|
:src="require(`../../assets/img/tools/${item.icon}.png`)"
|
:title="item.name"
|
alt=""
|
/>
|
</div>
|
</div>
|
</transition>
|
</div>
|
</template>
|
|
<script setup>
|
import { reactive, ref } from "vue";
|
import LayerTree from "@/components/tools/LayerTree.vue";
|
import seeAnalyze from "@/components/tools/seeAnalyze.vue";
|
import TopographyDia from "@/components/tools/TopographyDia.vue";
|
import Aspect from "@/components/tools/Aspect.vue";
|
import SlopeAnalysis from "@/components/tools/SlopeAnalysis.vue";
|
import mapUtils from "@/utils/tools.js";
|
import Rain from "@/components/tools/Rain.vue";
|
import Snow from "@/components/tools/Snow.vue";
|
|
// 切换展开/收缩状态
|
function toggleCollapse() {
|
// isCollapsed.value = !isCollapsed.value;
|
}
|
|
const showLayerTree = ref(false);
|
|
const isPopupVisible = ref(false); // 控制弹窗是否可见
|
const currentToolOptions = ref([]); // 当前工具的功能选项
|
const isCollapsed = ref(false); // 是否已收缩,默认展开
|
const isPickActive = ref(false);
|
const isflfx = ref(false);
|
const isFlood = ref(false);
|
const isContourLabel = ref(false);
|
const showRain = ref(false);
|
const showSnow = ref(false);
|
|
// 剖面分析弹窗
|
const topographyShow = ref(false);
|
// 剖面分析echarts
|
const echartsShow = ref(false);
|
|
// 可视域弹窗
|
const seeAnalyzeShow = ref(false);
|
|
// 坡向箭头弹窗
|
const showAspect = ref(false);
|
|
// 坡度分析弹窗
|
const showSlope = ref(false);
|
|
// 工具列表
|
const toolList = ref([
|
{
|
name: "图层管理",
|
icon: "图层管理",
|
active: false,
|
options: [
|
{ name: "显示图层", icon: "图层" },
|
{ name: "隐藏图层", icon: "图层" },
|
{ name: "重置图层", icon: "图层" },
|
],
|
},
|
{
|
name: "测量",
|
icon: "测量",
|
active: false,
|
options: [
|
{ name: "坐标测量", icon: "坐标测量" },
|
{ name: "水平测量", icon: "水平测量" },
|
{ name: "直线测量", icon: "直线测量" },
|
{ name: "垂直测量", icon: "垂直测量" },
|
{ name: "面积测量", icon: "面积测量" },
|
{ name: "清除测量", icon: "清除分析" },
|
],
|
},
|
{
|
name: "分析",
|
icon: "分析",
|
active: false,
|
options: [
|
{ name: "点位信息提取", icon: "点位信息提取" },
|
{ name: "坡度分析", icon: "坡度坡向提取" },
|
{ name: "坡向分析", icon: "坡度坡向提取" },
|
{ name: "剖面提取", icon: "剖面提取" },
|
{ name: "挖填方计算", icon: "挖填方计算" },
|
{ name: "等高线分析", icon: "等高线分析" },
|
{ name: "水淹分析", icon: "水淹分析" },
|
{ name: "可视域分析", icon: "可视域分析" },
|
],
|
},
|
{
|
name: "标绘",
|
icon: "标绘",
|
active: false,
|
options: [
|
{ name: "文字标绘", icon: "文字标绘" },
|
{ name: "多段线标绘", icon: "多段线标绘" },
|
{ name: "多边形标绘", icon: "多边形标绘" },
|
{ name: "图形标绘", icon: "圆形标绘" },
|
{ name: "图片标绘", icon: "图片标绘" },
|
{ name: "模型导入", icon: "模型导入" },
|
{ name: "路径绘制", icon: "路径绘制" },
|
{ name: "清除标绘", icon: "清除分析" },
|
],
|
},
|
|
{
|
name: "天气",
|
icon: "天气",
|
active: false,
|
options: [
|
{ name: "雨天模式", icon: "雨天模式" },
|
{ name: "雪天模式", icon: "雪天模式" },
|
{ name: "清除天气", icon: "清除分析" },
|
],
|
},
|
]);
|
|
// 处理工具点击事件
|
function handleClick(tool, event) {
|
console.log(tool.options);
|
|
// 更新所有工具的 active 状态
|
toolList.value.forEach((item) => {
|
item.active = item.name === tool.name && currentToolOptions.value !== tool.options;
|
});
|
|
// 如果当前工具已经是激活状态,则关闭它
|
if (currentToolOptions.value === tool.options) {
|
currentToolOptions.value = null; // 清空当前工具选项
|
isPopupVisible.value = false; // 隐藏弹窗
|
seeAnalyzeShow.value = false; // 可视域
|
topographyShow.value = false; // 剖面
|
echartsShow.value = false; // 剖面echarts
|
showAspect.value = false; // 坡向箭头
|
showSlope.value = false; // 坡度箭头
|
showRain.value = false; // 雨天
|
showSnow.value = false; // 雪天
|
return;
|
}
|
|
// 如果工具名称是 "图层管理"
|
if (tool.name === "图层管理") {
|
showLayerTree.value = !showLayerTree.value; // 切换图层树的显示状态
|
isPopupVisible.value = false; // 隐藏弹窗
|
seeAnalyzeShow.value = false; // 可视域
|
topographyShow.value = false; // 剖面
|
echartsShow.value = false; // 剖面echarts
|
showAspect.value = false; // 坡向箭头
|
showSlope.value = false; // 坡度箭头
|
showRain.value = false; // 雨天
|
showSnow.value = false; // 雪天
|
return;
|
}
|
|
// 对于其他工具
|
isPopupVisible.value = true; // 显示弹窗
|
currentToolOptions.value = tool.options; // 设置当前工具的功能选项
|
seeAnalyzeShow.value = false; // 可视域
|
topographyShow.value = false; // 剖面
|
echartsShow.value = false; // 剖面echarts
|
showAspect.value = false; // 坡向箭头
|
showSlope.value = false; // 坡度箭头
|
showRain.value = false; // 雨天
|
showSnow.value = false; // 雪天
|
}
|
|
// 处理弹窗选项点击事件
|
function handleOptionClick(option) {
|
isPopupVisible.value = false;
|
console.log("Selected option:", option);
|
const actionMap = {
|
显示图层: () => (showLayerTree.value = true),
|
隐藏图层: () => (showLayerTree.value = false),
|
雨天模式: () => {
|
showRain.value = true;
|
onUpdateRain();
|
},
|
雪天模式: () => {
|
showSnow.value = true;
|
onUpdateSnow();
|
},
|
清除天气: () => {
|
if (1) {
|
showRain.value = false;
|
showSnow.value = false;
|
mapUtils.delRain(); // 关闭雨效果
|
mapUtils.delSnow(); // 关闭雪效果
|
console.log("天气效果已清除");
|
} else {
|
console.log("没有打开的天气效果");
|
}
|
},
|
|
文字标绘: () => mapUtils.CreateLabel("label", true),
|
多段线标绘: () => mapUtils.CreateLabel("polyline", true),
|
多边形标绘: () => mapUtils.CreateLabel("polygon", true),
|
图形标绘: () => mapUtils.CreateLabel("circle", true),
|
图片标绘: () => mapUtils.CreateLabel("billboard", true),
|
路径绘制: () => mapUtils.CreateLabel("polyline", true),
|
清除标绘: () => mapUtils.del(),
|
坐标测量: () => {
|
isPickActive.value = !isPickActive.value;
|
mapUtils.pick(isPickActive.value);
|
},
|
水平测量: () => mapUtils.spjl(),
|
直线测量: () => mapUtils.jl(),
|
垂直测量: () => mapUtils.czgd(),
|
面积测量: () => mapUtils.mjcl(),
|
清除测量: () => mapUtils.clear(),
|
可视域分析: () => {
|
seeAnalyzeShow.value = true;
|
},
|
剖面提取: () => {
|
topographyShow.value = true;
|
},
|
坡度分析: () => {
|
showSlope.value = true;
|
},
|
坡向分析: () => {
|
showAspect.value = true;
|
},
|
点位信息提取: () => {
|
isPickActive.value = !isPickActive.value;
|
mapUtils.pick(isPickActive.value);
|
},
|
挖填方计算: () => {
|
isflfx.value = !isflfx.value;
|
if (isflfx.value === false) {
|
mapUtils.toolClear();
|
} else {
|
mapUtils.flfx();
|
}
|
},
|
水淹分析: () => {
|
isFlood.value = !isFlood.value;
|
if (isFlood.value === false) {
|
mapUtils.FloodAnalysis("close");
|
} else {
|
mapUtils.FloodAnalysis();
|
}
|
},
|
等高线分析: () => {
|
isContourLabel.value = !isContourLabel.value;
|
if (isContourLabel.value === false) {
|
mapUtils.createContourLabel();
|
} else {
|
mapUtils.closeContourLabel();
|
}
|
},
|
};
|
if (actionMap[option.name]) {
|
actionMap[option.name]();
|
}
|
}
|
|
// 定义可视域参数的值
|
const option = reactive({
|
heading: 0,
|
verticalAngle: 60,
|
horizontalViewAngle: 90,
|
distance: 300,
|
});
|
|
// 显示视锥线
|
const showConeLine = ref(null);
|
|
// 监听 option 的更新并实时更新可视域的范围
|
const onUpdateOption = (newOption) => {
|
Object.assign(option, newOption); // 更新 option 对象
|
mapUtils.changeSyfx(option);
|
};
|
|
// 处理子组件传来的可视域显示锥线的值
|
function handleUpdateShowConeLine(value) {
|
showConeLine.value = value;
|
mapUtils.showSyfxViewCone(showConeLine.value);
|
}
|
|
// 鼠标绘制可视域
|
function onDraw() {
|
// 定义回调函数,用于接收 res 并更新 option
|
const callback = (res) => {
|
option.heading = res.heading;
|
option.distance = res.distance;
|
};
|
// 调用 syfxByClick 方法,并传入回调函数
|
mapUtils.syfxByClick(option, callback);
|
}
|
|
// 清除可视域
|
function onClear() {
|
mapUtils.syfxqc(option);
|
}
|
|
// 剖面提取
|
const handleDraw = (formData) => {
|
const sampleInterval = formData.sampleInterval;
|
const distance = parseFloat(sampleInterval); // 确保是数字
|
if (isNaN(distance)) {
|
ElMessage.error("请输入有效的采样间距");
|
return;
|
}
|
mapUtils.pmtq(distance);
|
echartsShow.value = true;
|
};
|
|
//剖面清除
|
const handleClear = () => {
|
mapUtils.handleClear();
|
};
|
|
//坡度的箭头角度(角度为0~1,范围内的均匀插值)
|
const angles = [
|
0.0, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7,
|
0.75, 0.8, 0.85, 1.0,
|
];
|
|
//坡度使用的颜色(颜色为hex格式)
|
const colors = [
|
"#0F3C72",
|
"#1F65A1",
|
"#2F9655",
|
"#3C8EB9",
|
"#345C35",
|
"#4AC9B4",
|
"#5C7B25",
|
"#6FBE3D",
|
"#8C6AC3",
|
"#823B3E",
|
"#961862",
|
"#C436BE",
|
"#CAB84F",
|
"#D82B2A",
|
"#DB7FB1",
|
"#E8B7D9",
|
"#F0AD56",
|
"#F2CC45",
|
];
|
|
const SlopeArrow = () => {
|
mapUtils.pxjt(colors, angles);
|
};
|
// 关闭坡向箭头
|
const SlopeArrowClose = () => {
|
mapUtils.cleanupAnalysisTools();
|
};
|
|
// 坡度分析
|
const formData = reactive({
|
terrainRender: 0,
|
contourLines: false,
|
color: "red",
|
spacing: 50,
|
lineWidth: 5,
|
});
|
|
const SlopeAnalysiss = () => {
|
mapUtils.pdfx(formData);
|
};
|
|
|
// 坡度
|
const onUpdateSlope = (newOption) => {
|
Object.assign(formData, newOption);
|
mapUtils.pdfx(formData);
|
};
|
|
// 雨
|
const rainForm = reactive({
|
rainSize: 0.5,
|
rainSpeed: 50,
|
rainColor: "#99B3CC",
|
});
|
const onUpdateRain = (newOption) => {
|
console.log(newOption, "new");
|
Object.assign(rainForm, newOption);
|
mapUtils.toggleRain(rainForm, true);
|
};
|
// 雪
|
const snowForm = reactive({
|
snowSize: 0.02, // 默认雪的大小
|
snowSpeed: 100, // 默认雪的速度
|
snowColor: "#FFFFFF", // 默认雪的颜色
|
});
|
|
const onUpdateSnow = (newOption) => {
|
console.log(newOption, "new");
|
Object.assign(snowForm, newOption);
|
mapUtils.toggleSnow(snowForm, true);
|
};
|
</script>
|
|
<style lang="less" scoped>
|
.tools {
|
background: url("@/assets/img/tools/plottingbg.png") no-repeat;
|
background-size: 100% 100%;
|
width: 60px;
|
padding-top: 20px;
|
z-index: 99;
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
align-items: center;
|
text-align: center;
|
}
|
|
.tools-title {
|
position: relative;
|
/* 确保子元素的绝对定位相对于 tools-title */
|
height: 30px;
|
line-height: 30px;
|
font-weight: 700;
|
font-size: 14px;
|
color: #9dc3cc;
|
cursor: pointer;
|
|
user-select: none;
|
/* 禁止选中文本 */
|
}
|
|
.tools-content {
|
margin-top: 5px;
|
}
|
|
.tools-item {
|
margin: 5px 8px;
|
cursor: pointer;
|
|
.icon {
|
width: 30px;
|
height: 30px;
|
}
|
}
|
|
.popup-menu {
|
position: absolute;
|
top: -20px;
|
right: 100%;
|
transform: translateX(-20px);
|
background: url("@/assets/img/tools/plotting_new.png") no-repeat;
|
filter: opacity(60%);
|
background-size: 100% 100%;
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
border-radius: 5px;
|
padding: 10px;
|
z-index: 100;
|
color: #f0f0f0;
|
white-space: nowrap;
|
}
|
|
.popup-item {
|
display: flex;
|
align-items: center;
|
padding: 5px 10px;
|
cursor: pointer;
|
transition: background-color 0.3s ease;
|
|
.popup-icon {
|
width: 20px;
|
height: 20px;
|
margin-right: 8px;
|
}
|
}
|
|
/* 动画效果 */
|
.fade-enter-active,
|
.fade-leave-active {
|
transition: opacity 0.3s ease, transform 0.3s ease;
|
}
|
|
.fade-enter-from,
|
.fade-leave-to {
|
opacity: 0;
|
transform: scaleY(0);
|
transform-origin: top;
|
}
|
|
.popup-menu-see {
|
position: absolute;
|
right: 60px;
|
top: -20px;
|
}
|
|
.sectionChars {
|
position: absolute;
|
top: auto;
|
width: 600px;
|
height: 200px;
|
bottom: -527px;
|
left: -575px;
|
padding: 10px 15px;
|
border-radius: 4px;
|
border: 1px solid rgba(128, 128, 128, 0.5);
|
color: #fff;
|
background: rgba(0, 0, 0, 0.4);
|
box-shadow: 0 3px 14px rgba(128, 128, 128, 0.5);
|
z-index: 9999;
|
// display: none;
|
}
|
</style>
|