高德地图区域掩模

171 阅读3分钟

效果如图

企业微信截图_17156787422084.png

import AMapLoader from '@amap/amap-jsapi-loader'
import { apiMap } from '@/api/screen.api'
let map = null
let district = null
const loadData = () => {
	apiMap().then(res => {
		console.log('地图数据', res)
		initMap(res)
	})
}
function initMap(mapData) {
	window._AMapSecurityConfig = {
		securityJsCode: '',
	}
	AMapLoader.load({
		//注册开发者/创建应用,选择web端JS API(必须)
		key: '', //首次load必填
		version: '1.4.15',
		plugins: [
			'AMap.DistrictSearch',
			'AMap.ToolBar',
			'AMap.Scale',
			'AMap.PolyEditor',
			'AMap.Geocoder',
			'AMap.Autocomplete',
			'AMap.PlaceSearch',
			'AMap.MouseTool',
			'AMap.Geolocation',
			'AMap.CitySearch',
			'AMap.MarkerClusterer',
			'Map3D',
			'AMap.DistrictLayer',
		],
	}).then(() => {
		var opts = {
			subdistrict: 2, //返回下一级行政区
			extensions: 'all', //返回行政区边界坐标组等具体信息
			level: 'district',
		}
		//实例化DistrictSearch
		district = new AMap.DistrictSearch(opts)
		district.search(mapData.areaName, function (status, result) {
			var bounds = result.districtList[0].boundaries
			var subBounds = result.districtList[0].districtList
			var centerPoint = result.districtList[0].center
			var mask = []
			for (var i = 0; i < bounds.length; i += 1) {
				mask.push([bounds[i]])
			}
			var object3Dlayer = new AMap.Object3DLayer({ zIndex: 1 })
			let mainCenter = getCenter(bounds[0])

			map = new AMap.Map('container', {
				mask: mask,
				center: [mainCenter[0], mainCenter[1]],
				viewMode: '3D',
				dragEnable: false,
				labelzIndex: 130,
				zoom: 9,
				cursor: 'pointer',
				layers: [object3Dlayer, new AMap.TileLayer.Satellite()],
			})
			var height = 80000
			var color = '#0F87FF' //rgba
			var prism = new AMap.Object3D.Wall({
				path: bounds,
				height: height,
				color: color,
			})
			prism.transparent = true
			prism.backOrFront = 'both'
			object3Dlayer.add(prism)
			for (var i = 0; i < bounds.length; i += 1) {
				new AMap.Polyline({
					path: bounds[i],
					strokeColor: '#A3FFF4',
					strokeWeight: 6,
					map: map,
				})
			}
			for (var i = 0; i < subBounds.length; i += 1) {
				// 创建子区域边界
				let centerOrigin = null
				district.search(subBounds[i].name, function (status, result) {
					let subRoute = result.districtList[0].boundaries
					centerOrigin = result.districtList[0].boundaries[0]
					for (var j = 0; j < subRoute.length; j++) {
						new AMap.Polyline({
							path: subRoute[j],
							strokeColor: 'rgba(233, 168, 83, 0.1)',
							strokeWeight: 2,
							strokeDasharray: [8, 8],
							map: map,
							strokeStyle: 'dashed',
						})
					}
				})
				let target = mapData.subMapUsedVolumeDTOs.find(item => item.areaName == subBounds[i].name)
				setTimeout(() => {
					let center = getCenter(centerOrigin)

					if (target) {
						// 在子区域中心点marker
						AMap.plugin('AMap.Marker', function () {
							// 创建标注
							var marker = new AMap.Marker({
								// position: new AMap.LngLat(subBounds[i].center.lng, subBounds[i].center.lat), // 标注的经纬度位置
								position: new AMap.LngLat(center[0], center[1]), // 标注的经纬度位置
								content: createColumnChart(target.usedVolume), // 标注显示的内容
								offset: new AMap.Pixel(-26, -13), // 标注的偏移量,调整标注位置
							})
							// 将标注添加到地图上
							marker.setMap(map)
						})
					}
				}, 1000)
			}
		})
	})
}
// 根据路径获取区域的中心点
function getCenter(PolygonArr) {
	console.log('PolygonArr', PolygonArr)
	let total = PolygonArr.length
	let X = 0
	let Y = 0
	let Z = 0
	PolygonArr.forEach(lnglat => {
		let lng = (lnglat.lng * Math.PI) / 180
		let lat = (lnglat.lat * Math.PI) / 180
		let x, y, z
		x = Math.cos(lat) * Math.cos(lng)
		y = Math.cos(lat) * Math.sin(lng)
		z = Math.sin(lat)
		X += x
		Y += y
		Z += z
	})
	X = X / total
	Y = Y / total
	Z = Z / total

	let Lng = Math.atan2(Y, X)
	let Hyp = Math.sqrt(X * X + Y * Y)
	let Lat = Math.atan2(Z, Hyp)
	return [(Lng * 180) / Math.PI, (Lat * 180) / Math.PI]
}
function createColumnChart(value) {
	// 创建一个div元素作为柱形图的容器
	let circle = new URL(`../../../assets/imgs/circle.svg`, import.meta.url).href
	let union = new URL(`../../../assets/imgs/union.svg`, import.meta.url).href
	let zhutou = new URL(`../../../assets/imgs/zhutou.svg`, import.meta.url).href

	var container = document.createElement('div')
	container.style.cssText = `width:50px;height:50px;background: url(${circle}) bottom center no-repeat;position:absolute;`

	// 创建柱形图的条形部分
	var bar = document.createElement('div')
	bar.style.cssText =
		'width:18px;height:' +
		(value * 100) / 10000 +
		'px;background:url(' +
		union +
		') bottom center no-repeat;position:absolute;bottom:10px;right:16px'
	// 创建柱形头部
	var unionH = document.createElement('div')
	unionH.style.cssText =
		'width:18px;height:10px;background:url(' +
		zhutou +
		') bottom center no-repeat;position:absolute;bottom:' +
		((value * 100) / 10000 + 10) +
		'px;right:16px'
	// 创建数据显示
	var box = document.createElement('div')
	box.setAttribute('class', 'gas-count')
	box.style.cssText =
		'display: flex;align-items: center;color: #fff;background: rgba(4, 27, 60, 0.8);border: 2px solid #bbdeff;border-radius: 100px;padding: 1px 12px;width: fit-content;position:absolute;bottom:' +
		((value * 100) / 10000 + 22) +
		'px;left: 50%;transform: translate(-50%)'
	var gasnum = document.createElement('div')
	gasnum.style.cssText = 'font-size: 24px;font-weight: 700;margin-right: 4px;'
	gasnum.innerText = value
	var unit = document.createElement('span')
	unit.innerText = 'm³'
	box.appendChild(gasnum)
	box.appendChild(unit)

	// 将条形图添加到容器中
	container.appendChild(bar)
	container.appendChild(unionH)
	container.appendChild(box)

	return container
}
onMounted(() => {
	loadData()
})
</script>
<template lang="pug">
#container.wrapMap
</template>
.gas-count {
	display: flex;
	align-items: center;
	color: #fff;
	background: #041b3c;
	border: 2px solid #bbdeff;
	border-radius: 100px;
	padding: 1px 12px;
	width: fit-content;
	.num {
		font-size: 24px;
		font-weight: 700;
		margin-right: 8px;
	}
}
.wrapMap {
	flex: 1;
	position: relative;
}
#container {
	background: #020414 url('../../../assets/imgs/bg1.jpg') top center no-repeat !important;
	background-size: cover !important;
}