【2025最新】ArcGIS for JS 范围裁剪(只保留特定区域显示),实现精准地理范围聚焦

ArcGIS for JS 实战:范围裁剪(只保留特定区域显示),实现精准地理范围聚焦 🗺️

在 ArcGIS for JavaScript 开发中,经常会遇到 "只显示指定区域,隐藏其他范围" 的需求,比如区域数据可视化、特定地理范围分析等场景。本文适用于 ArcGIS Maps SDK for JavaScri pt 4.28~4.33 版本,结合天地图底图,带大家一步步实现 "特定区域保留显示" 功能,代码可直接复用!

文章目录

  • [ArcGIS for JS 实战:范围裁剪(只保留特定区域显示),实现精准地理范围聚焦 🗺️](#ArcGIS for JS 实战:范围裁剪(只保留特定区域显示),实现精准地理范围聚焦 🗺️)
    • 效果图
    • [一、核心思路:图层混合模式实现 "范围裁剪" ✂️](#一、核心思路:图层混合模式实现 “范围裁剪” ✂️)
    • 二、完整代码解析📝
      • [1. 基础页面结构与样式](#1. 基础页面结构与样式)
      • [2. 核心模块引入与天地图加载](#2. 核心模块引入与天地图加载)
      • [3. 定义 "保留区域" 的地理范围 📍](#3. 定义 “保留区域” 的地理范围 📍)
      • [4. 构建 "裁剪层":关键的 GraphicsLayer 🎨](#4. 构建 “裁剪层”:关键的 GraphicsLayer 🎨)
      • [5. 组合图层并初始化地图 🚀](#5. 组合图层并初始化地图 🚀)
    • [三、关键注意事项 ⚠️](#三、关键注意事项 ⚠️)
    • [四、所有代码 🚀](#四、所有代码 🚀)
工具 /插件/系统 名 版本 说明
ArcGIS JS API 4.28~4.33 地图核心能力(底图加载、视图渲染)
天地图服务 - 提供街道、卫星、地形等底图数据源

效果图

一、核心思路:图层混合模式实现 "范围裁剪" ✂️

实现 "只保留特定区域" 的核心原理是利用 GraphicsLayer** 的 blendMode: "destination-in" 属性**:

  • destination-in 表示 "只显示当前图层与下层图层重叠的区域",非重叠区域会被透明化

  • 我们只需绘制一个 "目标保留区域" 的面图形,结合该混合模式,就能实现 "裁剪" 效果

  • 搭配天地图底图,可快速构建带区域聚焦的地图应用

二、完整代码解析📝

1. 基础页面结构与样式

首先搭建 HTML 骨架,设置地图容器占满全屏,确保地图显示无偏差:

复制代码
<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="utf-8" />

    <!-- 适配移动端,防止地图缩放异常 -->

    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />

    <title>ArcGIS for JS 只保留特定区域</title>

    <style>

        /* 地图容器全屏样式 */

        html, body, #viewDiv {

            padding: 0;

            margin: 0;

            height: 100%;

            width: 100%;

        }

    </style>

    <!-- 引入ArcGIS核心样式和JS库 -->

    <link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/light/main.css" />

    <script src="https://js.arcgis.com/4.33/"></script>

</head>

<body>

    <!-- 地图渲染容器 -->

    <div id="viewDiv"></div>

    <script type="module">

        // 核心逻辑代码在这里...

    </script>

</body>

</html>

2. 核心模块引入与天地图加载

通过 $arcgis.import 引入 ArcGIS 核心模块,同时加载天地图底图(需提前准备 tiandituLoader.js 工具类,也可以直接在《天地图底图加载》)中直接复制。

复制代码
// 1. 引入ArcGIS核心模块

const [Map, MapView, GraphicsLayer, GroupLayer] =

    await $arcgis.import([

        "@arcgis/core/Map.js",       // 地图实例

        "@arcgis/core/views/MapView.js", // 地图视图

        "@arcgis/core/layers/GraphicsLayer.js", // 矢量图形层

        "@arcgis/core/layers/GroupLayer.js" // 图层组(用于管理多个图层)

    ]);

// 2. 加载天地图底图(矢量图+注记层)

import { loadTiandituBasemap } from './js/tiandituLoader.js';

const {

    vecLayer: worldImagery,  // 天地图矢量底图

    cvaLayer: tileLayer     // 天地图注记层(显示地名)

} = await loadTiandituBasemap();

3. 定义 "保留区域" 的地理范围 📍

通过 rings 数组定义多边形坐标(支持多环,可用于包含 "飞地" 场景),坐标格式为 [经度, 纬度], spatialReference 设为 4326(WGS84 坐标系):

复制代码
// 定义保留区域的多边形坐标(示例为两个闭合区域)

const rings = [

    // 第一个区域(示例范围)

    [[123.09306581, 43.90257375], 

     [123.82517908, 43.58244008], 

     [124.26830027, 42.49823921], 

     [120.41507254, 41.97045084], 

     [120.33800799, 43.61034574], 

     [123.09306581, 43.90257375]], // 闭合坐标(首尾一致)

    

    // 第二个区域(可理解为"飞地")

    [[124.52760067, 45.86828802], 

     [121.05156665, 44.74454778], 

     [125.90119475, 44.46513338], 

     [124.52760067, 45.86828802]]

];

4. 构建 "裁剪层":关键的 GraphicsLayer 🎨

创建 GraphicsLayer 并设置 blendMode: "destination-in",这是实现 "只保留特定区域" 的核心步骤:

复制代码
const graphicsLayer = new GraphicsLayer({

    blendMode: "destination-in", // 核心混合模式:只显示重叠区域

    title: "特定保留区域",

    graphics: [

        new Graphic({

            geometry: {

                type: "polygon",    // 图形类型:多边形

                rings: rings,       // 绑定上面定义的区域坐标

                spatialReference: { wkid: 4326 } // 坐标系

            },

            symbol: { // 多边形样式(因混合模式,颜色仅影响重叠区域透明度)

                type: "simple-fill",

                color: [0, 0, 0, 1], // 黑色不透明(确保重叠区域完全显示)

                outline: { // 区域边界样式

                    color: [255, 0, 0], // 红色边界

                    width: 2 // 边界宽度

                }

            },

        })

    ]

});

5. 组合图层并初始化地图 🚀

将天地图底图、注记层、裁剪层组合成 GroupLayer,避免图层层级混乱,最后初始化地图视图:

复制代码
// 1. 组合图层(顺序:底图 → 注记 → 裁剪层)

const groupLayer = new GroupLayer({

    layers: [worldImagery, tileLayer, graphicsLayer],

    opacity: 1 // 整体图层透明度

});

// 2. 创建地图实例

const map = new Map({

    layers: [groupLayer] // 绑定图层组

});

// 3. 创建地图视图(控制地图显示)

const view = new MapView({

    container: "viewDiv",    // 绑定地图容器

    map: map,                // 绑定地图实例

    center: [125.8425456, 43.85312804], // 初始中心点坐标

    zoom: 8,                 // 初始缩放级别(根据区域大小调整)

    constraints: {

        minScale: 19499143,  // 最小缩放级别(防止缩太小看到无关区域)

        maxScale: 5000       // 最大缩放级别(防止放太大模糊)

    },

    popup: null // 暂时关闭弹窗(如需启用,可删除此配置)

});

// 可选:地图加载完成后提示

view.when(() => {

    console.log("地图加载完成,已显示特定保留区域!");

});

三、关键注意事项 ⚠️

  1. 坐标顺序问题 :ArcGIS 中 rings 坐标格式为 [经度, 纬度],不要和 [纬度, 经度] 混淆,否则区域会显示异常;

  2. 混合模式生效条件GraphicsLayer 必须放在最上层(图层顺序:底图 → 业务层 → 裁剪层),否则混合模式不生效;

  3. 天地图加载依赖tiandituLoader.js 需要正确配置天地图 Key(需自行申请天地图开发者账号,免费版足够测试);

  4. 多区域支持rings 数组支持多个子数组,可实现 "多个不连续区域同时保留"(如多个城市、多个地块)。

四、所有代码 🚀

index.html

复制代码
<!DOCTYPE html>
<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>Highlight a country with an effect | Sample | ArcGIS Maps SDK for JavaScript 4.33</title>
    <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }

        #messageDiv {
            padding-left: 10px;
            padding-right: 10px;
        }
    </style>

    <link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/light/main.css" />
    <script src="https://js.arcgis.com/4.33/"></script>

    <script type="module">
        const [Map, MapView, TileLayer, Graphic, GraphicsLayer, GroupLayer] =
            await $arcgis.import([
                "@arcgis/core/Map.js",
                "@arcgis/core/views/MapView.js",
                "@arcgis/core/layers/TileLayer.js",
                "@arcgis/core/Graphic.js",
                "@arcgis/core/layers/GraphicsLayer.js",
                "@arcgis/core/layers/GroupLayer.js"
            ]);

        import { loadTiandituBasemap } from './js/tiandituLoader.js';
        const {
            config,
            getUrlTemplate,
            WebTileLayer,
            vecLayer: worldImagery,
            cvaLayer: tileLayer,
            tileInfo } = await loadTiandituBasemap();


        const rings = [[[123.09306581, 43.90257375], [123.82517908, 43.58244008], [124.26830027, 42.49823921],
        [120.41507254, 41.97045084], [120.33800799, 43.61034574], [123.09306581, 43.90257375]],
        [[124.52760067, 45.86828802], [121.05156665, 44.74454778], [125.90119475, 44.46513338], [124.52760067, 45.86828802]]
        ]
        
        const graphicsLayer = new GraphicsLayer({
            blendMode: "destination-in",
            title: "layer",
            graphics: [
                new Graphic({
                    geometry: {
                        type: "polygon",
                        rings,
                        spatialReference: { wkid: 4326 }
                    },
                    attributes: {
                        objectid: 1,
                        // name:,
                        longitude: 116.397428,
                        latitude: 39.90923
                    },
                    symbol: {
                        type: "simple-fill",
                        color: [0, 0, 0, 1],
                        outline: {
                            color: [0, 0, 0],
                            width: 2
                        }
                    },
                }),
            ],
        });

        const groupLayer = new GroupLayer({
            layers: [
                worldImagery,
                tileLayer,
                graphicsLayer,

            ],
            opacity: 1,

        });
        const map = new Map({
            layers: [groupLayer]
        });

        const view = new MapView({
            container: "viewDiv",
            map: map,
            center: [125.8425456, 43.85312804], // 鍖椾含鍧愭爣
            popup: null,
            constraints: {
                minScale: 19499143,
            },
        });


    </script>
</head>

<body>
    <div id="viewDiv"></div>
</body>

</html>
相关推荐
前端小菜袅4 小时前
uniapp配置自动导入uni生命周期等方法
前端·javascript·uni-app
一枚前端小能手4 小时前
「周更第7期」实用JS库推荐:Vite
前端·javascript·vite
一根甜苦瓜4 小时前
Go语言Slice的一道骚题
开发语言·后端·golang
驰羽4 小时前
[GO]Go语言泛型详解
开发语言·golang·xcode
NPE~4 小时前
[手写系列]Go手写db — — 第五版(实现数据库操作模块)
开发语言·数据库·后端·golang·教程·手写系列·手写数据库
润 下5 小时前
C语言——深入解析C语言指针:从基础到实践从入门到精通(二)
c语言·开发语言·经验分享·笔记·学习·程序人生
布伦鸽5 小时前
C# WPF DataGrid使用Observable<Observable<object>类型作为数据源
开发语言·c#·wpf
say_fall5 小时前
精通C语言(4.四种动态内存有关函数)
c语言·开发语言
知识分享小能手5 小时前
微信小程序入门学习教程,从入门到精通,电影之家小程序项目知识点详解 (17)
前端·javascript·学习·微信小程序·小程序·前端框架·vue