arcgis for js4.x自定义图例位置添加到地图并导出

  • 前言
  • arcgis_js版本
  • 思路
  • 核心代码
  • 结果


前言

许久未写博客了,闲来无事动动手。最近客户有个需求,要求在前端手绘气象落区生成图例,并且能够自定义图例的位置,导出地图。

arcgis_js版本

arcgis_js_v413_api
参考示例:sdk的Print widget和Take a screenshot of a SceneView
参考博客:

思路

需求:在前端界面手绘地图落区生成图例,并且能够自定义地图位置,导出地图。
实现:1、首先,实现在前端界面选择要素,绘制地图上的气象落区并配上相应的颜色,这个地图交互的操作实现起来比较简单,参考sdk示例或者百度也行。2、然后,生成图例,可以选择使用自带图例或者自己写一个,但是实现图例位置自定义比较困难,参考的sdk示例并不能满足要求,一开始想的是自己写个图例,导出地图的时候,利用html2canvas将地图气象落区和图例的canvas拼接在一起,导出为图片,效果不好,也不能满足客户需求。3、最后,将自己写的图例利用html2canvas转为img,通过参考博客,将图片添加到地图,同时可以实现位置自定义,不过这种方式,图例的内容最好是固定的,不是动态添加的。4、最终,导出为图片,参考sdk的Print widget示例,事先设置好了导出范围。

核心代码

addLegendToMap() {
        let CustomImageOverlayLayer = arcMap.BaseDynamicLayer.createSubclass({
          properties: {
            dataSource: null,
            extent: null,
            image: null,
            canvas: null,
          },
          getImageUrl: function(extent, width, height) {
          	// 判断是否有数据源
            if (!this.dataSource) {
              return;
            }
            //创建Image
            if (!this.image) {
              this.image = new Image();
            }
            //将图片数据源传给Image
            this.image.src = this.dataSource; 
            if (!this.canvas.getContext) {
              console.log("您的浏览器不支持canvas标签。");
            }
            // 如果没有canvas,则创建canvas DOM元素
            if (!this.canvas) {
              this.canvas = document.createElement("canvas");
            }
            //设置canvas透明度,宽高
            this.canvas.getContext("2d").globalAlpha = 0.5;
            this.canvas.width = width;
            this.canvas.height = height;

            console.time("time");
            //左上角地理坐标转换屏幕坐标,为了获取canvas绘制图片的起点
            const mapPoint = {
              x: this.extent.xmin,
              y: this.extent.ymax,
              spatialReference: {
                wkid: 4490,	// 底图的坐标系
              },
            };
            const screenPoint = mapview.toScreen(mapPoint);
            //根据extent范围计算canvas绘制图片的宽度以及高度
            //左下角
            const leftbottom = {
              x: this.extent.xmin,
              y: this.extent.ymin,
              spatialReference: {
                wkid: 4490,
              },
            };
            const screen_leftbottom = mapview.toScreen(leftbottom);
            //右上角
            const righttop = {
              x: this.extent.xmax,
              y: this.extent.ymax,
              spatialReference: {
                wkid: 4490,
              },
            };
            const screen_righttop = mapview.toScreen(righttop);
            console.timeEnd("time");
            //绘制image
            this.canvas
              .getContext("2d")
              .drawImage(
                this.image,
                screenPoint.x,
                screenPoint.y,
                Math.abs(screen_righttop.x - screen_leftbottom.x),
                Math.abs(screen_righttop.y - screen_leftbottom.y)
              );
            return this.canvas.toDataURL("image/png");
          },
        });

        mapview.when(
          function() {
            let canvas = document.createElement("canvas"); // 创建canvas
            _legendPosOverlayLayer = new CustomImageOverlayLayer({
              dataSource: opt.dataUrl,	// 获取图片数据
              // 设置图片绘制的范围,需要仔细调整
              extent: {
                xmin: null,	// 最小经度
                ymin: null,		// 最小纬度
                xmax: null,	// 最大经度
                ymax: null,		// 最大纬度
              },
              canvas: canvas,
            });
            map.add(_legendPosOverlayLayer);
          },
          function(error) {
            console.log("图片叠加失败: ", error);
          }
        );
     },

结果

arcgis for javascript添加自定义图标 arcgis自定义图例添加_javascript