【超图 SuperMap3D】【基础API使用示例】54、超图SuperMap3D -鼠标左键拖拽绘制圆

前言

引擎下载地址:[添加链接描述](http://support.supermap.com.cn/DownloadCenter/DownloadPage.aspx?id=2524)
通过左键按下拖拽的方式在地图上进行贴地的圆绘制
完整代码拷贝直接本地运行即可查看效果

效果

在这里插入图片描述

核心代码

// 绘制圆形
function startDrawCircleHandler () {
  if (circleEntity) {
    viewer.entities.remove(circleEntity)
    circleEntity = null
  }
  customPanel.innerHTML = '请按下鼠标左键拖拽进行拉框放大操作'
  showTooltip = true
  circle.classList.add('active')
  disableMouseOperateHandler()

  function downHandler (e) {
    drawStatus = true
    customPanel.innerHTML = '拖动松开以结束绘制'
    center = viewer.scene.pickPosition(e.position)
  }

  function upHandler () {
    drawStatus = false
    showTooltip = false
    customPanel.style.left = '-10000px'
    customPanel.style.top = '-10000px'
    customPanel.style.display = 'none'
    circle.classList.remove('active')
    resetMouseOperateHandler()
    handler.removeInputAction(SuperMap3D.ScreenSpaceEventType.LEFT_DOWN)
    handler.removeInputAction(SuperMap3D.ScreenSpaceEventType.LEFT_UP)

    // TODO 调用iserver服务查询
    // 可参考 https://www.bilibili.com/read/cv22219129/
  }

  handler.setInputAction(downHandler, SuperMap3D.ScreenSpaceEventType.LEFT_DOWN)
  handler.setInputAction(upHandler, SuperMap3D.ScreenSpaceEventType.LEFT_UP)
}

// 地图上move操作
function mousemoveHandler (SuperMap3D) {
  handler.setInputAction((e) => {
    if (showTooltip) {
      // 点击的位置显示面板
      customPanel.style.left = e.endPosition.x + 20 + 'px'
      customPanel.style.top = e.endPosition.y + 'px'
      customPanel.style.display = 'block'
    }
    if (drawStatus) {
      end = viewer.scene.pickPosition(e.endPosition)
      radius = getDistanceHandler(center, end)
      drawCircleHandler(radius)
    }
  }, SuperMap3D.ScreenSpaceEventType.MOUSE_MOVE)
}

// 绘制圆
function drawCircleHandler (radius) {
  if (circleEntity) {
    circleEntity.ellipse.semiMinorAxis = new SuperMap3D.CallbackProperty(function () {
      return radius;
    }, false)
    circleEntity.ellipse.semiMajorAxis = new SuperMap3D.CallbackProperty(function () {
      return radius;
    }, false)
  } else {
    circleEntity = viewer.entities.add({
      position: center,
      ellipse: {
        semiMinorAxis: radius,
        semiMajorAxis: radius,
        // height: 0,
        material: SuperMap3D.Color.GREEN.withAlpha(0.5),
        outline: true, // height must be set for outline to display
        // clampToGround: true,
        disableDepthTestDistance: Number.POSITIVE_INFINITY
      }
    })
  }
}

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
  <meta name="viewport"
    content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
  <title></title>

  <link href="https://www.supermapol.com/webgl/Build/SuperMap3D/Widgets/widgets.css" rel="stylesheet">
  <link href="https://www.supermapol.com/webgl/examples/webgl/css/pretty.css" rel="stylesheet">
  <link href="https://www.supermapol.com/webgl/examples/webgl/style/colorCorrection.css" rel="stylesheet">
  <link href="https://www.supermapol.com/webgl/examples/webgl/css/bootstrap-select.min.css" rel="stylesheet">
  <script src="https://www.supermapol.com/webgl/examples/webgl/js/jquery.min.js"></script>
  <script src="https://www.supermapol.com/webgl/examples/webgl/js/bootstrap.min.js"></script>
  <script src="https://www.supermapol.com/webgl/examples/webgl/js/bootstrap-select.min.js"></script>
  <script src="https://www.supermapol.com/webgl/examples/webgl/js/tooltip.js"></script>
  <script src="https://www.supermapol.com/webgl/examples/webgl/js/slider.js"></script>
  <script src="https://www.supermapol.com/webgl/examples/webgl/js/config.js"></script>
  <script type="text/javascript" src="https://www.supermapol.com/webgl/Build/SuperMap3D/SuperMap3D.js"></script>

  <link rel="stylesheet" href="https://www.supermapol.com/webgl/web/libs/bootstrap/css/bootstrap.min.css">
  <link href="https://www.supermapol.com/webgl/examples/webgl/style/flood.css" rel="stylesheet">
  <style>
    .circle {
      position: fixed;
      left: 100px;
      top: 100px;
    }

    .circle.active {
      color: red;
    }

    .custom-panel {
      position: fixed;
      left: -1000px;
      top: -1000px;
      z-index: 1;
      border-radius: 10px;
      display: none;
      color: #fff;
      background-color: rgba(0, 0, 0, 0.3);
    }
  </style>
</head>

<body>
  <div id="Container"></div>
  <button class="circle" onclick="startDrawCircleHandler()">绘制</button>
  <div class="custom-panel"></div>

  <script type="text/javascript">
    let viewer, handler
    const initMouseOperate = {}
    const customPanel = document.querySelector('.custom-panel')
    const circle = document.querySelector('.circle')
    function onload (SuperMap3D) {
      var EngineType = getEngineType()
      viewer = new SuperMap3D.Viewer('Container', {
        navigation: false, // 默认为true,是否显示导航罗盘控件。隐藏可在初始化场景时设置为false
        animation: true, //是否创建动画小器件,左下角仪表
        contextOptions: {
          contextType: Number(2)  // Webgl2:2  WebGPU:3
        }
      })

      viewer.scenePromise.then(function (scene) {
        handler = new SuperMap3D.ScreenSpaceEventHandler(viewer.scene.canvas) // event事件处理程序
        init(SuperMap3D, scene, viewer)
        mousemoveHandler(SuperMap3D)
        setInitOperateInfoHandler()
      })
    }
    function init (SuperMap3D, scene, viewer) {
      viewer.imageryLayers.addImageryProvider(new SuperMap3D.BingMapsImageryProvider({
        url: 'https://dev.virtualearth.net',
        mapStyle: SuperMap3D.BingMapsStyle.AERIAL,
        key: URL_CONFIG.BING_MAP_KEY//当场景出现黑球时可至官网(https://www.bingmapsportal.com/)申请key
      }))
      viewer.resolutionScale = window.devicePixelRatio

      scene.lightSource.ambientLightColor = new SuperMap3D.Color(0.65, 0.65, 0.65, 1)

      var widget = viewer.Widget

      try {
        //添加S3M图层服务
        var promise = scene.open(URL_CONFIG.SCENE_XGPARK)
        SuperMap3D.when(promise, function (layers) {
          setInitCameraViewHandler()
        }, function (e) {
          errorPanelHandler(widget, e)
        })
      }
      catch (e) {
        errorPanelHandler(widget, e)
      }
    }

    let drawStatus = false
    let showTooltip = false
    let center, end, radius, circleEntity
    // 绘制圆形
    function startDrawCircleHandler () {
      if (circleEntity) {
        viewer.entities.remove(circleEntity)
        circleEntity = null
      }
      customPanel.innerHTML = '请按下鼠标左键拖拽进行拉框放大操作'
      showTooltip = true
      circle.classList.add('active')
      disableMouseOperateHandler()

      function downHandler (e) {
        drawStatus = true
        customPanel.innerHTML = '拖动松开以结束绘制'
        center = viewer.scene.pickPosition(e.position)
      }

      function upHandler () {
        drawStatus = false
        showTooltip = false
        customPanel.style.left = '-10000px'
        customPanel.style.top = '-10000px'
        customPanel.style.display = 'none'
        circle.classList.remove('active')
        resetMouseOperateHandler()
        handler.removeInputAction(SuperMap3D.ScreenSpaceEventType.LEFT_DOWN)
        handler.removeInputAction(SuperMap3D.ScreenSpaceEventType.LEFT_UP)

        // TODO 调用iserver服务查询
        // 可参考 https://www.bilibili.com/read/cv22219129/
      }

      handler.setInputAction(downHandler, SuperMap3D.ScreenSpaceEventType.LEFT_DOWN)
      handler.setInputAction(upHandler, SuperMap3D.ScreenSpaceEventType.LEFT_UP)
    }

    // 地图上move操作
    function mousemoveHandler (SuperMap3D) {
      handler.setInputAction((e) => {
        if (showTooltip) {
          // 点击的位置显示面板
          customPanel.style.left = e.endPosition.x + 20 + 'px'
          customPanel.style.top = e.endPosition.y + 'px'
          customPanel.style.display = 'block'
        }
        if (drawStatus) {
          console.log('move');
          console.log(viewer.scene.pickPosition(e.endPosition));
          end = viewer.scene.pickPosition(e.endPosition)
          radius = getDistanceHandler(center, end)
          drawCircleHandler(radius)
        }
      }, SuperMap3D.ScreenSpaceEventType.MOUSE_MOVE)
    }

    // 绘制圆
    function drawCircleHandler (radius) {
      if (circleEntity) {
        circleEntity.ellipse.semiMinorAxis = new SuperMap3D.CallbackProperty(function () {
          return radius;
        }, false)
        circleEntity.ellipse.semiMajorAxis = new SuperMap3D.CallbackProperty(function () {
          return radius;
        }, false)
      } else {
        circleEntity = viewer.entities.add({
          position: center,
          ellipse: {
            semiMinorAxis: radius,
            semiMajorAxis: radius,
            // height: 0,
            material: SuperMap3D.Color.GREEN.withAlpha(0.5),
            outline: true, // height must be set for outline to display
            // clampToGround: true,
            disableDepthTestDistance: Number.POSITIVE_INFINITY
          }
        })
      }
    }

    // 计算两点之间的距离\半径
    function getDistanceHandler (center, end) {
      // 创建两个世界坐标点
      const point1 = new SuperMap3D.Cartesian3(center.x, center.y, center.z);
      const point2 = new SuperMap3D.Cartesian3(end.x, end.y, end.z);

      // 计算两点之间的距离
      return SuperMap3D.Cartesian3.distance(point1, point2);
    }

    // 设置相机视角,便于查看模型
    function setInitCameraViewHandler () {
      viewer.scene.camera.setView({
        destination: new SuperMap3D.Cartesian3.fromDegrees(114.2158, 22.4169, 419),
        orientation: {
          up: new SuperMap3D.Cartesian3(-0.1629169048778112, 0.7143202157541026, 0.6805914424014209),
          direction: new SuperMap3D.Cartesian3(0.5945902470233576, -0.4793925407032518, 0.6454806194323606),
          heading: 5.899584294129949
        }
      })
    }

    // 错误面板
    function errorPanelHandler (widget, e) {
      if (widget._showRenderLoopErrors) {
        var title = '渲染时发生错误,已停止渲染。'
        widget.showErrorPanel(title, undefined, e)
      }
    }

    // 记录存储初始化时的操作信息
    function setInitOperateInfoHandler () {
      initMouseOperate.zoomEventTypes = JSON.parse(JSON.stringify(viewer.scene.screenSpaceCameraController.zoomEventTypes))
      initMouseOperate.tiltEventTypes = JSON.parse(JSON.stringify(viewer.scene.screenSpaceCameraController.tiltEventTypes))
      initMouseOperate.lookEventTypes = JSON.parse(JSON.stringify(viewer.scene.screenSpaceCameraController.lookEventTypes))
      initMouseOperate.translateEventTypes = viewer.scene.screenSpaceCameraController.translateEventTypes
      initMouseOperate.enableTranslate = viewer.scene.screenSpaceCameraController.enableTranslate
      initMouseOperate.enableTilt = viewer.scene.screenSpaceCameraController.enableTilt
      initMouseOperate.enableZoom = viewer.scene.screenSpaceCameraController.enableZoom
      initMouseOperate.enableRotate = viewer.scene.screenSpaceCameraController.enableRotate
    }

    // 还原鼠标操作
    function resetMouseOperateHandler () {
      viewer.scene.screenSpaceCameraController.tiltEventTypes = initMouseOperate.tiltEventTypes
      viewer.scene.screenSpaceCameraController.lookEventTypes = initMouseOperate.lookEventTypes
      viewer.scene.screenSpaceCameraController.translateEventTypes = initMouseOperate.translateEventTypes
      viewer.scene.screenSpaceCameraController.enableTranslate = initMouseOperate.enableTranslate
      viewer.scene.screenSpaceCameraController.enableTilt = initMouseOperate.enableTilt
      viewer.scene.screenSpaceCameraController.enableZoom = initMouseOperate.enableZoom
      viewer.scene.screenSpaceCameraController.enableRotate = initMouseOperate.enableRotate
      viewer.scene.screenSpaceCameraController.zoomEventTypes = initMouseOperate.zoomEventTypes
    }

    // 禁止鼠标操作
    function disableMouseOperateHandler () {
      viewer.scene.screenSpaceCameraController.zoomEventTypes = []
      viewer.scene.screenSpaceCameraController.tiltEventTypes = []
      viewer.scene.screenSpaceCameraController.lookEventTypes = []
      viewer.scene.screenSpaceCameraController.translateEventTypes = []
      viewer.scene.screenSpaceCameraController.enableTranslate = false
      viewer.scene.screenSpaceCameraController.enableTilt = false
      viewer.scene.screenSpaceCameraController.enableZoom = false
      viewer.scene.screenSpaceCameraController.enableRotate = false
    }

    if (typeof SuperMap3D !== 'undefined') {
      window.startupCalled = true
      onload(SuperMap3D)
    }
  </script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/487014.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探究橡胶手套与乳胶手套的区别及选择指南

在探寻手部防护的世界里&#xff0c;橡胶手套与乳胶手套各自闪耀着独特的光芒。然而&#xff0c;对于许多人来说&#xff0c;这两者之间的细微差异仍然笼罩在一层迷雾之中。本文将如同一盏明灯&#xff0c;照亮这片迷雾&#xff0c;为您提供一份详尽的选择指南。 首先&#xff…

高性价比 惠海MOS管选型推荐 30V60V100V150V NMOS管和PMOS管

mos管选型建议&#xff1a; 需要抗电流冲击的&#xff0c;普通逻辑开关或者工作频率很低比如50kHZ以内的&#xff0c;电流非常大的情况比如实际工作6A以上的话一般建议选择平面mos管。6A以内的应用&#xff0c;大电流沟槽型mos管即可。 需要高频开关&#xff0c;比如500kHZ以…

2024/3/23打卡数组分割(第14届蓝桥杯)——二项式定理,快速幂

目录 题目 思路 代码 题目 思路 分析该题&#xff0c;要将集合 划分成两个子集 &#xff0c;且两个子集的和都是偶数。 可知&#xff1a;偶数 偶数 偶数&#xff1b;偶数 奇数 奇数&#xff1b;奇数 奇数 偶数&#xff1b; 分析可得&#xff1a;如果该集合的和为奇…

AtCoder Regular Contest 133 B - Dividing Subsequence 复杂版LIS最长上升子序列

B - Dividing Subsequence 题意&#xff1a; 数组a和数组b&#xff0c;找出最长公共子序列&#xff0c;使得每个b[ i ] 都是 a[ i ]的倍数。 思路&#xff1a; AtCoder Regular Contest 133 B(最长上升子序列) C(思维) - 知乎 这种题应把问题转化&#xff0c;把 要找的 和 …

父类子类构造方法调用示例

父类写无参构造&#xff0c;子类不写构造&#xff0c;实例化子类&#xff0c;会同时调用父类构造方法 public class Father {private String name;private int age;public Father() {System.out.println("父类无参构造");}} public class Son extends Father {priva…

prometheus监控oracle

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

element-ui实现各种证件照上传预览下载组件封装,图片上传回显及长宽自定义功能单个图片上传功能附带源码

element-ui实现证件照上传预览下载组件封装 效果&#xff1a; 参数说明 我只写了两个参数&#xff0c;后续有需求再对其组件进行丰富~ 参数说明fileListProp用来存储上传后后端返回的图片UR了uploadUrl图片上传返回的URL后端接口地址widthProp图片上传框的宽度heightProp图片…

人脸聚类原理和算法解释

人脸聚类是指将大量人脸图像根据它们的相似性分组到不同的群集中的过程。人脸聚类通常利用人脸的特征向量表示来度量人脸之间的相似性&#xff0c;并将相似的人脸图像聚集在一起。 以下是人脸聚类的一般原理&#xff1a; 人脸特征提取&#xff1a;对每张人脸图像提取特征向量。…

FPGA结构与片上资源

文章目录 0.总览1.可配置逻辑块CLB1.1 6输入查找表&#xff08;LUT6&#xff09;1.2 选择器&#xff08;MUX&#xff09;1.3 进位链&#xff08;Carry Chain&#xff09;1.4 触发器&#xff08;Flip-Flop&#xff09; 2.可编程I/O单元2.1 I/O物理级2.2 I/O逻辑级 3.布线资源4.其…

为什么静态成员函数不能是虚函数

在面向对象编程中&#xff0c;静态成员函数和虚函数都是常见的概念&#xff0c;但它们之间存在着本质上的差异。由于其特性上的差异&#xff0c;静态成员函数不能声明为虚函数。下面我们来探讨一下为什么静态成员函数不能是虚函数。 我在网上查到最多的说法是静态函数没有this指…

机场防鸟 | 真驱鸟煤气炮驱鸟器产品分析

机场的机坪跑道上&#xff0c;飞机频繁起降&#xff0c;而在机场的上空&#xff0c;偶尔会有几只灵活的小鸟&#xff0c;趁着飞机起降的间隙&#xff0c;在机坪区穿梭&#xff0c;它们或许在寻找食物&#xff0c;或许只是在享受这片广阔的天空。 对于机场驱鸟员来说&#xff0c…

嵌入式学习44-哈希算法和排序算法

Hash 哈希算法&#xff1a; 在记录的 存储位置 和它的 关键字 之间建立一种去特定的对应关系&#xff0c;使得每个关键字key对应一个存储位置&#xff1b; 查找时&#xff0c;根据确定的对应关系&#xff0c;找到给定的 key 的映射。 记录的存储位置 f&a…

vscode安装mysql相关插件

在Visual Studio Code (VSCode) 中安装 MySQL 客户端插件可以让你在 VSCode 中直接连接到 MySQL 数据库&#xff0c;并执行 SQL 查询。以下是如何安装和使用 MySQL 客户端插件的步骤&#xff1a; 1.打开 VSCode。 2.按下 Ctrl Shift X 打开扩展商店&#xff08;或点击侧边栏…

Mysql - date、datetime、timestamp 的区别

date、datetime 的区别 顾名思义&#xff0c;date 日期&#xff0c;datetime 日期时间&#xff0c;所以 date 是 datetime 的日期部分MySQL 以 格式检索和显示 datetime 值 YYYY-MM-DD hh:mm:ss datetime 支持的日期时间范围 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 d…

SpringBoot学习之ElasticSearch下载安装和启动(Windows版)(三十)

本文先写windows下的下载安装和启动,后续有时间再补充其他环境下(Mac、Linux、Docker)的,这里我们后续对ElasticSearch简称为ES,读者习惯这一称呼就好。 一,ES下载 可以百度【ElasticSearch官网】或者直接点击这里的ES官网下载地址:​​​​​ Download Elasticsearch…

电路笔记 :灯光画 元器件焊接+连锡处理

https://oshwhub.com/qazwsx1987/dengguanghua_0#P3 基础工具 常用的电路焊接工具&#xff1a; 工具描述电烙铁我买了一个便携电烙铁&#xff0c;但是烙铁头温度太低&#xff0c;焊锡总是粘在烙铁头上&#xff08;因为电量不足&#xff09;, 打火机秒变电烙铁焊台用于支撑工…

集成学习 | 集成学习思想:Boosting思想 | XGBoost算法、LightGBM算法

目录 一. XGBoost 算法1. XGBoost 算法流程2. XGBoost 算法评价 二. LightGBM 算法2. LightGBM 算法优势 上一篇文章中&#xff0c;我们了解了Boosting思想的两种算法&#xff1a;Adboost和GBDT&#xff1b;其中对于GBDT算法&#xff0c;存在两种改进&#xff0c;即&#xff1a…

SQLAlchemy操作数据库

数据库是一个网站的基础。 比如 MySQL 、 MongoDB 、 SQLite 、 PostgreSQL 等&#xff0c;这里我们以 MySQL为例进行讲解。 SQLAlchemy 是一个 ORM 框架 我们会以 MySQL SQLAlchemy 组合进行讲解。 在操作数据库操作之前&#xff0c;先确保你已经安装了以下两个插件&#…

阿里云服务器新/老用户优惠价格收费标准(2024最新更新)

2024年阿里云服务器优惠价格表&#xff0c;一张表整理阿里云服务器最新报价&#xff0c;阿里云服务器网整理云服务器ECS和轻量应用服务器详细CPU内存、公网带宽和系统盘详细配置报价单&#xff0c;大家也可以直接移步到阿里云CLUB中心查看 aliyun.club 当前最新的云服务器优惠券…
最新文章