|
|
<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> |