效果如图
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;
}