从零开始Vue项目中使用MapboxGL开发三维地图教程(五)实现框选要素功能、可拖动点展示坐标以及地图上实时更新要素

news2024/10/7 6:41:47

文章目录

      • 1、实现框选要素功能
          • 1.1、添加点数据的图层:
          • 1.2、增加绘图插件(mapbox-draw)
          • 1.3、实现框选并让选择的目标数据高亮
      • 2、实现地图上可拖动点
          • 2.1、实现功能:
          • 2.2、实现思路:
          • 2.3、代码示例:
      • 3、实时更新要素功能

1、实现框选要素功能

1.1、添加点数据的图层:

数据源名称为earthquakes,点图层id为clusters

map.addSource('earthquakes', {
            type: 'geojson',
            data: 'https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson',
            cluster: true,
            clusterMaxZoom: 14, // Max zoom to cluster points on
            clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
          });

          map.addLayer({
            id: 'clusters',
            type: 'circle',
            source: 'earthquakes',
            filter: ['has', 'point_count'],
            paint: {
              'circle-color': [
                'step',
                ['get', 'point_count'],
                '#51bbd6',
                100,
                '#f1f075',
                750,
                '#f28cb1'
              ],
              'circle-radius': [
                'step',
                ['get', 'point_count'],
                20,
                100,
                30,
                750,
                40
              ]
            }
          });
1.2、增加绘图插件(mapbox-draw)
    // 绘图插件
      let draw = new mapboxdraw({
        displayControlsDefault: false,
        controls: {
          polygon: true,
          trash: true
        }
      });
      map.addControl(draw);
    map.on('draw.create', function (e) {
        var features = draw.getAll();
    })
 
    map.on('draw.delete', function (e) {
        map.removeLayer('selected')
    });

在这里插入图片描述

1.3、实现框选并让选择的目标数据高亮

基本思路是:通过turf来计算出在框选区域内的所有点(数据),将这些数据构成一个新的图层,置放于最上层,用不同的颜色来表示。

核心代码:

 map.on('draw.create', createArea);

createArea方法:

        function createArea(e) {
          const data = draw.getAll();
          const answer = document.getElementById('calculated-area');

          const drawCoordinatesvalue = data.features[0].geometry.coordinates
          var features_Layer = map.queryRenderedFeatures(e.point, {
            layers: ['clusters']
          });
          var selectedFeatures = []
          drawCoordinatesvalue.forEach(coordinate => {
            features_Layer.forEach(feature => {
              const point = turf.point(feature.geometry.coordinates) // 将要素转为 Turf.js 中的 Point 对象
              if (turf.booleanPointInPolygon(point, turf.polygon([coordinate]))) { // 判断要素是否在绘制的区域内
                selectedFeatures.push(feature) // 如果在区域内,则添加到选中要素数组中
              }
            })
          })
          // 将选中的要素添加到目标数组 便于后续高亮显示
          const source = {
            type: 'geojson',
            data: {
              type: 'FeatureCollection',
              features: selectedFeatures
            }
          }
          map.addLayer({
            id: 'selected',
            type: 'circle',
            source: source,
            paint: {
              'circle-radius': 15,
              'circle-color': '#ddec0a'
            }
          })

          //计算面积和面要素的中心点坐标
          if (data.features.length > 0) {
            const area = turf.area(data);
            // const polygonfeatures = turf.points([data.features[0].geometry.coordinates[0]])
            const centrepostion = turf.centroid(data.features[0])
            // Restrict the area to 2 decimal points.
            const rounded_area = Math.round(area * 100) / 100;
            answer.innerHTML = `<p>面积为:<strong>${rounded_area}</strong>square meters</p>
           <br />
            <p>中心点坐标:${centrepostion.geometry.coordinates}</p>`;

            console.log(centrepostion)
          } else {
            answer.innerHTML = '';
            if (e.type !== 'draw.delete')
              alert('Click the map to draw a polygon.');
          }
        }

运行效果如下:
在这里插入图片描述

2、实现地图上可拖动点

2.1、实现功能:

可以将点拖动到地图上的新位置,并在地图上显示新的点坐标。

2.2、实现思路:

首先定义一个空的点要素集合GeoJSON变量,用来存放拖动点坐标信息;然后使用MapTouchEvents来防止默认的地图拖动行为并获取更新的坐标。最后使用map.getSource中的setData对变量更新赋值,

2.3、代码示例:

首先dom中添加如下标签:

<pre id="coordinates" class="coordinates"></pre>
const canvas = map.getCanvasContainer();

const geojson = {
    'type': 'FeatureCollection',
    'features': [{
            'type': 'Feature',
            'geometry': {
                'type': 'Point',
                'coordinates': [0, 0]
            }
        }
    ]
};

function onMove(e) {
    const coords = e.lngLat;

    // Set a UI indicator for dragging.
    canvas.style.cursor = 'grabbing';

    // Update the Point feature in `geojson` coordinates
    // and call setData to the source layer `point` on it.
    geojson.features[0].geometry.coordinates = [coords.lng, coords.lat];
    map.getSource('point').setData(geojson);
}

function onUp(e) {
    const coords = e.lngLat;

    // Print the coordinates of where the point had
    // finished being dragged to on the map.
    coordinates.style.display = 'block';
    coordinates.innerHTML = `Longitude: ${coords.lng}<br />Latitude: ${coords.lat}`;
    canvas.style.cursor = '';

    // Unbind mouse/touch events
    map.off('mousemove', onMove);
    map.off('touchmove', onMove);
}

map.on('load', () => {
    // Add a single point to the map.
    map.addSource('point', {
        'type': 'geojson',
        'data': geojson
    });

    map.addLayer({
        'id': 'point',
        'type': 'circle',
        'source': 'point',
        'paint': {
            'circle-radius': 10,
            'circle-color': '#F84C4C' // red color
        }
    });

    // When the cursor enters a feature in
    // the point layer, prepare for dragging.
    map.on('mouseenter', 'point', () => {
        map.setPaintProperty('point', 'circle-color', '#3bb2d0');
        canvas.style.cursor = 'move';
    });

    map.on('mouseleave', 'point', () => {
        map.setPaintProperty('point', 'circle-color', '#3887be');
        canvas.style.cursor = '';
    });

    map.on('mousedown', 'point', (e) => {
        // Prevent the default map drag behavior.
        e.preventDefault();

        canvas.style.cursor = 'grab';

        map.on('mousemove', onMove);
        map.once('mouseup', onUp);
    });

    map.on('touchstart', 'point', (e) => {
        if (e.points.length !== 1)
            return;

        // Prevent the default map drag behavior.
        e.preventDefault();

        map.on('touchmove', onMove);
        map.once('touchend', onUp);
    });
});

效果展示:
在这里插入图片描述

3、实时更新要素功能

实现功能:通过更新地图上的现有要素的数据来添加新坐标来动态显示路径
代码示例:

map.on('load', async () => {
// We fetch the JSON here so that we can parse and use it separately
// from GL JS's use in the added source.
const response = await fetch(
'https://docs.mapbox.com/mapbox-gl-js/assets/hike.geojson'
);
const data = await response.json();
// save full coordinate list for later
const coordinates = data.features[0].geometry.coordinates;
 
// start by showing just the first coordinate
data.features[0].geometry.coordinates = [coordinates[0]];
 
// add it to the map
map.addSource('trace', { type: 'geojson', data: data });
map.addLayer({
'id': 'trace',
'type': 'line',
'source': 'trace',
'paint': {
'line-color': 'yellow',
'line-opacity': 0.75,
'line-width': 5
}
});
 
// setup the viewport
map.jumpTo({ 'center': coordinates[0], 'zoom': 14 });
map.setPitch(30);
 
// on a regular basis, add more coordinates from the saved list and update the map
let i = 0;
const timer = setInterval(() => {
if (i < coordinates.length) {
data.features[0].geometry.coordinates.push(coordinates[i]);
map.getSource('trace').setData(data);
map.panTo(coordinates[i]);
i++;
} else {
window.clearInterval(timer);
}
}, 10);
});

效果展示:
在这里插入图片描述

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

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

相关文章

已安装过PageOfiice,谷歌浏览器反复提示PageOffice安装

原因&#xff1a;Chrome开发团队以网络安全为由&#xff0c;强推ssl证书&#xff0c;希望所有部署在公网的网站&#xff0c;全部改用https访问&#xff0c;所以最新的谷歌和edge升级到94版本后对公网上的http请求下的非同域的http请求进行了拦截&#xff0c;于是就出现了目前遇…

火灾发生时如何实时地选择逃生路线

安科瑞虞佳豪 南京大学无菌动物房改造项目&#xff0c;位于位于南京江北新区学府路 12 号。改造面积约为 1100m2&#xff0c;均在原有建筑底层。其中&#xff0c;动物房区域含饲养室 6 间&#xff0c;层高 4.9m。功能实验区域含实验室 4间、手术室 1 间、暂养室 2 间、内外准备…

Linux进程信号 | 信号产生

前面的文章中我们讲述了进程间通信的部分内容&#xff0c;在本文中我们继续来学习进程信号相关的知识点。 信号入门 生活角度的信号 在我们的日常生活中&#xff0c;就有着各种各样的信号&#xff0c;它会给我们传递各种各样的信息&#xff0c;可以知道的是一个信号例如&…

webpack提升开发体验SourceMap

一、开发场景介绍 开发中我们不可避免的会写一些bug出来&#xff0c;这时候要调试&#xff0c;快速定位到bug到底出现在哪尤为关键。 例如我故意在sum函数中写一个错误代码如下&#xff1a; 这时我们用前面章节已经写好的开发模式的webpack.dev.js运行&#xff0c;控制台会出…

【Spring】— MyBatis与Spring的整合

目录 1.整合环境1.1准备所需的JAR包1&#xff0e;所需Spring框架的JAR包2&#xff0e;所需MyBatis框架的JAR包3&#xff0e;MyBatis与Spring整合所需的中间JAR包4&#xff0e;数据库驱动JAR包5&#xff0e;数据源所需JAR包 1.2 编写配置文件 2.整合2.1 传统DAO方式的开发整合1&…

龙蜥社区第 17 次运营委员会会议顺利召开

5 月 26 日&#xff0c;龙蜥社区走进 Arm 北京办公室召开了第 17 次运营委员会会议。本次会议由龙蜥社区运营委员会副主席金美琴主持。来自 Arm、阿里云、电信、红旗软件、飞腾、海光、Intel、浪潮信息、联通软研院、龙芯、凝思软件、麒麟软件、普华基础软件、申泰、统信软件、…

Vue-Element-Admin项目学习笔记(7)用Node.js写一个简单后端接口

前情回顾&#xff1a; vue-element-admin项目学习笔记&#xff08;1&#xff09;安装、配置、启动项目 vue-element-admin项目学习笔记&#xff08;2&#xff09;main.js 文件分析 vue-element-admin项目学习笔记&#xff08;3&#xff09;路由分析一:静态路由 vue-element-adm…

Opencv-C++笔记 (3) : opencv的库介绍以及和C++对接转换

文章目录 一、Opencv库的介绍calib3dcontribcoreimgprocfeatures2dflannhighguilegacymlnonfreeobjdetectoclphotostitchingsuperrestsvideoVideostab 二、C和MAT 转换方式2.1、一维Vector2.2、二维vector2.3 数组2.4、类型转换 ——一维转 数组2.5、类型转换 -------- 一维MAT…

抖音同城榜相关介绍来啦,这篇文不若与众带你去详细了解它

一、抖音同城榜是什么&#xff1f; 抖音同城榜是抖音平台上的一个功能&#xff0c;它可以根据用户所在的地理位置&#xff0c;推荐附近热门的视频和达人。用户可以通过同城榜来了解当地的热门话题、美食、景点等信息&#xff0c;也可以通过同城榜认识志同道合的朋友和达人&…

DTD怎样进行元素类型定义?【语法格式】

Bootstrap常用组件包括按钮、导航、菜单和表单等。使用Bootstrap不需要编写复杂的样式代码&#xff0c;只需要使用Bootstrap组件就可以实现复杂的页面架构。下面将对Boolstrap按钮组件进行详细讲解。 Bootstrap提供了多种样式的按钮&#xff0c;每个样式的按钮都有自己的语义用…

动态规划:最长公共子序列

动态规划&#xff1a;最长公共子序列 前言一、动态规划 前言 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在…

练习1:线性回归

练习1&#xff1a;线性回归 介绍 在本练习中&#xff0c;您将 实现线性回归并了解其在数据上的工作原理。 在开始练习前&#xff0c;需要下载如下的文件进行数据上传&#xff1a; ex1data1.txt -单变量的线性回归数据集ex1data2.txt -多变量的线性回归数据集 在整个练习中&…

【IMX6ULL驱动开发学习】09.Linux驱动之GPIO中断(附SR501人体红外感应驱动代码)

Linux驱动的GPIO中断编程主要有以下几个步骤&#xff1a; 1、 通过GPIO号获取软件中断号 (中断编程不需要设置GPIO输入输出&#xff0c;当然申请GPIO&#xff0c;设置输入也没问题) int gpio_to_irq(unsigned int gpio)参数含义gpioGPIO引脚编号 2、 注册中断处理函数&#…

k8s中docker0默认ip修改

原因&#xff1a; 由于ip冲突&#xff0c;必须要修改docker0的默认ip 过程&#xff1a; &#xff08;1&#xff09;修改文件 /etc/docker/daemon.json 添加内容 “bip”: “ip/netmask” [ 切勿与宿主机同网段 ] &#xff08;2&#xff09; &#xff08;3&#xff09;重启docke…

视觉SLAM十四讲——ch9实践(后端1)

视觉SLAM十四讲——ch9的实践操作及避坑 0.实践前小知识介绍0.1 数据集的使用 1. 实践操作前的准备工作2. 实践过程2.1 Ceres BA2.2 g2o求解BA 3. 遇到的问题及解决办法3.1 查看.ply文件时报警告 0.实践前小知识介绍 0.1 数据集的使用 Ceres BA使用的是BAL数据集。在本例中&a…

为什么说2023年最难招聘的岗位是高性能计算工程师?

随着毕业季的临近&#xff0c;高校毕业生将进入就业关键阶段。据统计&#xff0c;2023届全国高校毕业生预计达到1158万人&#xff0c;同比增加82万人&#xff0c;再创新高。尽管有千万的大学毕业生&#xff0c;但是企业反馈依然很难招聘到合适的高性能计算工程师。 这主要归因于…

看到就赚到的5款小众软件

今天推荐5款十分小众的软件&#xff0c;知道的人不多&#xff0c;但是每个都是非常非常好用的&#xff0c;有兴趣的小伙伴可以自行搜索下载。 图文识别——PandaOCR PandaOCR是一款用于识别和转换图片中的文字的工具。它可以让你对任何格式的图片进行文字识别&#xff0c;并输…

STM32速成笔记—按键检测

如果需要本文程序工程&#xff0c;请评论区留邮箱或者私信。 文章目录 一、按键检测原理二、硬件连接三、程序设计3.1 初始化GPIO3.2 按键扫描函数 四、按键控制LED4.1 初始化LED和KEY的GPIO4.2 编写按键扫描函数4.2 编写LED控制函数4.3 编写按键服务函数 五、拓展5.1 一个按键…

如何使用二维码实现配电箱巡检

施工工地的外部环境条件恶劣,加之工地上机动车辆的运行和机械设备的应用&#xff0c;均易导致电气故障的发生。现场配电箱缺乏专业技术人员的管理,易造成触电伤害、火灾等事故。现场纸质巡检存在以下问题&#xff1a; 1、信息查询不便:配电箱信息、负责人&#xff0c;历史巡检维…

Flowable服务组件-扩展组件

Flowable服务组件-扩展组件 扩展组件 文章目录 Flowable服务组件-扩展组件前言Flowable给我们提供了非常丰富的组件&#xff0c;但是在实际场景中&#xff0c;我们有需要企业个性化的组件&#xff0c;如何扩展自己的组件至关重要 一、扩展微服务回调组件二、程序步骤1.定义我们…