Openlayers 教程 - feature(图形要素)点击和双击事件

news2024/11/26 14:33:43

Openlayers 教程 - feature(图形要素)点击和双击事件

    • 核心代码
    • 完整代码:
    • 在线示例

地图中图形要素(Feature)的点击事件非常常用,曾经通过给整个地图绑定点击事件,然后判断图形要素(Feature)的方式实现功能,但是效果不太合适。

这里介绍一下通过地图传递事件的方式,契合面向对象的思想,实现图形要素(Feature)的点击和双击事件

本文包括核心代码、完整代码以及在线示例。


核心代码

地图初始化事件,传递给图形要素(Feature)。

在直接给图形要素(Feature)绑定点击和双击事件。


// 注册地图单击和双击事件
function registerMapEvent(){
    map.on('click', function (event) {
        map.forEachFeatureAtPixel(event.pixel, function (feature) {
            // 为点击的 feature 发送自定义的 click 消息
            try {
                feature && feature.set('position', map.getCoordinateFromPixel(event.pixel));
            } catch (e) {
                console.error(e);
            }
            feature.dispatchEvent && feature.dispatchEvent({ type: 'click', event });
        });
    });

    map.on('dblclick', function (event) {
        map.forEachFeatureAtPixel(event.pixel, function (feature) {
            // 为点击的 feature 发送自定义的 dblclick 消息
            try {
                feature && feature.set('position', map.getCoordinateFromPixel(event.pixel));
            } catch (e) {
                console.error(e);
            }
            feature.dispatchEvent && feature.dispatchEvent({ type: 'dblclick', event });
        });
    });
}


const feature1 = getFeatureByWKT(polygon1);
const feature2 = getFeatureByWKT(polygon2);

// 单击事件对象
const func1 = function (e){
    alert('触发单击事件,当前图形要素位置:' + e.target.get('position'))
    console.log(e.target)
}

// 记录对象,用于清除事件
feature1.set('eventFunction',func1);
feature1.on('click',func1);

// 双击事件对象
const func2 = function (e){
    alert('触发双击事件,当前图形要素位置:' + e.target.get('position'))
    console.log(e.target)
}

// 记录对象,用于清除事件
feature2.set('eventFunction',func2);
feature2.on('dblclick',func2);


完整代码:



<html lang="en">
<head>
    <meta charSet="utf-8">
    <!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
    <link rel="stylesheet" href="http://openlayers.vip/examples/css/ol.css" type="text/css">
    <style>
        /* 注意:这里必须给高度,否则地图初始化之后不显示;一般是计算得到高度,然后才初始化地图 */
        .map {
            height: 400px;
            width: 100%;
            float: left;
        }
    </style>
    <!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
    <script src="http://openlayers.vip/examples/resources/ol.js"></script>
    <script src="./turf.min.js"></script>
    <script src="./tiandituLayers.js"></script>
    <title>OpenLayers example</title>
    <script>
        var _hmt = _hmt || [];
        (function () {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    </script>
</head>
<body>
<h2>OpenLayers feature click and double click</h2>
<!--地图容器,需要指定 id -->
<div id="map" class="map"></div>
<br/>
<br/>
<script type="text/javascript">

    var map = new ol.Map({
        // 地图容器
        target: 'map',
        // 地图图层,比如底图、矢量图等
        layers: [
            getIMG_CLayer(),
            getIBO_CLayer(),
            getCIA_CLayer(),
        ],
        // 地图视野
        view: new ol.View({
            projection: "EPSG:4326",
            // 定位
            center: [115.67724700667199, 37.73879478106912],
            // 缩放
            zoom: 6,
            maxZoom: 18,
            minZoom: 1,
        })
    });

    // 注册地图单击和双击事件
    function registerMapEvent(){
        map.on('click', function (event) {
            map.forEachFeatureAtPixel(event.pixel, function (feature) {
                // 为点击的 feature 发送自定义的 click 消息
                try {
                    feature && feature.set('position', map.getCoordinateFromPixel(event.pixel));
                } catch (e) {
                    console.error(e);
                }
                feature.dispatchEvent && feature.dispatchEvent({ type: 'click', event });
            });
        });

        map.on('dblclick', function (event) {
            map.forEachFeatureAtPixel(event.pixel, function (feature) {
                // 为点击的 feature 发送自定义的 dblclick 消息
                try {
                    feature && feature.set('position', map.getCoordinateFromPixel(event.pixel));
                } catch (e) {
                    console.error(e);
                }
                feature.dispatchEvent && feature.dispatchEvent({ type: 'dblclick', event });
            });
        });
    }

    registerMapEvent();

    // 默认样式
    var defaultStyle = new ol.style.Style({
        //边框样式
        stroke: new ol.style.Stroke({
            color: 'red',
            width: 2,
        }),
        //填充样式
        fill: new ol.style.Fill({
            color: 'rgba(0, 0, 255, 0.3)',
        }),
        image: new ol.style.Circle({
            radius: 5,
            fill: new ol.style.Fill({
                color: 'white',
            })
        })
    })
    // 初始化图层
    var layer = initVectorLayer();
    // 点线面数组
    var features = [];

    // 初始默认数据
    let polygon1 = "POLYGON((112.80630306271966 46.27140545436643,116.23403743771966 44.33781170436643,117.81606868771966 40.29484295436643,117.90395931271966 38.36124920436643,117.81606868771966 35.02140545436643,116.14614681271966 32.38468670436643,113.50942806271966 33.26359295436643,111.75161556271966 34.58195232936643,110.60903743771966 35.46085857936643,113.28970150021968 36.03214764186642,111.35610775021968 36.33976482936642,110.91665462521968 36.91105389186642,111.22427181271968 37.52628826686642,112.10317806271968 37.30656170436642,112.41079525021968 37.78996014186642,112.32290462521968 38.36124920436642,111.44399837521968 38.66886639186642,110.52114681271968 39.10831951686642,110.38931087521968 39.81144451686642,111.09243587521968 40.07511639186642,112.19106868771968 40.38273357936642,112.49868587521968 41.04191326686642,111.88345150021968 41.21769451686642,111.26821712521968 40.86613201686642,110.43325618771968 40.91007732936642,110.65298275021968 41.39347576686642,110.47720150021968 42.66788982936642,111.79556087521968 42.75578045436642,110.38931087521968 43.19523357936642,110.56509212521968 44.24992107936642,111.44399837521968 43.76652264186642,111.79556087521968 44.16203045436642,111.09243587521968 44.60148357936642,111.22427181271968 45.30460857936642,112.10317806271968 44.95304607936642,112.67446712521968 45.26066326686642,111.75161556271968 45.78800701686642,111.88345150021968 46.40324139186642,112.14712337521968 47.94132732936642,112.45474056271968 47.15031170436642,113.99282650021968 47.28214764186642,113.28970150021968 46.79874920436642,114.95962337521968 46.71085857936642,112.80630306271966 46.27140545436643))";
    let polygon2 = "POLYGON((123.94676492355833 44.03121337817592,118.40965554855833 38.23043212817592,121.66160867355833 32.82515869067592,129.30809304855833 33.39644775317592,129.92332742355833 39.46090087817592,123.94676492355833 44.03121337817592))";

    addFeatures();

    // 添加点线面
    function addFeatures() {

        // 这里处理一下,可以自由传图形要素 start===================================================
        layer.getSource().clear();

        features = [];

        const feature1 = getFeatureByWKT(polygon1);
        const feature2 = getFeatureByWKT(polygon2);

        // 单击事件对象
        const func1 = function (e){
            alert('触发单击事件,当前图形要素位置:' + e.target.get('position'))
            console.log(e.target)
        }

        // 记录对象,用于清除事件
        feature1.set('eventFunction',func1);
        feature1.on('click',func1);

        // 双击事件对象
        const func2 = function (e){
            alert('触发双击事件,当前图形要素位置:' + e.target.get('position'))
            console.log(e.target)
        }

        // 记录对象,用于清除事件
        feature2.set('eventFunction',func2);
        feature2.on('dblclick',func2);

        features.push(...[feature1,feature2]);

        layer.getSource().addFeatures(features);

        map.getView().fit(layer.getSource().getExtent(), {
            duration: 1,//动画的持续时间,
            callback: null,
        });
    }

    /**
     * @todo 矢量图层
     * @returns {VectorLayer}
     * @constructor
     */
    function initVectorLayer() {
        //实例化一个矢量图层Vector作为绘制层
        let source = new ol.source.Vector();
        //创建一个图层
        let customVectorLayer = new ol.layer.Vector({
            source: source,
            zIndex: 2,
            //设置样式
            style: defaultStyle,
        });
        //将绘制层添加到地图容器中
        map.addLayer(customVectorLayer);

        return customVectorLayer;
    }

    /**
     * @todo wkt格式数据转化成图形对象
     * @param {string} wkt   "POINT(112.7197265625,39.18164062499999)" 格式数据
     * @param {string|Projection} sourceCode 源投影坐标系
     * @param {string|Projection} targetCode 目标投影坐标系
     * @returns {Feature}
     */
    function getFeatureByWKT(wkt, sourceCode, targetCode) {
        try {
            let view = map.getView();
            if (!wkt) {
                return null;
            }
            let format = new ol.format.WKT();

            let feature;

            feature = format.readFeature(wkt, {
                featureProjection: targetCode || view.getProjection(),
                dataProjection: sourceCode || view.getProjection(),
            });

            return feature;
        } catch (e) {
            console.log(e);
            return null;
        }
    }

    // 清空事件
    function clearFunc() {

        if(Array.isArray(features) && features.length > 0){
            for (let i = 0; i < features.length; i++) {
                const feature = features[i];
                const func = feature.get('eventFunction');
                feature.un('click',func);
                feature.un('dblclick',func);
            }
        }

    }
</script>
<h4>左侧多边形测试单击事件!</h4>
<h4>右侧多边形测试双击事件!</h4>
<button id="clearFunc" onClick="clearFunc()">关闭事件</button>
</body>
</html>





在线示例

在线示例:Openlayers 教程 - feature(图形要素)点击和双击事件

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/993128.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

@Autowired自动装配对象为null,但是通过ApplicationContext注入的时候,却成功的注入了

错误&#xff1a;运行test1的时候&#xff0c;报bookController空指针异常 但是当我通过ApplicationContext注入的时候&#xff0c;却成功的注入了 原因是因为被注入的属性不能为静态属性&#xff01;&#xff01; 扩展&#xff1a; 1.一般而言&#xff0c;标注有(Component|…

RK3568-mpp(Media Process Platform)媒体处理软件平台

第一章 MPP 介绍 1.1 概述 瑞芯微提供的媒体处理软件平台(Media Process Platform,简称 MPP)是适用于瑞芯微芯片系列的通用媒体处理软件平台。 该平台对应用软件屏蔽了芯片相关的复杂底层处理,其目的是为了屏蔽不同芯片的差异,为使用者提供统一的视频媒体处理接口(Medi…

树,二叉树的概念与结构

&#x1f449;树&#xff0c;二叉树的概念与结构 1️⃣ .树的概念及结构1.1树的概念1.2树的相关概念1.3树的实现方式1.4树的实际用途 2️⃣.二叉树的概念及结构2.1二叉树的概念2.2特殊二叉树2.3二叉树的概念2.4二叉树的存储结构 所属专栏&#xff1a;初始数据结构❤️ &#x1…

【STL】模拟实现map和set {带头结点的红黑树;红黑树的核心结构;红黑树的迭代器;红黑树的插入和查找;map和set的封装}

模拟实现map和set map和set是红黑树的两种不同封装形式&#xff0c;底层使用同一颗泛型结构的红黑树。set是红黑树的K模型&#xff1b;map是红黑树的KV模型。 下面的代码和讲解着重体现红黑树的底层实现和map\set上层封装的衔接。关于二叉搜索树性质&#xff0c;map和set的介…

PowerDesigner 逆向工程

1、MySQL数据库连接&#xff08;JDBC方式&#xff09; 1.1 新建一个pdm&#xff0c;dbms选择mysql 1.2 Database - Connect 选择数据库连接 1.3 配置连接信息 数据库连接这里是通过一个配置文件来获取连接信息的&#xff0c;首次的话因为没有&#xff0c;所以我们需要选择…

采用BeautifulSouppqQueryxpath三种方法爬取电影详情页

采用三个框架BeautifulSoup&&pqQuery&&xpath&#xff0c;爬取知名的电影网页 主要是想体验这三种框架爬同一个网页的不同。 当然具体的不同我也说不清道不明 只能是体验了一把 以下代码都是本人亲自撸 如图所示&#xff0c;四个位置。分别爬取 电影名字 -&g…

docker 安装 Node-RED

Node-RED 是构建物联网应用程序的一个强大工具&#xff0c;使用可视化编程方法&#xff0c;连接起来执行任务。而homeassistant是家居智慧中枢&#xff0c;本文介绍如何安装Node-RED及HASS的插件 1、拉取镜像 docker pull nodered/node-red # 2、部署镜像 创建目录 mkidr -…

微调文本到图像扩散模型新方法DreamBooth,实现主题驱动生成(CVPR 2023)

来源&#xff1a;投稿 作者&#xff1a;橡皮 编辑&#xff1a;学姐 论文链接&#xff1a; https://arxiv.org/pdf/2208.12242 项目主页&#xff1a;https://dreambooth.github.io/ 图1. 只需要拍摄某个主题&#xff08;左&#xff09;的几张图像&#xff08;通常为 3-5 张&…

Java守护线程的理解及应用

在Java中有两类线程&#xff0c;分别是User Thread&#xff08;用户线程&#xff09;和Daemon Thread&#xff08;守护线程&#xff09; 。 用户线程很好理解&#xff0c;我们日常开发中编写的业务逻辑代码&#xff0c;运行起来都是一个个用户线程。而守护线程相对来说则要特别…

Java发送(QQ)邮箱、验证码发送

前言 使用Java应用程序发送 E-mail 十分简单&#xff0c;但是首先需要在项目中导入 JavaMail API 和Java Activation Framework (JAF) 的jar包。 菜鸟教程提供的下载链接&#xff1a; JavaMail mail.jar 1.4.5JAF&#xff08;版本 1.1.1&#xff09; activation.jar 1、准备…

C语言“牵手”拼多多商品详情数据方法,拼多多商品详情API接口,拼多多API申请指南

拼多多是中国最大的自营式电商企业&#xff0c;在线销售计算机、手机及其它数码产品、家电、汽车配件、服装与鞋类、奢侈品、家居与家庭用品、化妆品与其它个人护理用品、食品与营养品、书籍与其它媒体产品、母婴用品与玩具、体育与健身器材以及虚拟商品等。 拼多多平台的商品…

容器编排学习(十)控制器介绍与使用

一 控制器 控制器是 k8s内置的管理工具。可以帮助用户实现 Pod的自动部署、自维护、扩容、滚动更新等功能的自动化程序。 为什么要使用控制器? 有大量的 Pod需要维护管理需要维护 Pod的健康状态控制器可以像机器人一样可以替用户完成维护管理的工作 二 Deployment 1 概…

ROS学习笔记(四)---使用 VScode 启动launch文件运行多个节点

ROS学习笔记文章目录 01. ROS学习笔记(一)—Linux安装VScode 02. ROS学习笔记(二)—使用 VScode 开发 ROS 的Python程序&#xff08;简例&#xff09; 03. ROS学习笔记(三)—好用的终端Terminator 一、什么是launch文件 虽然说Terminator终端是能够比较方便直观的看运行的节点…

Spring-MVC的文件上传,下载的技术攻克

目录 一.前言 二.文件上传 文件上传的步骤&#xff1a; 三.文件下载 四.多文件上传 一.前言 SpringMVC的文件上传下载的主要作用是让用户能够将文件上传到服务器或从服…

消息队列基本原理和选型对比

消息队列使用场景 消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用耦合&#xff0c;异步消息&#xff0c;削峰填谷等问题。实现高性能、高可用、可伸缩和最终一致性架构。 解耦&#xff1a;多个服务监听、处理同一条消息&#xff0c;避免多次 rpc 调用。 异步…

计算机网络基础知识(非常详细)

1. 网络模型 1.1 OSI 七层参考模型 七层模型&#xff0c;亦称 OSI&#xff08;Open System Interconnection&#xff09;参考模型&#xff0c;即开放式系统互联&#xff0c;是网络通信的标准模型。一般称为 OSI 参考模型或七层模型。 它是一个七层的、抽象的模型体&#xff…

Web学习笔记-React(组合Components)

笔记内容转载自 AcWing 的 Web 应用课讲义&#xff0c;课程链接&#xff1a;AcWing Web 应用课。 CONTENTS 1. 创建父组件2. 从上往下传递数据3. 传递子节点4. 从下往上调用函数 本节内容是组件与组件之间的组合&#xff0c;例如用不同组件构成 DOM 树&#xff0c;以及给不同的…

看完这篇 教你玩转渗透测试靶机Vulnhub——Momentum:2

Vulnhub靶机Momentum:2渗透测试详解 Vulnhub靶机介绍&#xff1a;Vulnhub靶机下载&#xff1a;Vulnhub靶机安装&#xff1a;Vulnhub靶机漏洞详解&#xff1a;①&#xff1a;信息收集&#xff1a;②&#xff1a;漏洞发现&#xff1a;③&#xff1a;文件上传漏洞利用&#xff1a;…

【C++基础】8. 函数

文章目录 【 1. 函数的定义 】【 2. 函数声明 】【 3. 调用函数 】【 4. 函数参数 】4.1 传值调用4.2 指针调用4.3 引用调用 【 5. 形参默认值 】【 6. lambda函数 】 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数&#xff0c;即主函数 main() 。可以把代码…

Fiddler工具使用汇总

Fiddler工作原理 fiddler作为一个代理服务器&#xff0c;跟浏览器建立连接之后&#xff0c;浏览器像目标服务器发送的请求都会经过fiddler代理&#xff0c;所以fiddler可以捕获到http&#xff08;s&#xff09;请求&#xff0c;从而可以解释、分析、甚至重写发出去的http&…