aiMap/src/components/map/index.vue
2024-11-27 18:50:09 +08:00

1343 lines
40 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import "./index.less";
// @ts-ignore
import anhuiLine from "./component/anhuiLine";
import { HeatmapLayer, LineLayer, Marker, PointLayer, Scene } from "@antv/l7";
import { GaodeMap } from "@antv/l7-maps";
import { onMounted, reactive, ref } from "vue";
import {
getFieldEnumTree,
getFieldGetFieEnumList,
handleGetBaiDuTrafficInfo,
handleGetMonthlySPINCAnalysis,
handleGetPeriodWarningList,
handleGetProvinceVehicleTreeList,
handleGetServerpartList,
} from "./service";
import { ElLoading, ElMessage } from "element-plus";
// @ts-ignore
import RobotDialogueBox from "./component/RobotDialogueBox.vue";
// @ts-ignore
import RightSearchBox from "./component/RightSearchBox.vue";
// @ts-ignore
import detailText from "./component/detailText";
import { nextTick } from "process";
import moment from "moment";
import { log } from "console";
import {
formatNumber,
parseThousandSeparatedNumber,
} from "../../options/serveice";
// 地图实例
const scene = ref<any>();
// 对话框的实例
const RobotDialogueBoxRef = ref();
// 右侧的选择实例
const RightSearchBoxRef = ref();
// 悬浮框实例
const hoverPoint = ref<any>();
// 所有服务区的数据
let defaultServerPartList = reactive<any>([]);
// 服务区类型的枚举
let ServerpartTypeObj = reactive<any>({});
// 判断是否有加载效果
const isShowLoading = ref<boolean>(false);
// 当前选中的服务区
const currentServerPartDetail = ref<any>();
// 搜索选中的服务区id
let searchSelectServerPartId = reactive<any>([]);
// 当前右侧选中的查询类型
let nowSelectId = ref<string>("");
// 全部服务区的id集合
let allServerPartIdList = reactive<any>([]);
onMounted(async () => {
scene.value = new Scene({
id: "map",
map: new GaodeMap({
pitch: 0,
mapStyle: "amap://styles/dark",
center: [117.455467, 31.856928],
zoom: 6,
minZoom: 5.5,
token: "edb93fe4f1b3d313128b82082c5b3877",
mapConfig: {
logoVisible: false,
},
}),
});
const loadingInstance = ElLoading.service({
fullscreen: true,
background: "#00000080",
text: "数据加载中...",
});
// 请求枚举
await handleGetEnumeration();
console.log("ServerpartTypeObj", ServerpartTypeObj);
// 请求到所有的服务区
await handleGetAllService();
// 给服务区标上点
handleAllServiceMarkedPoint();
// 标出安徽省的边界
handleGetAnHuiBoundary();
hoverPoint.value = handlePointHover();
loadingInstance.close();
});
// 标出安徽省的边界
const handleGetAnHuiBoundary = () => {
const blurLine = new LineLayer();
blurLine.name = "blurLine";
let list: any = anhuiLine;
blurLine.source(list).size(1).style({
opacity: 0.6,
sourceColor: "#b6cad7",
targetColor: "#b6cad7",
linearDir: "horizontal",
});
scene.value.addLayer(blurLine);
};
// 请求拿到所有服务区数据
const handleGetAllService = async () => {
const req: any = {
Province_Code: "340000",
ShowWeather: true, // 显示天气
};
const data = await handleGetServerpartList(req);
console.log("data", data);
if (data && data.length > 0) {
let res: any = [];
let allId: any = [];
data.forEach((item: any) => {
if (item.SPREGIONTYPE_ID !== 89 && item.SPREGIONTYPE_ID) {
res.push(item);
allId.push(item.SERVERPART_ID.toString());
}
});
defaultServerPartList = res;
allServerPartIdList = allId;
}
return data;
};
// 给所有服务区标上圆点
const handleAllServiceMarkedPoint = async () => {
// 先判断有没有服务区 没有就去请求 有就直接拿
let list: any = [];
if (defaultServerPartList && defaultServerPartList.length > 0) {
list = defaultServerPartList;
} else {
list = await handleGetAllService();
}
// 标点
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("SPREGIONTYPE_ID", (value) => {
return Number(value || 0) === 65 ||
Number(value || 0) === 45 ||
Number(value || 0) === 47
? "#34B6B7"
: "#CEF8D6";
});
pointLayer.style({
opacity: 0.6,
});
pointLayer.on("mousemove", (ev: any) => {
const detail: any = ev.feature;
hoverPoint.value.style.top = `${ev.y}px`;
hoverPoint.value.style.left = `${ev.x}px`;
hoverPoint.value.style.display = "block";
hoverPoint.value.innerHTML = `<div>
<div>${detail?.SERVERPART_NAME || ""}${
detail?.SERVERPART_TYPE
? `${
ServerpartTypeObj ? ServerpartTypeObj[detail?.SERVERPART_TYPE] : ""
}`
: ""
}</div>
${
// 天气
nowSelectId.value && nowSelectId.value.indexOf("1") !== -1
? `
<div style="background-color: black; color: white; border-radius: 5px; font-size: 14px; border: none;box-shadow: none;">
<div>天气情况:</div>
<div>${"今天"}${detail.weatherModel.DAY_WEATHER}${
detail.weatherModel.NIGHT_WEATHER
},气温${detail.weatherModel.NIGHT_AIR_TEMPERATURE}℃~${
detail.weatherModel.DAY_AIR_TEMPERATURE
}℃</div>
<div>${"明天"}${detail.tmwWeatherModel.DAY_WEATHER}${
detail.tmwWeatherModel.NIGHT_WEATHER
},气温${detail.tmwWeatherModel.NIGHT_AIR_TEMPERATURE}℃~${
detail.tmwWeatherModel.DAY_AIR_TEMPERATURE
}℃</div>
</div>
`
: ``
}
${
// 路况
(nowSelectId.value && nowSelectId.value.indexOf("2") !== -1) ||
detail.roadConditions
? `
<div style="max-height: 250px;overflow-y: auto">
<div>实时路况(${moment().format("YY月DD日 HH点mm分")}</div>
<div>${
detail?.roadConditions?.EXPRESSWAY_NAME
? detail?.roadConditions?.EXPRESSWAY_NAME + ""
: ""
}${detail?.roadConditions?.evaluation.status_desc || ""}</div>
</div>
`
: ""
}
${
// 热力图
nowSelectId.value && nowSelectId.value.indexOf("3") !== -1
? `<div>${moment().format("YYYY年MM月")}对客销售累计:${formatNumber(
detail?.revenueData / 10000
)}万元</div>`
: ""
}
${
// 车辆归属地
nowSelectId.value &&
nowSelectId.value.indexOf("4") !== -1 &&
detail.provinceListTooltip &&
detail.provinceListTooltip.length > 0
? `<div>
${detail.provinceListTooltip
.map(
(item: any) =>
`<div>${moment(moment().startOf("y")).format(
"YYYY年MM月"
)}${moment().format("YYYY年MM月")}${
detail?.SERVERPART_NAME || ""
}总入区车流:${formatNumber(item.TotalCount || 0)}
${
item.children?.length > 0
? `<div>${item.children
.map(
(subItem: any) =>
`<div>${
subItem.ProvinceOrCityName
}:占比:${formatNumber(
(subItem.TotalCount / item.TotalCount) * 100
)}% Top3
${
subItem.children && subItem.children.length > 0
? `<span>
${subItem.children
.map((thirdItem: any, thirdIndex: number) => {
return thirdItem.ProvinceOrCityName !== "其他"
? `${thirdItem.ProvinceOrCityName}`
: "";
})
.join("")}
</span>`
: ""
}</div>`
)
.join("")}
</div>`
: ""
}
</div>`
)
.join("")}
</div>`
: ""
}
${
// 经营业态
nowSelectId.value && nowSelectId.value.indexOf("5") !== -1
? `<div>
${detail?.tradeType || ""}${
detail?.shopName ? `${detail?.shopName}` : ""
}
</div>`
: ""
}
${
// 预警类型
nowSelectId.value && nowSelectId.value.indexOf("6") !== -1
? `<div>
${detail?.waringText || ""}
</div>`
: ""
}
</div>`;
});
// 鼠标移出
pointLayer.on("mouseout", (ev: any) => {
hoverPoint.value.style.display = "none";
});
// 点击事件
pointLayer.on("click", (e) => {
console.log("e", e);
handleClickPointLayer(e.feature);
});
// 鼠标取消点击
pointLayer.on("unclick", () => {
handleChangeToDefault();
});
scene.value.addLayer(pointLayer);
};
// 点击服务区圆点触发的时间
const handleClickPointLayer = async (detail: any) => {
// 给当前选中的服务区存储值
currentServerPartDetail.value = detail;
// 地图上出现选中服务区的效果
handleAddSelect(detail);
// 先清空现有的全部图层
handleDeleteNoDefault("");
// 查看右边选中了哪些 调用在新的上面
let nowSelect: string = RightSearchBoxRef.value.selectFilterList;
await handleChangeMapShow(nowSelect);
};
// 给服务区圆点加上选中效果
const handleAddSelect = (detail: any) => {
let current: any = handleGetThisLayer("lightPointLayer");
if (current) {
scene.value.removeLayer(current);
}
const lightPointLayer = new PointLayer({});
lightPointLayer.name = "lightPointLayer";
lightPointLayer.shape("circle");
lightPointLayer.size(15);
lightPointLayer.color("#efff19");
lightPointLayer.style({
opacity: 0.6,
});
lightPointLayer.source([detail], {
parser: {
type: "json",
x: "SERVERPART_X",
y: "SERVERPART_Y",
},
});
scene.value.addLayer(lightPointLayer);
};
// 取消服务区选中等效果的实现方法
const handleChangeToDefault = () => {
// 清除当前选中的服务区值
currentServerPartDetail.value = undefined;
// 取消搜索选中的服务区
searchSelectServerPartId = [];
// 取消点击时要清除的图层名称列表
const list: any = ["lightPointLayer", "searchPointLayerText"];
list.forEach((item: any) => {
let current: any = handleGetThisLayer(item);
if (current) {
scene.value.removeLayer(current);
}
});
// 将进入搜索状态的服务区正常圆点 变回正常颜色
let current: any = handleGetThisLayer("pointLayer");
current.color("SPREGIONTYPE_ID", (value: number) => {
return Number(value || 0) === 65 ||
Number(value || 0) === 45 ||
Number(value || 0) === 47
? "#34B6B7"
: "#CEF8D6";
});
current.render();
};
// 鼠标移入点触发的时间
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 handleGetEnumeration = async () => {
const ServerpartTypeList = await getFieldEnumTree({
FieldExplainField: "SERVERPART_TYPE",
});
console.log("ServerpartTypeList", ServerpartTypeList);
const typeObj: any = {};
if (ServerpartTypeList && ServerpartTypeList.length > 0) {
ServerpartTypeList.forEach((item: any) => {
typeObj[item.value] = item.label;
});
}
ServerpartTypeObj = typeObj;
};
// 给传入的服务区 标上高亮点
// 判断当前是否已经存在高亮图层 如果存在的话 就改变值 不用重新添加图层
const handleLightServerpart = (infoList: any) => {
let current: any = handleGetThisLayer("searchPointLayerText");
let idList: any = infoList.split(",");
// infoList.forEach((item: any) => {
// idList.push(item.SERVERPART_ID);
// });
console.log("idList", idList);
searchSelectServerPartId = idList;
let searchRes: any = [];
defaultServerPartList.forEach((item: any) => {
if (idList.indexOf(item.SERVERPART_ID.toString()) !== -1) {
searchRes.push(item);
}
});
console.log("searchRes", searchRes);
// 删除原有的 添加新的
if (current) {
scene.value.removeLayer(current);
}
let searchPointLayerText = new PointLayer({
zIndex: 9,
});
searchPointLayerText.name = "searchPointLayerText";
searchPointLayerText.source(searchRes, {
parser: {
type: "json",
x: "SERVERPART_X",
y: "SERVERPART_Y",
},
});
searchPointLayerText.shape("circle");
searchPointLayerText.size(8);
searchPointLayerText.color("#fdff3d");
searchPointLayerText.style({
opacity: 0.7, // 透明度
});
// searchPointLayerText.on("mousemove", (ev: any) => {
// const detail: any = ev.feature;
// hoverPoint.value.style.top = `${ev.y}px`;
// hoverPoint.value.style.left = `${ev.x}px`;
// hoverPoint.value.style.display = "block";
// hoverPoint.value.innerHTML = `<div>
// <div>${detail?.SERVERPART_NAME || ""}</div>
// </div>`;
// });
// // 鼠标移出
// searchPointLayerText.on("mouseout", (ev: any) => {
// hoverPoint.value.style.display = "none";
// });
scene.value.addLayer(searchPointLayerText);
};
// 传入服务区id 在地图上出现一个选中的效果 且 id只能传入一个服务区
const handleSelectedServerpart = (id: any) => {
if (defaultServerPartList && defaultServerPartList.length > 0) {
let seletObj: any = {};
defaultServerPartList.forEach((item: any) => {
if (item.SERVERPART_ID === id) {
seletObj = item;
}
});
}
};
// 查找当前全部图层中是否有传入的图层名称 有的话 输出图层数据
const handleGetThisLayer = (name: string) => {
let res: any;
let allLayers: any = scene.value.getLayers();
console.log("allLayers", allLayers);
if (allLayers && allLayers.length > 0) {
allLayers.forEach((item: any) => {
if (item.name === name) {
res = item;
}
});
}
if (res) {
return res;
}
};
// 进入搜索状态 改变现在的服务区点位颜色 全部变成灰色
const handleEnterySearch = () => {
let current: any = handleGetThisLayer("pointLayer");
current.color("#dededd");
current.render();
};
// 添加天气效果
const handleAddWeather = () => {
console.log("defaultServerPartList", defaultServerPartList);
defaultServerPartList.forEach((item: any) => {
if (item.weatherModel) {
if (item.weatherModel.DAY_WEATHER_PIC) {
const el = document.createElement("div");
el.style.width = "32px";
el.style.height = "24px";
el.style.paddingBottom = "4px";
el.style.textAlign = "center";
// 创建并插入 <img> 元素
const img = document.createElement("img");
img.src = item.weatherModel.DAY_WEATHER_PIC;
img.style.width = "15px";
img.style.height = "15px";
img.style.borderRadius = "50%"; // 圆形图片(可选)
// img.title = item.DAY_WEATHER
el.appendChild(img);
const marker = new Marker({ element: el }).setLnglat([
item.SERVERPART_X,
item.SERVERPART_Y,
] as any);
if (currentServerPartDetail.value) {
if (
item.SERVERPART_ID === currentServerPartDetail.value.SERVERPART_ID
) {
scene.value.addMarker(marker);
}
} else if (
searchSelectServerPartId &&
searchSelectServerPartId.length > 0
) {
if (
searchSelectServerPartId.indexOf(item.SERVERPART_ID.toString()) !==
-1
) {
scene.value.addMarker(marker);
}
} else {
scene.value.addMarker(marker);
}
}
}
});
};
// 遍历给实况车流图层的赋值
const handleSetCarData = async (
id: any,
roadTestList: any,
featuresList: any
) => {
let selectObj: any = {};
let selectRoad: any = {};
if (roadTestList && roadTestList.length > 0) {
roadTestList.forEach((item: any) => {
if (item.SERVERPART_ID.toString() === id) {
selectObj = item;
}
});
}
let roadReq: any = {};
let heightWay: any = [
366, 803, 381, 756, 708, 646, 805, 710, 476, 694, 714, 490, 658, 819, 659,
811, 716, 499, 941, 652, 943, 513, 510, 600, 707, 592, 706,
];
if (heightWay.indexOf(Number(selectObj.SERVERPART_ID)) === -1) {
roadReq = {
RoadName: selectObj.SERVERPART_NAME || "",
CityName: selectObj.SERVERPART_ADDRESS || "",
};
} else {
roadReq = {
RoadName: selectObj.EXPRESSWAY_NAME || "",
CityName: selectObj.SERVERPART_ADDRESS || "",
};
}
console.log("selectObj", selectObj);
const data = await handleGetBaiDuTrafficInfo(roadReq);
let roadItem: any = JSON.parse(data);
console.log("roadItem", roadItem);
if (featuresList && featuresList.length > 0) {
featuresList.forEach((item: any) => {
if (item.properties.SERVERPART_ID.toString() === id) {
item.properties.expediteNumber =
roadItem.status === 0 ? roadItem.evaluation.status : null;
selectRoad = item;
}
});
}
// 给服务区的鼠标移入点位显示的内容
if (defaultServerPartList && defaultServerPartList.length > 0) {
defaultServerPartList.forEach((item: any) => {
if (item.SERVERPART_ID === selectObj.SERVERPART_ID) {
nextTick(() => {
item.roadConditions = {
...selectObj,
...roadItem,
};
console.log("item", item);
console.log("defaultServerPartList", defaultServerPartList);
let allLayers: any = scene.value.getLayers();
if (allLayers && allLayers.length > 0) {
let obj: any = {};
allLayers.forEach((item: any) => {
if (item.name === "pointLayer") {
obj = item;
}
});
if (obj) {
obj.setData(defaultServerPartList);
}
}
});
}
});
}
if (selectRoad) {
return selectRoad;
}
return {};
};
// 拿到实况车流数据
const hanleGetRealTrafficData = async (id: any) => {
let roadList: any = JSON.parse(JSON.stringify(detailText.lineData));
let roadTestList: any = JSON.parse(JSON.stringify(detailText.roadTest));
let onceRoadList: any = {
type: "FeatureCollection",
features: [],
};
let featuresList: any = roadList.features;
let list: any = [];
for (let i = 0; i < id.length; i++) {
if (nowSelectId.value.indexOf("2") === -1) {
return;
}
const selectRoad = await handleSetCarData(
id[i],
roadTestList,
featuresList
);
list.push(selectRoad);
onceRoadList.features = list;
let allLayers: any = scene.value.getLayers();
console.log("allLayers", allLayers);
let haveList: any = allLayers.filter(
(item: any) => item.name === "lineLayerOnce"
);
console.log("haveList", haveList);
if (haveList && haveList.length > 0) {
let obj: any = haveList[0];
console.log("obj", obj);
nextTick(() => {
scene.value.removeLayer(obj);
const lineLayer = new LineLayer({
zIndex: 11,
});
lineLayer.name = `lineLayerOnce`;
lineLayer
.size(3) // 线条宽度
.shape("line") // 线条形状
.color("expediteNumber", (value) => {
// 根据 expediteNumber 动态设置颜色
if (value === 1) {
return "#35cf66"; // 绿色
} else if (value === 2) {
return "#c99c1c"; // 黄色
} else if (value === 3 || value === 4) {
return "#e64a4a"; // 红色
} else {
return "transparent"; // 灰色
}
})
.style({
opacity: 1, // 透明度
});
lineLayer.source(onceRoadList); // 设置数据源为 GeoJSON
scene.value.addLayer(lineLayer); // 将线图层添加到场景中
});
} else {
const lineLayer = new LineLayer({
zIndex: 11,
});
lineLayer.name = `lineLayerOnce`;
lineLayer
.size(3) // 线条宽度
.shape("line") // 线条形状
.color("expediteNumber", (value) => {
// 根据 expediteNumber 动态设置颜色
if (value === 1) {
return "#35cf66"; // 绿色
} else if (value === 2) {
return "#c99c1c"; // 黄色
} else if (value === 3 || value === 4) {
return "#e64a4a"; // 红色
} else {
return "transparent"; // 灰色
}
})
.style({
opacity: 1, // 透明度
});
lineLayer.source(onceRoadList); // 设置数据源为 GeoJSON
scene.value.addLayer(lineLayer); // 将线图层添加到场景中
}
}
};
// 实况车流
const handleGetRealTraffic = async () => {
let roadList: any = JSON.parse(JSON.stringify(detailText.lineData));
let roadTestList: any = JSON.parse(JSON.stringify(detailText.roadTest));
// 单个服务区查询的车流实况的最后结果 可以直接传入图层当数据
let onceRoadList: any = {
type: "FeatureCollection",
features: [],
};
let featuresList: any = roadList.features;
console.log("roadList", roadList);
console.log("featuresList", featuresList);
console.log("currentServerPartDetail.value", currentServerPartDetail.value);
// 选中
if (currentServerPartDetail.value) {
await hanleGetRealTrafficData([
currentServerPartDetail.value.SERVERPART_ID.toString(),
]);
} else if (searchSelectServerPartId && searchSelectServerPartId.length > 0) {
// 查询高亮
console.log("searchSelectServerPartId", searchSelectServerPartId);
await hanleGetRealTrafficData(searchSelectServerPartId);
} else {
// 默认全部
await hanleGetRealTrafficData(allServerPartIdList);
}
};
// 传入名字清除图层
const handleDeleteLayer = (name: string) => {
let allLayers: any = scene.value.getLayers();
console.log("allLayers", allLayers);
if (allLayers && allLayers.length > 0) {
allLayers.forEach((item: any) => {
if (item.name === name) {
scene.value.removeLayer(item);
}
});
}
};
// 清空一些非默认图层
const handleDeleteNoDefault = (nowSelect: string) => {
if (nowSelect) {
if (nowSelect.indexOf("1") === -1) {
scene.value.removeAllMarkers();
}
if (nowSelect.indexOf("2") === -1) {
handleDeleteLayer("lineLayerOnce");
}
if (nowSelect.indexOf("3") === -1) {
handleDeleteLayer("heatmapLayer");
}
if (nowSelect.indexOf("4") === -1) {
handleDeleteLayer("enterCarPoint");
handleDeleteLayer("enterLine");
}
if (nowSelect.indexOf("5") === -1) {
handleDeleteLayer("BUSINESS_TRADELayer");
}
if (nowSelect.indexOf("6") === -1) {
handleDeleteLayer("warningLayer");
}
} else {
console.log("22222", defaultServerPartList);
scene.value.removeAllMarkers();
handleDeleteLayer("lineLayerOnce");
handleDeleteLayer("heatmapLayer");
handleDeleteLayer("enterCarPoint");
handleDeleteLayer("enterLine");
handleDeleteLayer("warningLayer");
handleDeleteLayer("BUSINESS_TRADELayer");
}
};
// 更新服务区点数据的方法
const handleUpdateMapPoint = () => {
let allLayers: any = scene.value.getLayers();
if (allLayers && allLayers.length > 0) {
let obj: any = {};
allLayers.forEach((item: any) => {
if (item.name === "pointLayer") {
obj = item;
}
});
if (obj) {
obj.setData(defaultServerPartList);
}
}
};
// 营收热力的方法
const handleGetServerpartRevenue = async () => {
const revenueReq: any = {
calcType: 2,
pushProvinceCode: 340000,
curYear: moment().format("YYYY"),
compareYear: moment().subtract(1, "year").format("YYYY"),
StatisticsDate: moment().format("YYYY-MM-DD"),
StatisticsMonth: moment().format("YYYYMM"),
};
const revenueData: any = await handleGetMonthlySPINCAnalysis(revenueReq);
const revenueObj: any = {};
if (revenueData && revenueData.length > 0) {
revenueData.forEach((item: any) => {
revenueObj[item.ServerpartId] = item.RevenueINC.curYearData;
});
}
if (defaultServerPartList && defaultServerPartList.length > 0) {
nextTick(() => {
defaultServerPartList.forEach((item: any) => {
item.revenueData = revenueObj[item.SERVERPART_ID]
? revenueObj[item.SERVERPART_ID]
: "";
item.lng = item.SERVERPART_X;
item.lat = item.SERVERPART_Y;
});
handleUpdateMapPoint();
console.log("defaultServerPartList", defaultServerPartList);
let filteredData: any = [];
defaultServerPartList.forEach((item: any) => {
if (item.lng && item.lat && item.revenueData !== "") {
filteredData.push(item);
}
});
console.log("filteredData", filteredData);
const heatmapLayer = new HeatmapLayer({
zIndex: 11,
})
.source(defaultServerPartList, {
parser: {
type: "json",
x: "lng", // 指定经度字段
y: "lat", // 指定纬度字段
},
})
.size("revenueData", [0, 1]) // 根据值映射热力点大小
.shape("heatmap") // 指定热力图的形状
.style({
intensity: 5, // 控制强度
radius: 20, // 控制点半径
opacity: 0.8, // 图层透明度
rampColors: {
colors: ["#0e5a7e", "#63B8FF", "#FFF68F", "#FF6347", "#FF4500"], // 颜色梯度
positions: [0, 0.25, 0.5, 0.75, 1], // 对应颜色的位置
},
});
heatmapLayer.name = "heatmapLayer";
scene.value.addLayer(heatmapLayer);
});
}
};
// 车辆归属地
const handleGetCarComeForm = async () => {
const enterReq: any = {
serverPartId: currentServerPartDetail.value.SERVERPART_ID,
statisticsStartMonth: moment(moment().startOf("y")).format("YYYYMM"),
statisticsEndMonth: moment(moment()).format("YYYYMM"),
rankNum: 3,
};
const enterData: any = await handleGetProvinceVehicleTreeList(enterReq);
console.log("enterData", enterData);
let provinceListTooltip: any = [];
let provinceList: any = [];
if (enterData && enterData.length > 0) {
let children: any = [];
let obj: any = {};
enterData.forEach((item: any) => {
obj = JSON.parse(JSON.stringify(item));
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any, subIndex: number) => {
if (subIndex <= 4) {
provinceList.push(subItem);
children.push(subItem);
}
});
}
obj.children = children;
provinceListTooltip.push(obj);
});
}
nextTick(() => {
if (defaultServerPartList && defaultServerPartList.length > 0) {
defaultServerPartList.forEach((item: any) => {
if (
item.SERVERPART_ID.toString() ===
currentServerPartDetail.value.SERVERPART_ID.toString()
) {
item.provinceListTooltip = provinceListTooltip;
}
});
handleUpdateMapPoint();
}
});
let homeCarList: any = [];
if (provinceList && provinceList.length > 0) {
provinceList.forEach((item: any) => {
let list: any = [];
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any, subIndex: number) => {
if (subIndex <= 2) {
list.push(subItem);
}
});
}
item.children = list;
homeCarList.push(item);
});
}
let featuresList: any = [];
let enterPointList: any = [];
let cityCoordinate: any = detailText.cityCoordinate;
if (homeCarList && homeCarList.length > 0) {
homeCarList.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
enterPointList.push({
label: subItem.ProvinceOrCityName + "市",
SERVERPART_X: cityCoordinate[subItem.ProvinceOrCityName + "市"]
? cityCoordinate[subItem.ProvinceOrCityName + "市"][0]
: [],
SERVERPART_Y: cityCoordinate[subItem.ProvinceOrCityName + "市"]
? cityCoordinate[subItem.ProvinceOrCityName + "市"][1]
: [],
});
featuresList.push({
type: "Feature",
geometry: {
type: "LineString",
coordinates: [
cityCoordinate[subItem.ProvinceOrCityName + "市"]
? cityCoordinate[subItem.ProvinceOrCityName + "市"]
: [], // 起点
cityCoordinate[currentServerPartDetail.value.SERVERPART_NAME]
? cityCoordinate[
currentServerPartDetail.value.SERVERPART_NAME
]
: [], // 终点
],
},
properties: {
value: subItem.TotalCount, // 可以映射成动画效果
},
});
});
}
});
}
const enterLineData: any = {
type: "FeatureCollection",
features: featuresList,
};
const enterLine = new LineLayer({})
.source(enterLineData)
.size(2) // 设置线条宽度
.shape("line") // 线条类型
.color("value", ["#93cdf8", "#77c0f6"]) // 根据值映射颜色// ['#a1c4fd', '#2193b0', '#1565c0']
.style({
opacity: 0.8, // 设置透明度
lineType: "dash", // 虚线样式
dashArray: [5, 5], // 虚线间隔
})
.animate({
interval: 1, // 动画间隔
duration: 2, // 每条线条动画持续时间
trailLength: 0.5, // 轨迹长度
});
enterLine.name = "enterLine";
scene.value.addLayer(enterLine);
// 给车辆的出发点 也打上圆点图层
const enterPoint = new PointLayer({
zIndex: 9,
});
enterPoint.name = "enterCarPoint";
enterPoint.source(enterPointList, {
parser: {
type: "json",
x: "SERVERPART_X",
y: "SERVERPART_Y",
},
});
enterPoint.shape("circle");
enterPoint.size(8);
enterPoint.color("#58b1f5");
scene.value.addLayer(enterPoint);
};
// 拿到经营业态
const handleGetBusinessFormat = async () => {
await RobotDialogueBoxRef.value.handleGetBusinessTrade();
let formData: any = RightSearchBoxRef.value.form;
console.log("formData", formData);
const req: any = {
BusinessTrade: formData?.BUSINESS_TRADE.toString(),
ShowNormal: true,
PeriodState: 1,
DataType: 3,
};
const tradeData = await handleGetPeriodWarningList(req);
console.log("tradeData", tradeData);
// 拿到所有查询的业态所对应的服务区
const obj: any = {};
// 搜索的业态包含的服务区
const shopObj: any = {};
// 拿到门店的id
let shopIdObj: any = {};
if (tradeData && tradeData.length > 0) {
console.log("tradeData3232", tradeData);
tradeData.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
if (subItem.children && subItem.children.length > 0) {
subItem.children.forEach((thirdItem: any) => {
if (obj[thirdItem.SERVERPART_ID]) {
const old: any = obj[thirdItem.SERVERPART_ID];
old.push(thirdItem.BUSINESS_TRADE);
obj[thirdItem.SERVERPART_ID] = old;
} else {
const list: any = [thirdItem.BUSINESS_TRADE];
obj[thirdItem.SERVERPART_ID] = list;
}
if (thirdItem.children && subItem.children.length > 0) {
let shopName: string = "";
let shopIdList: any = [];
thirdItem.children.forEach((fourthItem: any) => {
if (shopName) {
shopName += `, ${fourthItem.SERVERPARTSHOP_NAME} `;
} else {
shopName = `${fourthItem.SERVERPARTSHOP_NAME} `;
}
if (fourthItem?.SERVERPARTSHOP_ID) {
let list: any = fourthItem?.SERVERPARTSHOP_ID.split(",");
if (list && list.length > 0) {
list.forEach((item: any) => {
shopIdList.push(item);
});
}
}
});
shopObj[thirdItem.SERVERPART_ID] = shopName;
shopIdObj[thirdItem.SERVERPART_ID] = shopIdList;
}
});
}
});
}
});
}
let BusinessTradeIdsObj: any =
RightSearchBoxRef.value.selectBusinessTradeIdsObj;
console.log("BusinessTradeIdsObj", BusinessTradeIdsObj);
console.log("obj", obj);
nextTick(() => {
defaultServerPartList.forEach((item: any) => {
if (obj[item.SERVERPART_ID] && obj[item.SERVERPART_ID].length > 0) {
const newObj: any = JSON.parse(JSON.stringify(item));
let str: string = "";
const tradeList: any = obj[item.SERVERPART_ID];
tradeList.forEach((subItem: any) => {
if (str) {
str += `${BusinessTradeIdsObj[subItem]} `;
} else {
str = BusinessTradeIdsObj[subItem];
}
});
item.tradeType = str;
if (shopObj[item.SERVERPART_ID]) {
item.shopName = shopObj[item.SERVERPART_ID];
}
if (shopIdObj[item.SERVERPART_ID]) {
item.shopIdList = shopIdObj[item.SERVERPART_ID];
}
}
});
handleUpdateMapPoint();
});
console.log("defaultServerPartList", defaultServerPartList);
const tradeRes: any = [];
defaultServerPartList.forEach((item: any) => {
if (obj[item.SERVERPART_ID] && obj[item.SERVERPART_ID].length > 0) {
const newObj: any = JSON.parse(JSON.stringify(item));
let str: string = "";
const tradeList: any = obj[item.SERVERPART_ID];
tradeList.forEach((item: any) => {
if (str) {
str += `${BusinessTradeIdsObj[item]} `;
} else {
str = BusinessTradeIdsObj[item];
}
});
newObj.tradeType = str;
if (shopObj[item.SERVERPART_ID]) {
newObj.shopName = shopObj[item.SERVERPART_ID];
}
if (shopIdObj[item.SERVERPART_ID]) {
newObj.shopIdList = shopIdObj[item.SERVERPART_ID];
}
tradeRes.push(newObj);
}
});
console.log("tradeRes", tradeRes);
const BUSINESS_TRADELayer = new PointLayer({
zIndex: 10,
});
BUSINESS_TRADELayer.name = "BUSINESS_TRADELayer";
BUSINESS_TRADELayer.source(tradeRes, {
parser: {
type: "json",
x: "SERVERPART_X",
y: "SERVERPART_Y",
},
});
BUSINESS_TRADELayer.shape("circle");
BUSINESS_TRADELayer.size(8);
BUSINESS_TRADELayer.color("#1890ff");
scene.value.addLayer(BUSINESS_TRADELayer);
};
// 预警类型
const handleWarningData = async () => {
await RobotDialogueBoxRef.value.handleSetWarningData();
};
// 对预警类型的地图进行操作
const handleWarningMap = async (warningData: any) => {
let waringObj: any = RobotDialogueBoxRef.value.descObjRef;
console.log("waringObj", waringObj);
let warningRes: any = [];
// 拿到所有查询的业态所对应的服务区
const obj: any = {};
// 拿到所有查询到的预警类型对应的门店
let shopIdObj: any = {};
console.log("warningData2", warningData);
if (warningData && warningData.length > 0) {
warningData.forEach((item: any) => {
if (obj[item.SERVERPART_ID] && obj[item.SERVERPART_ID].length > 0) {
const old: any = obj[item.SERVERPART_ID];
old.push(item);
} else {
obj[item.SERVERPART_ID] = [item];
}
if (
shopIdObj[item.SERVERPART_ID] &&
shopIdObj[item.SERVERPART_ID].length > 0
) {
const old: any = shopIdObj[item.SERVERPART_ID];
let list: any = item.SERVERPARTSHOP_ID.split(",");
if (list && list.length > 0) {
list.forEach((subItem: any) => {
old.push(subItem);
});
}
} else {
let res: any = [];
let list: any = item.SERVERPARTSHOP_ID.split(",");
if (list && list.length > 0) {
list.forEach((subItem: any) => {
res.push(subItem);
});
}
shopIdObj[item.SERVERPART_ID] = res;
}
});
}
nextTick(() => {
defaultServerPartList.forEach((item: any) => {
if (obj[item.SERVERPART_ID] && obj[item.SERVERPART_ID].length > 0) {
let str: string = "";
const tradeList: any = obj[item.SERVERPART_ID];
tradeList.forEach((key: any) => {
if (str) {
str += `${key.SERVERPARTSHOP_NAME}; `;
} else {
str = `${waringObj[key.WARNING_TYPE]}${key.SERVERPARTSHOP_NAME} `;
}
});
if (
shopIdObj[item.SERVERPART_ID] &&
shopIdObj[item.SERVERPART_ID].length > 0
) {
item.warningShop = shopIdObj[item.SERVERPART_ID];
}
item.waringText = str;
}
});
handleUpdateMapPoint();
});
defaultServerPartList.forEach((item: any) => {
if (obj[item.SERVERPART_ID] && obj[item.SERVERPART_ID].length > 0) {
const newObj: any = JSON.parse(JSON.stringify(item));
let str: string = "";
const tradeList: any = obj[item.SERVERPART_ID];
tradeList.forEach((key: any) => {
if (str) {
str += `${key.SERVERPARTSHOP_NAME}; `;
} else {
str = `${waringObj[key.WARNING_TYPE]}${key.SERVERPARTSHOP_NAME} `;
}
});
if (
shopIdObj[item.SERVERPART_ID] &&
shopIdObj[item.SERVERPART_ID].length > 0
) {
newObj.warningShop = shopIdObj[item.SERVERPART_ID];
}
newObj.waringText = str;
warningRes.push(newObj);
}
});
console.log("warningRes", warningRes);
console.log("defaultServerPartList", defaultServerPartList);
const warningLayer = new PointLayer({
zIndex: 10,
});
warningLayer.name = "warningLayer";
warningLayer.source(warningRes, {
parser: {
type: "json",
x: "SERVERPART_X",
y: "SERVERPART_Y",
},
});
warningLayer.shape("circle");
warningLayer.size(8);
warningLayer.color("#ff3a02");
scene.value.addLayer(warningLayer);
};
// 根据右侧的选择列表 来对地图进行操作
const handleChangeMapShow = async (nowSelect: string) => {
// 清空没有值的图层
handleDeleteNoDefault(nowSelect);
console.log("nowSelect", nowSelect);
nowSelectId.value = nowSelect;
// 有值 根据值来判断显示的内容
if (nowSelect) {
if (nowSelect.indexOf("1") !== -1) {
// 添加天气锚点
handleAddWeather();
}
if (nowSelect.indexOf("2") !== -1) {
// 实况车流
await handleGetRealTraffic();
}
if (nowSelect.indexOf("3") !== -1) {
const loadingInstance = ElLoading.service({
fullscreen: true,
background: "#00000080",
text: "数据加载中...",
});
// 营收热力
await handleGetServerpartRevenue();
loadingInstance.close();
}
if (nowSelect.indexOf("4") !== -1) {
const loadingInstance = ElLoading.service({
fullscreen: true,
background: "#00000080",
text: "数据加载中...",
});
// 车辆归属地
await handleGetCarComeForm();
loadingInstance.close();
}
if (nowSelect.indexOf("5") !== -1) {
// 经营业态
await handleGetBusinessFormat();
}
if (nowSelect.indexOf("6") !== -1) {
const loadingInstance = ElLoading.service({
fullscreen: true,
background: "#00000080",
text: "数据加载中...",
});
// 预警类型
await handleWarningData();
loadingInstance.close();
}
if (nowSelect.indexOf("7") !== -1) {
// 清空
nowSelectId.value = "";
handleDeleteNoDefault(nowSelectId.value);
}
}
};
</script>
<template>
<div id="map" class="mapBox">
<div class="RobotBox">
<RobotDialogueBox
ref="RobotDialogueBoxRef"
@handleLightServerpart="handleLightServerpart"
@handleEnterySearch="handleEnterySearch"
@handleWarningMap="handleWarningMap"
:currentServerPartDetail="currentServerPartDetail"
:allServerPartIdList="allServerPartIdList"
/>
</div>
<div class="rightSearchBox">
<RightSearchBox
ref="RightSearchBoxRef"
@handleChangeMapShow="handleChangeMapShow"
:currentServerPartDetail="currentServerPartDetail"
/>
</div>
</div>
</template>