高德地图jsApi的右键设置
可视化的业务当中,除了我们熟悉的各种图标,柱状图、饼状图、折线图等等,地图这类也是可视化的重要的一部分,这部分要么使用百度要么使用高德,其API的学习成本还是比较高的,这一篇我们主要来看一下右键菜单的设置
注意:本文档中所有点位置信息和线信息都是虚构,无任何实际意义
- 这一篇是本系列第三篇,前两篇大家可以点击链接访问 高德地图jsApi的使用 高德地图jsApi的点和线配置 完成代码请查看代码仓库 其实我在第一篇的代码中,已经把右键菜单的简单实现写上去了,不过没有写逻辑,都是官方的放大和缩小,大家可以看一下: (这里了不让传大图,这个效果大家看下面的下图吧) 上面有两种右键,这点需要注意,高德的右键分为右键菜单和点标记右键,在我们点上面的右键 和地图上的右键是两种不同的设置方式,而基于这点,也更方便与我们来做交互,这一期我要实现的就是点击地图中第一个点,有选中和取消选中的选项,选中以后,点击第二个点,选择连接上一个点,可以将两个点进行连线,点击空白区域,则取消选中的点信息
- 这一部分如果用框架来实现,比如
vue
或react
可以做到保存状态,也就是选中一个点以后的状态,是比较简答的,而如果不使用框架,状态又该如何保存呢?大家可以先自己思考一下 存储着一块大家可以自行发挥,因为我这个只是一个demo
, 所以并没有后端,正常项目中应该是和后端接口进行通信的,数据肯定是存储在数据库,那现在我们自己,可以不存储,直接使用代码完成,这样就是刷新以后不保存状态,也可以选择session
存储,但是每次刷新都要存取,逻辑或增加很多,为了降低复杂度,我就直接代码搞了哦~
首先来看视图右键
如图所示,这里没有点,直接在地图上搞的右键,这个右键我在业务中已经完成了,但是非点位的右键我现在只是需要一个功能,就是清除上次选中信息。
这里只用小图了,大图应该不能通过~\
- 这个功能实际上在我第一版代码中也有了,只不过没有加业务逻辑而已,这部分右键的功能在 这里
//创建右键菜单
var menu = new ContextMenu(map);
//自定义菜单类
function ContextMenu(map)
{
var me = this;
//地图中添加鼠标工具MouseTool插件
this.mouseTool = new AMap.MouseTool(map);
this.contextMenuPositon = null;
var content = [];
content.push("<div class='info context_menu'>");
content.push(" <p onclick='menu.delMarkerMenu()'>移除上次选中信息</p>");
content.push("</div>");
//通过content自定义右键菜单内容
this.contextMenu = new AMap.ContextMenu({ isCustom: true, content: content.join('') });
//地图绑定鼠标右击事件——弹出右键菜单
map.on('rightclick', function (e)
{
me.contextMenu.open(map, e.lnglat);
me.contextMenuPositon = e.lnglat; //右键菜单位置
});
}
ContextMenu.prototype.delMarkerMenu = function ()
{
// 右键菜单上次选中点的信息
clearPoint()
this.mouseTool.close();
this.contextMenu.close();
};
接下来看点右键
如上,实现的就是第一个点点击右键,选中,然后点位的样式样色有个变化,点击第二个点的时候,连线,如果在第二个点选择设置起点,则点位信息变化,刚才选择的点样式还原,如果点连线,没有选择起点,则给提示
- 在点上面的点击事件,这个点在高德上称之为覆盖物,所以我们在查找的时候,直接找覆盖物相关的就可以了,在
API
中便是覆盖物右键啦~
这里有一些业务逻辑,就是操作点信息和存储点信息的逻辑,这点我做了抽离:
// 存储当前选中点 DOM
var currentPonit = '';
// 当前选重点信息
var currentData = {};
// 修改DOM 类名
function changeStyle(res,data){
if(currentPonit !== ''){
currentPonit.classList.remove('active');
}
currentPonit = res.children[0];
currentData = data;
currentPonit.classList.add('active');
}
// 清除点信息
function clearPoint(){
if(currentPonit){
currentPonit.classList.remove('active');
}
currentPonit = "";
currentData = {}
}
// 设置线信息
function setLines(lnglat,color,weight){
return new AMap.Polyline({
path:lnglat,
// showDir:true ,// 设置线方向
strokeColor:color, // 线颜色
strokeWeight: weight, // 线宽
strokeOpacity:1 // 透明度
})
}
- 然后覆盖物右键这里 需要给每个点位都添加,这相当于我们创建点位的时候,就添加了对应的事件侦听器~
coordData.forEach(function (marker)
{
//创建右键菜单
var contextMenu = new AMap.ContextMenu();
//右键放大
contextMenu.addItem("放大一级", function ()
{
map.zoomIn();
}, 0);
//右键缩小
contextMenu.addItem("缩小一级", function ()
{
map.zoomOut();
},1);
contextMenu.addItem("设置起点", function ()
{
console.log(marker,markerd.dom);
changeStyle(markerd.dom,marker)
contextMenu.close() // 关闭右键菜单
});
contextMenu.addItem("与起点连线", function ()
{
if(!currentPonit){
alert('请选择起点')
contextMenu.close()
return
}else{
// 这里其实可以根据数据判定线类型了,因为第二个选中点的信息和第一个选中点的信息都有了,但是过滤方法会比较复杂
let path = [currentData.position,marker.position];
const polyline1 = setLines(path,'#3366bb',5);
map.add([polyline1]);
clearPoint();
}
contextMenu.close() // 关闭右键菜单
});
let content = '<div class="marker-route"></div>';
let markerd = new AMap.Marker(
{
map: map,
// icon: marker?.icon,
content,
offset: new AMap.Pixel(-8,-8),
visible:true, // 点标记是否可见
position: [marker.position[0], marker.position[1]],
});
//绑定鼠标右击事件——弹出右键菜单
markerd.on('rightclick', function (e)
{
contextMenu.open(map, e.lnglat);
});
});
- 点位事件侦听这里,大家这一期可以思考一下,我们新增的点位应该如何来添加呢?
之前是一个完整的数据坐标,在创建的时候直接侦听,这次新增一个点位,要添加我们这一期所有对应的事件和交互,应该怎么办? 下期就搞他!
转载自:https://juejin.cn/post/7176104463516565559