mabpox实现图标移动并判断与面是否相交

<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>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小满blue

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值