
<template>
<div class="map-box">
<div id="map" class="map-box-cavas"></div>
<div class="pop-box">
<a-alert
v-if="showIcon == 2"
message="提示"
description="你已进入当前地理区域"
type="error"
show-icon
>
<template #icon><smile-outlined /></template>
</a-alert>
<a-alert
v-if="showIcon == 1"
message="提示"
description="你已离开当前地理区域"
type="info"
show-icon
>
<template #icon><smile-outlined /></template>
</a-alert>
</div>
</div>
</template>
<script lang="ts" setup>
import mapboxgl from 'mapbox-gl';
import { Alert, message } from 'ant-design-vue';
import { SmileOutlined } from '@ant-design/icons-vue';
import { onMounted, ref } from 'vue';
import * as turf from '@turf/turf';
import imgPoint from '../../../../assets/images/map/point12.png';
const publick = `${import.meta.env.BASE_URL}`;
const showIcon = ref(1);
let counter = 0;
const steps = 300;
let line = [
[104.04326249990527, 30.701493150304387],
[104.12383913963447, 30.6976592358632],
[104.12129650489345, 30.663771440933473],
[104.05673256145923, 30.64937207231857],
];
let ploygon = [
[
[104.011786, 30.718407],
[104.08962, 30.670089],
[104.161658, 30.625998],
[104.225163, 30.712098],
[104.011786, 30.718407],
],
];
const route = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: line,
},
},
],
};
const init = () => {
mapboxgl.accessToken = null;
class Cjmapbox extends mapboxgl.Map {}
// eslint-disable-next-line @typescript-eslint/no-empty-function
Cjmapbox.prototype.__proto__._authenticate = function () {};
const map = new mapboxgl.Map({
container: 'map',
style: {
version: 8,
name: 'BlankMap',
glyphs: `${publick}lib/glyphs/{fontstack}/{range}.pbf`,
sources: {},
layers: [
{
id: 'background',
type: 'background',
paint: {
'background-color': '#08294A',
} /* 背景颜色 */,
},
],
},
center: [104.06284277196889, 30.661042653840443], // Set the initial center of the map
zoom: 11,
});
map.on('load', () => {
map.addSource('DZDT_Vector_BZB', {
type: 'raster',
tiles: [
'http://t3.tianditu.com/DataServer?T=vec_w&tk=915de993ea6873664830bf5d8217723c&x={x}&y={y}&l={z}',
],
tileSize: 256,
});
map.addSource('SatelliteRS_RS_G2000', {
type: 'raster',
tiles: [
'http://t3.tianditu.com/DataServer?T=cva_w&tk=915de993ea6873664830bf5d8217723c&x={x}&y={y}&l={z}',
],
tileSize: 256,
});
map.addLayer({
id: 'DZDT_Vector_BZB',
type: 'raster',
source: 'DZDT_Vector_BZB',
paint: {},
});
map.addLayer({
id: 'SatelliteRS_RS_G2000',
type: 'raster',
source: 'SatelliteRS_RS_G2000',
paint: {},
});
// 绘制范围
map.addLayer({
id: 'fill',
type: 'fill',
source: {
type: 'geojson',
data: turf.polygon(ploygon),
},
paint: {
'fill-color': '#5388e1',
'fill-opacity': 0.7,
},
});
// 绘制线
map.addLayer({
id: 'line',
type: 'line',
source: {
type: 'geojson',
data: turf.lineString(line),
},
layout: {
'line-join': 'round',
'line-cap': 'round',
},
paint: {
'line-color': '#ffd78a',
'line-width': 0,
},
});
map.loadImage(
imgPoint,
function (error: AnyObject, imgPoint: AnyObject) {
if (error) throw error;
map.addImage('imgPoint', imgPoint);
},
);
// 加载图标
map.addSource('point', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: line[0][0],
},
},
],
},
});
map.addLayer({
id: 'point',
type: 'symbol',
source: 'point',
layout: {
'icon-image': 'imgPoint',
'icon-size': 0.15,
},
});
// 创建一个弹窗
function animateMarker() {
const routeCoordinates = route.features[0].geometry.coordinates;
const routeLength = routeCoordinates.length;
counter = (counter + 1) % (routeLength * steps);
const coordIndex = Math.floor(counter / steps);
const t = (counter % steps) / steps;
const currentCoord = routeCoordinates[coordIndex];
const nextCoord = routeCoordinates[(coordIndex + 1) % routeLength];
const lng = currentCoord[0] + t * (nextCoord[0] - currentCoord[0]);
const lat = currentCoord[1] + t * (nextCoord[1] - currentCoord[1]);
const point = turf.point([lng, lat]);
const polygon = turf.polygon(ploygon);
const isInside = turf.booleanPointInPolygon(point, polygon);
if (isInside) {
showIcon.value = 2;
} else {
showIcon.value = 1;
}
// 更新弹窗的位置
// popup.setLngLat([lng, lat]);
map.getSource('point').setData({
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [lng, lat],
},
},
],
});
requestAnimationFrame(animateMarker);
}
animateMarker();
});
};
onMounted(() => {
init();
});
</script>
<style lang="scss" scoped>
.map-box {
width: 100%;
height: 100%;
position: relative;
&-cavas {
width: auto;
height: 100%;
}
}
.pop-box {
position: absolute;
top: 255px;
right: 100px;
}
</style>