高德地图选择多个marker点

<template>
    <div class="container-multimap">
        <div class="searchBox">
            <el-input v-model="searchQuery" @keyup.enter="searchPlace" border placeholder="搜索地点" />
            <el-button @click="searchPlace" type="success">搜索</el-button>
            <el-button @click="clearMarkers" type="success">清空</el-button>
        </div>
        <div id="mapContainer" style="width: 100%; height:55vh;"></div>
    </div>
</template>

<script>
import AMapLoader from "@amap/amap-jsapi-loader"; //引入AMapLoader
import { getRandomAvatar } from "@/api/robot/manage.js"
export default {
    name: 'Map',
    props: {
        markersArray: {
            type: Array,
            default: []
        }
    },
    data() {
        return {
            map: null,
            markers: [], // 存储所有的标记点
            searchQuery: '',// 搜索查询
            placeSearch: null
        };
    },
    mounted() {
        this.initMap();
    },
    watch: {},
    methods: {
        initMap() {
            AMapLoader.load({
                key: "key", // 申请好的Web端开发者Key,首次调用 load 时必填
                version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
                plugins: ["AMap.Geocoder"],
            })
            // 初始化地图
            this.map = new AMap.Map('mapContainer', {
                center: [120.264777, 30.221391], // 地图中心点
                zoom: 14 // 地图缩放级别
            });
            // 监听地图的点击事件
            this.map.on('click', this.addMarker);
        },
        async addMarker(event) {
            let position = ''
            let markerAddress = ''
            // 获取点击的位置
            if (event.type == "markerClick") {
                event = event.data
                position = [event.location.lng, event.location.lat];
                markerAddress = event.name
            } else {
                position = event.lnglat ? [event.lnglat.getLng(), event.lnglat.getLat()] : event;
                markerAddress = await this.getAddress(position)
            }
            // 生成唯一的ID
            const id = Date.now();
            let markerContent = document.createElement('div')
            let txtContent = document.createElement('div')
            let imgContent = document.createElement('img')
            imgContent.src = "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png";
            markerContent.className = 'custom-content-marker'
            markerContent.appendChild(imgContent);
            // 添加地址文字描述
            txtContent.className = 'txt-content'
            txtContent.innerHTML = markerAddress
            markerContent.appendChild(txtContent);

            // 添加删除按钮
            let deleteButton = document.createElement('div');
            deleteButton.innerHTML = 'X';
            deleteButton.className = 'close-btn';
            deleteButton.style.position = 'absolute';
            markerContent.appendChild(deleteButton);
            // 创建一个新的标记点
            let marker = new AMap.Marker({
                position: position,
                content: markerContent,
                map: this.map,
                extData: { id }, // 写入你的item对象,必须要加{
                offset: new AMap.Pixel(0, 0)
            });
            marker.on('click', (e) => {
                marker.setMap(null)
                let clickId = e.target.getExtData().id
                this.markers = this.markers.filter(m => m.id !== clickId);
                this.$emit('update:markersArray', this.markers)
            });
            // 将标记点存储到 markers 数组中
            const [lng, lat] = position
            const { data: { avatar, name, gender } } = await getRandomAvatar()
            this.markers.push({ id, marker, lng, lat, markerAddress, avatar, name, gender });
            this.$emit('update:markersArray', this.markers)
        },
        searchPlace() {
            if (!this.searchQuery) {
                return;
            }
            // 创建PlaceSearch实例
            this.placeSearch = new AMap.PlaceSearch({
                map: this.map
            });
            // 搜索查询
            this.placeSearch.search(this.searchQuery, (status, result) => {
                if (status === 'complete' && result.info === 'OK') {
                    // 设置地图中心到第一个搜索结果
                    if (result.poiList.pois.length > 0) {
                        this.map.setCenter(result.poiList.pois[0].location);
                    }
                } else {
                    alert('搜索失败,请重试');
                }
            });
            this.placeSearch.on('markerClick', this.addMarker)
        },
        clearMarkers() {
            this.markers.forEach(m => {
                m.marker.setMap(null);
            });
            this.markers = [];
            this.$emit('update:markersArray', this.markers)
            this.placeSearch.clear()
        },
        getAddress(position) {
            return new Promise((resolve, reject) => {
                let geocoder = new AMap.Geocoder({});
                geocoder.getAddress(position, (status, result) => {
                    if (status === "complete" && result.regeocode) {
                        const { regeocode: {
                            formattedAddress
                        } } = result
                        resolve(formattedAddress)
                    }
                });
            })
        },
        handlerMarker(id) {
            this.markers.forEach(m => {
                if (m.id == id) {
                    m.marker.setMap(null)
                }
            });
            this.markers = this.markers.filter(m => m.id !== id);
            this.$emit('update:markersArray', this.markers)
        }
    }
};
</script>

<style>
#mapContainer {
  width: 400px;
  height: 200px;
}
.searchBox {
  position: absolute;
  top: 20px;
  right: 20px;
  display: flex;
  z-index: 1;
}
.custom-content-marker {
  z-index: 1;
  position: relative;
  width: 40px;
  height: 50px;
}

.custom-content-marker img {
  position: absolute;
  top: -50px;
  left: -20px;
  width: 100%;
  height: 100%;
}

.custom-content-marker .close-btn {
  position: absolute;
  top: -106px;
  right: -10px;
  width: 15px;
  height: 15px;
  font-size: 12px;
  background: #ccc;
  border-radius: 50%;
  color: #fff;
  text-align: center;
  line-height: 15px;
  box-shadow: -1px 1px 1px rgba(10, 10, 10, 0.2);
}

.custom-content-marker .close-btn:hover {
  background: #666;
}
.txt-content {
  position: absolute;
  top: -100px;
  right: 0;
  color: #fff;
  padding: 4px;
  box-shadow: 1px 1px 1px rgba(10, 10, 10, 0.2);
  white-space: nowrap;
  font-size: 12px;
  font-family: "";
  background-color: #25a5f7;
  border-radius: 3px;
}
</style>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Vue 3 中结合 TypeScript 使用高德地图 (AMap) 实现添加多个标记(Marker)可以分为以下几个步骤: 1. **安装依赖**: 首先需要安装 `vue-amap` 和 `typescript` 的支持库。你可以通过 npm 或者 yarn 进行安装: ```bash npm install vue-amap @types/amapjs @types/vue --save ``` 2. **配置 AMap SDK**: 在 `main.ts` 或者 `amap-vue.config.js` 中引入并初始化 AMap API: ```typescript import { createApp } from 'vue' import App from './App.vue' import Amap from 'vue-amap' Amap.initAMapApiLoader({ key: 'your_amap_key', // 在高德官网获取您的 API 密钥 plugin: ['AMap.Geolocation', 'AMap.Marker', 'AMap.PolyEditor'], }) const app = createApp(App) app.use(Amap).mount('#app') ``` 3. **创建 Marker 组件**: 创建一个自定义组件,比如 `Marker.vue`,包含地址和击事件: ```typescript <template> <div class="marker"> <a-amap-marker :position="position" @click="onClick"></a-amap-marker> </div> </template> <script lang="ts"> import { Component, Prop } from 'vue' import { AMapComponent, AMapPosition } from 'vue-amap'; export default class Marker extends AMapComponent { @Prop({ required: true }) position!: AMapPosition; onClick() { console.log('Marker clicked:', this.position); } } </script> ``` 4. **在父组件中使用 Marker**: 父组件里实例化并传入地址数据: ```html <template> <div id="app"> <Marker v-for="(location, index) in locations" :key="index" :position="location" /> </div> </template> <script lang="ts"> import Marker from '@/components/Marker.vue'; export default { components: { Marker, }, data() { return { locations: [ { latitude: ..., longitude: ... }, // 标记的经纬度 ... // 添加更多的标记 ], }; }, }; </script> ``` 5. **样式及美化**: 可以根据需要为 `.marker` 类添加样式,调整图标、图标大小等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值