Bootstrap

vue2 vue3 获取当前位置坐标(Navigator.geolocation AMap.Geo) 引用高德地图在地图上标点获取坐标 @amap/amap-jsapi-loader vue-amap

一、安装插件

amap-jsapi-loader:

amap-jsapi-loader 是一个 JavaScript 库,用于加载和管理高德地图 JavaScript API。

主要功能是帮助在网页中动态加载高德地图 API,使开发者可以更灵活地控制地图加载时机。

使用 amap-jsapi-loader 可以避免在页面加载时一次性加载整个高德地图 API,从而提高网页性能和加载速度。

适合那些希望动态加载高德地图 API 的开发者或对地图加载性能有要求的项目。

npm install @amap/amap-jsapi-loader --save

vue-amap:

vue-amap 是一个针对 Vue.js 框架的高德地图组件库,提供了在 Vue 项目中方便集成和使用高德地图的功能。

主要用于在 Vue.js 项目中展示高德地图和与地图交互,提供了一系列 Vue 组件用于方便地操作地图和地图相关功能。

vue-amap 封装了常用的地图操作、事件处理等功能,提供了更加友好的 Vue 组件接口。

适合在 Vue.js 项目中快速集成和使用高德地图服务的开发者。

npm install vue-amap --save

二、具体代码

vue2版本在地图上标点获取坐标如下:

<template>
	<div class="map-container">
		<div id="mapconPosition" class="map" tabindex="0"></div>
		<div id="mappickerBox">
			<input id="mappickerInput" placeholder="请输入关键字选取地点" />
			<div id="mappoiInfo"></div>
		</div>
	</div>
</template>

<script>
import AMapLoader from '@amap/amap-jsapi-loader';

export default {
	data() {
		return {
			myCity: '',
			mapSta: null,
			map: null,
			MyMap: null,
			path: [],
			current_position: [],
			markerList: [],
			circleList: [],
		};
	},
	props: {
		positionProp: {
			type: String,
			required: false,
		},
		positionStatus: {
			type: Object,
			required: false,
		},
	},
	computed: {},
	mounted() {
		if (this.positionStatus) {
			this.mapSta = this.positionStatus.sta;
		}
		this.initMap();
	},
	beforeDestroy() {
		// 销毁地图,并清空地图容器
		this.map.destroy();
	},
	methods: {
		initMap() {
			AMapLoader.load({
				key: "xxxxxxxxxxxxxxxxxxx", // 申请好的Web端开发者Key,首次调用 load 时必填
				version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
				// plugins:[''], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
				AMapUI: { // 重点就是这个
					version: '1.1',
					plugins: ['misc/PoiPicker'], // 需要加载的 AMapUI ui插件
				},
			}).then((AMap) => {
				this.MyMap = AMap; // 保存AMap
				this.map = new this.MyMap.Map("mapconPosition", { // 设置地图容器id
					viewMode: "3D", // 是否为3D地图模式
					zoom: 13, // 初始化地图级别
					center: [xxxxxx, xxxxxxx], // 初始化地图中心点位置
				});

				if (this.positionProp) {
					this.path.push(this.positionProp.split(','));
					this.addMarker(this.positionProp.split(','));
				}

				if (this.mapSta === 'view') {
					return;
				}

				AMapUI.loadUI(['misc/PoiPicker'], function (PoiPicker) {
					var poiPicker = new PoiPicker({
						// city: 'xxxxxxx',
						input: 'mappickerInput',
					});

					// 初始化poiPicker
					window.poiPicker = poiPicker;

					// 选取了某个POI
					poiPicker.on('poiPicked', function (poiResult) {
						var source = poiResult.source,
							poi = poiResult.item,
							info = {
								source: source,
								id: poi.id,
								name: poi.name,
								location: poi.location.toString(),
								address: poi.address,
							};

						if (this.path.length === 5) {
							this.$modal.msgWarning("仅允许选择5个地址坐标!");
							return;
						}

						this.path.push([poi.location.lng, poi.location.lat]);
						this.$emit('positionEvent', this.path);

						this.addMarker(poi.location);
					}.bind(this));
				}.bind(this));

				// 单击
				this.map.on('click', (e) => {
					if (this.path.length === 5) {
						this.$modal.msgWarning("仅允许选择5个地址坐标!");
						return;
					}
					this.current_position = [e.lnglat.lng, e.lnglat.lat];
					this.path.push([e.lnglat.lng, e.lnglat.lat]);
					this.$emit('positionEvent', this.path);
					this.addMarker(this.current_position);
				});
			}).catch((e) => {
				console.log(e);
			});
		},

		addMarker(curposition) {
			console.log(curposition);
			const marker = new this.MyMap.Marker({
				icon: "xxxxxxxxxx",// icon地址 或者 base64格式也可以
				position: curposition, // 这里我们通过上面的点击获取经纬度坐标,实时添加标记
				offset: new this.MyMap.Pixel(-11, -30),
			});
			const circle= new this.MyMap.Circle({
				center: new this.MyMap.LngLat(curposition[0] ? curposition[0] : curposition.lng, curposition[1] ? curposition[1] : curposition.lat), // 圆心位置
				radius: 500,  //半径
				strokeColor: "#2c92ff",  //线颜色
				strokeOpacity: 1,  //线透明度
				strokeWeight: 3,  //线粗细度
				fillColor: "#a3d1ee",  //填充颜色
				fillOpacity: 0.35, //填充透明度
				bubble:true
			});
			
			marker.setMap(this.map);
			this.map.add(circle);
			this.circleList.push(circle);
			this.map.setCenter(marker.getPosition());
			this.markerList.push(marker);

			this.MyMap.Event.addListener(marker, "click", this.handleQuery); // 注册监听,当选中某条记录时会触发
		},

		handleQuery(Event) {
			let value1 = null;
			let value2 = null;
			if (Event.target._position.lng) {
				value1 = Event.target._position.lng;
				value2 = Event.target._position.lat;
			} else {
				value1 = Event.target._position[0];
				value2 = Event.target._position[1];
			}

			let num = null;
			this.path.forEach((item, index) => {
				if (item[0] === value1 && item[1] === value2) {
					num = index;
				}

				if (index === this.path.length - 1 && num !== null) {
					this.path.splice(num, 1);
					this.markerList.splice(num, 1);
					this.circleList.splice(num, 1);

					this.$emit('positionEvent', this.path);
					this.map.clearMap();
					this.map.add(this.circleList);
					this.map.add(this.markerList);
				}
			});
		},
	},
};
</script>

<style lang='scss' scoped>
.map-container {
	position: relative;
	// border: 1px solid red;
	width: 100%;
	height: 100%;
	padding: 0px;
	// height: 800px;
}

#mapconPosition {
	width: 100%;
	height: 100%;
	margin: 0px;
	font-size: 13px;
}

#mappickerBox {
	position: absolute;
	z-index: 9999;
	top: 10px;
	right: 5px;
	width: 300px;

	::v-deep .sugg-no-id {
		display: none;
	}

	::v-deep .amap-ui-poi-picker-sugg-container {
		width: 292px;
	}
}

#mappickerInput {
	width: 292px;
	padding: 9px 5px 10px 5px;
}

#mappoiInfo {
	background: #fff;
}

.amap_lib_placeSearch .poibox.highlight {
	background-color: #CAE1FF;
}

.amap_lib_placeSearch .poi-more {
	display: none !important;
}
</style>

vue3版本在地图上标点获取坐标如下:

<template>
    <div class="app-container">
        <div id="mapconPosition" class="map" tabindex="0"></div>
        <div id="mappickerBox">
            <input id="mappickerInput" placeholder="请输入关键字选取地点" />
            <div id="mappoiInfo"></div>
        </div>
    </div>
</template>
 
<script setup name="AMap">
import AMapLoader from '@amap/amap-jsapi-loader';

import { shallowRef } from '@vue/reactivity';
const { proxy } = getCurrentInstance();
import { ref } from "vue";
let myCity = ref('');
let mapSta = ref(null);

let map = shallowRef(null);
let MyMap = null;

const path = ref([]);
const current_position = ref([]);
const markerList = ref([]);
const emit = defineEmits(['positionEvent']);
const props = defineProps({
    positionProp: {
        type: String,
        required: false
    },
    positionStatus: {
        type: Object,
        required: false
    }
});

onMounted(() => {
    if (props.positionStatus) {
        mapSta.value = props.positionStatus.sta;
    }
    initMap();
});

onUnmounted(() => {
    // 销毁地图,并清空地图容器
    map.destroy();
});

function initMap() {

    AMapLoader.load({
        key: "xxxxxxxxxxxxxxxxxxxx", // 申请好的Web端开发者Key,首次调用 load 时必填
        version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
        // plugins:[''], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        AMapUI: {//重点就是这个
            version: '1.1',
            plugins: ['misc/PoiPicker']// 需要加载的 AMapUI ui插件
        }
    }).then((AMap) => {
        MyMap = AMap;// 保存AMap
        map = new MyMap.Map("mapconPosition", {  //设置地图容器id
            viewMode: "3D",    //是否为3D地图模式
            zoom: 13,           //初始化地图级别
            center: [xxxxxxx, xxxxxxxxxxx], //初始化地图中心点位置
        });
        if (props.positionProp) {
            path.value.push(props.positionProp.split(','));
            addMarker(props.positionProp.split(','));
        }

        if (mapSta.value == 'view') {
            return;
        }

        AMapUI.loadUI(['misc/PoiPicker'], function (PoiPicker) {
            var poiPicker = new PoiPicker({
                // city: 'xxxxxxxxx',
                input: 'mappickerInput'
            });

            window.poiPicker = poiPicker;

            //选取了某个POI
            poiPicker.on('poiPicked', function (poiResult) {
                var source = poiResult.source,
                    poi = poiResult.item,
                    info = {
                        source: source,
                        id: poi.id,
                        name: poi.name,
                        location: poi.location.toString(),
                        address: poi.address
                    };

                if (path.value.length == 1) {
                    proxy.$modal.msgWarning("仅允许选择一个地址坐标!");
                    return;
                }

                path.value.push([poi.location.lng, poi.location.lat]);
                emit('positionEvent', path.value);
                addMarker(poi.location);
            });
        });

        // 单击
        map.on('click', (e) => {
            if (path.value.length == 1) {
                proxy.$modal.msgWarning("仅允许选择一个地址坐标!");
                return;
            }
            current_position.value = [e.lnglat.lng, e.lnglat.lat];
            path.value.push([e.lnglat.lng, e.lnglat.lat]);
            emit('positionEvent', path.value);
            addMarker(current_position.value);
        });
    }).catch(e => {
        console.log(e);
    });
}

function addMarker(curposition) {
    const marker = new MyMap.Marker({
        icon: "xxxxxxxxxxxx",
        position: curposition, // 这里我们通过上面的点击获取经纬度坐标,实时添加标记
        offset: new MyMap.Pixel(-11, -30),
    });
    marker.setMap(map);
    map.setCenter(marker.getPosition());
    markerList.value.push(marker);

    MyMap.Event.addListener(marker, "click", handleQuery);//注册监听,当选中某条记录时会触发
}

function handleQuery(Event) {

    let value1 = null;
    let value2 = null;
    if (Event.target._position.lng) {
        value1 = Event.target._position.lng;
        value2 = Event.target._position.lat;
    } else {
        value1 = Event.target._position[0];
        value2 = Event.target._position[1];
    }

    let num = null;
    path.value.forEach((item, index) => {
        if (item[0] == value1 && item[1] == value2) {
            num = index;
        }

        if (index == path.value.length - 1 && num != null) {
            path.value.splice(num, 1);
            markerList.value.splice(num, 1);
            emit('positionEvent', path.value);

            map.clearMap();
            map.add(markerList.value);
        }
    });
}
</script>

<style lang='scss' scoped>
.app-container {
    position: relative;
    width: 100%;
    height: 100%;
    padding: 0px;
}

#mapconPosition {
    width: 100%;
    height: 100%;
    margin: 0px;
    font-size: 13px;
}

#mappickerBox {
    position: absolute;
    z-index: 9999;
    top: 50px;
    right: 30px;
    width: 300px;

    :deep(.sugg-no-id) {
        display: none;
    }

    :deep(.amap-ui-poi-picker-sugg-container) {
        width: 292px;
    }
}

#mappickerInput {
    width: 292px;
    padding: 9px 5px 10px 5px;
}

#mappoiInfo {
    background: #fff;
}

.amap_lib_placeSearch .poibox.highlight {
    background-color: #CAE1FF;
}

.amap_lib_placeSearch .poi-more {
    display: none !important;
}
</style>

三、获取当前位置坐标

其一:AMap.Geolocation 插件

定位-参考手册-地图 JS API 1.4 | 高德地图API

高德地图查看经纬度信息

坐标拾取器 | 高德地图API

其二:Navigator.geolocation
export const getPosition = (
    timeout = 10000,
    maximumAge = 60000,
    enableHighAcuracy = false
) =>
    new Promise((resolve, reject) => {
        if (!navigator && !navigator.geolocation) {
            return reject(new Error("浏览器不支持定位!"));
        }

        const success = (loc) => {
            const location = {
                latitude: loc.coords.latitude, // 纬度
                longitude: loc.coords.longitude, // 经度
                accuracy: loc.coords.accuracy, // 精确度
            };
            resolve(location);
        };

        const error = (err) => {
            var errorType = [
                "您已拒绝请求地理位置信息!",
                "获取不到位置信息!",
                "获取位置信息超时!",
            ];
            reject(errorType[err.code - 1]);
        };

        navigator.geolocation.getCurrentPosition(success, error, {
            enableHighAcuracy, // 指示浏览器获取高精度的位置,默认为false
            timeout, // 指定获取地理位置的超时时间,默认不限时,单位为毫秒
            maximumAge, // 最长有效期,在重复获取地理位置时,此参数指定多久再次获取位置。
        });
    });

;