ylj20011123 08b0e8cb95 update
2025-08-18 10:55:06 +08:00

405 lines
11 KiB
Vue

<script setup lang="ts">
import { onMounted, reactive, ref, watch } from 'vue';
import './PageMap.less'
import { GaodeMap, LineLayer, PointLayer, Scene } from '@antv/l7';
import { handleGetServerpartList, handleGetServerPartListJava } from '../../service';
// @ts-ignore
import yunNanData from '../../../../options/anhuiLine.js'
// @ts-ignore
import YNHighWayLine from '../../../../options/YNHighWayLine.js'
// 地图实例
const scene = ref<any>();
// 配色方案一
let colorList1 = [
"#4F83FA",
"#A39BFF",
"#63B6FC",
"#88DFB2",
"#88C3BF",
"#d9dcf3",
];
// 所有服务区的数据
let defaultServerPartList = reactive<any>([]);
// 全部服务区的id集合
let allServerPartIdList = reactive<any>([]);
// 不同片区的标点颜色数组
let SPREGIONTYPECOLORList = reactive<any>([]);
// 片区对应的颜色
let SPREGIONTYPECOLOR = ref<any>();
// 悬浮框实例
const hoverPoint = ref<any>();
// 当前的服务区
let currentService = ref<any>()
const props = defineProps<{
selectPointServicePart?: any
mapClickComeForm?: string
noticeMessageObj?: any
}>();
watch(
() => props.selectPointServicePart,
(newVal, oldVal) => {
if (newVal && newVal.length > 0) {
// 获取播报数据
handleHighLightServerpartIds(newVal)
}
},
{ deep: true }
);
onMounted(async () => {
scene.value = new Scene({
id: "map",
map: new GaodeMap({
pitch: 0,
mapStyle: "amap://styles/dark",
// center: [101.6329, 26.38],
center: [109.988078, 26.353654],
zoom: 5,
minZoom: 7,
token: "edb93fe4f1b3d313128b82082c5b3877",
mapConfig: {
logoVisible: false,
},
}),
});
// 请求全部服务区数据
await handleGetServiceList()
// 给地图加上点位
handleAllServiceMarkedPoint()
// 画出省份边界图
handleGetAnHuiBoundary()
// 画出高速公路的线段
handleGetExpressway()
hoverPoint.value = handlePointHover();
})
// 画出高速公路的线段
const handleGetExpressway = async () => {
const higeWayLin = new LineLayer();
higeWayLin.name = "higeWayLin";
// 边界线数据
let list: any = YNHighWayLine
higeWayLin.source(list).size(1).style({
opacity: 1,
sourceColor: "#ebaf60",
targetColor: "#ebaf60",
linearDir: "horizontal",
});
scene.value.addLayer(higeWayLin);
}
// 拿到服务区数据
const handleGetServiceList = async () => {
const req: any = {
Province_Code: "530000",
ShowWeather: true, // 显示天气
};
const data = await handleGetServerPartListJava(req)
let str: string = "";
if (data && data.length > 0) {
let res: any = [];
let allId: any = [];
let SPREGIONTYPETYPELIST: any = {};
// 属性值为具体的颜色
let SPREGIONTYPETYPEObj: any = {};
// 片区名称对应的 颜色数组 用于放在中间底部的
let SPREGIONTYPECOLORLIST: any = [];
let typeID: number = 0;
data.forEach((item: any) => {
if (item.SPREGIONTYPE_ID) {
if (
SPREGIONTYPETYPELIST[item.SPREGIONTYPE_ID] ||
SPREGIONTYPETYPELIST[item.SPREGIONTYPE_ID] === 0
) {
item.SPREGIONTYPETYPE = SPREGIONTYPETYPELIST[item.SPREGIONTYPE_ID];
} else {
SPREGIONTYPETYPELIST[item.SPREGIONTYPE_ID] = typeID;
item.SPREGIONTYPETYPE = typeID;
SPREGIONTYPETYPEObj[item.SPREGIONTYPE_ID] = colorList1[typeID];
SPREGIONTYPECOLORLIST.push({
label: item.SPREGIONTYPE_NAME,
value: colorList1[typeID],
});
typeID += 1;
}
if (item.SPREGIONTYPE_ID !== 89 && item.SPREGIONTYPE_ID) {
res.push(item);
allId.push(item.SERVERPART_ID.toString());
}
}
if (str) {
str += `${item.SERVERPART_NAME} ${item.SERVERPART_ID}`;
} else {
str = `${item.SERVERPART_NAME} ${item.SERVERPART_ID}`;
}
});
defaultServerPartList = res;
allServerPartIdList = allId;
SPREGIONTYPECOLORList = SPREGIONTYPECOLORLIST;
SPREGIONTYPECOLOR.value = SPREGIONTYPETYPEObj;
emit("handleGetMapLegend", SPREGIONTYPECOLORLIST)
}
}
// 给所有的服务区标点
const handleAllServiceMarkedPoint = async () => {
// 先判断有没有服务区 没有就去请求 有就直接拿
let list: any = [];
if (defaultServerPartList && defaultServerPartList.length > 0) {
list = defaultServerPartList;
}
// 标点
const pointLayer = new PointLayer({});
pointLayer.name = "pointLayer";
pointLayer.source(list, {
parser: {
type: "json",
x: "SERVERPART_X",
y: "SERVERPART_Y",
},
});
pointLayer.shape("circle");
pointLayer.size(8);
pointLayer.color("SPREGIONTYPETYPE", (value) => {
return colorList1[value];
});
pointLayer.style({
opacity: 0.6,
});
pointLayer.on("mousemove", (ev: any) => {
console.log('props?.noticeMessageObj', props?.noticeMessageObj);
const detail: any = ev.feature;
console.log('detail.SERVERPART_ID', detail.SERVERPART_ID);
hoverPoint.value.style.maxWidth = `500px`;
hoverPoint.value.style.top = `${ev.y + 5}px`;
hoverPoint.value.style.left = `${ev.x + 5}px`;
hoverPoint.value.style.transform = `translate(-100%,-100%)`;
hoverPoint.value.style.display = "block";
hoverPoint.value.innerHTML = `<div>
${props?.mapClickComeForm === 'notice' ? `<div>招商信息:</div><div>${props?.noticeMessageObj && props?.noticeMessageObj[Number(detail.SERVERPART_ID)] ? props?.noticeMessageObj[Number(detail.SERVERPART_ID)] : ""}</div>` : `<div>${detail?.SERVERPART_NAME || ""}</div>`}
</div>`
})
// 鼠标移出
pointLayer.on("mouseout", (ev: any) => {
hoverPoint.value.style.display = "none";
});
// 点击事件
pointLayer.on("click", (e) => {
handleClickPointLayer(e.feature)
});
// 鼠标取消点击
pointLayer.on("unclick", () => {
handleLayerToDefault();
emit("handleChangeComeForm", "")
});
scene.value.addLayer(pointLayer);
}
// 标出云南省的边界
const handleGetAnHuiBoundary = () => {
const blurLine = new LineLayer();
blurLine.name = "blurLine";
// 边界线数据
let provinceObj: any = yunNanData;
let list: any = provinceObj["530000"];
blurLine.source(list).size(1).style({
opacity: 0.6,
sourceColor: "#b6cad7",
targetColor: "#b6cad7",
linearDir: "horizontal",
});
scene.value.addLayer(blurLine);
};
// 鼠标移入点触发的事件
const handlePointHover = () => {
const el = document.createElement("div");
el.style.background = "#000";
el.style.color = "#fff";
el.style.position = "absolute";
el.style.padding = "10px";
el.style.borderRadius = "10px";
el.style.zIndex = "9999";
el.style.transition = "0.5s";
el.style.display = "none";
const wrap: any = document.getElementById("map");
wrap.appendChild(el);
return el;
};
// 点击服务区圆点触发的事件
const handleHighLightServerpartIds = (idList: number[]) => {
handleDeleteLayer("lightPointLayer");
handleAllPonitToGray()
console.log('idList', idList);
let selectServerpartDetailList: any = []
if (defaultServerPartList && defaultServerPartList.length > 0) {
defaultServerPartList.forEach((item: any) => {
if (idList.indexOf(item.SERVERPART_ID) !== -1) {
selectServerpartDetailList.push(item)
}
})
}
handleAddSelect(selectServerpartDetailList)
}
// 全部服务区点位变为灰色的点
const handleAllPonitToGray = () => {
let current: any = handleGetThisLayer("pointLayer");
current.color("#dededd");
current.render();
}
// 查找当前全部图层中是否有传入的图层名称 有的话 输出图层数据
const handleGetThisLayer = (name: string) => {
let res: any;
let allLayers: any = scene.value.getLayers();
if (allLayers && allLayers.length > 0) {
allLayers.forEach((item: any) => {
if (item.name === name) {
res = item;
}
});
}
if (res) {
return res;
}
};
// 点击服务区圆点触发的事件
const handleClickPointLayer = async (detail: any) => {
if (detail.SERVERPART_ID === currentService.value?.SERVERPART_ID) {
} else {
if (props.mapClickComeForm !== 'notice') {
handleDeleteLayer("lightPointLayer");
handleAddSelect(detail)
}
}
}
// 服务区的选中效果
const handleAddSelect = (detail: any) => {
if (Array.isArray(detail)) {
} else {
currentService.value = detail
emit("handleGetCurrentService", detail)
}
const lightPointLayer = new PointLayer({});
lightPointLayer.name = "lightPointLayer";
lightPointLayer.shape("circle");
lightPointLayer.size(12);
lightPointLayer.color("#efff19");
lightPointLayer.style({
opacity: 0.6,
});
lightPointLayer.source(Array.isArray(detail) ? detail : [detail], {
parser: {
type: "json",
x: "SERVERPART_X",
y: "SERVERPART_Y",
},
});
scene.value.addLayer(lightPointLayer);
let allLayers: any = scene.value.getLayers();
}
// 传入名字清除图层
const handleDeleteLayer = (name: string) => {
let allLayers: any = scene.value.getLayers();
if (allLayers && allLayers.length > 0) {
// 找到要删除的图层
const layerToRemove = allLayers.find((layer: any) => layer.name === name);
if (layerToRemove) {
// 使用 scene 的 removeLayer 方法删除图层
scene.value.removeLayer(layerToRemove);
// 确保更新渲染
scene.value.render();
}
}
};
// 图层变回原先
const handleLayerToDefault = () => {
emit("handleGetCurrentService", null)
emit("handleMapToChangeNotice")
handleDeleteLayer("lightPointLayer");
let allLayers: any = scene.value.getLayers();
let current: any = handleGetThisLayer("pointLayer");
if (current) {
// 重置颜色映射
current.color("SPREGIONTYPETYPE", (value: any) => {
return colorList1[value];
});
// 更新样式并立即重绘
current.style({
opacity: 0.6,
});
// 强制更新
current.render();
// 确保场景也更新
scene.value.render();
}
}
const emit = defineEmits<{
(e: "handleGetCurrentService", obj: any): void;
(e: "handleMapToChangeNotice"): void;
(e: "handleGetMapLegend", list: any): void;
(e: "handleChangeComeForm", str: string): void;
}>();
</script>
<template>
<div class="PageMapBox" style="position: relative;">
<div class="mapContent" id="map">
</div>
</div>
</template>