| | |
| | | <van-image width="20" height="20" :src="locationIcon" /> |
| | | <div class="label">定位</div> |
| | | </div> |
| | | <div class="nav-btn" @click="openNavigation" v-show="navigationTarget"> |
| | | <van-image width="20" height="20" :src="mapnavIcon" /> |
| | | <div class="label">导航</div> |
| | | </div> |
| | | <van-action-sheet |
| | | v-model:show="navigationSheetShow" |
| | | :actions="navigationActions" |
| | | cancel-text="取消" |
| | | @select="handleNavigationSelect" |
| | | /> |
| | | |
| | | |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { searchGeocoder } from '@/utils/util' |
| | | import { showToast } from 'vant' |
| | | import mapnavIcon from '@/appDataSource/appwork/mapnav.svg' |
| | | import incidentPoint from '@/appDataSource/appwork/positioning1.svg' |
| | | import userLocationIcon from '@/appDataSource/leafletMapIcon/user-location.svg' |
| | |
| | | }) |
| | | const currentAddress = ref('') |
| | | const AMAP_KEY = '5b8ba312d053e4bdb44911733ece7d63' |
| | | const navigationSheetShow = ref(false) |
| | | const navigationActions = [{ name: '高德地图' }, { name: '百度地图' }, { name: '腾讯地图' }] |
| | | const navigationTarget = computed(() => { |
| | | if (!workNavigationShow || !mapCurrentDetail?.longitude || !mapCurrentDetail?.latitude) return null |
| | | |
| | | const lat = parseFloat(mapCurrentDetail.latitude) |
| | | const lng = parseFloat(mapCurrentDetail.longitude) |
| | | if (Number.isNaN(lat) || Number.isNaN(lng)) return null |
| | | |
| | | return { |
| | | lat, |
| | | lng, |
| | | name: mapCurrentDetail.eventLocation || mapCurrentDetail.address || '工单位置', |
| | | } |
| | | }) |
| | | |
| | | const basemap0 = L.layerGroup([basemapLayer0, basemapLayer1]) |
| | | const basemap1 = L.layerGroup([basemapLayer2, basemapLayer3]) |
| | |
| | | } |
| | | } |
| | | |
| | | function openNavigation() { |
| | | if (!navigationTarget.value) { |
| | | showToast('暂无可导航的位置') |
| | | return |
| | | } |
| | | |
| | | navigationSheetShow.value = true |
| | | } |
| | | |
| | | function handleNavigationSelect(action) { |
| | | navigationSheetShow.value = false |
| | | const url = getNavigationUrl(action.name, navigationTarget.value) |
| | | if (url) { |
| | | window.location.href = url |
| | | } |
| | | } |
| | | |
| | | function getNavigationUrl(type, target) { |
| | | const [gcjLng, gcjLat] = wgs84ToGcj02(target.lng, target.lat) |
| | | const name = encodeURIComponent(target.name) |
| | | |
| | | if (type === '高德地图') { |
| | | return `https://uri.amap.com/navigation?to=${gcjLng},${gcjLat},${name}&mode=car&policy=1&coordinate=gaode&callnative=1` |
| | | } |
| | | |
| | | if (type === '百度地图') { |
| | | return `https://api.map.baidu.com/direction?destination=latlng:${gcjLat},${gcjLng}|name:${name}&mode=driving&coord_type=gcj02&output=html&src=ja-web` |
| | | } |
| | | |
| | | if (type === '腾讯地图') { |
| | | return `https://apis.map.qq.com/uri/v1/routeplan?type=drive&tocoord=${gcjLat},${gcjLng}&to=${name}&referer=ja-web` |
| | | } |
| | | |
| | | return '' |
| | | } |
| | | |
| | | let lastLocationMarker = null |
| | | const getMapLocation = async () => { |
| | | const customIcon = L.icon({ |
| | |
| | | // 存储事件点标记实例,用于后续更新或移除 |
| | | let incidentMarker = null |
| | | |
| | | function formatCoordinate(value) { |
| | | const numberValue = Number(value) |
| | | return Number.isNaN(numberValue) ? value : numberValue.toFixed(6) |
| | | } |
| | | |
| | | // 添加事件点标记 |
| | | function addIncidentMarker(data) { |
| | | // 检查地图和标记层是否已初始化 |
| | |
| | | |
| | | // 存储关联数据 |
| | | incidentMarker.options.customData = data |
| | | incidentMarker.bindTooltip( |
| | | `<div class="coordinate-label"> |
| | | <div>经度:${formatCoordinate(lng)}</div> |
| | | <div>纬度:${formatCoordinate(lat)}</div> |
| | | </div>`, |
| | | { |
| | | permanent: true, |
| | | direction: 'top', |
| | | offset: L.point(0, -16), |
| | | opacity: 1, |
| | | className: 'incident-coordinate-tooltip', |
| | | } |
| | | ) |
| | | |
| | | // 定位到该标记点 |
| | | mapSetView({ |
| | |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | .location-btn{ |
| | | .location-btn, |
| | | .nav-btn{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | |
| | | .location-btn { |
| | | bottom: 76px; |
| | | } |
| | | .nav-btn { |
| | | bottom: 28px; |
| | | } |
| | | } |
| | | |
| | | // 位置标记闪烁效果 |
| | |
| | | animation: blink 1s ease-in-out; |
| | | } |
| | | |
| | | :deep(.incident-coordinate-tooltip) { |
| | | padding: 0; |
| | | border: 0; |
| | | background: transparent; |
| | | box-shadow: none; |
| | | |
| | | &::before { |
| | | display: none; |
| | | } |
| | | } |
| | | |
| | | :deep(.coordinate-label) { |
| | | padding: 4px 7px; |
| | | background: rgba(255, 255, 255, 0.95); |
| | | border: 1px solid rgba(76, 133, 255, 0.35); |
| | | border-radius: 4px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18); |
| | | font-size: 11px; |
| | | line-height: 16px; |
| | | color: #222324; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | @keyframes blink { |
| | | 0% { |
| | | transform: scale(1); |