vue或uni-app的高德地图marker功能实现

<template>
	<div class="m-map">
		<!-- <picker style="z-index: 9999;background: #4A9FF4;color: #FFFDEF;" @change="bindPickerChange" :value="index" :range="array">
			<div
				class="uni-input"
				style="text-align: center;line-height: 40px;width: 40px;height: 40px;z-index: 999;background: #4A9FF4;border-radius: 60upx;position: fixed;top: 100upx;right: 32upx;"
			>
				分类
			</div>
		</picker> -->
		<div id="js-container" class="map">正在加载中 ...</div>
	</div>
</template>

<script>
const MapKey = '43fcce2baefbd309a4afe81279946689';
const MapCityName = '北京';
export default {
	props: ['lat', 'lng', 'defaultV'],
	data() {
		return {
			list: [],
			address: undefined,
			index: 0,
			array: ['全部', '银行', '保险'],
			placeSearch: null,
			dragStatus: false,
			AMapUI: null,
			AMap: null
		};
	},
	watch: {
		defaultV() {
			console.log(this.defaultV);
			if (this.defaultV !== undefined) {
				console.log(this.defaultV);
			}
		}
	},
	async created() {
		function remoteLoad(url, hasCallback) {
			return createScript(url);
			/**
			 * 创建script
			 * @param url
			 * @returns {Promise}
			 */
			function createScript(url) {
				let scriptElement = document.createElement('script');
				document.body.appendChild(scriptElement);
				let promise = new Promise((resolve, reject) => {
					scriptElement.addEventListener(
						'load',
						e => {
							removeScript(scriptElement);
							if (!hasCallback) {
								resolve(e);
							}
						},
						false
					);

					scriptElement.addEventListener(
						'error',
						e => {
							removeScript(scriptElement);
							reject(e);
						},
						false
					);

					if (hasCallback) {
						window.____callback____ = function() {
							resolve();
							window.____callback____ = null;
						};
					}
				});

				if (hasCallback) {
					url += '&callback=____callback____';
				}

				scriptElement.src = url;

				return promise;
			}

			/**
			 * 移除script标签
			 * @param scriptElement script dom
			 */
			function removeScript(scriptElement) {
				document.body.removeChild(scriptElement);
			}
		}
		// 已载入高德地图API,则直接初始化地图
		if (window.AMap && window.AMapUI) {

			uni.request({
				url: 'https://www.yunfucpa.com/manage/Wx/map/list',
				method: 'GET',
				success: res => {
					this.list = res.data.data;
					this.initMap();
				}
			});
		} else {
			await remoteLoad(`https://webapi.amap.com/maps?v=1.4.4&key=${MapKey}&plugin=AMap.Geocoder,AMap.PlaceSearch,AMap.ToolBar`);
			await remoteLoad('https://webapi.amap.com/ui/1.0/main.js');

			uni.request({
				url: 'https://www.yunfucpa.com/manage/Wx/map/list',
				method: 'GET',
				success: res => {
					this.list = res.data.data;
					this.initMap();
				}
			});
		}
	},
	methods: {
		 getData(industry) {
			if (industry && industry != '全部') {
				uni.request({
					url: 'https://www.yunfucpa.com/manage/Wx/map/list?industry=' + industry,
					method: 'GET',
					success: res => {
						this.list = res.data.data;
						this.initMap();
					}
				});
			} else {
				uni.request({
					url: 'https://www.yunfucpa.com/manage/Wx/map/list',
					method: 'GET',
					success: res => {
						this.list = res.data.data;
					}
				});
			}
		},
		bindPickerChange: function(e) {
			console.log('picker发送选择改变,携带值为', e.target.value);
			this.index = e.target.value;
			this.getData(this.array[e.target.value]);
		},
		// 搜索
		handleSearch() {
			if (this.searchKey) {
				this.placeSearch.search(this.searchKey);
			}
		},
		// 实例化地图
		initMap() {
			let AMapUI = (this.AMapUI = window.AMapUI);
			let AMap = (this.AMap = window.AMap);
			let that = this;
			AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
				let mapConfig = {
					zoom: 14,
					center: [112.04851, 22.926136],
					cityName: MapCityName
				};
				let map = new AMap.Map('js-container', mapConfig);
				let list = this.list;
				let markers = [];
				for (var i = 0; i < list.length; i++) {
					var marker = new AMap.Marker({
						position: [list[i].lng, list[i].lat],
						icon: new AMap.Icon({
							image: 'https://www.yunfucpa.com/file/img/marker.png',
							size: new AMap.Size(40, 40), //图标大小
							imageSize: new AMap.Size(40, 40)
						}),
						offset: new AMap.Pixel(-23, -30)
					});

					marker.setMap(map);

					// label默认蓝框白底左上角显示,样式className为:amap-marker-label
					marker.setLabel({
						offset: new AMap.Pixel(20, -30), //设置文本标注偏移量
						content: "<div class='info' style='padding: 3px 5px;'>" + list[i].name + '</div>', //设置文本标注内容
						direction: 'right' //设置文本标注方位
					});
					map.addControl(new AMap.ToolBar());
					marker.positon = list[i].id;
					//鼠标点击marker弹出自定义的信息窗体
					marker.on('click', function(e) {
						uni.request({
							url: 'https://www.yunfucpa.com/manage/Wx/map/detail/' + e.target.positon,
							method: 'GET',
							success: res => {
								console.error(res);
								var data = res.data.data;
								if (!res.data.data.logo) {
									data.logo = 'https://www.yunfucpa.com/file/img/mem_11.jpg';
								}
								if (!res.data.data.phone) {
									data.phone = '暂无联系电话';
								}
								//实例化信息窗体
								var content = [];
								content.push(
									"<div id='close' style='color: #333333;font-size:16px;textAlign:center;margin-bottom:10px'><img src='" +
										data.logo +
										"' style='height:30px;border-radius:4px;margin-right:12px'></img>" +
										data.name +
										'</div>'
								);
								content.push("<div style='font-size: 12px;color: #898989;margin-bottom:6px'>地址:" + data.address + '</div>');
								content.push("<div style='font-size: 12px;color: #898989;margin-bottom:6px'>电话:<a href='tel:" + data.phone + "'>" + data.phone + '</a></div>');
								content.push(
									"<div style='display:flex'><div style='float: left;background: #4A9FF4;margin: 0 0 0 5px;border-radius: 5px;width: 45%;text-align: center;line-height: 32px;' id='calls'>一键拨号</div><div style='float: left;background: #4A9FF4;margin: 0 0 0 5px;border-radius: 5px;width: 45%;text-align: center;line-height: 32px;' id='goPage'>一键导航</div></div>"
								);
								content.push(
									"<div id='details' style='float: left;background: #4A9FF4;margin: 8px 0 0 5px;border-radius: 5px;width: 92%;text-align: center;line-height: 32px;'>机构详情查看</div>"
								);

								infoWindow.setContent(createInfoWindow(content.join('')));
								infoWindow.open(map, e.lnglat);
								setTimeout(function() {
									var close = document.getElementById('close');
									// 详情
									close.addEventListener('click', function() {
										map.clearInfoWindow();
									});
									var details = document.getElementById('details');
									// 详情
									details.addEventListener('click', function() {
										uni.navigateTo({
											url: '/pages/map/details?id=' + data.id
										});
									});
									var calls = document.getElementById('calls');
									// 拨打电话
									calls.addEventListener('click', function() {
										window.location.href = 'tel://' + data.phone;
									});
									var goPage = document.getElementById('goPage');
									// 导航
									goPage.addEventListener('click', function() {
										marker.markOnAMAP({
											position: e.lnglat
										});
									});
								}, 500);
							},
							fail: () => {},
							complete: () => {}
						});
					});
					markers.push(marker);
				}
				map.on('click', function(e) {
					map.clearInfoWindow();
				});
				var infoWindow = new AMap.InfoWindow({
					isCustom: true, //使用自定义窗体
					offset: new AMap.Pixel(16, -30)
				});

				//构建自定义信息窗体
				function createInfoWindow(content) {
					var info = document.createElement('div');
					info.style.background = '#FFFFFF';
					info.style.width = '250px';
					info.style.height = '170px';
					info.style.textAlign = 'left';
					info.style.color = '#FFFFFF';
					info.style.padding = '16px';
					info.innerHTML = content;
					return info;
				}

				//关闭信息窗体
				function closeInfoWindow() {
					map.clearInfoWindow();
				}

				// 创建地图拖拽
				let positionPicker = new PositionPicker({
					mode: 'dragMarker', // 设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'
					map: map // 依赖地图对象
				});

				// 拖拽完成发送自定义 drag 事件
				positionPicker.on('success', positionResult => {
					this.$emit('drag', {
						address:
							positionResult.regeocode.addressComponent.district +
							positionResult.regeocode.addressComponent.township +
							positionResult.regeocode.addressComponent.street +
							positionResult.regeocode.addressComponent.streetNumber,
						lng: positionResult.position.lng,
						lat: positionResult.position.lat
					});
					this.address = positionResult.address;
					openInfo([positionResult.position.lng, positionResult.position.lat]);
				});
				if (this.lat && this.lng) {
					mapConfig.center = [this.lng, this.lat];
					positionPicker.start([this.lng, this.lat]);
					map.panBy(0, 1);
				}
				AMap.plugin('AMap.Geolocation', function() {
					var geolocation = new AMap.Geolocation({
						// 是否使用高精度定位,默认:true
						enableHighAccuracy: true,
						// 设置定位超时时间,默认:无穷大
						timeout: 10000,
						// 定位按钮的停靠位置的偏移量,默认:Pixel(10, 20)
						buttonOffset: new AMap.Pixel(10, 20),
						//  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
						zoomToAccuracy: true,
						//  定位按钮的排放位置,  RB表示右下
						buttonPosition: 'RB'
					});

					geolocation.getCurrentPosition();
					AMap.event.addListener(geolocation, 'complete', onComplete);
					AMap.event.addListener(geolocation, 'error', onError);

					function onComplete(data) {
						// data是具体的定位信息
						console.error(data);
						// map.setCenter("")
					}

					function onError(data) {
						// 定位出错
					}
				});
				// 坐标-地址转换
				var geocoder = new AMap.Geocoder({});
				AMap.plugin(['AMap.Autocomplete'], function() {
					// 输入提示
					var autoOptions = {
						input: 'complete'
					};
					var auto = new AMap.Autocomplete(autoOptions);
					var placeSearch = new AMap.PlaceSearch({}); // 构造地点查询类,注意:这里如果实例的时候设置了map,下面再自定义增加marker时,会导致marker点重复和相关的marker设置失效。
					AMap.event.addListener(auto, 'select', select); // 注册监听,当选中某条记录时会触发
					function select(e) {
						positionPicker.start([e.poi.location.lng, e.poi.location.lat]);
						map.panBy(0, 1);
						openInfo([e.poi.location.lng, e.poi.location.lat]);
						placeSearch.setCity(e.poi.adcode);
						placeSearch.setCityLimit(true);
						// placeSearch.search(e.poi.name, searchBack) // 关键字查询查询
					}
				});
				// 启用工具条
				AMap.plugin(['AMap.ToolBar'], function() {
					map.addControl(
						new AMap.ToolBar({
							position: 'RB'
						})
					);
				});
				// 在指定位置打开信息窗体
				function openInfo(lnglat) {
					// console.log(that)
					geocoder.getAddress(lnglat, function(status, result) {
						if (status === 'complete' && result.regeocode) {
							// outer.$emit('drag', {address: result.district + result.township + result.street + result.streetNumber, lng: lnglat['lng'], lat: lnglat['lat']})
							// 地址
							var address = result.regeocode.formattedAddress;
							// 构建信息窗体中显示的内容
							var info = [];
							info.push("<p class='input-item' style='margin:0; line-height:25px'><span style='font-weight: bolder'>详细地址</span>: " + address + '</p>');
							info.push(
								"<p class='input-item' style='margin:0; line-height:25px'><span style='font-weight: bolder'>附近路口</span>: " +
									result.regeocode.addressComponent.street +
									result.regeocode.addressComponent.streetNumber +
									'</p>'
							);
							info.push(
								"<p class='input-item' style='margin:0; line-height:25px'><span style='font-weight: bolder'>附近街道</span>: " +
									result.regeocode.addressComponent.township +
									'</p>'
							);
							info.push('</div></div>'); // 可以根据自己需要,将获取到POI信息进行传递
							var infoWindow = new AMap.InfoWindow({
								content: info.join(''), // 使用默认信息窗体框样式,显示信息内容
								offset: new AMap.Pixel(0, -20)
							});
							infoWindow.open(map, lnglat);
						} else {
							alert(JSON.stringify(result));
						}
					});
				}

				// 启动拖放
				// positionPicker.start()
			});
		}
	}
};
</script>

<style>
.amap-marker-label {
	background-color: rgb(255, 255, 255);
	border: 1px dashed rgb(255, 204, 102) !important;
}
.content-window-card {
	position: relative;
	box-shadow: none;
	bottom: 0;
	left: 0;
	width: auto;
	padding: 0;
}

.content-window-card p {
	height: 2rem;
}

.custom-info {
	border: solid 1px silver;
}

.info-top {
	position: relative;
	background: none repeat scroll 0 0 #f9f9f9;
	border-bottom: 1px solid #ccc;
	border-radius: 5px 5px 0 0;
}

.info-top div {
	display: inline-block;
	color: #333333;
	font-size: 14px;
	font-weight: bold;
	line-height: 31px;
	padding: 0 10px;
}

.info-top img {
	position: absolute;
	top: 10px;
	right: 10px;
	transition-duration: 0.25s;
}

.info-top img:hover {
	box-shadow: 0px 0px 5px #000;
}

.info-middle {
	font-size: 12px;
	padding: 10px 6px;
	line-height: 20px;
}

.info-bottom {
	height: 0px;
	width: 100%;
	clear: both;
	text-align: center;
}

.info-bottom img {
	position: relative;
	z-index: 104;
}

span {
	margin-left: 5px;
	font-size: 11px;
}

.info-middle img {
	float: left;
	margin-right: 6px;
}
.m-map {
	width: 100%;
	min-height: 100%;
	position: relative;
}
.m-map .map {
	width: 100%;
	height: 720px;
	text-align: center;
}
.m-map .search {
	overflow: scroll;
	position: absolute;
	top: 10px;
	left: 10px;
	width: 500px;
	height: 30px;
	padding-left: 5px;
	z-index: 1;
	border: 1px solid #ccc;
	line-height: 20px;
	outline: none;
}
.m-map .result {
	max-height: 300px;
	overflow: auto;
	margin-top: 10px;
}
</style>

猜你喜欢

转载自blog.csdn.net/weixin_39706415/article/details/104334395