加入右键菜单,首先我们要监听鼠标右键点击的操作,我们知道鼠标右键事件名是 contextmenu。当鼠标在 html 元素之上,点击鼠标右键,便会触发 contextmenu 事件,在 contextmenu 事件的回调函数中实现对应的显示菜单功能就可以。

那么在 openlayers 中。在地图中加入这个事件,我们从哪里下手呢?首先我们得了解 openlayers 的初始化页面的过程。

openlayers 初始化页面过程

openlayers 也是一个前端库,那么它肯定离不开 html 的运用,比方,我们首先须要在页面放置一个显示地图的 html 元素,一个 div 元素(如果其 id 属性设置为 “map”。后面简称为 map div),然后在地图初始化的时候指定这个元素,openlayers 会首先在这个元素中创建一个 class 为 ol-viewport 的 div 元素,其尺寸保持与 map div 同样,然后在 ol-viewport div 中创建一个 canvas 元素。在这个 canvas 元素中渲染请求到的地图。其次。还会加入一个 class 为 ol-overlaycontainer 的 div 元素,用来放置 overlay。最后,加入一个 class 为 ol-overlaycontainer-stopevent 的 div 元素,主要是放置 openlayers 的控件,上一篇加入 自己定义扩展控件 的文章开篇有讲过。这里不是重点。我们不详细介绍了。

最后形成的 html dom 结构例如以下图:



图1 形成的DOM结构

我们会想到在这个 map div 元素加入事件。然后右键弹出菜单。这个想法非常自然,也确实能够实现,然而我们要想到后面的事情。至少对事情有一个全局的认识再下手,我们显示出菜单后。往往是要依据对应的地图所在位置进行一定的操作,那么我们的 contextmenu 的事件对象包括发生点击的屏幕坐标,可是怎样依据屏幕坐标获得地图中的对应坐标系下的坐标将会比較困难。

困难在哪里呢?主要有以下的三点:

  • 首先,事件对象所含的坐标是相对于整个浏览器的视口、页面或者整个屏幕的。
  • 其次。而显示地图的元素往往又是任意的大小和位置。
  • 最后,屏幕的坐标系和地图的坐标系又往往全然不同,怎样将相对与地图元素的坐标再转化为地图坐标系下的坐标?

首先。我们须要获得事件坐标相对于 map div (包括地图的元素)的坐标,然后将相对于 map div 的坐标转化为地图中的实际坐标。

第一步中,我们能够通过计算获得,可是第二步必须通过 openlayers 来完毕,由于仅仅有 openlayers 对地图的坐标系最清楚。这在 openlayers 中也有相关的功能。庆幸的是。openlayers 中我们能够一步完毕上述操作。仅仅须要一个函数:map.getEventCoordinate(event),在以下的详细实现中,我会详细说到这个函数。

以下我们看看详细怎样实现吧。

鼠标右键菜单详细实现


  • 为了方便,文章中的代码使用了 JQuery。
  • 文章中的实例完整代码能够到我的 GitHub 中查看或者下载。实用的话别忘了点一下 star。


以下我们一步一步地加入右键菜单功能,我们分为三步:

  1. 对 html 元素加入 contextmenu 事件;
  2. 获取地图对应的点击坐标;
  3. 地图对应位置加入菜单 。

对 html 元素加入 contextmenu 事件

html 元素的鼠标右键事件名为 contextmenu,这个事件全部主流浏览器都支持,这里不要混淆 html 新增的属性 contextmenu,这个属性眼下仅仅有 firefox 支持。我们仅仅是使用 oncontextmenu 这个事件。

对包括地图的不论什么 html 元素绑定这个事件都能够,openlayers 会处理坐标转换这些问题。例如以下,map.getViewport() 会返回 openlayers 初始化页面时创建的 class 为 ol-viewport 的 div 元素。也就是直接包括地图的元素。由于浏览器都有默认的右键菜单。所以我们要取消默认的菜单,仅仅要调用 e.preventDefault(); 就可以:

$(map.getViewport()).on("contextmenu", function(event){
e.preventDefault();
// 书写事件触发后的函数
});

获取地图对应的点击坐标

获取地图对应的点击坐标仅仅须要一句就可以。例如以下。

var coordinate = map.getEventCoordinate(event);

函数參数是 oncontextmenu 对应的事件对象。该函数包括对 map.getCoordinateFromPixel() 的调用。map.getCoordinateFromPixel() 參数为 ol.pixel,是一个坐标。数组格式[x, y],事实上现中又调用了 ol.vec.Mat4.multVec2(),该函数完毕处理坐标转换的实际工作。

地图对应位置加入菜单

这里我们结合 overlay 加入菜单,之前的文章介绍过 overlay。这里就不再详细展开了。

首先,我们在 html 页面加入一个文件夹,详细的 css 样式能够自己设定,想看完整源代码的能够到我的 GitHub 中查看或者下载完整的代码:

<div id="contextmenu_container" class="contextmenu">
<ul>
<li><a href="#">设置中心</a></li>
<li><a href="#">加入地标</a></li>
<li><a href="#">距离丈量</a></li>
</ul>
</div>

使用这个 html 元素初始化一个 overlay,并将 overlay 加入到地图中:

var menu_overlay = new ol.Overlay({
element: document.getElementById("contextmenu_container"),
positioning: 'center-center'
});
menu_overlay.setMap(map);

接下来,我们就能够在鼠标右键菜单的事件回调函数中,依据获取的地图坐标位置,设置 overlay 的显示位置:

menu_overlay.setPosition(coordinate);

菜单隐藏

当我们鼠标点击右键,菜单出现,可是我们不能让菜单总是显示在地图中,这时我们能够加入鼠标左键单击,菜单消失功能。或者当选择某项功能时。菜单消失。这个比較easy实现,仅仅要一句便能够实现,放在鼠标左键事件的回调函数或者菜单功能运行函数中就可以。例如以下:

menu_overlay.setPosition(undefined);

总结

这篇文章中,主要讲了 openlayers 初始化页面地图元素的过程,并介绍了在地图上实现“鼠标右键菜单功能”。和隐藏菜单的实现。我们并没有对菜单中的条目绑定事件,由于我们的重点在于实现右键菜单,对于菜单的条目要绑定什么功能,和普通的 javascript 事件绑定并无二致,所以没有展开。

好的,就写到这里,有什么问题,能够在文章以下留言或者给我发邮件。


文章中的实例完整代码能够到我的 GitHub 中查看或者下载,实用的话别忘了点一下 star。


OpenLayers 3 之 加入地图鼠标右键菜单的更多相关文章

  1. jQuery自定义Web页面鼠标右键菜单

    jQuery自定义Web页面鼠标右键菜单 右键菜单是固定的,很多时候,我们需要自定义web页面自定义菜单,指定相应的功能. 自定义的原理是:jQuery封装了鼠标右键的点击事件(“contextmen ...

  2. Qt creator 创建鼠标右键菜单 (不新建类)

    界面 步骤 打开你的界面文件并选中你要添加右键的控件,选择“CustomContextMenu” 右键选择“转到槽...” -> customContextMenuRequested 插入下面代 ...

  3. 如何在C#添加鼠标右键菜单

    C#添加鼠标右键方法步骤: 1 选中要添加右键功能的Form或者控件,打开控件的设计页面. 2 从工具箱中找到ContextMenuStrip控件,将这个控件拖曳到Form或者控件的设计页面上.这时系 ...

  4. 将EmEditor加入到鼠标右键菜单

    在清理系统的时候,无意中将EmEditor的鼠标右键功能给清理掉了,在EmEditor的配置中又没有找到如何加入到鼠标右键菜单的方法,只好使用导入注册表功能了,以下的代码,拷贝到记事本中,保存为EmE ...

  5. JAVA GUI学习 - JPopupMenu鼠标右键菜单组件学习

    public class JPopmenuKnow { public void test() { //为表格添加鼠标右键菜单 JMenuItem jMenuItemFileInfo = new JMe ...

  6. WinForm -- 为TextBox文本框添加鼠标右键菜单

    WinForm -- 为TextBox文本框添加鼠标右键菜单 1. 新建一个WinForm项目,放置一个TextBox控件 2. 从工具箱拖进来一个ContextMenuStrip 3. 将TextB ...

  7. Qt532.【转】Qt创建鼠标右键菜单

    ZC:可以通过 设置  (QWebView*)->setContextMenuPolicy(NoContextMenu); 来关闭 QWebView的默认右键菜单 Qt创建鼠标右键菜单_疯华正茂 ...

  8. Jquery如何禁止鼠标右键菜单

    jquery中使用contextmenu事件,如果返回true,则允许右键菜单:如果返回false,则禁止右键菜单 导入文件 <script type="text/javascript ...

  9. 将Sublime Text 添加到鼠标右键菜单的教程方法

    安装notepad++软件,在菜单右键自动会添加“edit with notepad++"的选项,那么怎么将Sublime Text 添加到鼠标右键菜单呢?下面是我的操作过程,希望有帮助! ...

随机推荐

  1. Leap Motion颠覆操控体验的超精致手势追踪技术【转】

    转自:http://www.cnblogs.com/emouse/archive/2013/02/28/2936689.html 先来看两段简介视频: 看了介绍视频后,对如此次超高精度的手势追踪非常好 ...

  2. C和C++的关键字区别

    c中数据类型是struct ,c++中可以是struct,也可以是class关于c++中<< 和>>分别是箭头往那边就是流向哪里的 比如cout<<这个就是流向屏幕 ...

  3. (3)WPF 布局

    一.布局原则 二.布局过程 三.布局容器 核心布局面板 布局属性

  4. (10)ERStudio

     1.外键 https://jingyan.baidu.com/article/f79b7cb37e9d219144023ea6.html 第一个图标:Identifying Relationship ...

  5. 每天一个Linux命令(10)cp命令

    cp命令用来将一个或多个源文件或者目录复制到指定的目的文件或目录.它可以将单个源文件复制成一个指定文件名的具体的文件或一个已经存在的目录下.cp命令还支持同时复制多个文件,当一次复制多个文件时,目标文 ...

  6. Topcoder 刷题之路_鶸的奋斗

    最近碰到的题不是水题就是坑题,实在没意思,听说神犇们都在Topcoder上刷SRM,于是我决定将SRM的DIV 1刷个遍.这里是目录 哎..好多转博客不注明出处的,这里给出本博客的出处:http:// ...

  7. CV3

    Self Assessment: 1.        Skilled in developing with HTML/JavaScript/ASP.NET/C#, experienced in 3-l ...

  8. c#作业(2班)

    第二章 1.编写一个控制台程序,要求: 接受从控制台输入的姓名,如:张三 程序响应:你好,张三. 在代码中使用规范的注释,说明程序的功能 编译程序,并执行. 程序执行效果如下图: using Syst ...

  9. EF执行存储工程报错 String[4]: Size 属性具有无效大小值 0。

    EF中执行存储过程报错 String[4]: Size 属性具有无效大小值 0 排查后是如下问题所致,给定的参数没有设定大小(加入红框内的就可以了) private string GetCode(MC ...

  10. vs2012 ultimate 密钥

    Visual Studio Ultimate 2012 静态激活密钥,可以试一下. RBCXF-CVBGR-382MK-DFHJ4-C69G8