|
@@ -1,4 +1,5 @@
|
|
|
<template>
|
|
<template>
|
|
|
|
|
+ <!-- <el-button @click="test1">测试</el-button> -->
|
|
|
<div
|
|
<div
|
|
|
id="tracking-map"
|
|
id="tracking-map"
|
|
|
ref="mapContainer"
|
|
ref="mapContainer"
|
|
@@ -230,6 +231,41 @@ const addMapLine = (l, IsDash, opts) => {
|
|
|
const showTrackLine = (pts, jj, opts) => {
|
|
const showTrackLine = (pts, jj, opts) => {
|
|
|
let arrow = L.polyline(pts, Object.assign({}, { color: '#ff7500', weight: 2 }, opts)).addTo(map)
|
|
let arrow = L.polyline(pts, Object.assign({}, { color: '#ff7500', weight: 2 }, opts)).addTo(map)
|
|
|
track_added_marker.push(arrow)
|
|
track_added_marker.push(arrow)
|
|
|
|
|
+
|
|
|
|
|
+ // 如果线段至少有两个点,才添加箭头
|
|
|
|
|
+ // if (pts.length >= 2) {
|
|
|
|
|
+ // // 获取线段的最后一个点和倒数第二个点
|
|
|
|
|
+ // const lastPoint = pts[pts.length - 1]
|
|
|
|
|
+ // const secondLastPoint = pts[pts.length - 2]
|
|
|
|
|
+
|
|
|
|
|
+ // // 计算线段末端的角度(以弧度为单位)
|
|
|
|
|
+ // const angle =
|
|
|
|
|
+ // Math.atan2(lastPoint[1] - secondLastPoint[1], lastPoint[0] - secondLastPoint[0]) *
|
|
|
|
|
+ // (180 / Math.PI)
|
|
|
|
|
+
|
|
|
|
|
+ // // 创建自定义箭头图标
|
|
|
|
|
+ // const arrowIcon = L.divIcon({
|
|
|
|
|
+ // html: `
|
|
|
|
|
+ // <div style="transform: rotate(${angle + 270}deg);" class="container">
|
|
|
|
|
+ // <div class="circle"></div>
|
|
|
|
|
+ // <span class="font_family icon-icon_ocean_b"></span>
|
|
|
|
|
+ // </div>
|
|
|
|
|
+
|
|
|
|
|
+ // `,
|
|
|
|
|
+ // className: 'arrow-icon',
|
|
|
|
|
+ // iconSize: [24, 24],
|
|
|
|
|
+ // iconAnchor: [12, 12], // 箭头的中心点
|
|
|
|
|
+ // popupAnchor: [0, -12] // 弹出框的锚点
|
|
|
|
|
+ // })
|
|
|
|
|
+
|
|
|
|
|
+ // // 创建箭头标记,并根据计算出的角度旋转箭头
|
|
|
|
|
+ // const arrowMarker = L.marker(lastPoint, {
|
|
|
|
|
+ // icon: arrowIcon
|
|
|
|
|
+ // }).addTo(map)
|
|
|
|
|
+ // console.log(angle, '角度')
|
|
|
|
|
+ // // 将箭头标记也存储在 track_added_marker 数组中,以便后续管理
|
|
|
|
|
+ // track_added_marker.push(arrowMarker)
|
|
|
|
|
+ // }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const addResetZoomButton = (center: L.LatLng, zoom: number) => {
|
|
const addResetZoomButton = (center: L.LatLng, zoom: number) => {
|
|
@@ -406,6 +442,35 @@ const getMarker = () => {
|
|
|
.then((res) => {
|
|
.then((res) => {
|
|
|
if (res.code === 200) {
|
|
if (res.code === 200) {
|
|
|
const { data } = res
|
|
const { data } = res
|
|
|
|
|
+ data.point = [
|
|
|
|
|
+ {
|
|
|
|
|
+ lng: '101.40000000',
|
|
|
|
|
+ lat: '3.00000000',
|
|
|
|
|
+ label: 'Origin',
|
|
|
|
|
+ infor: 'PORT KLANG, MALAYSIA',
|
|
|
|
|
+ sort: '1',
|
|
|
|
|
+ stime: null,
|
|
|
|
|
+ ptype: 'pol'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ lng: '-81.09008789',
|
|
|
|
|
+ lat: '32.08044084',
|
|
|
|
|
+ label: 'Destination',
|
|
|
|
|
+ infor: 'SAVANNAH, GA',
|
|
|
|
|
+ sort: '2',
|
|
|
|
|
+ stime: null,
|
|
|
|
|
+ ptype: 'pod'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ lng: '103.81666667',
|
|
|
|
|
+ lat: '1.26666667',
|
|
|
|
|
+ label: 'Transfer',
|
|
|
|
|
+ infor: 'SINGAPORE',
|
|
|
|
|
+ sort: '3',
|
|
|
|
|
+ stime: null,
|
|
|
|
|
+ ptype: 'poe'
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
data?.point &&
|
|
data?.point &&
|
|
|
data?.point.forEach((item) => {
|
|
data?.point.forEach((item) => {
|
|
|
const iconColorList = {
|
|
const iconColorList = {
|
|
@@ -422,9 +487,11 @@ const getMarker = () => {
|
|
|
iconColor: iconColorList[item.label].color
|
|
iconColor: iconColorList[item.label].color
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
- viewData.value = (data?.rangePoint || data?.point)?.map((item) => {
|
|
|
|
|
- return [Number(item.lat), (Number(item.lon) + 360) % 360]
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ viewData.value = (data?.rangePoint.length > 0 ? data?.rangePoint : data?.point)?.map(
|
|
|
|
|
+ (item) => {
|
|
|
|
|
+ return [Number(item.lat), (Number(item.lon || item.lng) + 360) % 360]
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
// 请求成功后添加标记,并动态添加重置按钮
|
|
// 请求成功后添加标记,并动态添加重置按钮
|
|
|
addMarkersToMap()
|
|
addMarkersToMap()
|
|
|
if (data?.dottedLine) {
|
|
if (data?.dottedLine) {
|
|
@@ -461,6 +528,95 @@ onMounted(() => {
|
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
|
map?.remove()
|
|
map?.remove()
|
|
|
})
|
|
})
|
|
|
|
|
+
|
|
|
|
|
+const test = () => {
|
|
|
|
|
+ // 定义一个更复杂的 HTML 标记
|
|
|
|
|
+ var complexIcon = L.divIcon({
|
|
|
|
|
+ html: `
|
|
|
|
|
+ <div class="container">
|
|
|
|
|
+ <div class="circle"></div>
|
|
|
|
|
+ <span class="font_family icon-icon_ocean_b"></span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ `,
|
|
|
|
|
+ className: 'complex-marker',
|
|
|
|
|
+ iconSize: [32, 50], // 考虑到额外的文字,设置更大的高度
|
|
|
|
|
+ iconAnchor: [16, 25] // 调整锚点以适应新的布局
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 在地图上添加一个带有复杂 HTML 标记的标记
|
|
|
|
|
+ L.marker([51.5, -0.09], { icon: complexIcon }).addTo(map)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const test1 = () => {
|
|
|
|
|
+ const data = {
|
|
|
|
|
+ point: [
|
|
|
|
|
+ {
|
|
|
|
|
+ lng: '101.40000000',
|
|
|
|
|
+ lat: '3.00000000',
|
|
|
|
|
+ label: 'Origin',
|
|
|
|
|
+ infor: 'PORT KLANG, MALAYSIA',
|
|
|
|
|
+ sort: '1',
|
|
|
|
|
+ stime: null,
|
|
|
|
|
+ ptype: 'pol'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ lng: '-81.09008789',
|
|
|
|
|
+ lat: '32.08044084',
|
|
|
|
|
+ label: 'Destination',
|
|
|
|
|
+ infor: 'SAVANNAH, GA',
|
|
|
|
|
+ sort: '2',
|
|
|
|
|
+ stime: null,
|
|
|
|
|
+ ptype: 'pod'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ lng: '103.81666667',
|
|
|
|
|
+ lat: '1.26666667',
|
|
|
|
|
+ label: 'Transfer',
|
|
|
|
|
+ infor: 'SINGAPORE',
|
|
|
|
|
+ sort: '3',
|
|
|
|
|
+ stime: null,
|
|
|
|
|
+ ptype: 'poe'
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ solidLine: [],
|
|
|
|
|
+ dottedLine: [],
|
|
|
|
|
+ rangePoint: []
|
|
|
|
|
+ }
|
|
|
|
|
+ data?.point &&
|
|
|
|
|
+ data?.point.forEach((item) => {
|
|
|
|
|
+ const iconColorList = {
|
|
|
|
|
+ Destination: { color: '#24ca5a', icon: destinationIcon },
|
|
|
|
|
+ Origin: { color: '#ED6D00', icon: originIcon },
|
|
|
|
|
+ Transfer: { color: '#ed0000', icon: transferIcon }
|
|
|
|
|
+ }
|
|
|
|
|
+ markerPositions.value.push({
|
|
|
|
|
+ lat: item.lat,
|
|
|
|
|
+ lng: (Number(item.lng) + 360) % 360,
|
|
|
|
|
+ city: item.infor,
|
|
|
|
|
+ label: item.label,
|
|
|
|
|
+ icon: iconColorList[item.label].icon,
|
|
|
|
|
+ iconColor: iconColorList[item.label].color
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+ console.log(data, '这是数据')
|
|
|
|
|
+ viewData.value = (data?.rangePoint.length > 0 ? data?.rangePoint : data?.point)?.map((item) => {
|
|
|
|
|
+ console.log(item.lon, '这是只')
|
|
|
|
|
+ return [Number(item.lat), (Number(item.lon || item.lng) + 360) % 360]
|
|
|
|
|
+ })
|
|
|
|
|
+ // 请求成功后添加标记,并动态添加重置按钮
|
|
|
|
|
+ addMarkersToMap()
|
|
|
|
|
+ if (data?.dottedLine) {
|
|
|
|
|
+ draw_marker(handleData(data.dottedLine), handleData(data.solidLine))
|
|
|
|
|
+ map.on('moveend', function () {
|
|
|
|
|
+ draw_marker(handleData(data.dottedLine), handleData(data.solidLine))
|
|
|
|
|
+ updateVisibleMarkers()
|
|
|
|
|
+ })
|
|
|
|
|
+ map.on('zoomend', function () {
|
|
|
|
|
+ draw_marker(handleData(data.dottedLine), handleData(data.solidLine))
|
|
|
|
|
+ updateVisibleMarkers()
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
<style lang="scss">
|
|
@@ -521,3 +677,64 @@ onUnmounted(() => {
|
|
|
padding: 6px;
|
|
padding: 6px;
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss">
|
|
|
|
|
+.tracking-map {
|
|
|
|
|
+ .container {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ height: 50px;
|
|
|
|
|
+ width: 50px;
|
|
|
|
|
+ /* background-color: #d9dddf; */
|
|
|
|
|
+ .font_family {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 50%;
|
|
|
|
|
+ left: 50%;
|
|
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ width: 12px;
|
|
|
|
|
+ height: 12px;
|
|
|
|
|
+ padding: 4px;
|
|
|
|
|
+ font-size: 9px;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ background-color: rgba(255, 117, 0, 1);
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .circle {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ width: 12px;
|
|
|
|
|
+ height: 12px;
|
|
|
|
|
+ background-color: rgba(255, 117, 0, 1);
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ animation: expandAndFade 1.3s linear infinite;
|
|
|
|
|
+ overflow: hidden; /* 确保子元素不会溢出 */
|
|
|
|
|
+
|
|
|
|
|
+ opacity: 0.9;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @keyframes expandAndFade {
|
|
|
|
|
+ 0% {
|
|
|
|
|
+ transform: scale(1);
|
|
|
|
|
+ opacity: 0.9;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ 50% {
|
|
|
|
|
+ transform: scale(1.44); /* 从 18px 扩展到 24px (18 * 1.33 = 24) */
|
|
|
|
|
+ opacity: 0.7;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ 100% {
|
|
|
|
|
+ transform: scale(1.67); /* 从 18px 扩展到 30px (18 * 1.67 ≈ 30) */
|
|
|
|
|
+ opacity: 0.2;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|