这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
之前在写项目时遇到了在主页嵌入地图,并且要展示3D效果,能够绘制边框和区域,展示标签,点击标签。 由于定制化和样式要求比较高,简单的使用echarts
已经不能满足需求了。所以我们在项目中使用了高德地图的API,能够达到下图的效果。
引入AMap
首先我们需要引入AMap: 在index.html中使用<script>
标签引入。
<body>
<script src="https://webapi.amap.com/maps?v=1.4.15&key=高德地图API的Key值&plugin=AMap.MouseTool,AMap.Geocoder,AMap.DistrictSearch"></script>
<noscript>
<strong>
We're sorry but <%= htmlWebpackPlugin.options.title %>
doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
</body>
复制代码
在这里我们需要先申请高德地图的key,在链接中我们能看到还传递了plugin参数,有AMap.MouseTool
、AMap.Geocoder
和AMap.DistrictSearch
,这些都是高德地图的工具,我们可以按需引入。 其中
- AMap.MouseTool是
- AMap.Geocoder是
- AMap.DistrictSearch是
初始化地图
我们需要有一个html元素容器,如果有UI设计的样式,还需要问UI要样式ID,这里我们使用AMap.Map()
构造方法生成一个Map实例:
const map = new AMap.Map('map_box', {
// 样式ID
mapStyle: `amap://styles/${样式ID}`,
center: [116.275034, 40.095882],
viewMode: '3D',
resizeEnable: true,
rotateEnable: true,
pitchEnable: true,
zoom: 16,
pitch: 45,
layers: [
// 楼块图层
new AMap.Buildings({
zooms: [2, 20],
zIndex: 11,
heightFactor: 2// 2倍于默认高度,3D下有效
})
]
});
//在data中保存Map实例
this.gxMap = map;
//Map实例生命周期完成状态时,才可以挂在标记点和区域
map.on('complete', () => {
this.drawBigBounds();
this.drawText(); // 默认展示上市企业
});
复制代码
挂载标记点和区域
我们可以看到,在初始化Map实例后,我们在地图实例的complete生命周期中调用了drawBigBounds()
和drawText()
方法。在这之前我们需要获取到标记点的经纬度坐标和区域的坐标数组。坐标数据结构可以如下:
也可以使用new AMap.LngLat(item.lng, item.lat)
方法使用遍历坐标数据。
- 我们首先绘制地图区域
// 行政区域
drawBigBounds() {
// 生成polygon-区域一
formatPhaseOneArr.forEach((item, index) => {
const phaseOnePolygon = new AMap.Polygon({
strokeWeight: 2,
path: item,
fillOpacity: 0,
fillColor: 'rgba(137, 116, 70, 1)',
strokeColor: '#38C8F5',
strokeOpacity: 1 - 0.2 * index
});
this.gxMap.add(phaseOnePolygon);
});
}
复制代码
new AMap.Polygon()
如字面意义,就是绘制区域的方法,在这里我们设置了区域颜色和透明度,边框的宽度颜色和透明度。如开始的图片中显示的,由于UI设计的区域样式是3D的栅栏一样,所以我采用了多次生成区域,将区域背景色设置为透明,边框设置为渐变来实现。
- 绘制标记点
list.forEach(item => {
const companyName = item.company_name;
const longitude = item.lnglat[0];
const latitude = item.lnglat[1];
const dom = `
<div style="" class="company-marker-content">
<div class="content-container">
<div class="content-text-bg"></div>
<p class="content-text">${companyName}</p>
</div>
<div class="marker-line"></div>
<div class="marker-circle outer">
<div class="marker-circle inner"></div>
</div>
</div>`;
const marker = new AMap.Marker({
position: new AMap.LngLat(longitude, latitude),
content: dom, // 添加 Icon 图标 URL
title: companyName,
anchor: 'bottom-center',
offset: new AMap.Pixel(0, -8),
});
this.markerArr.push(marker);
marker.on('click', () => {
that.openCompanyDetail(item.company_id);
});
this.gxMap.add(marker);
});
this.enterpriseData[index].marker = this.markerArr; // 存储marker 用于remove(应该有更好的方案)
复制代码
我们使用new AMap.Marker()
构造方法遍历点数据,之后将marker实例添加到Map实例中, 需要注意的是,我们将marker实例保存到了数组中,这样我们在地图上切换选项修改数据时,就可以使用Map实例的remove()方法将之前的数据删除。
结尾
这样,我们就完成了AMap生成地图,添加标记点和区域的功能了。