提交媒体地图代码
This commit is contained in:
parent
284de71a0f
commit
4fe156325e
|
@ -5,8 +5,20 @@
|
|||
<el-col :span="12">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" class="searchInputForm">
|
||||
<el-form-item label="" prop="templateName">
|
||||
<el-input v-model="queryParams.keyword" placeholder="请输入媒体名称/媒体编号/关键字" :prefix-icon="Search"
|
||||
style="width: 400px;" />
|
||||
<!-- <el-input v-model="queryParams.keyword" placeholder="请输入媒体名称/媒体编号/关键字" :prefix-icon="Search"
|
||||
style="width: 400px;" /> -->
|
||||
<el-select class="filterSelect" v-model="queryParams.keyword" filterable remote
|
||||
reserve-keyword :remote-method="getLocaleListList" :loading="selectLoading"
|
||||
@change="currentSelect" placeholder="请输入关键字" remote-show-suffix clearable
|
||||
style="width: 400px">
|
||||
<el-option v-for="item in localeList" :key="item.id" :label="item.name" :value="item"
|
||||
class="one-text">
|
||||
<div style="height: 24px; line-height: 24px;font-size: 16px;">{{ item.name }}</div>
|
||||
<div style="color: #8492a6; font-size: 12px;height: 18px; line-height: 18px;">{{
|
||||
item.address
|
||||
}}</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
|
@ -41,13 +53,31 @@ import { useBackgroundStore } from '@/store/modules/background'
|
|||
import otherbg from '@/assets/images/otherbg.png'
|
||||
|
||||
import { mediaByMap } from "@/api/mediaLibrary"
|
||||
import { rAF } from 'element-plus/es/utils/raf.mjs';
|
||||
|
||||
const bgStore = useBackgroundStore()
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const { apiKey, secretKey } = window._CONFIG
|
||||
|
||||
// map实例
|
||||
const mapInstance = ref(null)
|
||||
const massMarks = ref(null)
|
||||
const centerMarker = ref(null)
|
||||
// 当前地图模式(2D/3D)
|
||||
const mapMode = ref('2D')
|
||||
// 是否全屏状态
|
||||
const isFullscreen = ref(false)
|
||||
const placeSearch = ref(null)
|
||||
|
||||
// 热区圆实例
|
||||
const circle = ref(null);
|
||||
const circleRadius = ref(2000); // 实际半径(米)
|
||||
const circleHandle = ref(null); // 拖拽手柄
|
||||
|
||||
// 选择地点展示框
|
||||
const selectLoading = ref(false)
|
||||
const localeList = ref([])
|
||||
|
||||
// 距离显示文本
|
||||
const distanceLable = ref('请选择')
|
||||
// 选择的距离值
|
||||
|
@ -79,23 +109,211 @@ const resetQuery = () => {
|
|||
y: undefined, //中心点纬度
|
||||
distance: undefined,
|
||||
}
|
||||
handleQuery()
|
||||
// 距离显示文本
|
||||
distanceLable.value = '请选择'
|
||||
// 选择的距离值
|
||||
activeLableIndex.value = null
|
||||
circleRadius.value = 2000; // 实际半径(米)
|
||||
|
||||
// 清除现有的圆形和标记
|
||||
if (centerMarker.value) {
|
||||
mapInstance.value.remove(centerMarker.value);
|
||||
centerMarker.value = null;
|
||||
}
|
||||
if (circle.value) {
|
||||
mapInstance.value.remove(circle.value);
|
||||
circle.value = null;
|
||||
}
|
||||
if (circleHandle.value) {
|
||||
mapInstance.value.remove(circleHandle.value);
|
||||
circleHandle.value = null;
|
||||
}
|
||||
|
||||
// 重新渲染数据点
|
||||
renderMassMarks()
|
||||
}
|
||||
|
||||
|
||||
// 调用API获取地点
|
||||
const getLocaleListList = (searchValue) => {
|
||||
selectLoading.value = true
|
||||
if (searchValue !== "") {
|
||||
placeSearch.value.search(searchValue, function (status, result) {
|
||||
// 查询成功时,result即对应匹配的POI信息
|
||||
console.log(result.poiList, result.poiList.pois, result.poiList.pois?.length)
|
||||
if (result.poiList.pois?.length) {
|
||||
localeList.value = result.poiList?.pois
|
||||
}
|
||||
selectLoading.value = false
|
||||
});
|
||||
}
|
||||
}
|
||||
// 中心点选择
|
||||
const currentSelect = (val) => {
|
||||
console.log('val', val)
|
||||
queryParams.value.keyword = val.name
|
||||
queryParams.value.x = val.location.lng
|
||||
queryParams.value.y = val.location.lat
|
||||
queryParams.value.distance = circleRadius.value
|
||||
|
||||
// 距离显示文本
|
||||
distanceLable.value = '2000米'
|
||||
// 选择的距离值
|
||||
activeLableIndex.value = 2000
|
||||
|
||||
// 清除现有的圆形和标记
|
||||
if (circle.value) {
|
||||
mapInstance.value.remove(circle.value);
|
||||
circle.value = null;
|
||||
}
|
||||
if (circleHandle.value) {
|
||||
mapInstance.value.remove(circleHandle.value);
|
||||
circleHandle.value = null;
|
||||
}
|
||||
|
||||
createCircle(val)
|
||||
addCenterMark(val)
|
||||
}
|
||||
// 创建中心点标记
|
||||
const addCenterMark = (val) => {
|
||||
if (centerMarker.value) mapInstance.value.remove(centerMarker.value);
|
||||
centerMarker.value = new AMap.Marker({
|
||||
position: [val.location.lng, val.location.lat],
|
||||
title: val.name,
|
||||
zIndex: 100,
|
||||
draggable: false, // 是否可以拖拽
|
||||
cursor: 'move'
|
||||
});
|
||||
// 将点添加到地图
|
||||
mapInstance.value.add(centerMarker.value);
|
||||
mapInstance.value.setFitView();
|
||||
}
|
||||
|
||||
// 创建圆形热区
|
||||
const createCircle = (val) => {
|
||||
// 创建圆形覆盖物
|
||||
circle.value = new AMap.Circle({
|
||||
center: [val.location.lng, val.location.lat],
|
||||
radius: circleRadius.value,
|
||||
strokeColor: '#4e54c8',
|
||||
strokeOpacity: 0.8,
|
||||
strokeWeight: 2,
|
||||
fillColor: '#4e54c8',
|
||||
fillOpacity: 0.15,
|
||||
zIndex: 100,
|
||||
bubble: true,
|
||||
cursor: 'move',
|
||||
draggable: false // 是否可以拖拽
|
||||
});
|
||||
|
||||
// 将圆形添加到地图
|
||||
mapInstance.value.add(circle.value);
|
||||
|
||||
// 创建圆形边缘拖拽手柄
|
||||
createCircleHandle();
|
||||
|
||||
// 渲染数据点
|
||||
renderMassMarks()
|
||||
}
|
||||
|
||||
|
||||
// 创建圆形边缘拖拽手柄
|
||||
const createCircleHandle = () => {
|
||||
// 计算手柄的初始位置(圆形右侧边缘)
|
||||
const center = circle.value.getCenter();
|
||||
const radius = circle.value.getRadius();
|
||||
// 更精确地计算手柄位置
|
||||
const handlePosition = new AMap.LngLat(
|
||||
center.lng + radius / (111320 * Math.cos(center.lat * Math.PI / 180)),
|
||||
center.lat
|
||||
);
|
||||
console.log('手柄', handlePosition)
|
||||
// 创建手柄标记
|
||||
circleHandle.value = new AMap.Marker({
|
||||
position: [handlePosition.lng, handlePosition.lat],
|
||||
icon: new AMap.Icon({
|
||||
size: new AMap.Size(20, 20),
|
||||
image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
|
||||
imageSize: new AMap.Size(20, 20)
|
||||
}),
|
||||
offset: new AMap.Pixel(-10, -10),
|
||||
zIndex: 101,
|
||||
draggable: true,
|
||||
cursor: 'pointer'
|
||||
});
|
||||
|
||||
mapInstance.value.add(circleHandle.value);
|
||||
|
||||
// 监听手柄拖拽事件
|
||||
circleHandle.value.on('dragging', (e) => {
|
||||
const handlePos = e.lnglat;
|
||||
const center = circle.value.getCenter();
|
||||
const newRadius = Math.round(calculateDistance(center, handlePos));
|
||||
circleRadius.value = newRadius;
|
||||
distanceLable.value = `${Math.round(circleRadius.value)}米`;
|
||||
queryParams.value.distance = circleRadius.value // 更改查询条件距离
|
||||
if (circleRadius.value !== 1000 && circleRadius.value !== 2000 && circleRadius.value !== 3000 && circleRadius.value !== 5000) activeLableIndex.value = null
|
||||
else activeLableIndex.value = circleRadius.value
|
||||
circle.value.setRadius(newRadius);
|
||||
});
|
||||
|
||||
circleHandle.value.on('dragend', () => {
|
||||
// 拖拽结束后更新手柄位置
|
||||
updateCircleHandlePosition();
|
||||
// 重新渲染数据点
|
||||
renderMassMarks()
|
||||
});
|
||||
}
|
||||
// 更新圆形拖拽手柄位置
|
||||
const updateCircleHandlePosition = () => {
|
||||
if (!circle.value || !circleHandle.value) return;
|
||||
|
||||
const center = circle.value.getCenter();
|
||||
const radius = circle.value.getRadius();
|
||||
|
||||
const handlePosition = new AMap.LngLat(
|
||||
center.lng + radius / (111320 * Math.cos(center.lat * Math.PI / 180)),
|
||||
center.lat
|
||||
);
|
||||
|
||||
circleHandle.value.setPosition(handlePosition);
|
||||
};
|
||||
// 计算两点之间的距离(米)
|
||||
const calculateDistance = (point1, point2) => {
|
||||
const lng1 = point1.lng;
|
||||
const lat1 = point1.lat;
|
||||
const lng2 = point2.lng;
|
||||
const lat2 = point2.lat;
|
||||
|
||||
const radLat1 = lat1 * Math.PI / 180.0;
|
||||
const radLat2 = lat2 * Math.PI / 180.0;
|
||||
const a = radLat1 - radLat2;
|
||||
const b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
|
||||
|
||||
let distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
|
||||
Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
|
||||
distance = distance * 6378.137;
|
||||
distance = Math.round(distance * 10000) / 10;
|
||||
|
||||
return distance;
|
||||
};
|
||||
|
||||
// 选择距离
|
||||
const handleChangeDistance = (itemDistance) => {
|
||||
queryParams.value.distance = itemDistance.value
|
||||
activeLableIndex.value = itemDistance.value
|
||||
distanceLable.value = itemDistance.label
|
||||
distanceLable.value = itemDistance.value + '米'
|
||||
|
||||
// 更新热区
|
||||
circleRadius.value = itemDistance.value;
|
||||
circle.value.setRadius(itemDistance.value);
|
||||
updateCircleHandlePosition();
|
||||
|
||||
// 重新渲染数据点
|
||||
renderMassMarks()
|
||||
}
|
||||
|
||||
// map实例
|
||||
const mapInstance = ref(null)
|
||||
const massMarks = ref(null)
|
||||
// 当前地图模式(2D/3D)
|
||||
const mapMode = ref('2D')
|
||||
// 是否全屏状态
|
||||
const isFullscreen = ref(false)
|
||||
|
||||
// 初始化地图
|
||||
const loadMap = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -106,7 +324,7 @@ const loadMap = () => {
|
|||
|
||||
AMapLoader.load({
|
||||
key: apiKey,
|
||||
plugins: [],
|
||||
plugins: ["AMap.PlaceSearch"],
|
||||
AMapUI: {
|
||||
plugins: []
|
||||
}
|
||||
|
@ -117,18 +335,23 @@ const loadMap = () => {
|
|||
|
||||
mapInstance.value = new AMap.Map("mapContainer", {
|
||||
resizeEnable: true,
|
||||
zoom: 14,
|
||||
center: [116.397428, 39.90923], // 默认中心点
|
||||
// center: [116.397428, 39.90923], // 默认中心点
|
||||
pitch: initialPitch, // 倾斜角度决定2D/3D模式
|
||||
rotation: initialRotation, // 旋转角度
|
||||
buildingAnimation: true,
|
||||
expandZoomRange: true,
|
||||
zooms: [3, 20],
|
||||
// buildingAnimation: true,
|
||||
// expandZoomRange: true,
|
||||
zoom: 16,
|
||||
zooms: [3, 16],
|
||||
viewMode: mapMode.value // 启用3D视图
|
||||
});
|
||||
|
||||
// 先添加基本控件
|
||||
mapInstance.value.setZoom(14);
|
||||
// // 先添加基本控件
|
||||
mapInstance.value.setZoom(16);
|
||||
|
||||
placeSearch.value = new AMap.PlaceSearch({
|
||||
// city 指定搜索所在城市,支持传入格式有:城市名、citycode和adcode
|
||||
city: '全国'
|
||||
})
|
||||
|
||||
// 添加自定义控件容器
|
||||
addCustomControls(AMap);
|
||||
|
@ -141,6 +364,8 @@ const loadMap = () => {
|
|||
// 监听地图渲染完成事件
|
||||
mapInstance.value.on('render', hideAmapLogo);
|
||||
|
||||
// 添加缩放变化监听
|
||||
mapInstance.value.on('zoomchange', handleZoomChange);
|
||||
// 在地图完全加载后执行点数据处理
|
||||
renderMassMarks();
|
||||
|
||||
|
@ -152,6 +377,15 @@ const loadMap = () => {
|
|||
});
|
||||
});
|
||||
}
|
||||
// 处理地图缩放事件
|
||||
const handleZoomChange = () => {
|
||||
const currentZoomLevel = mapInstance.value.getZoom();
|
||||
// 如果缩放级别超过16,自动调整回16
|
||||
if (currentZoomLevel > 16) {
|
||||
mapInstance.value.setZoom(16);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 添加自定义控件
|
||||
const addCustomControls = (AMap) => {
|
||||
// 创建控件容器
|
||||
|
@ -312,7 +546,7 @@ const renderMassMarks = () => {
|
|||
if (itemPoint.businessType == 2) points.value.push({ "lnglat": [itemPoint.x, itemPoint.y], "name": itemPoint.mediaId, "style": 1 })
|
||||
});
|
||||
}
|
||||
}).then(res => {
|
||||
}).then(res => {
|
||||
console.log('points', points.value)
|
||||
// 创建MassMarks对象
|
||||
massMarks.value = new AMap.MassMarks(points.value, {
|
||||
|
@ -342,7 +576,9 @@ const hideAmapLogo = () => {
|
|||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
mapInstance.value?.destroy()
|
||||
if (mapInstance.value) {
|
||||
mapInstance.value.destroy();
|
||||
}
|
||||
})
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
|
@ -524,4 +760,9 @@ onMounted(() => {
|
|||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.one-text {
|
||||
height: 50px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user