视觉变量

字数统计: 2k
阅读时长: 约 5 分钟
当前版本: 4.29

使用简单渲染器和视觉变量样式化气象站,以显示空气温度

什么是视觉变量?

视觉变量是从人的视觉角度来表示属性的差异程度。**它是显示数字型属性分类间隔样式的一种替代方法。**与属性值分离成离散的数据范围不同,视觉变量会在数据停靠点之间进行线性插值,创建平滑、连续的可视化效果。

常用四个视觉变量:颜色大小透明度旋转

如何使用视觉变量

渲染器中有一个 visualVariables 属性,所有的视觉变量都可以通过该属性设置。一个渲染器可以使用多个视觉变量,但一次添加多个视觉变量容易造成混乱。

了解如何在简单渲染器中有效地使用多个视觉变量,可以查看多元可视化

颜色

颜色视觉变量根据数值型字段值或计算表达式返回的数据,划分成渐变色带来表示符号颜色。使用前,应进行归一化处理,特别是面图层数据。

颜色视觉变量需要如下两个属性:

  1. 字段名称或 Arcade 表达式。

  2. 两个或以上色标(用于与数据值匹配)。介于相邻色标之间的符号颜色是线性插值计算。

以下示例采用连续色带渲染气象站报告的当前温度。

样例代码
js
<html>
    <head>
        
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
        <title>GeoScene Developer Guide: Visual variables (color)</title>
        <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }
        </style>

        <link rel="stylesheet" href="https://js.geoscene.cn/4.29/geoscene/themes/light/main.css" />
        <script src="https://js.geoscene.cn/4.29/"></script>

        <script>
        require([
            "geoscene/Map",
            "geoscene/views/MapView",
            "geoscene/layers/FeatureLayer",
            "geoscene/widgets/Legend",
            "geoscene/widgets/Expand"
        ], function(
            Map,
            MapView,
            FeatureLayer,
            Legend,
            Expand
        ) {
            const referenceScale = 9244650*4;

            const renderer = {
            type: "simple",
            symbol: {
                type: "simple-marker",
                style: "circle",
                color: [250, 250, 250],
                outline: {
                color: [255, 255, 255, 0.5],
                width: 0.5
                },
                size: "8px"
            },
            visualVariables: [
                {
                type: "color",
                field: "TEMP",
                stops: [
                    { value: 20, color: "#2b83ba" },
                    { value: 35, color: "#abdda4" },
                    { value: 50, color: "#ffffbf" },
                    { value: 65, color: "#fdae61" },
                    { value: 80, color: "#d7191c" }
                ]
                }
            ]
            };
            const layer = new FeatureLayer({
            url: "https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/NOAA_METAR_current_wind_speed_direction_v1/FeatureServer",
            title: "Current weather conditions",
            renderer: renderer
            });

            const map = new Map({
            basemap: "tianditu-vector",
            layers: [layer]
            });

            const view = new MapView({
            container: "viewDiv",
            map: map,
            scale: referenceScale,
            center: [108.9, 34.5],
            constraints: {
                snapToZoom: false
            }
            });

            view.ui.add(new Expand({
            content: new Legend({
                view: view
            }),
            view: view,
            expanded: false
            }), "top-right");
        });
        </script>
    </head>
    <body>
        <div id="viewDiv"></div>
    </body>
</html>

大小

大小视觉变量根据数值型字段值或计算表达式返回的数据设置符号的大小,符号大小是连续覆盖属性值范围。不适用于具有填充符号的渲染器。要按大小可视化面图层,应使用标记符号,在面的质心处进行渲染。 可通过两种不同的方式定义大小视觉变量:

  1. 符号大小的分割值

  2. maxDataValuemaxSize 进行匹配;将 minDataValueminSize 进行匹配。

大小视觉变量需要有以下两个属性:

  1. 字段名称或 Arcade 表达式。

  2. 两个或以上的符号大小断点(用于将数据值与符号大小相匹配)。数据值介于指定断点之间的符号大小是线性插值的。

以下示例使用连续大小符号渲染气象站报告的当前风速。

样例代码
js
<!DOCTYPE html>
<html>
    <head>
        
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
        <title>Size visual variable</title>
        <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }
        </style>

        <link rel="stylesheet" href="https://js.geoscene.cn/4.29/geoscene/themes/light/main.css" />
        <script src="https://js.geoscene.cn/4.29/"></script>

        <script>
        require([
            "geoscene/Map",
            "geoscene/views/MapView",
            "geoscene/layers/FeatureLayer",
            "geoscene/widgets/Legend",
            "geoscene/widgets/Expand"
        ], function(
            Map,
            MapView,
            FeatureLayer,
            Legend,
            Expand
        ) {
            const referenceScale = 9244650*2;
            const renderer = {
                type: "simple",
                symbol: {
                    type: "simple-marker",
                    style: "circle",
                    color: [50, 50, 50, 0.4],
                    outline: {
                    color: [255, 255, 255, 0.3],
                    width: 0.2
                },
                size: "8px"
            },
            visualVariables: [{
                type: "size",
                field: "WIND_SPEED",
                minDataValue: 5,
                maxDataValue: 60,
                minSize: 4,
                maxSize: 22
            }]};
            const layer = new FeatureLayer({
                url:"https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/NOAA_METAR_current_wind_speed_direction_v1/FeatureServer",
                title: "Current weather conditions",
                renderer: renderer
            });

            const map = new Map({
                basemap: "tianditu-vector",
                layers: [layer]
            });

            const view = new MapView({
                container: "viewDiv",
                map: map,
                scale: referenceScale,
                center: [108.9, 34.5],
                constraints: {
                    snapToZoom:false
                }
            });

            view.ui.add(new Expand({
                content: new Legend({
                    view: view
                }),
                view: view,
                expanded: false
            }), "top-right");
        });
        </script>
    </head>
    <body>
        <div id="viewDiv"></div>
    </body>
</html>

旋转

旋转变量可基于从字段或表达式返回的数值数据值设置符号的旋转。这通常用于旋转指示方向性的符号,例如:

  • 风向

  • 交通流量

  • 坡向

旋转视觉变量与其他视觉变量的不同之处在于,它们仅需一个数据值,而不需要停止点。

  1. 基于字段名称或 Arcade 表达式引用数据值。

  2. 可选旋转类型,表示几何或算术旋转。

以下示例通过使用箭头标记气象站,并根据风向旋转它们来进行可视化。

样例代码
js
<!doctype html>
<html>
  <head>
    
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
    <title>Rotation visual variable</title>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }
    </style>

    <link rel="stylesheet" href="https://js.geoscene.cn/4.29/geoscene/themes/light/main.css" />
    <script src="https://js.geoscene.cn/4.29/"></script>

    <script>
      require([
        "geoscene/Map",
        "geoscene/views/MapView",
        "geoscene/layers/FeatureLayer",
        "geoscene/widgets/Legend",
        "geoscene/widgets/Expand",
      ], function (Map, MapView, FeatureLayer, Legend, Expand) {
        const referenceScale = 9244650 * 2;
        const renderer = {
          type: "simple",
          symbol: {
            type: "simple-marker",
            // Arrow marker defined as SVG path
            path: "M14.5,29 23.5,0 14.5,9 5.5,0z",
            color: [50, 50, 50],
            outline: {
              color: [255, 255, 255, 0.5],
              width: 0.5,
            },
            angle: 180,
            size: "20px",
          },
          visualVariables: [
            {
              type: "rotation",
              field: "WIND_DIRECT",
              rotationType: "geographic",
            },
          ],
        };

        // Set the renderer on the feature layer
        const layer = new FeatureLayer({
          url: "https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/NOAA_METAR_current_wind_speed_direction_v1/FeatureServer",
          title: "Current weather conditions",
          renderer: renderer,
        });

        const map = new Map({
          basemap: "tianditu-vector",
          layers: [layer],
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          scale: referenceScale,
          center: [108.9, 34.5],
          constraints: {
            snapToZoom: false,
          },
        });

        view.ui.add(
          new Expand({
            content: new Legend({
              view: view,
            }),
            view: view,
            expanded: false,
          }),
          "top-right"
        );
      });
    </script>
  </head>
  <body>
    <div id="viewDiv"></div>
  </body>
</html>

不透明度

透明度变量将基于从字段或表达式返回的数值型数据值覆盖符号的透明度。此变量通常用于展示某些要素比其他要素更突出。

不透明度视觉变量需要满足以下条件:

  1. 基于字段名称或 Arcade 表达式引用数据值。

  2. 至少两个透明度停靠点,用于将数据值与介于 01 之间的透明度值相匹配。数据值在指定停靠点之间的符号的透明度是线性插值的。

以下示例可视化了主要作物情况。渲染器具有一个透明度变量,可通过比较来强调拥有大量农田的地区,并淡化拥有很少农田的地区。

样例代码
js
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>GeoScene Developer Guide: Visual variables (opacity)</title>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }
    </style>

    <link rel="stylesheet" href="https://js.geoscene.cn/4.29/geoscene/themes/dark/main.css" />
    <script src="https://js.geoscene.cn/4.29/"></script>

    <script>
      require([
        "geoscene/Map",
        "geoscene/views/MapView",
        "geoscene/layers/FeatureLayer",
        "geoscene/widgets/Legend",
        "geoscene/widgets/Expand"
      ], function(
        Map,
        MapView,
        FeatureLayer,
        Legend,
        Expand
      ) {
        const referenceScale = 9244650*2;

        function createSymbol(color){
          return {
            type: "simple-fill",
            outline: {
              color: "rgba(50,50,50,0.1)",
              width: 0.5
            },
            color,
            style: "solid"
          }
        }

        const renderer = {
          type: "unique-value",
          field: "DOM_CROP_ACRES",
          uniqueValueInfos: [{
            value: "Corn",
            symbol: createSymbol("#e6d800")
          }, {
            value: "Wheat",
            symbol: createSymbol("#9b19f5")
          }, {
            value: "Soybeans",
            symbol: createSymbol("#0bb4ff")
          }, {
            value: "Cotton",
            symbol: createSymbol("#50e991")
          }, {
            value: "Vegetables",
            symbol: createSymbol("#e60049")
          }],
          visualVariables: [
            {
              type: "opacity",
              field: "TotalFarmedAcres",
              normalizationField: "AREA_ACRES",
              legendOptions: {
                showLegend: false,
              },
              stops: [
                { value: 0.0, opacity: 0.2 },
                { value: 0.1, opacity: 0.5 },
                { value: 0.5, opacity: 0.8 },
                { value: 0.9, opacity: 1.0 }
              ]
            }
          ]
        };

        // Set the renderer on the feature layer
        const layer = new FeatureLayer({
          url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/US_county_crops_2007_clean/FeatureServer/0",
          title: "U.S. counties",
          renderer: renderer
        });

        const map = new Map({
          basemap: "tianditu-vector",
          layers: [layer]
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          scale: referenceScale,
          center: [ -95, 38.5 ],
          constraints: {
            snapToZoom:false
          }
        });

        view.ui.add(new Expand({
          content: new Legend({
            view: view
          }),
          view: view,
          expanded: false
        }), "top-right");
      });
    </script>
  </head>
  <body>
    <div id="viewDiv"></div>
  </body>
</html>