mapbox 高亮相同特征的要素数据

news2024/9/20 8:10:27

一、完整代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Highlight features containing similar data</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v3.1.2/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v3.1.2/mapbox-gl.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<style>
    .map-overlay {
        font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
        background-color: #fff;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
        border-radius: 3px;
        position: absolute;
        width: 25%;
        top: 10px;
        left: 10px;
        padding: 10px;
        display: none;
    }
</style>

<div id="map"></div>
<div id="map-overlay" class="map-overlay"></div>

<script>
	// TO MAKE THE MAP APPEAR YOU MUST
	// ADD YOUR ACCESS TOKEN FROM
	// https://account.mapbox.com
	mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
    const map = new mapboxgl.Map({
        container: 'map',
        // Choose from Mapbox's core styles, or make your own style with Mapbox Studio
        style: 'mapbox://styles/mapbox/streets-v12',
        center: [-98, 38.88],
        minZoom: 2,
        zoom: 3
    });

    const overlay = document.getElementById('map-overlay');

    // Create a popup, but don't add it to the map yet.
    const popup = new mapboxgl.Popup({
        closeButton: false
    });

    // Because features come from tiled vector data,
    // feature geometries may be split
    // or duplicated across tile boundaries.
    // As a result, features may appear
    // multiple times in query results.
    function getUniqueFeatures(features, comparatorProperty) {
        const uniqueIds = new Set();
        const uniqueFeatures = [];
        for (const feature of features) {
            const id = feature.properties[comparatorProperty];
            if (!uniqueIds.has(id)) {
                uniqueIds.add(id);
                uniqueFeatures.push(feature);
            }
        }
        return uniqueFeatures;
    }

    map.on('load', () => {
        // Add a custom vector tileset source. The tileset used in
        // this example contains a feature for every county in the U.S.
        // Each county contains four properties. For example:
        // {
        //     COUNTY: "Uintah County",
        //     FIPS: 49047,
        //     median-income: 62363,
        //     population: 34576
        // }
        map.addSource('counties', {
            'type': 'vector',
            'url': 'mapbox://mapbox.82pkq93d'
        });
        // Add transparent county polygons
        // for default display.
        map.addLayer(
            {
                'id': 'counties',
                'type': 'fill',
                'source': 'counties',
                'source-layer': 'original',
                'paint': {
                    'fill-outline-color': 'rgba(0,0,0,0.1)',
                    'fill-color': 'rgba(0,0,0,0.1)'
                }
            },
            // Place polygons under labels, roads and buildings.
            'building'
        );

        // Add filled county polygons
        // for highlighted display.
        map.addLayer(
            {
                'id': 'counties-highlighted',
                'type': 'fill',
                'source': 'counties',
                'source-layer': 'original',
                'paint': {
                    'fill-outline-color': '#484896',
                    'fill-color': '#6e599f',
                    'fill-opacity': 0.75
                },
                // Display none by adding a
                // filter with an empty string.
                'filter': ['in', 'COUNTY', '']
            },
            // Place polygons under labels, roads and buildings.
            'building'
        );

        map.on('mousemove', 'counties', (e) => {
            // Change the cursor style as a UI indicator.
            map.getCanvas().style.cursor = 'pointer';

            // Use the first found feature.
            const feature = e.features[0];

            // Query the counties layer visible in the map.
            // Only onscreen features are returned.
            // Use filter to collect only results
            // with the same county name.
            const relatedCounties = map.querySourceFeatures('counties', {
                sourceLayer: 'original',
                filter: ['in', 'COUNTY', feature.properties.COUNTY]
            });

            // Remove duplicates by checking for matching FIPS county ID.
            const uniqueCounties = getUniqueFeatures(relatedCounties, 'FIPS');

            // Total the populations of all features.
            const populationSum = uniqueCounties.reduce((memo, feature) => {
                return memo + feature.properties.population;
            }, 0);

            // Render found features in an overlay.
            const title = document.createElement('strong');
            title.textContent =
                feature.properties.COUNTY +
                ' (' +
                uniqueCounties.length +
                ' found)';

            const population = document.createElement('div');
            population.textContent =
                'Total population: ' + populationSum.toLocaleString();

            overlay.innerHTML = '';
            overlay.style.display = 'block';

            overlay.appendChild(title);
            overlay.appendChild(population);

            // Add features with the same county name
            // to the highlighted layer.
            map.setFilter('counties-highlighted', [
                'in',
                'COUNTY',
                feature.properties.COUNTY
            ]);

            // Display a popup with the name of the county.
            popup
                .setLngLat(e.lngLat)
                .setText(feature.properties.COUNTY)
                .addTo(map);
        });

        map.on('mouseleave', 'counties', () => {
            map.getCanvas().style.cursor = '';
            popup.remove();
            map.setFilter('counties-highlighted', ['in', 'COUNTY', '']);
            overlay.style.display = 'none';
        });
    });
</script>

</body>
</html>

二、效果截图

三、 代码分析

  1. 添加矢量瓦片数据源

    map.addSource('counties', {
        'type': 'vector',
        'url': 'mapbox://mapbox.82pkq93d'
    });
  2. 添加矢量瓦片底图图层

    
    // Add transparent county polygons
    // for default display.
    map.addLayer(
        {
            'id': 'counties',
            'type': 'fill',
            'source': 'counties',
            'source-layer': 'original',
            'paint': {
                'fill-outline-color': 'rgba(0,0,0,0.1)',
                'fill-color': 'rgba(0,0,0,0.1)'
            }
        },
        // Place polygons under labels, roads and buildings.
        'building'
    );
  3. 添加矢量瓦片高亮图层

    map.addLayer(
        {
            'id': 'counties-highlighted',
            'type': 'fill',
            'source': 'counties',
            'source-layer': 'original',
            'paint': {
                'fill-outline-color': '#484896',
            'fill-color': '#6e599f',
            'fill-opacity': 0.75
            },
            // Display none by adding a
            // filter with an empty string.
            'filter': ['in', 'COUNTY', '']
        },
        // Place polygons under labels, roads and buildings.
        'building'
    );
  4. 底图图层添加鼠标移入事件

    map.on('mousemove', 'counties', (e) => {
    
    }
  5. 底图图层鼠标移出事件

    map.on('mouseleave', 'counties', () => {
    
    }
  6. 获取相关联要素数据信息

    // 1 鼠标移入图层后修改鼠标手势
    map.getCanvas().style.cursor = 'pointer';
    
    // 2 获取鼠标移入第一个要素
    const feature = e.features[0];
    
    // 3 根据第一个要素的属性信息,根据图层获取与该属性相同的要素
    const relatedCounties = map.querySourceFeatures('counties', {
        sourceLayer: 'original',
        filter: ['in', 'COUNTY', feature.properties.COUNTY]
    });
    
    // 4 对关联关联要素数据进行去重
    const uniqueCounties = getUniqueFeatures(relatedCounties, 'FIPS');
    
    function getUniqueFeatures(features, comparatorProperty) {
        const uniqueIds = new Set();
        const uniqueFeatures = [];
        for (const feature of features) {
            const id = feature.properties[comparatorProperty];
            if (!uniqueIds.has(id)) {
                uniqueIds.add(id);
                uniqueFeatures.push(feature);
            }
        }
        return uniqueFeatures;
    }
    
    // 5 获取去重后关联图层人口总和
    const populationSum = uniqueCounties.reduce((memo, feature) => {
        return memo + feature.properties.population;
    }, 0);
    
    // 6 创建dom展示人口相关信息
    const title = document.createElement('strong');
    title.textContent =
        feature.properties.COUNTY +
        ' (' +
        uniqueCounties.length +
    ' found)';
     
    const population = document.createElement('div');
    population.textContent =
        'Total population: ' + populationSum.toLocaleString();
     
    overlay.innerHTML = '';
    overlay.style.display = 'block';
     
    overlay.appendChild(title);
    overlay.appendChild(population);
    
    // 7 修改高亮图层过滤条件显示高亮要素
    map.setFilter('counties-highlighted', [
        'in',
        'COUNTY',
        feature.properties.COUNTY
    ]);
    
    // 8 根据过滤条件清空高亮要素
    map.setFilter('counties-highlighted', ['in', 'COUNTY', '']);
    

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

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

相关文章

VUE3+TS使用OpenSeadragon学习之旅,实现多图片切换效果

1.官方网站&#xff1a;OpenSeadragon 2.使用npm下载插件&#xff1a;npm install openseadragon 3.在 index.html文件引入资源 <link rel"stylesheet" href"node_modules/openseadragon/build/openseadragon/openseadragon.css" /><script src…

正点原子--STM32定时器学习笔记(1)

这部分是笔者对基本定时器的理论知识进行学习与总结&#xff01;&#xff0c;主要记录自己在学习过程中遇到的重难点&#xff0c;其他一些基础点就一笔带过了&#xff01; 1. 定时器概述 1.1 软件定时原理 使用纯软件&#xff08;CPU死等&#xff09;的方式实现定时&#xf…

Python之运算符汇总

1.算数运算符 假设 a 10, b 20 2.比较运算符 3.赋值运算符 4.逻辑运算符 逻辑运算的顺序排列:从左往右开始执行 () > not > and > or and or 一真一假 都为真: 取后面的 取前面的 取假的…

sentinel的Context创建流程分析

sentinel入门 功能 限流&#xff1a;通过限制请求速率、并发数或者用户数量来控制系统的流量&#xff0c;防止系统因为流量过大而崩溃或无响应的情况发生。 熔断&#xff1a;在系统出现故障或异常时将故障节点从系统中断开&#xff0c;从而保证系统的可用性。 降级&#xf…

PyTorch 2.2 中文官方教程(十三)

在 C中注册一个分发的运算符 原文&#xff1a;pytorch.org/tutorials/advanced/dispatcher.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 分发器是 PyTorch 的一个内部组件&#xff0c;负责确定在调用诸如torch::add这样的函数时实际运行哪些代码。这可能并不简…

元数据驱动的思想

元数据驱动的思想 元数据驱动的思想应该不会陌生&#xff0c;但元数据驱动的实践应该会非常陌生。 因为元数据驱动架构是为了解决高频个性化的复杂业务而诞生的&#xff0c;而这种业务场景只存在2B领域。 有关元数据驱动的架构思想&#xff0c;在这里暂先简单抛几个点。&#…

【动态规划】【树形dp】【C++算法】968监控二叉树

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode:968监控二叉树 给定一个二叉树&#xff0c;我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所…

机器学习:线性判别分析LDA(Python)

一、线性判别分析的定义 二、线性判别分析——二分类模型 lda2classify.py import numpy as npclass LDABinaryClassifier:"""线性判别分析二分类模型"""def __init__(self):self.mu None # 各类别均值向量self.Sw_i None # 各类内散度矩阵…

【电路笔记】-线圈的电感

线圈的电感 文章目录 线圈的电感1、概述2、线圈的电感3、电感示例14、电感示例2 电感是指抵抗流过其的电流变化的元件属性的名称&#xff0c;即使是直的电线也会有一些电感。 1、概述 线圈的电感是指感应线圈抵抗流过其的电流的任何变化所必须的电气特性。 因此&#xff0c;电…

Qt拖拽事件,实现控件内项的相互拖拽

文章目录 1拖拽演示2 步骤3 实现 这里主要以QTableview控件为例&#xff0c;实现表格内数据的相互拖拽。 1拖拽演示 2 步骤 自定以QTableView类&#xff0c;在自定义类中重写拖拽事件&#xff1a; void dropEvent(QDropEvent *event); void dragEnterEvent(QDragEnterEvent *…

装饰你的APP:使用Lottie-Android创建动画效果

装饰你的APP&#xff1a;使用Lottie-Android创建动画效果 1. Lottie-Android简介 Lottie-Android是一个强大的开源库&#xff0c;由Airbnb开发&#xff0c;旨在帮助开发者轻松地在Android应用中添加高质量的动画效果。它基于Adobe After Effects软件中的Bodymovin插件&#x…

一种缩短轮询时间的处理办法

我们平常处理轮询任务的时候&#xff0c;会用时间片的方式来分割开&#xff0c;每个时间片处理某一个任务。 有时候有些任务并不需要有动作&#xff0c;本轮轮询到它&#xff0c;它不需要干活&#xff0c;于是这个时间片就浪费了。但如果其他时间片里面的任务又急着呢&#xff…

微信小程序使用ucharts折线图,有负数显示0刻度线

当数据有负数和正数的时候默认不会显示0刻度线&#xff0c;不方便看出正负对比 实现思路&#xff1a;显示的刻度线是根据数据的最大值和最小值自动分配到刻度线上面&#xff0c;把最大值和最小值设置为一样&#xff0c;然后平均分配给五个刻度线中间的刻度线就会为0就实现了显…

深入理解Istio服务网格(一)数据平面Envoy

一、服务网格概述(service mesh) 在传统的微服务架构中&#xff0c;服务间的调用&#xff0c;业务代码需要考虑认证、熔断、服务发现等非业务能力&#xff0c;在某种程度上&#xff0c;表现出了一定的耦合性 服务网格追求高级别的服务流量治理能力&#xff0c;认证、熔断、服…

如何在Vue应用程序中使用Vue-Router来实现路由嵌套动画效果

Vue-Router是Vue.js官方的路由管理插件&#xff0c;可以帮助我们轻松管理应用程序的路由。除了基本的路由功能外&#xff0c;Vue-Router还允许我们在切换路由时添加动画效果&#xff0c;提升用户体验。本文将介绍如何使用Vue-Router来实现路由嵌套动画效果&#xff0c;并提供具…

跟着pink老师前端入门教程-day17

2、CSS3 动画 动画&#xff08;animation&#xff09;是CSS3中就要有颠覆性的特征之一&#xff0c;可通过设置多个节点来精确控制一个或一组动画&#xff0c;常用来实现复杂的动画效果 相比较过渡&#xff0c;动画可以实现更多变化&#xff0c;更多控制&#xff0c;连续自动播…

Python3 交叉编译 numpy pandas scipy scikit-learn

1. 概述 由于需要将Python3.7 和一些软件包交叉编译到 armv7 平台硬件&#xff0c;如果是arm64位的系统&#xff0c;很多包都有预编译好的版本&#xff0c;可直接下载。本文主要在基于 crossenv(https://github.com/benfogle/crossenv)环境下交叉编译。 2. 编译环境搭建 创建…

处理SERVLET中的错误

处理SERVLET中的错误 问题陈述 一位用户在使用在线计算机应用程序时输入一个非数字字符做数字加法。servlet试图将用户输入的值转换成整数型时,引发了NumberFormException类型的异常。要创建一个Web应用程序来使用自定义错误页面处理该异常。该自定义错误页面需要向用户提供关…

【原创】点火线圈项目

一、项目介绍 此点火线圈项目主要实现对各部件的自动组装、测试、以及下料。 二、各个工位实现动作流程 1、合装移载位,这个工位通过伺服电机和气缸夹爪把上游设备加工的点火线圈插头移载到合装位。 通过伺服设置抓料位置(绝对定位)伺服电机到了抓料位后伸出气缸伸出,夹…

acwing869. 试除法求约数870. 约数个数AcWing871. 约数之和872. 最大公约数

869. 试除法求约数 思路&#xff1a; 约数和质数的求解有着共性&#xff0c; 就是都是使用 for (int i 1; i < n/i; i) 进行计算的。这样的原因是因为约数必然也是两两一组&#xff0c; 那么我们求出小的自然也就知道另一个&#xff0c;只要再判断一下n/i和i是否相同&a…