ArcGIS API 多类型服务自定义范围控制之动态服务

描述

详细描述请查看ArcGIS API 多类型服务自定义范围控制
这里只展示如何使用,效果视频也在上述文章~

动态服务

1、创建自定义动态图层

通过createSubclass()方法来创建 BaseDynamicLayer
创建自定义动态图层的原因:
• ArcGIS API for JavaScript未明确支持图像的来源
• 需要先对图像进行预处理,然后才能在视图中显示

const CustomImageOverlayLayer= BaseDynamicLayer.createSubclass({
   //规定属性
  properties: {
        picUrl: null,
        image: null,
        canvas: null,
        geometryExtent: null,
        geometry: null,
        layerid: null
      }
 })

2、获取当前图像地址

要请求从数据源预定义的图像,需覆盖getImageUrl() 方法,以便给它定范围,长和宽返回请求的URL。

  getImageUrl: function (extent, width, height) {
  //extent 视图的范围。该值由LayerView填充。
  //width  视图的宽度(以像素为单位)。该值由LayerView填充。
  //height 视图的高度(以像素为单位)。该值由LayerView填充。
    const pUrl = this.picUrl +"/export?bbox=" +
          `${extent.xmin},${extent.ymin},${extent.xmax},${extent.ymax}` +
          "&bboxSR=102100&imageSR=102100" +
          `&size=${width},${height}` +
          "&dpi=96&format=png32&transparent=true&layers=show%3A" +
          `${this.layerid}` +
          "&f=image";
  }

3、对图像进行预处理

根据生成的网址请求图像,绘制裁切图形并利用canvas的clip方法进行图像裁切返回canvas

  return request(pUrl, {
            responseType: "image",
            allowImageDataAccess: true
          })
          .then(
            function (response) {
              var image = response.data; //img
              var context = this.canvas.getContext("2d");

              //绘制裁切图形
              if (this.geometry.type == "extent") {
                context.rect(
                  zuobiao[0].x,
                  zuobiao[0].y,
                  stretchWidth,
                  stretchHeight
                );
              } else {
                context.beginPath();
                for (let i = 0; i <= zuobiao.length - 1; i++) {
                  if (i == zuobiao.length - 1) {
                    strokeLine(context, [zuobiao[i], zuobiao[0]]);
                  } else {
                    strokeLine(context, [zuobiao[i], zuobiao[i + 1]]);
                  }
                }
              }
              context.clip(); //裁切
              context.drawImage(image, 0, 0, width, height); //被裁切的图形
              return this.canvas.toDataURL("image/png");
            }.bind(this)
          )
          .catch(error => {});

4、实例化BaseDynamicLayer

 var ImageOverlayLayer = new CustomImageOverlayLayer({
      id: "RasterLayer",
      title: "裁切图层",
      picUrl: url,
      geometryExtent: geometry.extent,
      geometry: geometry,
      layerid: "0,1"
    });
    map.add(ImageOverlayLayer);

整体代码

 loadModules(["esri/layers/BaseDynamicLayer", "esri/request"], {
    css: true
  }).then(([BaseDynamicLayer, request]) => {
    //创建自定义动态图层
    var baseImageOverlayLayer = BaseDynamicLayer.createSubclass({
      //规定属性
      properties: {
        picUrl: null,
        image: null,
        canvas: null,
        geometryExtent: null,
        geometry: null,
        layerid: null
      },

      //覆盖getImageUrl()方法以生成图像的URL
      getImageUrl: function (extent, width, height) {
        //extent 视图的范围。该值由LayerView填充。
        //width  视图的宽度(以像素为单位)。该值由LayerView填充。
        //height 视图的高度(以像素为单位)。该值由LayerView填充。

        // 左上角
        var lefttop = {
          x: this.geometryExtent.xmin,
          y: this.geometryExtent.ymax,
          spatialReference: this.geometryExtent.spatialReference
        };
        var screen_lefttop = WaterMap.view.toScreen(lefttop);

        // 右下角
        var rightbottom = {
          x: this.geometryExtent.xmax,
          y: this.geometryExtent.ymin,
          spatialReference: this.extent.spatialReference
        };
        var screen_rightbottom = view.toScreen(rightbottom); //转屏幕坐标

        var stretchWidth = screen_rightbottom.x - screen_lefttop.x;
        var stretchHeight = screen_rightbottom.y - screen_lefttop.y;
        if (!this.canvas) {
          this.canvas = document.createElement("canvas");
        }
        this.canvas.width = width;
        this.canvas.height = height;

        //geometry转换屏幕多边形坐标
        let zuobiao = topm(this.geometry, this.extent.spatialReference);
        let pUrl =
          this.picUrl +
          "/export?bbox=" +
          `${extent.xmin},${extent.ymin},${extent.xmax},${extent.ymax}` +
          "&bboxSR=102100&imageSR=102100" +
          `&size=${width},${height}` +
          "&dpi=96&format=png32&transparent=true&layers=show%3A" +
          `${this.layerid}` +
          "&f=image";
        //request 根据生成的网址请求图像
        return request(pUrl, {
            responseType: "image",
            allowImageDataAccess: true
          })
          .then(
            function (response) {
              var image = response.data; //img
              var context = this.canvas.getContext("2d");

              //绘制裁切图形
              if (this.geometry.type == "extent") {
                context.rect(
                  zuobiao[0].x,
                  zuobiao[0].y,
                  stretchWidth,
                  stretchHeight
                );
              } else {
                context.beginPath();
                for (let i = 0; i <= zuobiao.length - 1; i++) {
                  if (i == zuobiao.length - 1) {
                    strokeLine(context, [zuobiao[i], zuobiao[0]]);
                  } else {
                    strokeLine(context, [zuobiao[i], zuobiao[i + 1]]);
                  }
                }
              }
              context.clip(); //裁切
              context.drawImage(image, 0, 0, width, height); //被裁切的图形
              return this.canvas.toDataURL("image/png");
            }.bind(this)
          )
          .catch(error => {});
      }
    });

 //实例化BaseDynamicLayer
 var ImageOverlayLayer = new CustomImageOverlayLayer({
      id: "RasterLayer",
      title: "裁切图层",
      picUrl: url,
      geometryExtent: geometry.extent,
      geometry: geometry,
      layerid: "0,1"
    });
    map.add(ImageOverlayLayer);
  });
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值