|
@@ -6,18 +6,6 @@
|
|
<button @click="zoomOut">缩小</button>
|
|
<button @click="zoomOut">缩小</button>
|
|
<button @click="toggleMapType">切换地图类型({{ mapType === 'BMAP_NORMAL_MAP' ? '地图' : '卫星' }})</button>
|
|
<button @click="toggleMapType">切换地图类型({{ mapType === 'BMAP_NORMAL_MAP' ? '地图' : '卫星' }})</button>
|
|
</div>
|
|
</div>
|
|
- <div v-if="selectedDevice" class="device-info-dialog" :style="{ left: dialogLeft + 'px', top: dialogTop + 'px' }">
|
|
|
|
- <div class="dialog-header">
|
|
|
|
- <h3>设备详情</h3>
|
|
|
|
- <button @click="closeDeviceInfo">×</button>
|
|
|
|
- </div>
|
|
|
|
- <div class="dialog-content">
|
|
|
|
- <p><strong>设备ID:</strong> {{ selectedDevice.id }}</p>
|
|
|
|
- <p><strong>设备名称:</strong> {{ selectedDevice.name }}</p>
|
|
|
|
- <p><strong>位置:</strong> {{ selectedDevice.location }}</p>
|
|
|
|
- <p><strong>状态:</strong> {{ deviceStatusMap[selectedDevice.status] }}</p>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
@@ -49,8 +37,6 @@ export default defineComponent({
|
|
const selectedDevice = ref<Device | null>(null);
|
|
const selectedDevice = ref<Device | null>(null);
|
|
const hoverDevice = ref<Device | null>(null);
|
|
const hoverDevice = ref<Device | null>(null);
|
|
const clusters = ref<Cluster[]>([]);
|
|
const clusters = ref<Cluster[]>([]);
|
|
- const dialogLeft = ref<number>(0);
|
|
|
|
- const dialogTop = ref<number>(0);
|
|
|
|
|
|
|
|
// 设备数据示例
|
|
// 设备数据示例
|
|
const devices = ref<Device[]>([
|
|
const devices = ref<Device[]>([
|
|
@@ -94,14 +80,7 @@ export default defineComponent({
|
|
initDeviceMarkers();
|
|
initDeviceMarkers();
|
|
map.value.addEventListener('zoomend', () => {
|
|
map.value.addEventListener('zoomend', () => {
|
|
initDeviceMarkers();
|
|
initDeviceMarkers();
|
|
- if (selectedDevice.value) {
|
|
|
|
- const point = new (window as any).BMap.Point(selectedDevice.value.lng, selectedDevice.value.lat);
|
|
|
|
- showDeviceInfo(selectedDevice.value, point);
|
|
|
|
- }
|
|
|
|
});
|
|
});
|
|
-
|
|
|
|
- // 添加地图点击事件监听器
|
|
|
|
- map.value.addEventListener('click', closeDeviceInfoIfOutside);
|
|
|
|
} else {
|
|
} else {
|
|
console.error('百度地图API加载失败');
|
|
console.error('百度地图API加载失败');
|
|
}
|
|
}
|
|
@@ -159,17 +138,7 @@ export default defineComponent({
|
|
|
|
|
|
// 添加点击事件
|
|
// 添加点击事件
|
|
marker.addEventListener('click', () => {
|
|
marker.addEventListener('click', () => {
|
|
- showDeviceInfo(device, point);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- // 添加鼠标悬停事件
|
|
|
|
- marker.addEventListener('mouseover', () => {
|
|
|
|
- hoverDevice.value = device;
|
|
|
|
- showDeviceInfo(device, point);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- marker.addEventListener('mouseout', () => {
|
|
|
|
- hoverDevice.value = null;
|
|
|
|
|
|
+ showDeviceInfoWindow(device, point);
|
|
});
|
|
});
|
|
|
|
|
|
return marker;
|
|
return marker;
|
|
@@ -265,47 +234,20 @@ export default defineComponent({
|
|
return 0.1;
|
|
return 0.1;
|
|
};
|
|
};
|
|
|
|
|
|
- const showDeviceInfo = (device: Device, point: any) => {
|
|
|
|
- selectedDevice.value = device;
|
|
|
|
- const pixel = map.value.pointToOverlayPixel(point);
|
|
|
|
- const dialogWidth = 300; // 对话框宽度
|
|
|
|
- const arrowWidth = 10; // 箭头宽度
|
|
|
|
- const arrowHeight = 10; // 箭头高度
|
|
|
|
-
|
|
|
|
- // 计算对话框的左偏移量,使箭头居中指向设备
|
|
|
|
- dialogLeft.value = pixel.x - dialogWidth / 2;
|
|
|
|
-
|
|
|
|
- // 计算对话框的上偏移量,使箭头指向设备
|
|
|
|
- dialogTop.value = pixel.y - arrowHeight;
|
|
|
|
-
|
|
|
|
- // 确保对话框不会超出地图边界
|
|
|
|
- if (dialogLeft.value < 0) {
|
|
|
|
- dialogLeft.value = 0;
|
|
|
|
- }
|
|
|
|
- if (dialogTop.value < 0) {
|
|
|
|
- dialogTop.value = 0;
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- const closeDeviceInfo = () => {
|
|
|
|
- selectedDevice.value = null;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- const closeDeviceInfoIfOutside = (e: any) => {
|
|
|
|
- const dialogElement = document.querySelector('.device-info-dialog');
|
|
|
|
- if (dialogElement && selectedDevice.value) {
|
|
|
|
- const rect = dialogElement.getBoundingClientRect();
|
|
|
|
- const x = e.pixel.x;
|
|
|
|
- const y = e.pixel.y;
|
|
|
|
- if (
|
|
|
|
- x < rect.left ||
|
|
|
|
- x > rect.right ||
|
|
|
|
- y < rect.top ||
|
|
|
|
- y > rect.bottom
|
|
|
|
- ) {
|
|
|
|
- closeDeviceInfo();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ const showDeviceInfoWindow = (device: Device, point: any) => {
|
|
|
|
+ const content = `
|
|
|
|
+ <div>
|
|
|
|
+ <p><strong>设备ID:</strong> ${device.id}</p>
|
|
|
|
+ <p><strong>设备名称:</strong> ${device.name}</p>
|
|
|
|
+ <p><strong>位置:</strong> ${device.location}</p>
|
|
|
|
+ <p><strong>状态:</strong> ${deviceStatusMap[device.status]}</p>
|
|
|
|
+ </div>
|
|
|
|
+ `;
|
|
|
|
+ const infoWindow = new (window as any).BMap.InfoWindow(content, {
|
|
|
|
+ width: 300,
|
|
|
|
+ height: 150
|
|
|
|
+ });
|
|
|
|
+ map.value.openInfoWindow(infoWindow, point);
|
|
};
|
|
};
|
|
|
|
|
|
const zoomIn = () => {
|
|
const zoomIn = () => {
|
|
@@ -346,11 +288,7 @@ export default defineComponent({
|
|
deviceStatusMap,
|
|
deviceStatusMap,
|
|
zoomIn,
|
|
zoomIn,
|
|
zoomOut,
|
|
zoomOut,
|
|
- toggleMapType,
|
|
|
|
- showDeviceInfo,
|
|
|
|
- closeDeviceInfo,
|
|
|
|
- dialogLeft,
|
|
|
|
- dialogTop
|
|
|
|
|
|
+ toggleMapType
|
|
};
|
|
};
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -384,45 +322,4 @@ export default defineComponent({
|
|
border-radius: 3px;
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
-
|
|
|
|
-.device-info-dialog {
|
|
|
|
- position: absolute;
|
|
|
|
- z-index: 1000;
|
|
|
|
- width: 300px;
|
|
|
|
- background: #fff;
|
|
|
|
- border-radius: 5px;
|
|
|
|
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
|
|
|
- padding: 15px;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-.dialog-header {
|
|
|
|
- display: flex;
|
|
|
|
- justify-content: space-between;
|
|
|
|
- align-items: center;
|
|
|
|
- margin-bottom: 10px;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-.dialog-header button {
|
|
|
|
- background: none;
|
|
|
|
- border: none;
|
|
|
|
- font-size: 18px;
|
|
|
|
- cursor: pointer;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-.dialog-content p {
|
|
|
|
- margin: 5px 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* 箭头样式 */
|
|
|
|
-.dialog-arrow {
|
|
|
|
- position: absolute;
|
|
|
|
- bottom: -10px; /* 调整箭头的垂直位置 */
|
|
|
|
- left: 50%; /* 使箭头水平居中 */
|
|
|
|
- transform: translateX(-50%); /* 使箭头水平居中 */
|
|
|
|
- width: 0;
|
|
|
|
- height: 0;
|
|
|
|
- border-left: 10px solid transparent;
|
|
|
|
- border-right: 10px solid transparent;
|
|
|
|
- border-top: 10px solid #fff; /* 箭头颜色与对话框背景色一致 */
|
|
|
|
-}
|
|
|
|
</style>
|
|
</style>
|