明树Git Lab

Commit d2a96b7a authored by chenron's avatar chenron

地图修改

parent c08f64cb
Pipeline #104199 passed with stage
in 12 seconds
<template> <template>
<div class="tourism">
<div id="container"></div> <div id="container"></div>
</div>
</template> </template>
<script setup> <script setup>
import AMapLoader from "@amap/amap-jsapi-loader"; import AMapLoader from "@amap/amap-jsapi-loader";
import { nextTick, onMounted, reactive, ref } from "vue"; import {
nextTick,
onMounted,
reactive,
ref,
onUnmounted,
onActivated,
defineEmits,
} from "vue";
// 定义事件
const emit = defineEmits(["province-selected"]);
import gansuLine from "./newLine.json"; import gansuLine from "./newLine.json";
let map = null; let map = null;
window._AMapSecurityConfig = { window._AMapSecurityConfig = {
...@@ -25,7 +34,7 @@ const handleInitMap = () => { ...@@ -25,7 +34,7 @@ const handleInitMap = () => {
map = new AMap.Map("container", { map = new AMap.Map("container", {
//设置地图容器id //设置地图容器id
viewMode: "2D", viewMode: "2D",
zoom: 4, //初始化地图级别 zoom: 4, //根据屏幕宽度设置初始化地图级别
center: [100.808299, 35.791787], //初始化地图中心点位置 center: [100.808299, 35.791787], //初始化地图中心点位置
expandZoomRange: true, // 开启显示范围设置 expandZoomRange: true, // 开启显示范围设置
mapStyle: "amap://styles/2d017848d08f94f20b6e50aaae661148", mapStyle: "amap://styles/2d017848d08f94f20b6e50aaae661148",
...@@ -34,22 +43,24 @@ const handleInitMap = () => { ...@@ -34,22 +43,24 @@ const handleInitMap = () => {
copyrightControl: false, copyrightControl: false,
logoControl: false, logoControl: false,
}); });
const mapSize = map.getSize();
mapSize.width < 780 ? map.setZoom(3.5) : map.setZoom(4); // 根据不同屏幕大小设置缩放
const minZoom = 4; // const mapSize = map.getSize();
// if (mapSize && mapSize.width < 780) {
// map.setZoom(3.5);
// }
handleDistrict(); handleDistrict();
addPolylines(); addPolylines();
handleAddMarket(selectName); handleAddMarket(selectName);
}) })
.catch((e) => {}); .catch((e) => {});
// if (map) return true;
}; };
// 高亮和描边 // 高亮和描边
const handleDistrict = () => { const handleDistrict = () => {
let districtSearch = new AMap.DistrictSearch({ let districtSearch = new AMap.DistrictSearch({
subdistrict: 0, //获取边界不需要返回下级行政区 subdistrict: 0, //获取边界不需要返回下级行政区
extensions: "all", //返回行政区边界坐标组等具体信息 extensions: "all", //返回行政区边界坐标组等具体信息
level: "province", //查询行政级别为 市 province-省 district- level: "province", //查询行政级别为 市 province-省 district-
}); });
let polygons = []; let polygons = [];
districtSearch.search("中华人民共和国", function (status, result) { districtSearch.search("中华人民共和国", function (status, result) {
...@@ -136,25 +147,21 @@ const addPolylines = () => { ...@@ -136,25 +147,21 @@ const addPolylines = () => {
}); });
// 鼠标双击 // 鼠标双击
polylineObj.on("dblclick", function (e) { polylineObj.on("dblclick", function (e) {});
const data = polylineObj.getExtData();
// showProject(data);
});
return polylineObj; return polylineObj;
}, },
}); });
map.add(geojsonObj); map.add(geojsonObj);
}; };
// 添加标记 // 添加标记
let currentMarkers = []; // 存储当前显示的标记 let currentMarkers = [];
const handleAddMarket = (selectName) => { const handleAddMarket = (selectName) => {
// 清除之前的所有标记 // 清除之前的所有标记
if (currentMarkers.length > 0) { if (currentMarkers.length > 0) {
map.remove(currentMarkers); map.remove(currentMarkers);
currentMarkers = []; currentMarkers = [];
} }
// 清除所有标记
// 额外确保清除所有标记(防止其他地方创建的标记)
if (map) { if (map) {
map.getAllOverlays("marker").forEach((marker) => { map.getAllOverlays("marker").forEach((marker) => {
map.remove(marker); map.remove(marker);
...@@ -176,6 +183,8 @@ const handleAddMarket = (selectName) => { ...@@ -176,6 +183,8 @@ const handleAddMarket = (selectName) => {
{ number: 2, position: [117.0009, 36.6758], province: "山东省" }, { number: 2, position: [117.0009, 36.6758], province: "山东省" },
// 河北 // 河北
{ number: 1, position: [114.5025, 38.0455], province: "河北省" }, { number: 1, position: [114.5025, 38.0455], province: "河北省" },
// 甘肃
{ number: 10, position: [103.8236, 36.058], province: "甘肃省" },
], ],
试运营: [ 试运营: [
// 四川 // 四川
...@@ -258,6 +267,69 @@ const handleAddMarket = (selectName) => { ...@@ -258,6 +267,69 @@ const handleAddMarket = (selectName) => {
infoWindow.close(); infoWindow.close();
}); });
// 点击事件:聚焦到对应省份并显示省份地图
marker.on("click", function (e) {
const provinceName = markerData.province; // 例如:甘肃省
emit("province-selected", true);
// 创建省份搜索
let districtSearch = new AMap.DistrictSearch({
subdistrict: 0,
extensions: "all",
level: "province",
});
// 搜索并定位到省份
districtSearch.search(provinceName, function (status, result) {
if (status === "complete") {
let bounds = result.districtList[0].boundaries;
if (bounds && bounds.length > 0) {
// 清除所有边界线(中国地图边界)
map.getAllOverlays("polyline").forEach((polyline) => {
map.remove(polyline);
});
// 清除所有标记点
map.getAllOverlays("marker").forEach((marker) => {
map.remove(marker);
});
// 清除所有覆盖物
map.getAllOverlays("polygon").forEach((polygon) => {
map.remove(polygon);
});
// 绘制省份边界线
for (let i = 0; i < bounds.length; i++) {
let provincePolyline = new AMap.Polyline({
path: bounds[i],
strokeColor: "#72A8FF",
strokeWeight: 3,
map: map,
});
map.add(provincePolyline);
}
// 绘制省份填充区域(可选)
let provincePolygon = new AMap.Polygon({
path: bounds[0],
strokeColor: "#72A8FF",
strokeWeight: 2,
fillColor: "rgba(114, 168, 255, 0.1)",
fillOpacity: 0.3,
});
map.add(provincePolygon);
// 重新添加新路线(确保新路线显示在地图上)
addPolylines();
// 设置地图视图到该省份
map.setFitView([provincePolygon]);
map.setZoom(8);
}
}
});
});
currentMarkers.push(marker); currentMarkers.push(marker);
} }
}; };
...@@ -269,27 +341,83 @@ const updateMarkers = (selectName) => { ...@@ -269,27 +341,83 @@ const updateMarkers = (selectName) => {
// 重置地图到初始状态 // 重置地图到初始状态
const resetMap = () => { const resetMap = () => {
if (map) { if (map) {
// 清除所有边界线(包括省份边界线)
map.getAllOverlays("polyline").forEach((polyline) => {
map.remove(polyline);
});
// 清除所有标记点
map.getAllOverlays("marker").forEach((marker) => {
map.remove(marker);
});
// 清除所有覆盖物
map.getAllOverlays("polygon").forEach((polygon) => {
map.remove(polygon);
});
// 重新绘制全国边界
handleDistrict();
// 恢复当前阶段的标记点
let selectName = sessionStorage.getItem("selectedContentBtn");
handleAddMarket(selectName);
// 设置地图视图
map.setZoom(4); map.setZoom(4);
map.setCenter([100.808299, 35.791787]); map.setCenter([100.808299, 35.791787]);
const mapSize = map.getSize();
mapSize.width < 780 ? map.setZoom(3.5) : map.setZoom(4);
} }
}; };
// 返回全国地图视图
const backToCountry = () => {
resetMap();
};
// 暴露方法给父组件 // 暴露方法给父组件
defineExpose({ defineExpose({
updateMarkers, updateMarkers,
resetMap, resetMap,
backToCountry,
}); });
onMounted(() => { onMounted(() => {
handleInitMap(); handleInitMap();
// 监听窗口大小变化
window.addEventListener("resize", handleResize);
});
// 处理窗口大小变化
const handleResize = () => {
if (map) {
map.resize();
}
};
// 组件卸载时移除事件监听
onUnmounted(() => {
window.removeEventListener("resize", handleResize);
});
onActivated(() => {
nextTick(() => {
const container = document.getElementById("container");
if (container) {
container.style.width = "100%";
container.style.height = "100%";
}
map ? map.resize() : handleInitMap();
});
}); });
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
.tourism { .tourism {
width: 100%; width: 100%;
.vh(height, 600); height: 100%;
}
#container {
width: 100%;
height: 100%;
} }
.custom-content-marker { .custom-content-marker {
position: relative; position: relative;
......
...@@ -50,8 +50,8 @@ html, body { ...@@ -50,8 +50,8 @@ html, body {
} }
#container { #container {
width: 100%; /* width: 100%; */
height: 100%; /* height: 100%;
overflow: hidden; overflow: hidden; */
} }
<template> <template>
<div class="construct-container"> <div class="construct-container">
<div class="construct-left"> <div class="construct-left">
<!-- <div class="tag-image">
<img src="@/assets/images/建设.png" />
</div> -->
<div class="construct-left-map"> <div class="construct-left-map">
<Map ref="mapRef" /> <Map ref="mapRef" />
</div> </div>
...@@ -51,7 +48,7 @@ import { ...@@ -51,7 +48,7 @@ import {
onUnmounted, onUnmounted,
shallowReactive, shallowReactive,
defineOptions, defineOptions,
onActivated onActivated,
} from "vue"; } from "vue";
import CircleProgress from "./CircleProgress.vue"; import CircleProgress from "./CircleProgress.vue";
...@@ -96,9 +93,10 @@ onActivated(() => { ...@@ -96,9 +93,10 @@ onActivated(() => {
<style scoped lang="less"> <style scoped lang="less">
.construct-container { .construct-container {
display: flex; display: flex;
.vh(margin-top,10); height: 100%;
.construct-left {
width: 100%; width: 100%;
.construct-left {
flex: 1;
height: 100%; height: 100%;
.tag-image { .tag-image {
img { img {
...@@ -106,22 +104,22 @@ onActivated(() => { ...@@ -106,22 +104,22 @@ onActivated(() => {
} }
} }
.construct-left-map { .construct-left-map {
.vh(height, 700); height: 100%;
.vh(padding-top, 4);
} }
} }
.construct-right { .construct-right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-around;
.vh(height,700); height: 100%;
.info-title { .info-title {
.vw(width, 180); .vw(width, 180);
.vh(height, 30); .vh(height, 30);
.vh(line-height, 30); .vh(line-height, 30);
.font(16); .font(16);
.vw(padding-left,20); .vw(padding-left,20);
.vh(margin-bottom,15); .vh(margin-bottom,10);
.vh(margin-top,15);
text-align: left; text-align: left;
color: #fff; color: #fff;
white-space: nowrap; white-space: nowrap;
......
<template> <template>
<div class="construct-container"> <div class="construct-container">
<div class="construct-left"> <div class="construct-left">
<!-- <div class="tag-image">
<img src="@/assets/images/建设.png" />
</div> -->
<div class="construct-left-map"> <div class="construct-left-map">
<Map ref="mapRef" /> <Map ref="mapRef" />
</div> </div>
...@@ -44,7 +41,7 @@ import { ...@@ -44,7 +41,7 @@ import {
onMounted, onMounted,
onUnmounted, onUnmounted,
defineOptions, defineOptions,
onActivated onActivated,
} from "vue"; } from "vue";
// 定义组件名称,用于keep-alive缓存 // 定义组件名称,用于keep-alive缓存
...@@ -121,8 +118,10 @@ onActivated(() => { ...@@ -121,8 +118,10 @@ onActivated(() => {
<style scoped lang="less"> <style scoped lang="less">
.construct-container { .construct-container {
display: flex; display: flex;
.construct-left { height: 100%;
width: 100%; width: 100%;
.construct-left {
flex: 1;
height: 100%; height: 100%;
.tag-image { .tag-image {
img { img {
...@@ -130,15 +129,14 @@ onActivated(() => { ...@@ -130,15 +129,14 @@ onActivated(() => {
} }
} }
.construct-left-map { .construct-left-map {
.vh(height, 700); height: 100%;
.vh(padding-top, 4);
} }
} }
.construct-right { .construct-right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-around;
.vh(height,612); height: 100%;
.info-title { .info-title {
.vw(width, 180); .vw(width, 180);
.vh(height, 30); .vh(height, 30);
......
<template> <template>
<div class="project-container"> <div class="project-container">
<CommonTotal :numberList="initiationList" /> <CommonTotal :numberList="initiationList" />
<div class="map-wrapper">
<Map ref="mapRef" @province-selected="onProvinceSelected" />
<div class="back-to-country-btn" @click="backToCountry" v-show="showBackBtn">
返回全国
</div>
</div>
</div> </div>
<Map ref="mapRef" />
</template> </template>
<script setup> <script setup>
...@@ -16,7 +21,7 @@ import { ...@@ -16,7 +21,7 @@ import {
computed, computed,
shallowRef, shallowRef,
defineOptions, defineOptions,
onActivated onActivated,
} from "vue"; } from "vue";
// 定义组件名称,用于keep-alive缓存 // 定义组件名称,用于keep-alive缓存
...@@ -32,6 +37,7 @@ const props = defineProps({ ...@@ -32,6 +37,7 @@ const props = defineProps({
}); });
const mapRef = ref(null); const mapRef = ref(null);
const showBackBtn = ref(false);
// 使用静态数据避免重复创建 // 使用静态数据避免重复创建
const STATIC_DATA = { const STATIC_DATA = {
立项: [ 立项: [
...@@ -70,10 +76,33 @@ watch( ...@@ -70,10 +76,33 @@ watch(
{ immediate: true } { immediate: true }
); );
// 返回全国地图
const backToCountry = () => {
if (mapRef.value && mapRef.value.backToCountry) {
mapRef.value.backToCountry();
showBackBtn.value = false;
}
};
// 监听省份选择事件
const onProvinceSelected = (show) => {
showBackBtn.value = show;
};
// 监听地图缩放级别来显示/隐藏返回按钮
const handleMapZoomChange = () => {
if (mapRef.value) {
// 这里可以添加监听地图缩放变化的逻辑
// 当缩放级别大于某个值时显示返回按钮
showBackBtn.value = true;
}
};
// 组件被激活时重置地图 // 组件被激活时重置地图
onActivated(() => { onActivated(() => {
if (mapRef.value && mapRef.value.resetMap) { if (mapRef.value && mapRef.value.resetMap) {
mapRef.value.resetMap(); mapRef.value.resetMap();
showBackBtn.value = false;
} }
}); });
</script> </script>
...@@ -81,7 +110,39 @@ onActivated(() => { ...@@ -81,7 +110,39 @@ onActivated(() => {
<style scoped lang="less"> <style scoped lang="less">
.project-container { .project-container {
display: flex; display: flex;
justify-content: center; flex-direction: column; // 垂直排列子元素
justify-content: center; // 水平居中
align-items: center; // 垂直居中
.vh(margin-top, 20); .vh(margin-top, 20);
height: 100%;
width: 100%;
.map-wrapper {
position: relative;
width: 100%;
height: 100%;
.back-to-country-btn {
position: absolute;
top: 20px;
right: 20px;
background: rgba(4, 66, 126, 0.9);
border: 1px solid #00ddeb;
border-radius: 4px;
color: #fff;
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
z-index: 1000;
backdrop-filter: blur(4px);
transition: all 0.3s ease;
&:hover {
background: rgba(0, 221, 235, 0.2);
border-color: #fff;
transform: scale(1.05);
}
}
}
} }
</style> </style>
<template> <template>
<div class="construct-container"> <div class="construct-container">
<div class="construct-left"> <div class="construct-left">
<!-- <div class="tag-image">
<img src="@/assets/images/建设.png" />
</div> -->
<div class="construct-left-map"> <div class="construct-left-map">
<Map ref="mapRef" /> <Map ref="mapRef" />
</div> </div>
...@@ -44,7 +41,7 @@ import { ...@@ -44,7 +41,7 @@ import {
onMounted, onMounted,
onUnmounted, onUnmounted,
defineOptions, defineOptions,
onActivated onActivated,
} from "vue"; } from "vue";
// 定义组件名称,用于keep-alive缓存 // 定义组件名称,用于keep-alive缓存
...@@ -136,8 +133,10 @@ onActivated(() => { ...@@ -136,8 +133,10 @@ onActivated(() => {
<style scoped lang="less"> <style scoped lang="less">
.construct-container { .construct-container {
display: flex; display: flex;
.construct-left { height: 100%;
width: 100%; width: 100%;
.construct-left {
flex: 1;
height: 100%; height: 100%;
.tag-image { .tag-image {
img { img {
...@@ -145,15 +144,14 @@ onActivated(() => { ...@@ -145,15 +144,14 @@ onActivated(() => {
} }
} }
.construct-left-map { .construct-left-map {
.vh(height, 700); height: 100%;
.vh(padding-top, 4);
} }
} }
.construct-right { .construct-right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-around;
.vh(height,612); height: 100%;
.info-title { .info-title {
.vw(width, 180); .vw(width, 180);
.vh(height, 30); .vh(height, 30);
......
<template> <template>
<div class="construct-container"> <div class="map-container">
<div class="construct-left"> <div id="container"></div>
<div class="tag-image"> <!-- 加载动画层 -->
<img src="@/assets/images/建设.png" /> <div class="loading-overlay" v-if="showLoading">
</div> <div class="loading-dot"></div>
<div class="construct-left-map">
<Map />
</div>
</div>
<div class="construct-right">
<div>
<div class="info-title">项目概况</div>
<CommonTotal :numberList="projectList" />
</div>
<div>
<div class="info-title">投资完成情况</div>
<CommonTotal :numberList="investmentList" />
</div>
<div>
<div class="info-title">经营计划完成情况</div>
<CommonComplete :numberList="completeList" />
</div>
<div>
<div class="info-title">投资回收完成情况</div>
<CommonTotal :numberList="recycleList" />
</div>
<div>
<div class="info-title">2025年经营计划完成进度</div>
<CommonPlant :numberList="operationList" />
</div>
</div> </div>
</div> </div>
</template> </template>
<style scoped>
.map-container {
position: relative;
width: 100%;
height: 100%;
}
.loading-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
/* background-color: rgba(252, 251, 251, 0); */
display: flex;
justify-content: center;
align-items: center;
z-index: 9999; /* 确保在地图上方显示 */
}
.loading-dot {
width: 30px;
height: 30px;
background-color: #00ddeb;
border-radius: 50%;
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.5);
opacity: 0.7;
}
100% {
transform: scale(1);
opacity: 1;
}
}
</style>
<script setup> <script setup>
import Map from "@/components/CommonMap.vue"; import AMapLoader from "@amap/amap-jsapi-loader";
import CommonTotal from "@/components/CommonTotal.vue"; import {
import CommonComplete from "@/components/CommonComplete.vue"; nextTick,
import CommonPlant from "@/components/CommonPlant.vue"; onMounted,
import { reactive, ref, onMounted, onUnmounted } from "vue"; reactive,
const projectList = reactive([ ref,
{ title: "总个数(个)", value: "59" }, onUnmounted,
{ title: "总投资(亿元)", value: "2733.35" }, onActivated,
{ title: "总规模(公里)", value: "5116.72" }, } from "vue";
]); import gansuLine from "./newLine.json";
const investmentList = reactive([ let map = null;
{ title: "10月完成投资(亿元)", value: "0" }, // 控制加载动画显示状态
{ title: "2025年完成投资(亿元)", value: "19.725" }, const showLoading = ref(true);
{ title: "累计完成投资(亿元)", value: "807.56" }, window._AMapSecurityConfig = {
]); securityJsCode: "75a8291a9e8f7c838fc5e4dd0d538f30",
const recycleList = reactive([ // securityJsCode: "7aee6d6553ba9a8178e0c57b60a51481",
{ title: "10月完成投资(亿元)", value: "0" }, };
{ title: "2025年完成投资(亿元)", value: "2.98" }, // 初始化地图
{ title: "完成率", value: "50.2%" }, const handleInitMap = () => {
]); // 先显示遮罩层,延迟3秒后再加载地图
const operationList = reactive([ setTimeout(() => {
{ title: "营业收入完成进度", value: "68.1%" }, let selectName = sessionStorage.getItem("selectedContentBtn");
{ title: "运营成本完成进度", value: "68.1%" },
{ title: "利润总额完成进度", value: "68.1%" }, // 获取地图容器并设置初始样式
]); const container = document.getElementById("container");
const completeList = reactive([ if (container) {
{ container.style.opacity = "0"; // 初始设置为透明
title: "营业收入", container.style.transition = "opacity 0.5s ease-in-out"; // 添加过渡效果
protitle: "11月完成", }
proValue: "1.1",
thirdTtile: "第三季度完成", AMapLoader.load({
thirdValue: "4.21", key: "c691971f068b92c897fb908c4ddef6d4", // 申请好的Web端开发者Key
compareValue: "+1.2%", // key: "9a22433229a51dc5114d4bbf92f687ee", // 申请好的Web端开发者Key
}, version: "2.0",
{ plugins: ["AMap.DistrictSearch", "AMap.GeoJSON"],
title: "运营成本", })
protitle: "11月完成", .then((AMap) => {
proValue: "47.98", map = new AMap.Map("container", {
thirdTtile: "第三季度完成", //设置地图容器id
thirdValue: "5.75", viewMode: "2D",
compareValue: "-0.5%", zoom: 4, //根据屏幕宽度设置初始化地图级别
}, center: [100.808299, 35.791787], //初始化地图中心点位置
{ expandZoomRange: true, // 开启显示范围设置
title: "利润总额", mapStyle: "amap://styles/2d017848d08f94f20b6e50aaae661148",
protitle: "11月完成", // mapStyle: "amap://styles/d9cd35cfbd75e272e528a7fde0bcfc53",
proValue: "9.90", rotateEnable: false, // 是否可以旋转
thirdTtile: "第三季度完成", copyrightControl: false,
thirdValue: "23.52", logoControl: false,
compareValue: "+1.2%", });
// 监听地图加载完成事件
map.on("complete", function () {
// 执行地图相关操作
handleDistrict();
addPolylines();
handleAddMarket(selectName);
// 隐藏加载动画
showLoading.value = false;
// 显示地图,添加过渡效果
if (container) {
setTimeout(() => {
container.style.opacity = "1";
}, 100);
}
});
})
.catch((e) => {
console.error(e);
// 加载失败时也隐藏加载动画
showLoading.value = false;
// 显示地图容器
if (container) {
container.style.opacity = "1";
}
});
}, 3000);
};
// 高亮和描边
const handleDistrict = () => {
let districtSearch = new AMap.DistrictSearch({
subdistrict: 0, //获取边界不需要返回下级行政区
extensions: "all", //返回行政区边界坐标组等具体信息
level: "province", //查询行政级别为 市 province-省 district-市
});
let polygons = [];
districtSearch.search("中华人民共和国", function (status, result) {
map.remove(polygons); //清除上次结果
let bounds = result.districtList[0].boundaries;
// 描边
for (let i = 0; i < bounds.length; i++) {
let outerPolyline = new AMap.Polyline({
path: bounds[i],
strokeColor: "#72A8FF",
strokeWeight: 3,
map: map,
});
map.add(outerPolyline);
}
map.add(polygons);
map.setFitView(polygons); //视口自适应
});
};
// 添加新路线
const addPolylines = () => {
let geojsonObj = new AMap.GeoJSON({
geoJSON: gansuLine,
getPolyline: function (geojson, lnglats) {
// 生成路线
let polylineObj = new AMap.Polyline({
path: lnglats,
strokeWeight: 4,
strokeColor: "#F0E82A",
extData: geojson.properties, // 自定义属性数据
});
// 生成新的路线,用于覆盖旧的
const newPolyline = new AMap.Polyline({
path: lnglats,
strokeWeight: 4,
strokeColor: "#00DDEB",
isOutline: true,
borderWeight: 2,
outlineColor: "rgba(0, 221, 235, 1)",
cursor: "pointer",
});
map.add(newPolyline);
newPolyline.hide();
// 获取路线数据
const properties = polylineObj.getExtData();
// 填报内容
let content = `
<div class="infoWindow-title">项目OOI</div>
<div class="infoWindow-content">
<p>
<span class="infoWindow-content-title">数据01:</span>
<span class="infoWindow-content-value">${properties.amount}<span class="infoWindow-unit">单位</span></span>
</p>
<p>
<span class="infoWindow-content-title">数据02:</span>
<span class="infoWindow-content-value">${properties.amount}<span class="infoWindow-unit">单位</span></span>
</p>
<p>
<span class="infoWindow-content-title">数据03:</span>
<span class="infoWindow-content-value">${properties.amount}<span class="infoWindow-unit">单位</span></span>
</p>
</div>
<div class="infoWindow-bottom"></div>
`;
// 创建 infoWindow 实例
let infoWindow = new AMap.InfoWindow({
isCustom: true, // 使用自定义窗体
autoMove: true, // 是否自动调整窗体到视野内
closeWhenClickMap: true, // 控制是否在鼠标点击地图后关闭信息窗体
content: content, // 传入 dom 对象,或者 html 字符串
offset: new AMap.Pixel(120, 100),
});
// 鼠标经过
polylineObj.on("mouseover", function (e) {
newPolyline.show();
infoWindow.open(map, [`${e.lnglat.getLng()}`, `${e.lnglat.getLat()}`]);
});
// 鼠标移出
polylineObj.on("mouseout", function (e) {
newPolyline.hide();
infoWindow.close();
});
// 鼠标双击
polylineObj.on("dblclick", function (e) {});
return polylineObj;
}, },
]); });
</script> map.add(geojsonObj);
};
// 添加标记
let currentMarkers = []; // 存储当前显示的标记
const handleAddMarket = (selectName) => {
// 清除之前的所有标记
if (currentMarkers.length > 0) {
map.remove(currentMarkers);
currentMarkers = [];
}
<style scoped lang="less"> // 额外确保清除所有标记(防止其他地方创建的标记)
.construct-container { if (map) {
display: flex; map.getAllOverlays("marker").forEach((marker) => {
.construct-left { map.remove(marker);
width: 100%; });
height: 100%;
.tag-image {
img {
.vw(width, 85);
} }
// 根据不同状态定义标记数据
const markerData = {
建设: [
// 安徽
{ number: 1, position: [117.27, 31.86], province: "安徽省" },
// 广东
{ number: 1, position: [113.2644, 23.1291], province: "广东省" },
// 陕西
{ number: 2, position: [108.948, 34.2632], province: "陕西省" },
// 广西
{ number: 2, position: [108.32, 22.824], province: "广西壮族自治区" },
// 山东
{ number: 2, position: [117.0009, 36.6758], province: "山东省" },
// 河北
{ number: 1, position: [114.5025, 38.0455], province: "河北省" },
],
试运营: [
// 四川
{ number: 2, position: [104.066, 30.5728], province: "四川省" },
// 山东
{ number: 3, position: [117.0009, 36.6758], province: "山东省" },
// 云南
{ number: 1, position: [102.7123, 25.0406], province: "云南省" },
// 陕西
{ number: 3, position: [108.948, 34.2632], province: "陕西省" },
// 广西
{ number: 1, position: [108.32, 22.824], province: "广西壮族自治区" },
// 湖北
{ number: 1, position: [114.2986, 30.5844], province: "湖北省" },
],
运营: [
// 四川
{ number: 1, position: [104.066, 30.5728], province: "四川省" },
// 山东
{ number: 1, position: [117.0009, 36.6758], province: "山东省" },
// 湖北
{ number: 1, position: [114.2986, 30.5844], province: "湖北省" },
],
退出: [
// 河南
{ number: 3, position: [113.6654, 34.757], province: "河南省" },
],
// 立项: [],
};
const positionsList = markerData[selectName] || [];
// 如果是"立项"或者没有数据,直接返回,不创建任何标记
if (!positionsList || positionsList.length === 0) {
return;
} }
.construct-left-map {
.vh(height, 700); // 创建新的标记
.vh(padding-top, 4); for (var i = 0; i < positionsList.length; i++) {
const markerData = positionsList[i];
// 创建悬浮窗口内容
const infoContent = `
<div class="marker-info-window">
<div class="marker-info-title">${markerData.province}</div>
<div class="marker-info-content">
<span class="marker-info-label">路线数量:</span>
<span class="marker-info-value">${markerData.number}</span>
<span class="marker-info-unit">条</span>
</div>
</div>
`;
// 创建信息窗口实例
const infoWindow = new AMap.InfoWindow({
isCustom: true,
content: infoContent,
offset: new AMap.Pixel(0, -35),
closeWhenClickMap: true,
});
const marker = new AMap.Marker({
map: map,
position: markerData.position,
offset: new AMap.Pixel(-13, -30),
content:
'<div class="custom-content-marker">' +
'<img src="//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png" style="width: 40px;height: 40px;">' +
`<div class="anchorPoint">${markerData.number}</div>` +
"</div>",
});
// 鼠标悬浮事件
marker.on("mouseover", function (e) {
infoWindow.open(map, e.lnglat);
});
// 鼠标移出事件
marker.on("mouseout", function () {
infoWindow.close();
});
currentMarkers.push(marker);
} }
};
// 暴露更新标记的方法给父组件
const updateMarkers = (selectName) => {
handleAddMarket(selectName);
};
// 重置地图到初始状态
const resetMap = () => {
if (map) {
map.setZoom(4);
map.setCenter([100.808299, 35.791787]);
} }
.construct-right { };
display: flex;
flex-direction: column; // 暴露方法给父组件
justify-content: space-between; defineExpose({
.info-title { updateMarkers,
.vw(width, 180); resetMap,
.vh(height, 30); });
.vh(line-height, 30); onMounted(() => {
.font(16); handleInitMap();
.vw(padding-left,20); // 监听窗口大小变化
.vh(margin-bottom,15); window.addEventListener("resize", handleResize);
.vh(margin-top,15); });
text-align: left;
color: #fff; // 处理窗口大小变化
white-space: nowrap; const handleResize = () => {
font-family: YouSheBiaoTiYuan; if (map) {
background-image: url("@/assets/images/tag.png"); map.resize();
}
};
// 组件卸载时移除事件监听
onUnmounted(() => {
window.removeEventListener("resize", handleResize);
});
// 组件从keep-alive缓存中激活时触发
onActivated(() => {
// 确保地图容器已经渲染完成
nextTick(() => {
// 获取地图容器元素
const container = document.getElementById("container");
// 如果容器存在,设置明确的尺寸和初始样式
if (container) {
container.style.width = "100%";
container.style.height = "100%";
container.style.opacity = "0"; // 初始设置为透明
container.style.transition = "opacity 0.5s ease-in-out"; // 添加过渡效果
}
// 无论地图实例是否存在,都重新显示遮罩层并延迟加载地图
showLoading.value = true;
// 清除之前可能存在的定时器
if (window.mapTimer) {
clearTimeout(window.mapTimer);
}
// 延迟300毫秒后重新初始化地图
window.mapTimer = setTimeout(() => {
// 如果地图实例已存在,先清除它
if (map) {
map.destroy();
map = null;
}
// 重新初始化地图
handleInitMap();
}, 300);
});
});
</script>
<style scoped lang="less">
.tourism {
width: 100%;
height: 100%;
}
#container {
width: 100%;
height: 100%;
}
.custom-content-marker {
position: relative;
width: 25px;
height: 34px;
}
:deep(.infoWindow-title) {
background-image: url("../assets/images/标题.png");
background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover;
background-position: center; background-position: center;
width: 299px;
line-height: 56px;
padding-left: 10px;
font-weight: 700;
}
:deep(.infoWindow-content) {
background-image: url("../assets/images/信息文本.png");
background-size: 100% 100%; background-size: 100% 100%;
} background-repeat: no-repeat;
} background-position: center;
width: 299px;
height: 100x;
padding-left: 10px;
padding-top: 5px;
padding-bottom: 5px;
}
:deep(.infoWindow-bottom) {
background-image: url("../assets/images/下标.png");
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
margin-top: 1px;
height: 22px;
}
:deep(.infoWindow-content-title) {
font-size: 18px;
color: #fff;
font-weight: 400;
}
:deep(.infoWindow-content-value) {
font-weight: 400;
font-size: 24px;
color: #93d2ff;
}
:deep(.infoWindow-unit) {
font-size: 20px;
color: #93d2ff;
display: inline-block;
margin-left: 3px;
}
:deep(.anchorPoint) {
position: absolute;
color: #fff;
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
}
// 标记悬浮窗口样式
:deep(.marker-info-window) {
background: #04427e;
border: 1px solid #00ddeb;
border-radius: 6px;
padding: 8px 12px;
box-shadow: 0 2px 8px rgba(0, 221, 235, 0.3);
backdrop-filter: blur(4px);
min-width: 120px;
}
:deep(.marker-info-title) {
font-size: 14px;
font-weight: 600;
color: #fff;
margin-bottom: 4px;
border-bottom: 1px solid rgba(0, 221, 235, 0.3);
padding-bottom: 2px;
}
:deep(.marker-info-content) {
display: flex;
align-items: center;
gap: 4px;
}
:deep(.marker-info-label) {
font-size: 12px;
color: #93d2ff;
font-weight: 400;
}
:deep(.marker-info-value) {
font-size: 16px;
font-weight: 600;
color: #00ddeb;
}
:deep(.marker-info-unit) {
font-size: 12px;
color: #93d2ff;
margin-left: 2px;
}
.amap-container {
background: none;
}
:deep(.amap-logo) {
display: none;
opacity: 0 !important;
}
:deep(.amap-copyright) {
opacity: 0;
} }
</style> </style>
...@@ -34,9 +34,7 @@ ...@@ -34,9 +34,7 @@
融资建设投资 融资建设投资
</div> </div>
</div> </div>
</div> <div class="header-fullscreen">
<div class="content">
<div class="fullscreen-btn">
<span @click="toggleFullscreen" class="fullscreen-text"> <span @click="toggleFullscreen" class="fullscreen-text">
<el-icon :size="18"> <el-icon :size="18">
<full-screen /> <full-screen />
...@@ -44,6 +42,8 @@ ...@@ -44,6 +42,8 @@
{{ isFullscreen ? "退出全屏" : "全屏" }} {{ isFullscreen ? "退出全屏" : "全屏" }}
</span> </span>
</div> </div>
</div>
<div class="content">
<div class="content-btn"> <div class="content-btn">
<span <span
v-for="item in navList" v-for="item in navList"
...@@ -56,11 +56,21 @@ ...@@ -56,11 +56,21 @@
<keep-alive include="ProjectApproval,Construct,Operation,TrialOperations"> <keep-alive include="ProjectApproval,Construct,Operation,TrialOperations">
<ProjectApproval <ProjectApproval
:currentName="selectedContentName" :currentName="selectedContentName"
:isFullscreen="isFullscreen"
v-if="selectedContentBtn === 1 || selectedContentBtn === 6" v-if="selectedContentBtn === 1 || selectedContentBtn === 6"
/> />
<Construct v-else-if="selectedContentBtn === 2" /> <Construct
<Operation v-else-if="selectedContentBtn === 4" /> :isFullscreen="isFullscreen"
<TrialOperations v-else-if="selectedContentBtn === 3" /> v-else-if="selectedContentBtn === 2"
/>
<Operation
:isFullscreen="isFullscreen"
v-else-if="selectedContentBtn === 4"
/>
<TrialOperations
:isFullscreen="isFullscreen"
v-else-if="selectedContentBtn === 3"
/>
</keep-alive> </keep-alive>
</div> </div>
<div class="bottom"></div> <div class="bottom"></div>
...@@ -133,23 +143,6 @@ const selectContentBtn = (item) => { ...@@ -133,23 +143,6 @@ const selectContentBtn = (item) => {
}, 100); }, 100);
}; };
// 暂时注释未使用的函数,避免lint警告
// const showProjectPopup = (event) => {
// currentProject.value = {
// name: "项目001",
// data: [
// { label: "数据01", value: "3654.89", unit: "单位" },
// { label: "数据02", value: "3654.89", unit: "单位" },
// { label: "数据03", value: "3654.89", unit: "单位" },
// ],
// };
// popupStyle.value = {
// left: `${event.clientX}px`,
// top: `${event.clientY - 100}px`,
// };
// showPopup.value = true;
// };
// 全屏切换功能 // 全屏切换功能
const toggleFullscreen = () => { const toggleFullscreen = () => {
const homeContainer = document.querySelector(".home-container"); const homeContainer = document.querySelector(".home-container");
...@@ -165,6 +158,8 @@ const toggleFullscreen = () => { ...@@ -165,6 +158,8 @@ const toggleFullscreen = () => {
} }
homeContainer.style.height = "100%"; homeContainer.style.height = "100%";
// 移除全屏类
homeContainer.classList.remove("fullscreen");
} else { } else {
// 进入全屏 // 进入全屏
if (homeContainer.requestFullscreen) { if (homeContainer.requestFullscreen) {
...@@ -176,6 +171,8 @@ const toggleFullscreen = () => { ...@@ -176,6 +171,8 @@ const toggleFullscreen = () => {
} }
homeContainer.style.height = "100vh"; homeContainer.style.height = "100vh";
// 添加全屏类
homeContainer.classList.add("fullscreen");
} }
isFullscreen.value = !isFullscreen.value; isFullscreen.value = !isFullscreen.value;
...@@ -188,14 +185,22 @@ onMounted(() => { ...@@ -188,14 +185,22 @@ onMounted(() => {
// 监听全屏变化事件 // 监听全屏变化事件
window.addEventListener("fullscreenchange", () => { window.addEventListener("fullscreenchange", () => {
const homeContainer = document.querySelector(".home-container");
if (!document.fullscreenElement) { if (!document.fullscreenElement) {
isFullscreen.value = false; isFullscreen.value = false;
const homeContainer = document.querySelector(".home-container"); if (homeContainer) {
if (homeContainer) homeContainer.style.height = "100%"; homeContainer.style.height = "100%";
// 移除全屏类
homeContainer.classList.remove("fullscreen");
}
} else { } else {
isFullscreen.value = true; isFullscreen.value = true;
const homeContainer = document.querySelector(".home-container"); if (homeContainer) {
if (homeContainer) homeContainer.style.height = "100vh"; homeContainer.style.height = "100vh";
// 添加全屏类
homeContainer.classList.add("fullscreen");
}
} }
}); });
</script> </script>
...@@ -208,7 +213,7 @@ window.addEventListener("fullscreenchange", () => { ...@@ -208,7 +213,7 @@ window.addEventListener("fullscreenchange", () => {
// background-position: center; // background-position: center;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: linear-gradient(to bottom, #04427E, #095DCC); background: linear-gradient(to bottom, #04427e, #095dcc);
overflow: hidden; overflow: hidden;
color: #fff; color: #fff;
display: flex; display: flex;
...@@ -220,16 +225,31 @@ window.addEventListener("fullscreenchange", () => { ...@@ -220,16 +225,31 @@ window.addEventListener("fullscreenchange", () => {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: flex-end; align-items: flex-end;
position: relative; // 为绝对定位提供参考
.header-fullscreen {
position: absolute;
right: 20px;
bottom: 0; // 与导航按钮底部对齐
cursor: pointer;
span {
color: white;
font-weight: 700;
.font(14);
display: flex;
align-items: center;
gap: 6px;
}
}
.header-middile { .header-middile {
background-image: url("@/assets/images/头部bg.png"); background-image: url("@/assets/images/头部bg.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
// background-size: 170% 100%;
background-size: cover; background-size: cover;
letter-spacing: 1px; letter-spacing: 1px;
font-weight: 400; font-weight: 400;
font-family: "YouSheBiaoTiHei"; font-family: "YouSheBiaoTiHei";
// .vw(width,950);
.vh(height,75); .vh(height,75);
display: flex; display: flex;
justify-content: center; justify-content: center;
...@@ -247,11 +267,6 @@ window.addEventListener("fullscreenchange", () => { ...@@ -247,11 +267,6 @@ window.addEventListener("fullscreenchange", () => {
.font(24); .font(24);
flex: 0.8; flex: 0.8;
} }
// @media screen and (max-width: 1280px) {
// flex: 0.4;
// .font(20);
// }
} }
.header-left { .header-left {
display: flex; display: flex;
...@@ -307,13 +322,37 @@ window.addEventListener("fullscreenchange", () => { ...@@ -307,13 +322,37 @@ window.addEventListener("fullscreenchange", () => {
} }
} }
.content { .content {
flex: 1; width: 100%;
.vw(padding-left, 20); .vw(padding-left, 20);
.vw(padding-right, 20); .vw(padding-right, 20);
.vh(margin-top,-16px); .vh(margin-top,-16px);
height: calc(100vh - 190px);
// 根据屏幕宽度调整高度,确保在不同尺寸下都能显示底部图标
@media screen and (max-width: 1450px) {
height: calc(100vh - 180px);
}
@media screen and (max-width: 1280px) {
height: calc(100vh - 170px);
}
// 全屏模式下的高度调整
.fullscreen & {
height: calc(100vh - 120px);
@media screen and (max-width: 1450px) {
height: calc(100vh - 110px);
}
@media screen and (max-width: 1280px) {
height: calc(100vh - 100px);
}
@media screen and (max-width: 1920px) {
height: calc(100vh - 80px);
}
}
.content-btn { .content-btn {
// .vh(margin-top,0);
// .vh(margin-bottom,20);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
...@@ -326,7 +365,7 @@ window.addEventListener("fullscreenchange", () => { ...@@ -326,7 +365,7 @@ window.addEventListener("fullscreenchange", () => {
justify-content: center; justify-content: center;
cursor: pointer; cursor: pointer;
flex-shrink: 0; flex-shrink: 0;
color: #fff; // 补充文字颜色(匹配蓝色按钮的白色文字) color: #fff;
} }
// 立项按钮 // 立项按钮
...@@ -394,18 +433,5 @@ window.addEventListener("fullscreenchange", () => { ...@@ -394,18 +433,5 @@ window.addEventListener("fullscreenchange", () => {
width: 100%; width: 100%;
.vh(height, 110); .vh(height, 110);
} }
.fullscreen-btn {
display: flex;
cursor: pointer;
span {
margin-left: auto;
color: white;
font-weight: 700;
.font(16);
display: flex;
align-items: center;
gap: 6px;
}
}
} }
</style> </style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment