加入右键菜单,首先我们要监听鼠标右键点击的操作,我们知道鼠标右键事件名是 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. linux 内存查看方法:meminfo\maps\smaps\status 文件解析

    linux 下面查看内存有多种渠道,比如通过命令 ps ,top,free 等,比如通过/proc系统,一般需要比较详细和精确地知道整机内存/某个进程内存的使用情况,最好通过/proc 系统,下面介绍 ...

  2. 3.Centos-Docker-rancher

    1.安装mysql,设置密码 docker run -d --name mysqldb -e MYSQL_ROOT_PASSWORD=密码 mysql:latest --character-set-s ...

  3. python tips;matplotlib 显示中文

    import numpy as npimport matplotlib.pyplot as pltimport matplotlib as mpl mpl.rcParams['axes.unicode ...

  4. Codeforces Round #444 (Div. 2)A. Div. 64【进制思维】

    A. Div. 64 time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  5. #424 Div2 C

    #424 Div2 C 题意 给出 k 个分数,初始分数未知,按顺序把这 k 个分数加到初始分数上,已知 n 个加入分数后的结果(无序),问初始分数有多少种可能. 分析 也就是说这 n 个结果,它们之 ...

  6. 设置iframe高度自适应屏幕高度

    写在前面: 最近在搭建项目前台页面框子的时候,把iframe设置成了固定的高度,导致不同的电脑尺寸访问的时候,高度差异较大,故查了下,将iframe设置成自动适应屏幕高度的方式,这里记录下. 还是直接 ...

  7. 1,java的跨平台原理

    简单讲一下java的跨平台原理: (1)为什么跨平台: 由于各OS支持的指令集各不相同,就需要程序在不同的平台执行不同的代码 (2)JAVA是如何实现的: ava开发了适合不同的OS及不同位数的jav ...

  8. threadlocal彻底理解

    如果你定义了一个单实例的java bean,它有若干属性,但是有一个属性不是线程安全的,比如说HashMap.并且碰巧你并不需要在不同的线程中共享这个属性,也就是说这个属性不存在跨线程的意义.那么你不 ...

  9. xcode 6 exporting ipa 提示 Your account already has a valid iOS distribution certificate 的另一种解决方法

    背景: 1. XCode 6.1 2. 证书:develop 证书 3. Scheme 为Device 操作: 在Product - Archive 包过程中,选择Save for Ad hoc De ...

  10. ios 字体类型设置 倾斜加粗等

    后面加-Bold就是加粗 加-Oblique就是倾斜等 还有不懂请看http://iosfonts.com/ iPhone 5.0 iPad 5.0 Font Families: 58 Font Fa ...