ArcGIS JS API教程:基于GPS航向旋转Web样式符号


ArcGIS JS API教程:基于GPS航向旋转Web样式符号

本教程详细介绍了如何利用arcgis j*ascript api实现web样式符号的动态旋转。我们将聚焦于使用`simplerenderer`中的`rotation`视觉变量,根据要素的属性(如gps航向数据)来精确控制地图上符号的方向。文章将通过代码示例、实现步骤和注意事项,指导开发者构建能够响应数据变化的地图应用,使符号(如车辆图标)能实时反映其在现实世界中的朝向。

1. 引言

在地图应用中,动态展示移动对象的方向是一个常见需求,例如在实时车辆追踪系统中,车辆图标应根据其GPS航向数据进行旋转,以准确反映其行驶方向。ArcGIS J*aScript API提供了强大的渲染能力,通过视觉变量(Visual Variables)可以轻松实现这一目标。本教程将深入探讨如何结合Web样式符号和SimpleRenderer的rotation视觉变量,实现基于数据属性的符号动态旋转。

2. 核心概念:使用SimpleRenderer和rotation视觉变量

ArcGIS API for J*aScript中的Renderer负责定义要素在地图上的显示方式。对于需要根据属性值动态改变外观的场景,Renderer的visualVariables属性是关键。其中,rotation视觉变量专门用于控制符号的旋转角度。

  • SimpleRenderer: 最基础的渲染器,用于为图层中的所有要素应用相同的符号样式。
  • visualVariables: Renderer的一个属性,它是一个数组,允许根据要素的属性动态调整符号的视觉效果,如颜色、大小、透明度或旋转。
  • rotation视觉变量:
    • type: 必须设置为 "rotation"。
    • field 或 valueExpression: 指定用于驱动旋转的属性字段名或一个Arcade表达式。
      • field: 直接使用要素属性中的某个字段的值作为旋转角度。
      • valueExpression: 提供一个Arcade表达式,可以对一个或多个字段进行计算,然后返回旋转角度。例如,"$feature.heading" 表示使用要素的heading属性值。
    • rotationType: (可选)定义旋转的原点,例如"geographic"(正北向上,顺时针增加)或"arithmetic"(正东向上,逆时针增加)。默认通常是"arithmetic"。对于GPS航向,通常使用"geographic"。

3. 实现步骤

要实现基于GPS航向的Web样式符号旋转,主要步骤如下:

3.1 准备Web样式符号

首先,定义一个Web样式符号。Web样式符号是ArcGIS API提供的一种便捷方式,可以引用预定义的符号库中的符号,例如交通工具、建筑物等。

const carSymbol = {
  type: "web-style", // 指定符号类型为Web样式
  styleName: "EsriRealisticTransportationStyle", // 选择一个样式库
  name: "BMW_3-Series" // 指定样式库中的具体符号名称
};

3.2 创建要素图层和渲染器

为了应用rotation视觉变量,我们需要将符号应用于一个FeatureLayer,并通过SimpleRenderer来管理其渲染。

  1. 准备要素数据: 假设我们有一个包含longitude、latitude和heading(航向角度)的GPS数据点。

    Decktopus AI Decktopus AI

    AI在线生成高质量演示文稿

    Decktopus AI 153 查看详情 Decktopus AI
    const gpsData = {
      longitude: -101.9498125,
      latitude: 41.2097775,
      heading: 45 // 假设初始航向为45度
    };
  2. 创建Graphic: 将GPS数据转换为ArcGIS Graphic对象。

    const carGraphic = new Graphic({
      geometry: {
        type: "point",
        x: gpsData.longitude,
        y: gpsData.latitude
      },
      attributes: {
        ObjectID: 1, // FeatureLayer需要ObjectID字段
        heading: gpsData.heading
      }
    });
  3. 定义SimpleRenderer并应用rotation视觉变量: 这是实现旋转的核心。

    const carRenderer = new SimpleRenderer({
      symbol: carSymbol, // 使用之前定义的Web样式符号
      visualVariables: [
        {
          type: "rotation",
          field: "heading", // 使用Graphic的heading属性作为旋转角度
          // 或者使用 valueExpression: "$feature.heading"
          rotationType: "geographic" // 如果航向是地理方向(正北0度,顺时针增加),则设置为geographic
        }
      ]
    });
  4. 创建FeatureLayer: 将Graphic和Renderer结合起来创建FeatureLayer。

    const carsLayer = new FeatureLayer({
      source: [carGraphic], // 图层数据源
      objectIdField: "ObjectID", // 必须指定ObjectID字段
      renderer: carRenderer // 应用渲染器
    });

3.3 将图层添加到地图

最后,将配置好的FeatureLayer添加到地图中。

require([
  "esri/Map",
  "esri/views/MapView",
  "esri/layers/FeatureLayer",
  "esri/Graphic",
  "esri/renderers/SimpleRenderer"
], (Map, MapView, FeatureLayer, Graphic, SimpleRenderer) => {

  const map = new Map({
    basemap: "satellite"
  });

  const view = new MapView({
    container: "viewDiv",
    map: map,
    zoom: 15,
    center: [-101.9498125, 41.2097775],
  });

  // 1. 准备Web样式符号
  const carSymbol = {
    type: "web-style",
    styleName: "EsriRealisticTransportationStyle",
    name: "BMW_3-Series"
  };

  // 2. 准备要素数据和Graphic
  const initialGpsData = {
    longitude: -101.9498125,
    latitude: 41.2097775,
    heading: 45 // 初始航向
  };

  const carGraphic = new Graphic({
    geometry: {
      type: "point",
      x: initialGpsData.longitude,
      y: initialGpsData.latitude
    },
    attributes: {
      ObjectID: 1,
      heading: initialGpsData.heading
    }
  });

  // 3. 定义SimpleRenderer并应用rotation视觉变量
  const carRenderer = new SimpleRenderer({
    symbol: carSymbol,
    visualVariables: [
      {
        type: "rotation",
        field: "heading", // 使用Graphic的heading属性
        rotationType: "geographic" // 假设航向是地理方向
      }
    ]
  });

  // 4. 创建FeatureLayer
  const carsLayer = new FeatureLayer({
    source: [carGraphic],
    objectIdField: "ObjectID",
    renderer: carRenderer
  });

  // 5. 将图层添加到地图
  map.add(carsLayer);

  // 示例:动态更新航向并刷新渲染
  let currentHeading = initialGpsData.heading;
  document.getElementById("rotatePlus45Button").addEventListener("click", () => {
    currentHeading = (currentHeading + 45) % 360; // 每次增加45度
    document.getElementById("rotationDisplay").innerHTML = currentHeading;

    // 更新Graphic的属性
    carGraphic.attributes.heading = currentHeading;

    // 重新设置渲染器,强制图层刷新以应用新的视觉变量
    // 注意:对于FeatureLayer,直接修改Graphic属性后,
    // 需要通过更新Renderer或重新设置图层数据来触发重绘。
    // 这里通过重新创建Renderer来强制刷新。
    carsLayer.renderer = new SimpleRenderer({
      symbol: carSymbol,
      visualVariables: [
        {
          type: "rotation",
          field: "heading",
          rotationType: "geographic"
        }
      ]
    });
  });

  document.getElementById("rotationDisplay").innerHTML = currentHeading;
});

3.4 完整的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 JS API教程:基于GPS航向旋转Web样式符号</title>

    <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }
        #controlPanel {
            position: absolute;
            top: 10px;
            left: 10px;
            background: rgba(255, 255, 255, 0.8);
            padding: 10px;
            border-radius: 5px;
            z-index: 10;
        }
    </style>

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

<body>
    <div id="controlPanel">
        当前航向: <span id="rotationDisplay"></span> 度
        <button id="rotatePlus45Button">旋转 +45°</button>
    </div>
    <div id="viewDiv"></div>

    <script>
        require([
            "esri/Map",
            "esri/views/MapView",
            "esri/layers/FeatureLayer",
            "esri/Graphic",
            "esri/renderers/SimpleRenderer"
        ], (Map, MapView, FeatureLayer, Graphic, SimpleRenderer) => {

            const map = new Map({
                basemap: "satellite"
            });

            const view = new MapView({
                container: "viewDiv",
                map: map,
                zoom: 15,
                center: [-101.9498125, 41.2097775],
            });

            const carSymbol = {
                type: "web-style",
                styleName: "EsriRealisticTransportationStyle",
                name: "BMW_3-Series"
            };

            const initialGpsData = {
                longitude: -101.9498125,
                latitude: 41.2097775,
                heading: 45 // 初始航向
            };

            const carGraphic = new Graphic({
                geometry: {
                    type: "point",
                    x: initialGpsData.longitude,
                    y: initialGpsData.latitude
                },
                attributes: {
                    ObjectID: 1,
                    heading: initialGpsData.heading
                }
            });

            const carRenderer = new SimpleRenderer({
                symbol: carSymbol,
                visualVariables: [
                    {
                        type: "rotation",
                        field: "heading",
                        rotationType: "geographic"
                    }
                ]
            });

            const carsLayer = new FeatureLayer({
                source: [carGraphic],
                objectIdField: "ObjectID",
                renderer: carRenderer
            });

            map.add(carsLayer);

            let currentHeading = initialGpsData.heading;
            document.getElementById("rotatePlus45Button").addEventListener("click", () => {
                currentHeading = (currentHeading + 45) % 360;
                document.getElementById("rotationDisplay").innerHTML = currentHeading;

                // 更新Graphic的属性
                carGraphic.attributes.heading = currentHeading;

                // 为了让FeatureLayer重新渲染并应用新的属性,
                // 最直接的方法是重新设置其renderer。
                // 在实际应用中,如果数据源是动态更新的FeatureLayer,
                // 可能需要调用 layer.queryFeatures() 或 layer.refresh(),
                // 或者直接修改数据源(如FeatureTable)来触发更新。
                carsLayer.renderer = new SimpleRenderer({
                    symbol: carSymbol,
                    visualVariables: [
                        {
                            type: "rotation",
                            field: "heading",
                            rotationType: "geographic"
                        }
                    ]
                });
            });

            document.getElementById("rotationDisplay").innerHTML = currentHeading;
        });
    </script>
</body>
</html>

4. 注意事项

  1. visualVariables应用于Renderer: 关键点在于rotation视觉变量是Renderer的属性,而不是直接应用于单个Graphic的symbol。如果你直接创建Graphic并将其添加到GraphicsLayer,你需要手动修改Graphic.symbol.angle属性来实现旋转。但对于数据驱动的批量旋转,FeatureLayer与Renderer的组合更为高效和推荐。
  2. field vs valueExpression:
    • field: 当旋转角度直接存储在要素的一个属性字段中时使用。
    • valueExpression: 当旋转角度需要通过一个或多个字段计算得出时使用,或者当字段名可能不固定时,它提供了更大的灵活性。
  3. rotationType: 根据你的数据来源,选择正确的rotationType非常重要。
    • "geographic": 0度指向正北,顺时针方向增加。这通常与GPS航向数据(heading)一致。
    • "arithmetic": 0度指向正东,逆时针方向增加。
  4. 动态数据更新: 当底层数据(例如GPS航向)发生变化时,你需要确保地图能够重新渲染以反映这些变化。
    • 如果使用FeatureLayer,更新要素属性后,可能需要重新设置layer.renderer来强制刷新,或者如果你的FeatureLayer是连接到实时数据源,数据更新会自动触发重绘。
    • 对于更复杂的实时更新场景,可以考虑使用StreamLayer或结合WebSocket等技术,并在数据更新时调用layer.refresh()。
  5. 性能考虑: 如果地图上有大量需要实时旋转的要素,频繁地更新Renderer或FeatureLayer可能会影响性能。在这种情况下,优化数据处理和渲染策略(例如,只更新视口内的要素)变得很重要。

5. 总结

通过本教程,我们学习了如何利用ArcGIS J*aScript API中的SimpleRenderer和rotation视觉变量,实现Web样式符号基于数据属性的动态旋转。这种方法不仅能够让地图上的符号更加生动地反映现实世界的状态,也为开发复杂的实时地理空间应用提供了强大的工具。掌握这一技术,将使你的地图应用在展示移动对象时更具表现力和实用性。

以上就是ArcGIS JS API教程:基于GPS航向旋转Web样式符号的详细内容,更多请关注其它相关文章!


# 设置为  # 学习seo后的感想  # 东平网站建设电话  # 邯郸网站建设推广报价表  # 津南视频号推广营销工具商城  # 知识付费推广营销  # 红桥区整合营销推广渠道  # 云浮网站优化技术公司  # 游轮营销推广方案  # 永州网页优化seo价格  # 关键词排名团队云尚网络  # 这是  # 是一个  # 顺时针  # 库中  # 输入框  # css  # 图上  # 渲染器  # 应用于  # 图层  #   # stream  # ai  # 工具  # websocket  # cad  # git  # js  # html  # java  # javascript 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 《下一站江湖2》大雪山加入方法  教育查询官方网站入口 教育个人档案查询免费官网  J*aScript模块加载器_RequireJS原理分析  CSS动画如何实现图标旋转并放大_transform rotate scale @keyframes实现  如何在mysql中比较InnoDB和MyISAM区别  qq邮箱格式填写示例 qq邮箱标准填写规范  歌词怎么展示在|直播|间视频号?有什么注意事项?  iQOO手机信号差网络不稳定怎么办 信号问题原因排查与增强设置【攻略】  路由器DNS怎么设置最快 优化DNS提升上网速度教程  tiktok国际版入口_tiktok官网网页版链接  HTML与J*aScript实现下拉菜单驱动的动态表格:构建交互式维修表单  12306售票时间最新规定 | 网上订票和车站窗口时间一样吗  电脑从睡眠中被自动唤醒怎么办_Windows唤醒源事件查看与禁用【解决】  钉钉任务无法提醒如何处理 钉钉任务提醒优化方法  智学网成绩单查询系统网_智学网学生平台登录  德邦快递会员怎么开通  小米倒班助手添加日历提醒  在Django中动态检查模型关联:一种灵活的解决方案  虫虫漫画绿色安全入口_虫虫漫画绿色安全入口安全看漫画  Win10显卡驱动安装失败怎么办 Win10使用DDU彻底卸载驱动【解决】  动漫岛在线动漫网 动漫岛动漫在线观看官方入口  word邮件合并怎么插入个性化图片_Word邮件合并插入个性化图片方法  PHP页面重载后变量状态保持:实现用户档案连续浏览的教程  如何查询个人病历记录  如何定制PrimeNG Sidebar的背景颜色  高德地图导航路线偏差报警频繁怎么办 高德地图路线偏差修复与优化方法  windows10怎么开启卓越性能_windows10电源选项代码激活  搜狗浏览器如何查找页面中的文字 搜狗浏览器Ctrl+F页面搜索功能  Flask 应用中图片动态更新与上传:实现客户端定时刷新与服务器端文件管理  mysql如何管理数据库账户_mysql数据库账户管理技巧  《律学法考》查看学习数据方法  TikTok私信无法发送表情怎么办 TikTok消息表情发送修复方法  花生壳内网映射新方案  抖音网页版官方链接 抖音网页版官网链接入口  J*aScript模拟悬停与点击:自动化网页动态元素交互指南  批改网官网首页登录 批改网学生用户登录入口  PyEZ 配置提交中 RpcTimeoutError 的健壮性处理策略  铁路12306怎么申请退票_铁路12306退票申请操作流程  Win11如何分屏操作_Win11多窗口分屏技巧  J*aScript类型数组_TypedArray使用  使用document.execCommand实现Web文本编辑器加粗/取消加粗  Word如何将文字快速转成表格 Word文本转换成表格功能使用技巧【效率】  邮编号码查询app有哪些_邮编号码查询推荐app及使用体验  服装短视频如何起号推广?服装短视频起号推广有什么要求?  Windows Audio服务启动失败怎么办_电脑没声音的终极服务修复法【修复】  POKI小游戏在线免费入口链接 POKI小游戏无下载秒玩玩  Yandex浏览器官方入口_Yandex搜索引擎中文版  VS Code如何设置默认配置  《漫蛙manwa2》防走失网页版链接2025  Apple Music无故扣费引质疑 

 2025-12-04

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.