You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
9.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="container">
<!-- 内容区域 -->
<div class="main-content">
<!-- 地图容器 -->
<div class="map-thumbnail">
<div id="mars2dContainerLuotu" class="mars2d-container"></div>
</div>
<!-- 悬浮的点位信息 div -->
<div class="floating-panel" v-if="floatingPanelVisible">
<div class="panel-header">
<span>{{ pointDialogTitle }}</span>
<el-button type="text" @click="hideFloatingPanel" class="close-button">关闭</el-button>
</div>
<div class="panel-body">
<el-form :model="pointForm" label-width="100px">
<el-form-item label="项目名称">
<el-input v-model="pointForm.name" ref="pointNameInput"></el-input>
</el-form-item>
<el-form-item label="纬度">
<el-input v-model="pointForm.lat" readonly></el-input>
</el-form-item>
<el-form-item label="经度">
<el-input v-model="pointForm.lng" readonly></el-input>
</el-form-item>
</el-form>
</div>
<div class="panel-footer">
<el-button @click="hideFloatingPanel">取消</el-button>
<el-button v-if="!isEditing" type="primary" @click="addPoint">确认</el-button>
<el-button v-else type="danger" @click="deletePoint"></el-button>
</div>
</div>
</div>
</div>
</template>
<script>
import 'mars2d/mars2d.css';
import * as mars2d from 'mars2d';
export default {
components: {},
dicts: ['tplx'],
data() {
const basePathUrl = window.basePathUrl || "";
return {
configUrl: basePathUrl + "config/config.json",
mapOptions: {
// 配置文档http://mars2d.cn/apidoc.html#Map
copyright: false, // 不显示厂商logo
basemaps: [
{
"id": 2021,
"pid": 10,
"name": "高德电子",
"icon": "img/basemaps/gaode_vec.png",
"type": "gaode",
"layer": "vec",
"show": true
},
],
center: { lat: 31.2304, lng: 120.6184 }, // 中心点
zoom: 10, // 设置地图缩放级别
},
// 对话框相关
dialogVisible: false,
dialogTitle: '编辑项目',
form: {
type: '外部', // 默认类型
},
map: null, // 地图实例
floatingPanelVisible: false, // 控制悬浮面板显示
pointDialogTitle: '新增点位', // 新增点位弹窗标题
pointForm: {
name: '',
lat: '',
lng: '',
},
selectedLatLng: null, // 选中的经纬度
existingMarker: null, // 存储已存在的点位标记
isEditing: false, // 标志变量,用于区分当前按钮状态
markerIcon: require('@/assets/images/detailsicon/icon-定位@2x.png'), // 使用 require 引入图片
};
},
methods: {
onload(map) {
// 地图组件构造完成
},
// 编辑操作
handleEdit() {
this.dialogTitle = '编辑项目';
this.dialogVisible = true;
// 填充表单数据
this.form = {
type: '外部', // 默认类型
};
},
// 提交表单
handleSubmit() {
this.dialogVisible = false;
// 调用 API 提交数据
},
// 初始化地图
initMap() {
if (!this.map) {
this.map = new mars2d.Map('mars2dContainerLuotu', this.mapOptions);
this.map.on('click', this.onMapClick);
}
},
// 地图点击事件
onMapClick(event) {
if (this.existingMarker) {
this.$message.warning('地图上已经存在一个点位,请先删除该点位后再添加新的点位。');
return;
}
const { latlng } = event;
this.selectedLatLng = latlng;
this.pointForm.lat = latlng.lat.toString();
this.pointForm.lng = latlng.lng.toString();
this.showFloatingPanel();
},
// 显示悬浮面板
showFloatingPanel() {
this.floatingPanelVisible = true;
this.$nextTick(() => {
this.$refs.pointNameInput.focus();
});
},
// 隐藏悬浮面板
hideFloatingPanel() {
this.floatingPanelVisible = false;
this.selectedLatLng = null;
this.pointForm.name = '';
this.pointForm.latlng = '';
},
// 新增点位
addPoint() {
if (this.selectedLatLng) {
if (this.existingMarker) {
this.map.graphicLayer.removeGraphic(this.existingMarker);
}
const marker = new mars2d.graphic.Marker({
latlng: this.selectedLatLng,
style: {
image: this.markerIcon, // 使用引入的图片路径
width: 32,
height: 32,
},
});
this.map.graphicLayer.addGraphic(marker);
this.existingMarker = marker;
this.isEditing = true; // 切换按钮状态
this.hideFloatingPanel();
this.$message.success('落图成功');
// 为点位添加点击事件监听器
marker.on('click', this.onMarkerClick);
}
},
// 删除点位
deletePoint() {
if (this.existingMarker) {
this.existingMarker.off('click', this.onMarkerClick); // 移除点击事件监听器
this.map.graphicLayer.removeGraphic(this.existingMarker);
this.existingMarker = null;
this.isEditing = false; // 切换按钮状态
this.hideFloatingPanel();
this.$message.success('点位已删除');
}
},
// 点击点位图标时显示悬浮面板
onMarkerClick(event) {
this.pointForm.name = this.existingMarker.name || '';
this.pointForm.latlng = `${this.existingMarker.latlng.lat}, ${this.existingMarker.latlng.lng}`;
this.showFloatingPanel();
},
},
mounted() {
this.initMap(); // 直接初始化地图
},
};
</script>
<style scoped>
.container {
display: flex;
flex-direction: column;
width: 100%;
background-color: #FFFFFF;
box-shadow: 0rem 0.13rem 0.63rem 0rem rgba(177, 177, 177, 0.1);
border-radius: 0.5rem 0.5rem 0.5rem 0.5rem;
gap: 1rem;
overflow: auto;
position: relative;
}
.containertop {
height: auto;
display: flex;
justify-content: space-between;
padding: .5rem;
border-bottom: 1px solid #E5E5E5;
}
.action-bar {
margin-bottom: 20px;
}
.carousel-container {
display: flex;
flex-direction: column;
gap: 1rem;
}
.carousel {
width: 21rem;
height: 12rem;
overflow: hidden;
}
.carousel-item {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
.carousel-item img {
width: 100%;
height: 100%;
object-fit: cover;
}
.carousel-item.active {
opacity: 1;
}
.carousel-control {
position: absolute;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
font-size: 1.5rem;
color: white;
padding: 0.5rem;
z-index: 10;
}
.carousel-control.left {
left: 0;
}
.carousel-control.right {
right: 0;
}
.topleft {
width: 8rem;
display: flex;
gap: 0.4rem;
align-items: center;
}
.topleft img {
width: 0.81rem;
height: 0.81rem;
}
.topleft span {
width: auto;
height: 0.88rem;
font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;
font-weight: 500;
font-size: 0.88rem;
color: #3D424C;
line-height: 0.88rem;
text-align: right;
font-style: normal;
text-transform: none;
}
.map-thumbnail {
width: 60rem;
height: 34rem;
position: relative;
}
.mars2d-container {
width: 60rem;
height: 34rem;
}
/* 悬浮面板样式 */
.floating-panel {
position: fixed;
top: 30%;
right: 25%;
width: 300px;
background-color: #FFFFFF;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-radius: 4px;
z-index: 1000;
display: flex;
flex-direction: column;
overflow: hidden;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 15px;
background-color: #F5F7FA;
border-bottom: 1px solid #E4E7ED;
}
.panel-header span {
font-size: 16px;
font-weight: 500;
}
.close-button {
font-size: 14px;
color: #909399;
}
.panel-body {
padding: 20px;
}
.panel-footer {
display: flex;
justify-content: flex-end;
padding: 10px 15px;
background-color: #F5F7FA;
border-top: 1px solid #E4E7ED;
}
.panel-footer .el-button {
margin-left: 10px;
}
</style>