9 changed files with 670 additions and 568 deletions
-
2public/static/config.js
-
1src/assets/fengmap/v2/fengmap.analyzer.min.js
-
1src/assets/fengmap/v2/fengmap.control.min.js
-
2src/assets/fengmap/v2/fengmap.core.min.js
-
2src/assets/fengmap/v2/fengmap.navi.min.js
-
136src/views/deviceManage/map/index copy.vue
-
592src/views/deviceManage/map/index.vue
-
492src/views/deviceManage/map/indexv3.vue
-
10vue.config.js
1
src/assets/fengmap/v2/fengmap.analyzer.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
1
src/assets/fengmap/v2/fengmap.control.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2
src/assets/fengmap/v2/fengmap.core.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2
src/assets/fengmap/v2/fengmap.navi.min.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,136 +0,0 @@ |
|||
<template> |
|||
<div class="map-container"> |
|||
<div class="toolBarDiv" /> |
|||
<div id="fengmap" /> |
|||
|
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
// import fengmap from '@/assets/fengmapSDK/fengmap.map.min.js' |
|||
|
|||
import { FMMap } from '@/assets/fengmap/fengmap.map.min.js' |
|||
import { |
|||
FMControlPosition, |
|||
FMCompass, |
|||
FMZoomBar, |
|||
FMToolbar, |
|||
FMScaleBar |
|||
} from '@/assets/fengmap/fengmap.plugin.ui.min.js' |
|||
|
|||
// import '@/assets/fengmap/fengmap.plugin.ui.min' // UI控件包 |
|||
// import '@/assets/fengmap/fengmap.analyser.min' // 分析器包 |
|||
// import '@/assets/fengmapSDK/fengmap.plugin.navi.min' // 导航包 |
|||
// import '@/assets/fengmapSDK/fengmap.effect.min' // 特效包 |
|||
// import '@/assets/fengmapSDK/fengmap.plugin.markers.min' // 特殊标注包 |
|||
// import '@/assets/fengmapSDK/fengmap.plugin.draw.min' // 绘图包 |
|||
// import '@/assets/fengmapSDK/fengmap.plugin.location.min' // 位置服务相关功能包 |
|||
// import '@/assets/fengmapSDK/fengmap.plugin.export.min' // 打印/出图包 |
|||
// import '@/assets/fengmapSDK/fengmap.plugin.layers.min' // 附加图层包 |
|||
// import '@/assets/fengmapSDK/fengmap.plugin.debug.min' // 性能监控包 |
|||
// import '@/assets/fengmapSDK/fengmap.plugin.fusion.min' // 数据融合信息工具包 |
|||
// import '@/assets/fengmapSDK/fengmap.plugin.loader.min' // JS外部模型/FBX动态模型加载器插件包 |
|||
export default { |
|||
name: 'FengmapComponent', |
|||
data() { |
|||
return { |
|||
map: null, // 地图实例 |
|||
marker: null // 标记点实例 |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.initMap() |
|||
}, |
|||
beforeDestroy() { |
|||
if (this.map) { |
|||
this.map.destroy() |
|||
this.map = null |
|||
} |
|||
}, |
|||
methods: { |
|||
// 初始化地图 |
|||
initMap() { |
|||
const mapOptions = { |
|||
container: document.getElementById('fengmap'), |
|||
appName: '武汉东西湖图书馆', |
|||
key: 'd0ebc0507c72e6fb8598a3e58517f9d3', |
|||
mapID: '1572162706543931393', |
|||
level: 3, |
|||
mapZoom: 19.5 |
|||
|
|||
} |
|||
|
|||
// 创建地图实例 |
|||
this.map = new FMMap(mapOptions) |
|||
|
|||
this.map.on('loaded', function() { |
|||
// 指北针控件 |
|||
const scrollCompassCtlOpt = { |
|||
position: FMControlPosition.RIGHT_TOP, |
|||
offset: { |
|||
x: -20, |
|||
y: 80 |
|||
} |
|||
|
|||
} |
|||
const compass = new FMCompass(scrollCompassCtlOpt) |
|||
compass.addTo(this.map) |
|||
|
|||
compass.on('click', function() { |
|||
this.map.setRotation({ |
|||
rotation: 0, |
|||
animate: true, |
|||
duration: 0.3, |
|||
finish: function() { console.log('setRotation') } |
|||
}) |
|||
}) |
|||
|
|||
// 缩放控件 |
|||
const scrollZoomCtlOpt = { |
|||
position: FMControlPosition.RIGHT_TOP, |
|||
offset: { |
|||
x: -20, |
|||
y: 600 |
|||
} |
|||
|
|||
} |
|||
const toolbar = new FMZoomBar(scrollZoomCtlOpt) |
|||
toolbar.addTo(this.map) |
|||
|
|||
// 楼层控件 |
|||
const scrollFloorCtlOpt = { |
|||
position: FMControlPosition.RIGHT_TOP, |
|||
floorButtonCount: 5, |
|||
offset: { |
|||
x: -20, |
|||
y: 150 |
|||
}, |
|||
viewModeControl: true, |
|||
floorModeControl: true, |
|||
needAllLayerBtn: true |
|||
|
|||
} |
|||
const scrollFloorControl = new FMToolbar(scrollFloorCtlOpt) |
|||
scrollFloorControl.addTo(this.map) |
|||
|
|||
// 比例尺控件 |
|||
const scrollScaleBarCtlOpt = { |
|||
fontSize: 18, |
|||
height: 30, |
|||
position: FMControlPosition.LEFT_BOTTOM, |
|||
offset: { |
|||
x: 20, |
|||
y: -20 |
|||
} |
|||
|
|||
} |
|||
const scaleBar = new FMScaleBar(scrollScaleBarCtlOpt) |
|||
scaleBar.addTo(this.map) |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
|||
@ -0,0 +1,492 @@ |
|||
<template> |
|||
<div class="app-container"> |
|||
<div id="fengmap" /> |
|||
<div class="toolBarDiv" /> |
|||
<div class="rightMask" /> |
|||
<div id="info" class="info" /> |
|||
<!-- <div v-if="debugInfo" class="debug-info"> |
|||
<pre>{{ debugInfo }}</pre> |
|||
</div> --> |
|||
<!-- <div class="control-panel"> |
|||
<div class="button-group"> |
|||
<el-button type="primary" @click="startTracking(0)">定位点1</el-button> |
|||
<el-button type="success" @click="startTracking(1)">定位点2</el-button> |
|||
<el-button type="warning" @click="startTracking(2)">定位点3</el-button> |
|||
<el-button type="danger" @click="stopAllTracking">停止所有</el-button> |
|||
</div> |
|||
<div class="tracking-info"> |
|||
<div v-for="(marker, index) in markers" :key="index" class="marker-status"> |
|||
<span :style="{ color: getMarkerColor(index) }"> |
|||
定位点{{ index + 1 }}: {{ marker.active ? '追踪中' : '已停止' }} |
|||
<template v-if="marker.remainTime > 0">({{ marker.remainTime }}s)</template> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
</div> --> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import fengmap from '@/assets/fengmap/fengmap.map.min' |
|||
import { FMControlPosition, FMCompass, FMZoomBar, FMToolbar, FMScaleBar } from '@/assets/fengmap/fengmap.plugin.ui.min.js' |
|||
import { FMSearchRequest, FMSearchAnalyser } from '@/assets/fengmap/fengmap.analyser.min' |
|||
import '@/assets/fengmap/fengmap.effect.min' |
|||
|
|||
export default { |
|||
name: 'FengNiaoYun', |
|||
data() { |
|||
return { |
|||
map: null, |
|||
markers: [ |
|||
{ marker: null, timer: null, remainTimer: null, remainTime: 0, active: false, positions: [] }, |
|||
{ marker: null, timer: null, remainTimer: null, remainTime: 0, active: false, positions: [] }, |
|||
{ marker: null, timer: null, remainTimer: null, remainTime: 0, active: false, positions: [] } |
|||
], |
|||
level: null, |
|||
levels: null, |
|||
floorObj: {}, |
|||
analyser: null, |
|||
imageMarkers: null, |
|||
marker: null, |
|||
floorInfo: [], |
|||
|
|||
debugInfo: null, |
|||
markerColors: ['#409EFF', '#67C23A', '#E6A23C'] // 三个点的颜色 |
|||
} |
|||
}, |
|||
mounted() { |
|||
console.log('组件已挂载') |
|||
const container = document.getElementById('fengmap') |
|||
console.log('容器尺寸:', container.offsetWidth, container.offsetHeight) |
|||
this.$nextTick(() => { |
|||
this.initMap() |
|||
}) |
|||
}, |
|||
methods: { |
|||
initMap() { |
|||
try { |
|||
console.log('开始初始化地图') |
|||
const options = { |
|||
container: document.getElementById('fengmap'), |
|||
appName: '武汉东西湖图书馆', |
|||
key: 'd0ebc0507c72e6fb8598a3e58517f9d3', |
|||
mapID: '1572162706543931393', |
|||
// themeID: '1574346301450625025', |
|||
// mapURL: '/fengmap/data/', |
|||
// themeURL: '/fengmap/data/theme/', |
|||
// level: 3, |
|||
mapZoom: 20.2 |
|||
} |
|||
console.log('地图配置:', options) |
|||
|
|||
this.map = new fengmap.FMMap(options) |
|||
console.log('地图实例已创建') |
|||
|
|||
this.map.on('loadingProcess', (event) => { |
|||
console.log('加载进度:', event.progress) |
|||
this.debugInfo = `加载进度: ${event.progress}%` |
|||
}) |
|||
|
|||
this.map.on('loaded', () => { |
|||
console.log('地图加载完成') |
|||
this.debugInfo = '地图加载完成' |
|||
this.map.setViewMode(fengmap.FMViewMode.MODE_3D) |
|||
|
|||
// 指北针控件 |
|||
const scrollCompassCtlOpt = { |
|||
position: FMControlPosition.RIGHT_TOP, |
|||
offset: { |
|||
x: -20, |
|||
y: 80 |
|||
} |
|||
|
|||
} |
|||
const compass = new FMCompass(scrollCompassCtlOpt) |
|||
compass.addTo(this.map) |
|||
|
|||
compass.on('click', function() { |
|||
this.map.setRotation({ |
|||
rotation: 0, |
|||
animate: true, |
|||
duration: 0.3, |
|||
finish: function() { console.log('setRotation') } |
|||
}) |
|||
}) |
|||
|
|||
// 缩放控件 |
|||
const scrollZoomCtlOpt = { |
|||
position: FMControlPosition.RIGHT_TOP, |
|||
offset: { |
|||
x: -20, |
|||
y: 600 |
|||
} |
|||
|
|||
} |
|||
const toolbar = new FMZoomBar(scrollZoomCtlOpt) |
|||
toolbar.addTo(this.map) |
|||
|
|||
// 楼层控件 |
|||
const scrollFloorCtlOpt = { |
|||
position: FMControlPosition.RIGHT_TOP, |
|||
floorButtonCount: 5, |
|||
offset: { |
|||
x: -20, |
|||
y: 150 |
|||
}, |
|||
viewModeControl: true, |
|||
floorModeControl: true, |
|||
needAllLayerBtn: true |
|||
} |
|||
const scrollFloorControl = new FMToolbar(scrollFloorCtlOpt) |
|||
console.log('scrollFloorControl', scrollFloorControl.p) |
|||
scrollFloorControl.addTo(this.map) |
|||
|
|||
// 比例尺控件 |
|||
const scrollScaleBarCtlOpt = { |
|||
fontSize: 18, |
|||
height: 30, |
|||
position: FMControlPosition.LEFT_BOTTOM, |
|||
offset: { |
|||
x: 20, |
|||
y: -20 |
|||
} |
|||
|
|||
} |
|||
const scaleBar = new FMScaleBar(scrollScaleBarCtlOpt) |
|||
scaleBar.addTo(this.map) |
|||
|
|||
this.analyser = new FMSearchAnalyser({ map: this.map }, () => { |
|||
// UI.initList() |
|||
}) |
|||
|
|||
console.log('当前楼层', this.map.getLevel()) |
|||
console.log('所有楼层', this.map.getLevels()) |
|||
|
|||
// 获取楼层信息 |
|||
this.level = this.map.getLevel() |
|||
this.levels = this.map.getLevels() |
|||
|
|||
// console.log('所有楼层', this.map.getVisibleLevels()) |
|||
this.floorInfo = this.map.getFloorInfos() |
|||
console.log('所有楼层信息', this.floorInfos) |
|||
|
|||
// 设置聚焦楼层 |
|||
// this.map.setLevel({ |
|||
// level: item |
|||
// }) |
|||
const ops = { |
|||
level: [1, 2, 3, 4], |
|||
// typeID: 210502, |
|||
text: '开架', |
|||
search: true // 精确查询 false 模糊查询 true |
|||
} |
|||
this.search(ops) |
|||
|
|||
// 根据FID查询 |
|||
const floor = this.map.getFloor(this.level) |
|||
const model = floor.getLayers(fengmap.FMType.MODEL_LAYER)[0].getFeatures().find(item => item.FID === '1026050201310') |
|||
console.log('model', model.getData()) |
|||
model.setColor('red') |
|||
model.flash('red') |
|||
}, { passive: true }) |
|||
|
|||
this.map.on('click', (e) => { |
|||
this.marker && this.marker.remove() |
|||
this.marker = null |
|||
const clickMode = e.targets.find(it => it.type === fengmap.FMType.MODEL) |
|||
let floor = this.floorInfo.find(it => it.level === e.level) |
|||
|
|||
// 更新界面的点击信息 |
|||
this.updateClickUI(e, clickMode, floor) |
|||
|
|||
// 添加点击mark |
|||
this.marker = new fengmap.FMImageMarker({ |
|||
url: 'https://developer.fengmap.com/fmAPI/images/red.png', |
|||
x: e.coords.x, |
|||
y: e.coords.y, |
|||
anchor: fengmap.FMMarkerAnchor.BOTTOM |
|||
}) |
|||
const level = this.map.getLevel() |
|||
floor = this.map.getFloor(level) |
|||
this.marker.addTo(floor) |
|||
}, { passive: true }) |
|||
|
|||
this.map.on('mapInitError', (err) => { |
|||
console.error('地图初始化错误:', err) |
|||
this.debugInfo = `地图初始化错误: ${err.message}` |
|||
}) |
|||
} catch (error) { |
|||
console.error('初始化地图失败:', error) |
|||
this.debugInfo = `初始化失败: ${error.message}` |
|||
} |
|||
}, |
|||
updateClickUI(event, clickMode, floor) { |
|||
// 拾取模型对象 |
|||
const target = event.targets[0] |
|||
console.log('event:', event) |
|||
console.log('拾取模型对象:', target) |
|||
console.log('name:', target?.name) |
|||
console.log('floor:', floor) |
|||
// 拾取模型类型 |
|||
const mType = target?.type || 'NONE' |
|||
console.log('拾取模型类型:', mType) |
|||
// 封装拾取信息(新增 clickMode 和 floor 的展示) |
|||
let infoHtml = '<div class="layui-card-body">' |
|||
// infoHtml += `<p><label>事件触发:</label>${event.type}</p>` |
|||
// infoHtml += `<p><label>拾取对象类:</label>${mType}</p>` |
|||
// infoHtml += `<p><label>点击模式(目标):</label>${clickMode?.type || clickMode}</p>` // 展示点击目标类型 |
|||
infoHtml += `<p><label>当前楼层:</label>${floor?.name || floor}</p>` // 展示楼层名称/信息 |
|||
infoHtml += `<p><label>当前区域:</label>${target?.name || '[位置]' + floor?.name}</p>` // 展示楼层名称/信息 |
|||
infoHtml += `<p><label>level:</label>${event?.level || ''}</p>` |
|||
infoHtml += `<p><label>FID:</label>${target?.FID || ''}</p>` |
|||
infoHtml += `<p><label>点击位置坐标:</label>x:${event.coords.x || ''}<br/>y:${event.coords.y || ''}</p>` |
|||
infoHtml += `<p><label>元素中心点坐标:</label>x:${target?.x || ''}<br/>y:${target?.y || ''}</p>` |
|||
infoHtml += `</div>` |
|||
const infoDiv = document.getElementById('info') |
|||
infoDiv.innerHTML = infoHtml |
|||
}, |
|||
|
|||
search(ops) { |
|||
console.log('搜索参数:', ops) |
|||
const searchRequest = new FMSearchRequest() |
|||
console.log('searchRequest', searchRequest) |
|||
searchRequest.levels = ops.level |
|||
console.log('fengmap.FMType.MODEL', fengmap.FMType.MODEL) |
|||
searchRequest.type = fengmap.FMType.MODEL |
|||
// searchRequest.addCondition({ 'typeID': ops.typeID }) |
|||
if (ops.text && ops.text !== '') { |
|||
searchRequest.addCondition({ 'keyword': { 'text': ops.text, fuzzy: ops.search }}) |
|||
} |
|||
console.log('searchRequest', searchRequest) |
|||
this.analyser.query(searchRequest, (result) => { |
|||
const newResult = result.filter((item) => item.name !== undefined) |
|||
let data = [] |
|||
if (ops.level.length > 1) { |
|||
data = newResult |
|||
} else { |
|||
data = newResult.filter((item) => item.level === ops.level[0]) |
|||
} |
|||
this.addImgMarker(data, ops) |
|||
}) |
|||
}, |
|||
addImgMarker(data, obj) { |
|||
if (this.imageMarkers) { |
|||
this.imageMarkers.forEach(item => { item.remove() }) |
|||
this.imageMarkers = null |
|||
} |
|||
console.log('搜索结果:', data) |
|||
this.imageMarkers = data.map(feature => { |
|||
const marker = new fengmap.FMImageMarker({ |
|||
url: 'https://developer.fengmap.com/fmAPI/images/red.png', |
|||
x: feature.center.x, |
|||
y: feature.center.y, |
|||
anchor: fengmap.FMMarkerAnchor.BOTTOM |
|||
}) |
|||
const floor = this.map.getFloor(feature.level) |
|||
const model = floor.getLayers(fengmap.FMType.MODEL_LAYER)[0].getFeatures().find(item => item.FID === feature.FID) |
|||
console.log('model', model.getData()) |
|||
model.setColor('red') |
|||
marker.addTo(floor) |
|||
return marker |
|||
}) |
|||
}, |
|||
// ----------------------------------------------------------------- |
|||
getMarkerColor(index) { |
|||
return this.markerColors[index] |
|||
}, |
|||
async addLocationMarker(index, ops = {}) { |
|||
try { |
|||
if (this.markers[index].marker) { |
|||
this.markers[index].marker.remove() |
|||
this.markers[index].marker = null |
|||
} |
|||
|
|||
const markerConfig = { |
|||
height: 0.2, |
|||
size: 23, |
|||
level: 5, |
|||
url: 'https://developer.fengmap.com/fmAPI/images/location.png', |
|||
x: 11791504, |
|||
y: 3418833.5, |
|||
color: this.markerColors[index], // 设置不同颜色 |
|||
...ops |
|||
} |
|||
|
|||
this.markers[index].marker = new fengmap.FMLocationMarker(markerConfig) |
|||
this.markers[index].marker.addTo(this.map) |
|||
} catch (error) { |
|||
console.error(`添加定位标记${index + 1}失败:`, error) |
|||
this.debugInfo = `添加标记${index + 1}失败: ${error.message}` |
|||
} |
|||
}, |
|||
async getRealtimePosition(index) { |
|||
// 模拟不同定位点的位置 |
|||
const baseX = 11791504 + (index * 50) // 不同定位点基础位置间隔50 |
|||
const baseY = 3418833.5 + (index * 50) |
|||
return { |
|||
x: baseX + Math.random() * 20 - 10, |
|||
y: baseY + Math.random() * 20 - 10, |
|||
level: 5 |
|||
} |
|||
}, |
|||
async updateMarkerPosition(index) { |
|||
try { |
|||
const position = await this.getRealtimePosition(index) |
|||
if (this.markers[index].marker) { |
|||
this.markers[index].marker.moveTo({ |
|||
x: position.x, |
|||
y: position.y, |
|||
level: position.level, |
|||
animate: true, |
|||
duration: 0.5 |
|||
}) |
|||
} else { |
|||
this.addLocationMarker(index, position) |
|||
} |
|||
|
|||
// 记录位置信息 |
|||
this.markers[index].positions.push({ |
|||
x: position.x, |
|||
y: position.y, |
|||
timestamp: new Date().toLocaleString() |
|||
}) |
|||
|
|||
this.debugInfo = `定位点${index + 1}更新: x=${position.x.toFixed(2)}, y=${position.y.toFixed(2)}` |
|||
} catch (error) { |
|||
console.error(`更新位置${index + 1}失败:`, error) |
|||
this.debugInfo = `更新位置${index + 1}失败: ${error.message}` |
|||
} |
|||
}, |
|||
startTracking(index) { |
|||
if (this.markers[index].timer) { |
|||
this.$message.warning(`定位点${index + 1}已在追踪中`) |
|||
return |
|||
} |
|||
|
|||
this.markers[index].active = true |
|||
this.markers[index].remainTime = 60 |
|||
this.markers[index].positions = [] // 清空历史位置记录 |
|||
|
|||
// 倒计时定时器 |
|||
this.markers[index].remainTimer = setInterval(() => { |
|||
this.markers[index].remainTime-- |
|||
if (this.markers[index].remainTime <= 0) { |
|||
this.stopTracking(index) |
|||
} |
|||
}, 1000) |
|||
|
|||
// 位置更新定时器 |
|||
this.updateMarkerPosition(index) |
|||
this.markers[index].timer = setInterval(() => { |
|||
this.updateMarkerPosition(index) |
|||
}, 3000) |
|||
|
|||
this.$message.success(`定位点${index + 1}开始追踪`) |
|||
}, |
|||
stopTracking(index) { |
|||
if (this.markers[index].timer) { |
|||
clearInterval(this.markers[index].timer) |
|||
clearInterval(this.markers[index].remainTimer) |
|||
this.markers[index].timer = null |
|||
this.markers[index].remainTimer = null |
|||
this.markers[index].remainTime = 0 |
|||
this.markers[index].active = false |
|||
|
|||
// 输出位置记录 |
|||
console.log(`定位点${index + 1}位置记录:`, this.markers[index].positions) |
|||
this.$message.info(`定位点${index + 1}追踪已停止`) |
|||
} |
|||
}, |
|||
stopAllTracking() { |
|||
this.markers.forEach((_, index) => { |
|||
this.stopTracking(index) |
|||
}) |
|||
this.$message.info('所有定位点追踪已停止') |
|||
}, |
|||
beforeDestroy() { |
|||
this.stopAllTracking() |
|||
this.markers.forEach(markerInfo => { |
|||
if (markerInfo.marker) { |
|||
markerInfo.marker.remove() |
|||
} |
|||
}) |
|||
if (this.map) { |
|||
this.map.dispose() |
|||
this.map = null |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
@import "~@/assets/fengmap/toolBarStyle.css"; |
|||
#fengmap { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background: #f5f5f5; |
|||
} |
|||
.rightMask{ |
|||
width: 162px; |
|||
height: 42px; |
|||
position: absolute; |
|||
bottom: 0; |
|||
right: 0; |
|||
background: #fff; |
|||
} |
|||
.debug-info { |
|||
position: absolute; |
|||
top: 10px; |
|||
left: 10px; |
|||
background: rgba(0, 0, 0, 0.7); |
|||
color: white; |
|||
padding: 10px; |
|||
border-radius: 4px; |
|||
font-size: 12px; |
|||
max-width: 80%; |
|||
z-index: 99999999; |
|||
} |
|||
|
|||
.info{ |
|||
position: absolute; |
|||
top: 0; |
|||
right: 20px; |
|||
background: rgba(0, 0, 0, 0.7); |
|||
color: white; |
|||
width: 400px; |
|||
// height: 200px; |
|||
padding: 10px; |
|||
z-index: 999999999999; |
|||
} |
|||
|
|||
/*.control-panel { |
|||
position: fixed; |
|||
top: 20px; |
|||
right: 20px; |
|||
background: rgba(255, 255, 255, 0.9); |
|||
padding: 15px; |
|||
border-radius: 4px; |
|||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
|||
z-index: 1000; |
|||
} |
|||
|
|||
.button-group { |
|||
display: flex; |
|||
gap: 10px; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
.tracking-info { |
|||
margin-top: 10px; |
|||
padding-top: 10px; |
|||
border-top: 1px solid #eee; |
|||
} |
|||
|
|||
.marker-status { |
|||
margin: 5px 0; |
|||
font-size: 14px; |
|||
} */ |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue