405 lines
11 KiB
Vue
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>
|