Vue+高德地图api

文章目录

  • 前言
  • 一、准备工作
    • 1.申请应用
    • 2.引入
    • 3.创建地图
  • 二、使用高德地图
    • 1.覆盖物
      • (1) 点标记
      • (2) 海量点标记
      • (3) 轨迹回放
    • 2.矢量图形
      • (1) 多边形
    • 3.图层
      • (1) 热力图
      • (2) Canvas图层
    • 4.坐标转换


前言

项目使用了高德地图进行开发,记录一下demo和使用中遇到的一些问题。想使用百度地图可以查看另一篇文章Vue+百度地图api


一、准备工作

1.申请应用

首先去官网申请密钥高德控制台

2.引入

在public index.html引入,注意密钥的设置一定要在地图之前,本文基于2.0版本。

<script>
  window._AMapSecurityConfig = {
    securityJsCode: '您申请的安全密钥',
  }
script>
<script src="https://webapi.amap.com/maps?v=2.0&key=您申请的key值">script>

config.js配置文件中

externals: {
  "AMap": "AMap"
},

3.创建地图

创建一个div当作容器,然后写一个初始化的方法即可

<template>
  <div class="map" id="map-center" ref="map-center"></div>
</template>

<script>
import AMap from "AMap";
export default {
  name: "map-center",
  data() {
    return {
      map: null,
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      this.map = new AMap.Map("map-center", {
      	// 3D或2D
      	viewMode: "2D",
        resizeEnable: true, //自适应大小
        zoom: 12, //设置地图显示的缩放级别
        center: [104.066301, 30.572961], //设置地图中心点坐标
      });
    },
  },
};
</script>

<style scoped>
.map {
  height: 800px;
  width: 100%;
}
</style>

以下所有案例都是以上述代码为基础

二、使用高德地图

1.覆盖物

(1) 点标记

最简单的使用

<script>
export default {
	data() {
		return {
			map: null,
			marker: null,
		}
	},
	methods: {
		// 添加点标记
		addMarker() {
			this.marker = new AMap.Marker({
				position: [104.066301, 30.572961], // 坐标
			});
			this.map.add(this.marker);
		},
		//删除点标记
		delMarker() {
			this.map.remove(this.marker);
		},
	},
}
</script>

Vue+高德地图api_第1张图片

也可以自定义点的图标样式

addMarker() {
	// 创建 AMap.Icon 实例:
	let icon = new AMap.Icon({
	  size: new AMap.Size(50, 50), // 图标尺寸
	  image: "http://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png", // Icon的图像
	  imageOffset: new AMap.Pixel(0, 0), // 图像相对展示区域的偏移量,适于雪碧图等
	  imageSize: new AMap.Size(0, 0), // 根据所设置的大小拉伸或压缩图片
	});
	// 将 Icon 实例添加到 marker 上:
	this.marker = new AMap.Marker({
	  position: new AMap.LngLat(104.066301, 30.572961),
	  offset: new AMap.Pixel(-10, -10),
	  icon: icon, // 添加 Icon 实例
	  title: "这是一个点",
	  zoom: 13,
	});
	this.map.add(this.marker);
},

Vue+高德地图api_第2张图片

(2) 海量点标记

如果要展示的点位过多,地图上渲染会很慢,这时候使用点聚合可以很好解决问题。
首先要引入MarkerCluster,两种方式
直接在引入地图的js链接后面跟上参数,就可以直接使用。注:所有的插件都可以用这两种方式引入

<script src="https://webapi.amap.com/maps?v=2.0&key=您申请的key值&plugin=AMap.MarkerCluster"></script>

或者

this.map.plugin(["AMap.MarkerCluster"], () => {
	// 业务代码
})
<script>
export default {
	data() {
    	return {
    		map: null,
    		markerCluster : null,
    	}
    },
    methods: {
    	addMarkerCluster() {
			/**
			 * 【经纬度】lnglat 为必填字段;
			 * 【权重】weight 为可选字段,聚合时以权重高的点为中心进行聚合
			 * 也可以自定义一些数据,如id
			 */
			let points = [
				{
					weight: 8,
					lnglat: [104.062374, 30.578265],
					id: 1,
				},
				{
					weight: 1,
					lnglat: [104.064091, 30.577157],
					id: 2,
				},
				{
					weight: 1,
					lnglat: [104.063919, 30.575679],
					id: 3,
				},
				{
					weight: 1,
					lnglat: [104.062889, 30.574866],
					id: 4,
				},
				{
					weight: 1,
					lnglat: [104.063748, 30.576418],
					id: 5,
				},
				{
					weight: 1,
					lnglat: [104.065292, 30.576639],
					id: 6,
				},
				{
					weight: 1,
					lnglat: [104.063404, 30.575901],
					id: 7,
				},
				{
					weight: 1,
					lnglat: [104.062546, 30.576085],
					id: 8,
				},
				{
					weight: 1,
					lnglat: [104.06349, 30.577489],
					id: 9,
				},
			];
			this.map.plugin(["AMap.MarkerCluster"], () => {
				this.markerCluster = new AMap.MarkerCluster(this.map, points, {
					// 聚合网格像素大小
					gridSize: 50,
				});
				// 绑定点击事件
				this.markerCluster.on("click", (res) => {
					// 点击聚合点的时候也会触发事件,所以为了确保点击的是某一个点,做了判断
					if (res.cluster.m.length === 1) {
						console.log(res.cluster.m[0].id);
					}
				});
			});
		},
		// 删除点聚合
	    delMarkerCluster() {
	    	// 两个方法可以删除,选择一种即可
	    	// 相当于把点聚合的坐标集给清空
			this.markerCluster.setData(null);
			// 相当于把地图上展示的点聚合清除
			this.markerCluster.setMap(null);
      		this.markerCluster= null;
		},
    },
}
</script>

(3) 轨迹回放

<script>
export default {
	data() {
		return {
			map: null,
			// 轨迹数据
			lineArr: [
				[104.054573, 30.582289],
				[104.057577, 30.582326],
				[104.06013, 30.582381],
				[104.0641, 30.582455],
				[104.06425, 30.580386],
				[104.064207, 30.575602],
				[104.059959, 30.575343],
				[104.054744, 30.575251],
			]
		}
	},
	methods: {
		// 添加轨迹
		addTrack() {
			// 用折线绘制轨迹
			this.polyline = new AMap.Polyline({
				map: this.map,
				path: this.lineArr,
				// 添加dirImg可以自定义路线的箭头,支持Image和Canvas
				showDir: true,
				dirImg:'https://a.amap.com/jsapi_demos/static/images/mass0.png',
				strokeColor: "#28F", //线颜色
				strokeOpacity: 1,     //线透明度
				strokeWeight: 6, //线宽
				strokeStyle: "solid"  //线样式
			});
			// 创建了一个车辆的点用于运动
			this.startMarker = new AMap.Marker({
				map: this.map,
				size: new AMap.Size(50, 52),
				// 第一个点为起点
				position: this.lineArr[0],
				icon: "https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png",
				offset: new AMap.Pixel(-35, -20),
			});
		},
		// 删除轨迹
		delTrack() {
			// 起点删除
			if (this.startMarker) {
				this.startMarker.remove();
				this.startMarker = null;
			}
			// 折线删除
			if (this.polyline) {
				this.polyline.setMap(null);
				this.polyline = null;
			}
			// 走过的折线删除
			if (this.passedPolyline) {
				this.passedPolyline.setMap(null);
				this.passedPolyline = null;
			}
		},
		// 开始运动
		startAnimation() {
			// 加载插件MoveAnimation
			AMap.plugin("AMap.MoveAnimation", () => {
				// 运动过的轨迹样式
				this.passedPolyline = new AMap.Polyline({
					map: this.map,
					strokeColor: "#AF5", //线颜色
					strokeWeight: 6, //线宽
				});
				// 绑定运动事件
				this.startMarker.on("moving", (e) => {
					this.passedPolyline.setPath(e.passedPath);
					this.map.setCenter(e.target.getPosition(), true);
				});
				// 开始运动
				this.startMarker.moveAlong(this.lineArr, {
					// 每段动画持续时长, 单位:ms
					duration: 500,
					// 覆盖物是否沿路径旋转
					autoRotation: true,
				});
			});
		},
		// 暂停运动
		pauseAnimation() {
			this.startMarker.pauseMove();
		},
		// 继续运动
		resumeAnimation() {
			this.startMarker.resumeMove();
		},
		// 停止运动
		stopAnimation() {
			this.startMarker.stopMove();
		},
	},
}
</script>

2.矢量图形

(1) 多边形

可以使用这个来当作网格

<script>
export default {
	data() {
		return {
			map: null,
			polygon: null
		}
	},
	methods: {
		// 添加多边形
		addPolygon() {
			// 使用一些坐标假数据,一般是从后端获取,这里添加了两个多边形
			let data = [
				[
					[
						[104.060169, 30.571391],
						[104.065534, 30.571483],
						[104.06592, 30.56607],
						[104.060384, 30.566162],
					],
				],
				[
					[
						[104.065987, 30.569562],
						[104.067682, 30.569571],
						[104.067489, 30.569007],
						[104.067714, 30.568305],
						[104.066126, 30.568305],
					],
				],
			];
			// 创建实例,用一个全局变量接收,方便调用其他方法
			this.polygon = new AMap.Polygon({
				// 坐标集
				path: data,
				// 多边形填充颜色,使用16进制颜色代码赋值
				fillColor: "#ccebc5",
				// 轮廓线透明度,取值范围 [0,1] ,0表示完全透明,1表示不透明
				strokeOpacity: 1,
				// 多边形填充透明度,取值范围 [0,1] ,0表示完全透明,1表示不透明
				fillOpacity: 0.5,
				// 线条颜色,使用16进制颜色代码赋值
				strokeColor: "#2b8cbe",
				// 轮廓线宽度
				strokeWeight: 1,
				// 轮廓线样式,实线:solid,虚线:dashed
				strokeStyle: "solid",
				// 虚线和间隙的样式,此属性在strokeStyle 为dashed 时有效
				strokeDasharray: [5, 5],
				// 鼠标悬停的样式
				cursor: "pointer",
			});
			// 绑定鼠标移上事件
			this.polygon.on("mouseover", () => {
				this.polygon.setOptions({
				  fillOpacity: 0.7,
				  fillColor: "#7bccc4",
				});
			});
			// 绑定鼠标移出事件
			this.polygon.on("mouseout", () => {
				this.polygon.setOptions({
				  fillOpacity: 0.5,
				  fillColor: "#ccebc5",
				});
			});
			// 把多边形放入地图上
			this.map.add(this.polygon);
		},
		// 隐藏
		hidePolygon() {
			this.polygon.hide();
		},
		// 显示
		showPolygon() {
			this.polygon.show();
		},
		// 销毁
		destroyPolygon() {
			this.polygon.destroy();
		}
	},
}
</script>

效果

3.图层

(1) 热力图

使用插件AMap.HeatMap

<script>
export default {
	data() {
		return {
			map: null,
			heatmap: null,
		}
	},
	methods: {
		// 添加热力图
		addHeatmap() {
			this.map.plugin(["AMap.HeatMap"], () => {
				// 初始化heatmap对象
				this.heatmap = new AMap.HeatMap(this.map, {
					// 热力图中单个点的半径
					radius: 25,
					// 热力图的透明度,取值范围[0,1],0表示完全透明,1表示不透明
					opacity: [0, 0.8],
					// 热力图的渐变区间, 其中 key 表示插值的位置, 0-1,value 为颜色值
					gradient: {
						0.5: "blue",
						0.65: "rgb(117,211,248)",
						0.7: "rgb(0, 255, 0)",
						0.9: "#ffea00",
						1.0: "red",
					},
				});
			});
			// lng经度,lat纬度,count权重
			let heatmapData = [
				{
					lng: 104.066301,
					lat: 30.572961,
					count: 12,
				},
				{
					lng: 104.066301,
					lat: 30.573113,
					count: 10,
				},
				{
					lng: 104.065437,
					lat: 30.574296,
					count: 9,
				},
				{
					lng: 104.067776,
					lat: 30.572153,
					count: 5,
				},
				{
					lng: 104.067261,
					lat: 30.57509,
					count: 11,
				},
				{
					lng: 104.061704,
					lat: 30.57424,
					count: 8,
				},
				{
					lng: 104.066017,
					lat: 30.571321,
					count: 15,
				},
			];
			// 设置数据
			this.heatmap.setDataSet({
				// 坐标数据集
				data: heatmapData,
				// 权重最大值,不填则取数据集count最大值
				max: 20,
			});
		},
		// 删除
		delHeatmap() {
	    	this.heatmap.setMap(null);
	    },
		// 显示
		showHeatmap() {
			this.heatmap.show();
		},
		// 隐藏
		hideHeatmap() {
			this.heatmap.hide();
		},
	},
}
</script>

Vue+高德地图api_第3张图片

(2) Canvas图层

<script>
export default {
	data() {
		return {
			context: null,
	    	canvasLayer: null,
	    	radious: 0,
		}
	},
	methods: {
		addCanvas() {
			/*
			* 添加Canvas图层
			*/
			let canvas = document.createElement("canvas");
			canvas.width = canvas.height = 200;
			this.canvasLayer = new AMap.CanvasLayer({
				canvas: canvas,
				bounds: new AMap.Bounds(
					[104.07368741587149, 30.579319946772618],
					[104.05891555268354, 30.566601636273084]
				),
				zooms: [3, 18],
			});
			this.canvasLayer.setMap(this.map);
			
			let context = canvas.getContext("2d");
			context.fillStyle = "rgb(0,100,255)";
			context.strokeStyle = "white";
			context.globalAlpha = 1;
			context.lineWidth = 2;
			this.context = context;
			this.draw();
		},
		draw() {
			let context = this.context;
			context.clearRect(0, 0, 200, 200);
			context.globalAlpha = (context.globalAlpha - 0.01 + 1) % 1;
			this.radious = (this.radious + 1) % 100;
			
			context.beginPath();
			context.arc(100, 100, this.radious, 0, 2 * Math.PI);
			context.fill();
			context.stroke();
			// 使用3D地图时需要调用
			// this.CanvasLayer.reFresh();
			AMap.Util.requestAnimFrame(this.draw);
		},
	},
}
</script>

虽然实现了,但是速度异常的慢,这里留个坑,以后解决
Vue+高德地图api_第4张图片

4.坐标转换

有三种类型,gps,baidu,mapbar

var gps = [116.3, 39.9];
AMap.convertFrom(gps, type, (status, result) => {
	if (result.info === 'ok') {
	  var lnglats = result.locations;
	}
});

你可能感兴趣的:(vue,vue.js,javascript,前端)