前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue ArcGis鼠标打点、中心打点绘制多边形

Vue ArcGis鼠标打点、中心打点绘制多边形

作者头像
inline705
发布2021-12-09 15:34:04
1.3K0
发布2021-12-09 15:34:04
举报
文章被收录于专栏:vue+ArcGisvue+ArcGis

一、前言

ArcGis绘制多边形这里没有用官方提供的api,官方提供的api是鼠标点击打点然后大于三个点位实时绘面,这种绘制多边形的方式在pc端体验感较佳,但在移动端会差点意思,所以这里提供了另一种绘制多边形的思路以供各位看官参考。

先上效果图

绘多边形2.gif
绘多边形2.gif

二、监听地图点击发布点位

这里在地图创建完毕后监听地图点击并且发布一个全局eventBus(vuex同理)

代码语言:javascript
复制
mapView.on("click", (event) => {
  // 获取点击地图时的点
  const pt = {
    type: 'point',
    x: event.mapPoint.x,
    y: event.mapPoint.y,
    latitude:event.mapPoint.latitude,
    longitude:event.mapPoint.longitude,
    spatialReference: mapView.spatialReference  // 几何图形的空间参照
  }
  // 事件总线 点
  this.$eventBus.$emit('addSpot',pt);
});
复制代码

在点击绘制多边形后订阅这个全局eventBus,并push进你的点位数组

代码语言:javascript
复制
this.$eventBus.$on('addSpot',data =>{
  data.id = `point_${this.spotArray.length + 1}`;
  this.spotArray.push(data)
})
复制代码

三、点点连线

watch监听你的点位数组,数组长度增加执行点点连线的方法

代码语言:javascript
复制
watch:{
  // 监听点位数组,变化时执行点点连线方法
  spotData(val, oldVal){
    if (val.length > oldVal.length){
      if (this.addSpotShow){
        this.spotConnect();
      }
    }
  }
}
复制代码

在点点连线的方法里判断下点位数组的长度,如果点位只有一个不执行画线,执行绘点;

代码语言:javascript
复制
// 点点测距 连线
spotConnect(){
  let point_id = this.spotArray.length;         // 点id
  if (this.spotArray.length === 1){             // 画地打第一个点时  点图形
    let spot = new this.gisGz.Graphic({                   // 图形是现实世界地理现象的矢量表示。它可以包含几何图形、符号和属性
      attributes: `point_${point_id}`,
      geometry: this.spotArray[0],                        // 定义图形位置的几何图形
      symbol: {                                           // 图形符号
        type: "simple-marker",
        color: [255, 255, 255, 0.8],
        size: 15,
        text: point_id,
        outline: {color: [255, 255, 255, 0]},
      },
    })
    this.sketchViewModel.add(spot);         // 绘制层添加当前几何图形
    // 点位文字说明
    let lengthSymbol = {
      type: "text",
      color: [50, 50, 50, 1],
      font: { size: 10 },
      text: "起点",
      xoffset: 0,
      yoffset: -20,
      haloColor: [255, 255, 255, 1],
      haloSize: 1,
    }

    let curPos = new this.gisGz.Point(this.spotArray[0].x, this.spotArray[0].y, this.mapView.spatialReference);
    let g = new this.gisGz.Graphic(curPos, lengthSymbol);
    g.attributes = `point_${point_id}`;
    this.rangingTextLayer.add(g);           // 测距文字层,添加 起点 文字

  }
  if (this.spotArray.length >= 2){
    // 实例化长度单位
    let params = new this.gisGz.LengthsParameters();
    // 计算多边形周长的长度单位
    params.lengthUnit = this.gisGz.GeometryService.UNIT_KILOMETER;
    // 定义几何的计算类型
    params.calculationType = "preserveShape";
    let one = this.spotArray[this.spotArray.length - 2];  // 上一个点信息
    let two = this.spotArray[this.spotArray.length - 1];  // 当前点信息
    let polyline = new this.gisGz.Polyline(               // 线信息,起始点,空间参照物
        [
          [one.x, one.y],
          [two.x, two.y],
        ],
        this.mapView.spatialReference
    )
    // 要计算其长度的折线数组
    params.polylines = [polyline];
    this.geometryKz.lengths(params).then((distance) => {
      let les = distance.lengths[0] * 1;
      let dis = 0;
      // 小于一公里单位为米
      if (les < 1) {
        dis = Math.round(les * 1000) + "米";
      } else {
        dis = les.toFixed(2) + "千米";
      }
      // 点图形
      let spot = new this.gisGz.Graphic({                   // 图形是现实世界地理现象的矢量表示。它可以包含几何图形、符号和属性
        attributes: `point_${point_id}`,
        geometry: two,                                      // 定义图形位置的几何图形
        symbol: {                                           // 图形符号
          type: "simple-marker",
          color: [255, 255, 255, 0.8],
          size: 15,
          text: point_id,
          outline: {color: [255, 255, 255, 0]},
        },
      })
      this.sketchViewModel.add(spot);         // 绘制层添加当前几何图形

      let textSymbol = {
        type: "text",
        geometry: two,
        color: [50, 50, 50, 1],
        font: { size: 10, },
        text: dis,          // 距离
        xoffset: 0,
        yoffset: -20,
        haloColor: [255, 255, 255, 1],
        haloSize: 1,
      };
      let curPos = new this.gisGz.Point(two.x, two.y, this.mapView.spatialReference)
      let g = new this.gisGz.Graphic(curPos, textSymbol);
      g.attributes = `point_${point_id}`;
      this.rangingTextLayer.add(g);           // 测距文字层
    });
  }
  // 绘线
  if (this.spotArray.length > 1) {
    let one = this.spotArray[this.spotArray.length - 2];      // 上一个点信息
    let two = this.spotArray[this.spotArray.length - 1];      // 当前点信息
    // 传入两个点 点点绘线
    this.connectLine(one, two);
  }
},
复制代码

如果大于等于两个点就获取点位数组里最后一个点以及它的前一个点,写一个公共的连线方法,把获取到的两个点传给这个方法

代码语言:javascript
复制
// 点点绘线
connectLine(lineOne,lineTwo){
  let polyline_id = this.lineArray.length + 1;  // 画线 线id
  let line = {    // 线信息
    id: `polyline_${polyline_id}`,
    type: "polyline",
    paths: [
      [lineOne.x, lineOne.y],
      [lineTwo.x, lineTwo.y],
    ],
    spatialReference: this.mapView.spatialReference,  // 当前线空间参照
  };
  let l = new this.gisGz.Graphic({
    attributes: `polyline_${polyline_id}`,
    geometry: line,
    symbol: {
      type: "simple-line",
      color: [236, 183, 103, 1],
      width: 2,
      style: "solid",
    },
  });
  this.sketchViewModel.add(l);          // 绘制层添加当前几何图形
  this.lineArray.push(line);            // push进线数组
},
复制代码

四、中心打点

中心打点你只需要获取你的地图mapView,然后取它的中心点信息并将其push进点位数组

代码语言:javascript
复制
// 打点层添加点位,根据页面中心点 需要拖动底图进行打点
obtainMapSpot(){
  const spot = {                      // 定义图形位置的几何图形  点信息
    id: `point_${this.spotArray.length + 1}`,
    type: "point",
    x: this.mapView.center.x,
    y: this.mapView.center.y,
    spatialReference: this.mapView.spatialReference,  // 几何图形的空间参照
  };
  // 将中心点位push进点位数组
  this.spotArray.push(spot);
},
复制代码

五、完成绘制

完成绘制其实就是绘制图形,用ArcGis api将所有点位传给polygon,完成绘制

代码语言:javascript
复制
// 完成绘制封闭图形 绘面
closeModel(){
  // 绘制点位小于3 return
  if (this.spotArray <= 3){
    return
  }
  let one = this.spotArray[0];                              // 第一个点信息
  let two = this.spotArray[this.spotArray.length - 1];      // 最后一个点信息
  // 传入两个点 点点绘线
  this.connectLine(one, two);
  let rings = [];
  this.spotArray.forEach((item) => {  // 获取所有点的图形位置
    rings.push([item.x, item.y]);
  });
  rings.push(rings[0]);
  rings.reverse();    // 颠倒数组
  let polygon = {
    type: "polygon",
    rings,
    spatialReference: this.mapView.spatialReference,    // 定义视图、图层或任务参数的空间参考
  };
  let p = new this.gisGz.Graphic({
    attributes: "remove",
    geometry: polygon,
    symbol: {
      type: "simple-fill",
      // color: [236, 183, 103, 0.5],
      style: "solid",
      outline: {
        // color: [236, 183, 103, 1],
        width: 1,
      },
    },
  });
  // 将坐标转换为地理坐标
  let Wgs84Geometry = this.gisGz.webMercatorUtils.webMercatorToGeographic(p.geometry);
  // 测试、测量和分析两个或多个 2D 几何之间的空间关系
  let Area = this.gisGz.geometryEngine.geodesicArea( Wgs84Geometry, "square-meters" );
  // 计算 亩 面积
  let Areas = Math.abs(Number(((Area + Area / 2) / 1000).toFixed(2)));
  let lengthSymbol = new this.gisGz.TextSymbol({
    color: new this.gisGz.Color([255, 255, 255, 1]),
    haloColor: new this.gisGz.Color([0, 0, 0, 1]),
    haloSize: 1,
    font: {
      size: 12,
      fontWeight: "bold",
    },
  });
  lengthSymbol.text = Areas + "亩";
  let t = new this.gisGz.Point( p.geometry.extent.center, this.mapView.spatialReference );
  let g = new this.gisGz.Graphic({ attributes: "mianji", geometry: t, symbol: lengthSymbol, });
  this.textLayer.add(g);          // 文字层
  this.sketchViewModel.add(p);    // 绘制层

  // 清除缓存的撤销点位
  this.revokeArray = [];
  // 关闭画地按钮禁用
  this.addSpotShow = false;

  this.spotArray = [];                    // 清空点位数组
  this.$eventBus.$off('addSpot');   // 清除事件订阅
  })
},
复制代码
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年11月02日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、监听地图点击发布点位
  • 三、点点连线
  • 四、中心打点
  • 五、完成绘制
相关产品与服务
事件总线
腾讯云事件总线(EventBridge)是一款安全,稳定,高效的云上事件连接器,作为流数据和事件的自动收集、处理、分发管道,通过可视化的配置,实现事件源(例如:Kafka,审计,数据库等)和目标对象(例如:CLS,SCF等)的快速连接,当前 EventBridge 已接入 100+ 云上服务,助力分布式事件驱动架构的快速构建。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档