three.js 航拍全景图(+陀螺仪)

news2024/11/26 16:51:12

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

右上角陀螺仪也可点击,需要https的环境,手动下载DeviceOrientationControls.js文件
后台包含打点功能

<template>
  <div id="quanjing" style="width: 100vw; height: 100vh; overflow: hidden">
    <span
      id="tip"
      style="position: absolute; color: red; top: 0; left: 0"
    ></span>
    <!-- 封面图切换结束 -->
    <img
      :src="imageUrl + aerialData.asteroidImg"
      style="
        position: absolute;
        top: 50%;
        height: 100vh;
        left: 50%;
        transform: translate(-50%, -50%);
      "
      v-if="isShowFM"
    />
    <img
      v-if="isShowHand"
      src="../assets/images/quanjingHand.png"
      style="
        z-index: 2;
        position: absolute;
        top: 50%;
        left: 50%;
        margin-left: -80px;
        margin-top: -90px;
        border-radius: 10px;
        width: 160px;
        height: 180px;
      "
    />
    <!-- 封面图切换结束 -->
    <img
      src="../assets/images/quanjinglogo.png"
      style="position: absolute; top: 10px; left: 10px; width: 100px"
    />

    <!-- 右上角全景图标切换开始 -->
    <div class="rig-list" id="hangpaiIcon" v-if="!isPc">
      <img v-if="isFull" src="../assets/images/hangpaiIcon.png" />
      <img v-else src="../assets/images/hangpaiIcon2.png" />
    </div>
    <!-- 右上角全景图标切换开始结束 -->
    <!-- 标注增删改查开始 -->
    <div class="addPoint" v-if="isShowPoint">
      <div class="row" v-for="(item, index) in biaojiList" :key="index">
        <div>地名:</div>
        <input placeholder="" class="inp" v-model="item.title" />
        <div>x:</div>
        <input placeholder="" class="inp" v-model="item.x" />
        <div>y:</div>
        <input placeholder="" class="inp" v-model="item.y" />
        <div>z:</div>
        <input placeholder="" class="inp" v-model="item.z" />
        <div
          style="
            background-color: rgb(253, 143, 143);
            margin-left: 10px;
            padding: 0 5px;
          "
          @click="delPoint(index)"
        >
          删除
        </div>
        <div
          style="
            background-color: rgb(249, 253, 143);
            margin-left: 10px;
            padding: 0 5px;
          "
          @click="huoqu(index)"
        >
          获取
        </div>
        <div
          style="
            background-color: rgb(104, 255, 111);
            margin-left: 10px;
            padding: 0 5px;
          "
          @click="baocun(index)"
        >
          保存
        </div>
      </div>
      <div class="row">
        <div
          @click="addPoint"
          style="
            background-color: rgb(143, 200, 253);
            margin-left: 10px;
            padding: 0 5px;
          "
        >
          新增
        </div>
        <div
          @click="submitPoint"
          style="
            background-color: rgb(143, 253, 191);
            margin-left: 10px;
            padding: 0 5px;
          "
        >
          上传
        </div>
        <span style="font-size: 12px"
          >(*1.点击获取按钮鼠标右键点击在航拍图上。2.确认坐标后点击同行保存按钮。3.标注完成后点击上传按钮)</span
        >
      </div>
    </div>
    <!-- 标注增删改查结束 -->
    <div id="biaozhudian"></div>
  </div>
</template>
<!-- [{"title":"东直门","x":"445.42720890862677","y":"-218.0846523283593","z":"-57.86235074865762"}] -->
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { DeviceOrientationControls } from "three/examples/jsm/controls/DeviceOrientationControls.js";
import TWEEN from "@tweenjs/tween.js";
import {
  CSS2DRenderer,
  CSS2DObject,
} from "three/examples/jsm/renderers/CSS2DRenderer.js";
import { aerialData, editAerial, updateMark } from "@/api/house/house.js";
export default {
  name: "quanjing",
  data() {
    return {
      isShowFM: false,
      isShowHand: false,
      imageUrl: "https://obj.qiniu.fangdadi.com/",
      title: "房大地-全景",
      scene: null,
      camera: null,
      renderer: null,
      css2Renderer: null,
      loader: null,
      texture: null,
      sphereGeometry: null,
      mesh: null,
      axesHelper: null,
      tween: null,
      controls: null,
      controls2: null,
      //标点
      vector: null,
      screenVector: null,
      doc: null,
      activePoint: null,
      div: null,
      raycaster: null,
      mouse: null,
      tagObject: null,
      //陀螺仪
      clock: null,
      isFull: null,

      dcontrols: null,
      aerialData: {},
      biaojiList: [],
      pointList: [{ title: "", x: "", y: "", z: "" }],
      pointIndex: null,
      isShowPoint: false,
      tagArray: [],
      isPc: false,
    };
  },
  watch: {},

  mounted() {
    //判断是什么环境,手机还是电脑
    if (document.documentElement.clientWidth < 720) {
      this.isPc = false;
    } else {
      this.isPc = true;
    }
    this.getAerialData();
    // 点击右上角陀螺仪
    document
      .getElementById("hangpaiIcon")
      .addEventListener("click", this.fullOrExit, false);
  },
  methods: {
    //获取数据
    getAerialData() {
      let idNum = null;
      console.log(this.$route.params.id.split("+"));
      if (this.$route.params.id.split("+").length == 2) {
        console.log(1111);
        this.isShowPoint = true;
        idNum = this.$route.params.id.split("+")[0];
      } else {
        console.log(22222222);
        this.isShowPoint = false;
        idNum = this.$route.params.id;
      }
      aerialData(idNum)
        .then((res) => {
          if (res.data) {
            this.aerialData = res.data;
            this.isShowFM = true;
            if (res.data.markData) {
              console.log(JSON.parse(res.data.markData));
              this.biaojiList = JSON.parse(res.data.markData);
              console.log(" this.biaojiList ", this.biaojiList.length);
            }
          }
        })

        .then(() => {
          this.clock = new THREE.Clock();
          this.container = document.body;
          this.isFull = false;
          //判断是什么环境,手机还是电脑
          // if (document.documentElement.clientWidth < 720) {
          // }
          this.initThree();
          this.clickBiaoji();
          this.objTween();

          window.addEventListener("pointerdown", this.onMouseDown, false);

          var _this = this;
          // 更改渲染器画布大小
          window.onresize = function () {
            // 重置渲染器输出画布canvas尺寸
            _this.renderer.setSize(window.innerWidth, window.innerHeight);
            // 全屏情况下:设置观察范围长宽比aspect为窗口宽高比
            _this.camera.aspect = window.innerWidth / window.innerHeight;
            // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
            // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
            // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
            _this.camera.updateProjectionMatrix();
          };
        });
    },
    // /**
    // 准备全景图像:
    // 首先,您需要获得或创建全景图像。全景图像是一种呈现完整360度视野的特殊图像。您可以使用专业相机拍摄全景照片,或者从互联网上获取全景图像。确保全景图像采用通常的全景图像格式,如equirectangular格式。
    // 设置Three.js场景:
    // 创建一个HTML页面,引入Three.js库。您可以从Three.js官方网站下载或使用CDN来加载库。
    // 创建Three.js场景:
    // 在您的HTML页面中,创建一个Three.js场景、相机和渲染器。
    //  */
    // // 相机第一个参数fov 130->75
    initThree() {
      this.scene = new THREE.Scene();
      this.camera = new THREE.PerspectiveCamera(
        130,
        window.innerWidth / window.innerHeight,
        1,
        1000
      );
      this.renderer = new THREE.WebGLRenderer();
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.renderer.domElement.style.zIndex = -1;
      this.css2Renderer = new CSS2DRenderer();
      this.css2Renderer.setSize(window.innerWidth, window.innerHeight);

      this.LoadingImg();
    },

    LoadingImg() {
      var _this = this;
      /*
    加载全景图像:
    使用Three.js的TextureLoader加载全景图像。
    */
      this.loader = new THREE.TextureLoader();
      this.texture = this.loader.load(
        this.imageUrl + this.aerialData.panoramaImg,
        function (obj) {
          console.log("加载完了");
          _this.isShowFM = false;
        }
      ); // If texture is used for color information, set colorspace.
      this.texture.encoding = THREE.sRGBEncoding;

      this.sphereGeometry = new THREE.SphereGeometry(500, 60, 40);
      this.sphereGeometry.scale(-1, 1, 1); //创建的球形几何体执行这个方法, 镜像就正回来了
      this.sphereMaterial = new THREE.MeshBasicMaterial({
        map: this.texture,
        side: THREE.DoubleSide,
      });
      this.mesh = new THREE.Mesh(this.sphereGeometry, this.sphereMaterial);
      this.scene.add(this.mesh);
      // // AxesHelper:辅助观察的坐标系
      // this.axesHelper = new THREE.AxesHelper(150);
      // this.scene.add(this.axesHelper);
      /*
    设置相机视角:
    将相机朝向全景图像的中心,以确保全景图像填充整个视野。
    */

      this.camera.position.set(0, 500, 0.1);
      this.camera.lookAt(0, 0, 0);
      /**
       * 模型旋转
       */
      this.mesh.rotateY(-Math.PI / 2); //绕x轴旋转π/2
    },

    objTween() {
      var _this = this;
      // // 旋转过渡效果
      this.tween = new TWEEN.Tween({
        x: 0,
        y: 500,
        z: 10,
        ry: -Math.PI / 2,
        fov: 130,
      }) // 开始位置(2D)
        .to(
          {
            x: 0,
            y: 0,
            z: 0.1,
            ry: 0,
            fov: 75,
          },
          3000
        ) // 结束位置(3D)
        .easing(TWEEN.Easing.Quadratic.InOut) // 缓动函数
        .onUpdate(function (obj) {
          _this.camera.position.set(obj.x * 1, obj.y * 1, obj.z * 1);
          _this.camera.lookAt(_this.scene.position);

          _this.mesh.rotation.y = obj.ry;
          _this.camera.rotation.x = obj.ry;
          _this.camera.fov = obj.fov;
          _this.camera.updateProjectionMatrix();
        })
        .delay(3000)
        .start()
        .onComplete(function () {
          //运动结束后地图打点
          _this.biaoji();
          _this.isShowHand = true;
          setTimeout(() => {
            _this.isShowHand = false;
          }, 2000);
        });

      this.OrbitControlsFun();
    },

    // /*
    // 渲染场景:
    // 使用requestAnimationFrame函数循环渲染Three.js场景。
    // */
    animate() {
      requestAnimationFrame(this.animate);
      TWEEN.update(); // 更新Tween.js动画
      this.renderer.render(this.scene, this.camera);
      this.css2Renderer.render(this.scene, this.camera);
      if (this.isFull) {
        this.dcontrols.update(this.clock.getDelta());
      }
    },

    /*
    添加交互性(可选):
    您还可以添加鼠标或触摸交互,以允许用户在全景图像中浏览。Three.js提供了相关的控制器,如OrbitControls。
    */
    OrbitControlsFun() {
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableZoom = false;
      this.controls.enablePan = false;
      this.controls2 = new OrbitControls(
        this.camera,
        this.css2Renderer.domElement
      );
      this.controls2.enableZoom = false;
      this.controls2.enablePan = false;

      // 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景

      document.getElementById("quanjing").appendChild(this.renderer.domElement);
      this.animate();
    },
    //设置标记点开始
    biaoji() {
      if (this.tagArray.length != 0) {
        this.tagArray.forEach((i) => {
          this.scene.remove(i);
        });
      }
      this.biaojiList.forEach((item) => {
        let info1 = document.createElement("div");
        info1.setAttribute("class", "info1");
        info1.style.width = "40px";
        info1.style.height = "40px";
        info1.style.position = "absolute";
        info1.style.pointerEvents = "auto";
        var img = document.createElement("img");
        img.src =
          "https://wimg.588ku.com/gif620/20/06/28/a47c5cb0333780628b29c0e94f3b9423.gif";
        img.style.width = "40px";
        img.style.height = "40px";
        info1.appendChild(img);
        var p = document.createElement("p");
        p.innerText = item.title;
        p.style.position = "absolute";
        p.style.bottom = "100%";
        p.style.left = "-70%";
        p.style.minWidth = "100px";
        p.style.textAlign = "center";
        p.style.minHeight = "20px";
        p.style.background = "#31313194";
        p.style.padding = "5px";
        p.style.borderRadius = "10px";
        p.style.color = "white";
        info1.appendChild(p);

        let tag = new CSS2DObject(info1);
        tag.name = "proLabel";
        tag.position.set(item.x, item.y, item.z);
        this.scene.add(tag);
        this.tagArray.push(tag);
        this.css2Renderer.domElement.style.position = "absolute";
        this.css2Renderer.domElement.style.top = "0";
        this.css2Renderer.domElement.style.pointerEvents = "none";

        document
          .getElementById("biaozhudian")
          .appendChild(this.css2Renderer.domElement);
      });
    },
    clickBiaoji() {
      this.vector = new THREE.Vector3();
      this.screenVector = new THREE.Vector3();
      this.doc = document;
      this.activePoint = null;
      this.div = this.doc.getElementById("tip");
      this.raycaster = new THREE.Raycaster();
      this.mouse = new THREE.Vector2();
      this.tagObject = new THREE.Object3D();
    },

    /**
     * 鼠标点击触发
     **/
    onMouseDown(event) {
      if (event.buttons === 2 && this.pointIndex != null) {
        // 屏幕坐标转标准设备坐标
        this.vector.set(
          (event.clientX / window.innerWidth) * 2 - 1,
          -(event.clientY / window.innerHeight) * 2 + 1,
          0
        );
        // 将标准设备坐标转为世界坐标
        this.vector.unproject(this.camera);

        this.raycaster = new THREE.Raycaster(
          this.camera.position,
          this.vector.sub(this.camera.position).normalize()
        );

        let intersects = this.raycaster.intersectObjects([this.mesh]);

        if (intersects.length > 0) {
          this.activePoint = intersects[0].point;
          let point = this.toScreenPosition({
            point: this.activePoint,
          });
          this.div.style.left = point.x + "px";
          this.div.style.top = point.y + 20 + "px";
        }
        let xyz = this.activePoint;
        this.biaojiList[this.pointIndex].x = xyz.x;
        this.biaojiList[this.pointIndex].y = xyz.y;
        this.biaojiList[this.pointIndex].z = xyz.z;
        console.log("点击坐标-----", JSON.stringify(this.activePoint)); // 传给后台的参数
      }
    },

    toScreenPosition({ obj = null, point = null }) {
      point ? this.screenVector.set(...point) : this.screenVector.set();
      // 屏幕坐标系中心
      let widthHalf = this.renderer.getContext().canvas.width / 2;
      let heightHalf = this.renderer.getContext().canvas.height / 2;

      if (obj) {
        // 更新物体及其后代的全局变换
        obj.updateMatrixWorld();
        // 提取位置相关的分量
        this.screenVector.setFromMatrixPosition(obj.matrixWorld);
      }

      // 世界坐标转标准设备坐标。范围[-1,1]
      this.screenVector.project(this.camera);

      //标准设备坐标转屏幕坐标(2D)
      this.screenVector.x = this.screenVector.x * widthHalf + widthHalf;
      this.screenVector.y = -this.screenVector.y * heightHalf + heightHalf;

      return {
        x: this.screenVector.x,
        y: this.screenVector.y,
      };
    },
    // 陀螺仪
    setOrientationControls(e) {
      // 判断手机电脑端
      if (!e.alpha) {
        return;
      }
      this.isFull = true;
      this.dcontrols = new DeviceOrientationControls(this.camera, true);

      this.dcontrols.connect();
      this.dcontrols.update();
      window.removeEventListener(
        "deviceorientation",
        this.setOrientationControls,
        true
      );
    },

    // 陀螺仪权限判断
    fullOrExit() {
      let _this = this;
      if (!_this.isFull) {
        try {
          console.log("浏览器UA---->", navigator.userAgent);
          if (
            navigator.userAgent.includes("iPhone") ||
            navigator.userAgent.includes("iPad") ||
            navigator.userAgent.includes("iPod") ||
            navigator.userAgent.includes("Macintosh")
          ) {
            // 这是苹果设备上的浏览器
            console.log("这是苹果设备上的浏览器");
            if (
              window.DeviceOrientationEvent !== undefined &&
              typeof window.DeviceOrientationEvent.requestPermission ===
                "function"
            ) {
              window.DeviceOrientationEvent.requestPermission()
                .then(function (response) {
                  if (response == "granted") {
                    window.addEventListener(
                      "deviceorientation",
                      _this.setOrientationControls,
                      true
                    );
                  }
                })
                .catch(function (error) {
                  console.error(
                    "THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:",
                    error
                  );
                });
            } else {
              window.addEventListener(
                "deviceorientation",
                _this.setOrientationControls,
                true
              );
            }
          } else {
            // 这不是苹果设备上的浏览器
            console.log("这不是苹果设备上的浏览器");
            window.addEventListener(
              "deviceorientation",
              _this.setOrientationControls,
              true
            );
          }
        } catch (error) {
          console.error("监听事件处理程序出错:", error);
        }
      } else {
        if (_this.dcontrols) {
          _this.dcontrols.disconnect();
          _this.dcontrols.update();
          window.removeEventListener(
            "deviceorientation",
            _this.setOrientationControls,
            true
          );
        } else {
          console.log("dcontrols 未创建");
        }
        _this.isFull = false;
      }
    },
    // 增删改查数据开始
    //删除标点
    delPoint(index) {
      this.pointIndex = null;
      this.biaojiList.splice(index, 1);
      this.biaoji();
    },
    //获取标点
    huoqu(index) {
      this.pointIndex = index;
    },
    //保存标点
    baocun(index) {
      this.pointIndex = null;
      this.biaoji();
    },
    //上传标点信息
    async submitPoint() {
      let FormData = new window.FormData();
      FormData.append("aerialId", this.aerialData.aerialId);
      FormData.append("markData", JSON.stringify(this.biaojiList));

      let res = await updateMark(FormData);
      if (res.data == 1) {
        this.$message.success("上传成功");
        console.log(res);
      }
    },
    //新增标点数据
    addPoint() {
      this.biaojiList.push({ title: "", x: "", y: "", z: "" });
    },
    // 增删改查数据结束
  },
};
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
// ::v-deep

#quanjing {
  overflow: hidden;
  width: 100vw;
  height: 100vh;
  touch-action: none;
  position: absolute;
  top: 0px;
}
.info1 {
  position: absolute;

  width: 40px;
  height: 40px;
}

.info1 img {
  width: 40px;
  height: 40px;
}

.info1 p {
  position: absolute;
  bottom: 100%;
  left: -70%;
  min-width: 100px;
  text-align: center;
  min-height: 20px;

  color: white;
}
.rig-list {
  position: absolute;
  right: 10px;
  top: 40px;
  img {
    width: 40px;
    height: 40px;
    margin-bottom: 10px;
  }
  #hangpaiIcon {
    z-index: 2;
  }
}
.addPoint {
  width: 750px;
  background: rgba(255, 255, 255, 0.453);
  min-height: 50px;
  position: absolute;
  top: 0;
  left: 50%;
  margin-left: -375px;
}
.row {
  width: 100%;
  overflow: hidden;
  margin-bottom: 5px;
  div {
    float: left;
    margin-left: 10px;
  }
  .inp {
    float: left;
    border: none;
    outline: none;
    width: 100px;
    margin-left: 10px;
  }
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

骨骼动画详解

【物体怎么样是在动】 当物体的位置、朝向、大小即Transform有任意一者发生变化时&#xff0c;物体在动。 但变化要达到一定的幅度时&#xff0c;我们会看到物体在动&#xff0c;幅度是多少却决于我们看这个物体的距离、方向&#xff0c;物体的朝向等因素。 这里说的幅度是指…

【Windows】解决电脑可以正常使用微信,但是打不开网页

问题 啊哈 如题&#xff0c;在安装软件的过程中突然就发现浏览器不能用了&#xff0c;但是微信可以正常接发消息。 记录一下解决过程。 解决 1、自动DNS 打开控制面板->网络和Internet->网络和共享中心&#xff0c;点击以太网&#xff0c;找到属性Internet协议4(TCP/…

手机怎么打包?三个方法随心选!

有的时候&#xff0c;电脑不在身边&#xff0c;只有随身携带的手机&#xff0c;这个时候又急需把文件打包发送给同事或者同学&#xff0c;如何利用手机操作呢&#xff1f;下面介绍了具体的操作步骤。 一、通过手机文件管理自带压缩功能打包 1、如果是iOS系统&#xff0c;就在手…

猫头虎分享从Python到JavaScript传参数:多面手的数据传递术

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

dell r720

dell r720的idrac的地址默认是192.168.1.110&#xff0c;root 默认密码calvin fatal Error! All channnels have been disabled due to all DIMMs failed the Memoey 是什么意思 Dell PowerEdge T320服务器 开机显示 Fatal Errort!all channells have been disabled due to …

【鹰王系统】又一个干净纯净的window系统下载站点,值得推荐!

今天给大家分享一个高质量的window系统下载站点【鹰王系统】&#xff0c;此站长自己制作了winxp、win7、win10、win11等各种版本系统&#xff0c;都是非常不错的系统镜像&#xff0c;都是免费下载没有任何捆绑信息&#xff0c;值得推荐。 网站首页截图 系统下载截图&#xff1a…

Java 高效生成按指定间隔连续递增的列表(int,double)

简介 Java 按照指定间隔生成连续递增的List 列表&#xff08;引入Stream 类和流操作来提高效率&#xff09;&#xff1a; 1. 生成递增的List< Integer> Testpublic void test009(){int start 1;int interval 2;int count 10;List<Integer> list IntStream.ite…

集群外访问计算节点gpu上的web链接

情况描述 现在有一个程序&#xff0c;通过提交作业的方式在集群的计算节点C上运行&#xff0c;运行后给了一个web的地址,如下图所示 然而&#xff0c;在自己电脑A上只能访问集群的管理节点B&#xff0c;无法直接访问计算节点。管理节点可以访问计算节点&#xff0c;计算节点无…

Git extension 中合并工具kdiff3乱码问题

打开kdiff3合并工具&#xff0c;setting->region settings 设置下面的编码格式为utf-8就可以啦&#xff01; 注意&#xff1a;需要在合并工具中设置编码格式&#xff0c; 在git 中配置编码格式没有效果

Keep-Alive中通过component多次加载同样的动态组件无法保持状态的解决办法

Keep-Alive中通过component多次加载同样的动态组件无法保持状态的解决办法 Keep-Alive中通过component多次加载同样的动态组件无法保持状态的解决办法 | 软件开发服务商 (yidianhulian.com)https://yidianhulian.com/?p12263 问题描述 项目功能上有需要动态添加组件的需求&…

Python学习-shutil模块和OS模块学习

shutil模块 针对文件的拷贝&#xff0c;删除&#xff0c;移动&#xff0c;压缩和解压操作 # 1.copyfileobj只能复制文件内容&#xff0c;无法复制权限#复制文件时&#xff0c;要选择自己有权限的目录执行操作&#xff0c;创建的文件会根据系统umask设定的参数来指定用户权限 s…

Ubuntu 18.04.6 LTS安装docker和docker-compose、镜像导入导出

Ubuntu 18.04.6 LTS安装docker和docker-compose、镜像导入导出 文章目录 Ubuntu 18.04.6 LTS安装docker和docker-compose、镜像导入导出安装docker更新数据源&#xff0c;安装必要插件添加GPG密钥设置存储库再更新apt包索引安装docker-ce查看docker状态运行docker hello-world …

医学专题(6)--多组学在肿瘤分型研究中的应用思路

研究背景 肿瘤免疫分型的由来&#xff1a;每一种肿瘤&#xff0c;甚至每一位患者的肿瘤浸润免疫细胞都存在差异&#xff0c;研究者根据免疫细胞浸润的特点将肿瘤大致分为“冷”肿瘤和“热”肿瘤&#xff0c;此概念的提出是肿瘤免疫分型的雏形。 对肿瘤免疫分型的研究有很多&a…

HDFS速通之一文详解HDFS全部知识点

文章目录 HDFS介绍HDFS体系HDFS的Shell介绍HDFS的常见Shell操作 HDFS案例实操Java操作HDFS配置环境 HDFS的回收站HDFS的安全模式实战&#xff1a;定时上传数据至HDFSHDFS的高可用和高扩展HDFS的高可用(HA)HDFS的高扩展(Federation) HDFS介绍 HDFS是一个分布式的文件系统 假设…

二叉树的最大深度(C++解法)

题目 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;root [1,null,2…

2005-2021年全国各省家庭承包耕地面积和家庭承包耕地流转总面积数据(无缺失)

2005-2021年全国各省家庭承包耕地面积和家庭承包耕地流转总面积数据 1、时间&#xff1a;2005-2021年 2、来源&#xff1a;农村经营管理统计NB 3、指标&#xff1a;家庭承包经营耕地面积、家庭承包耕地流转总面积&#xff08;单位&#xff1a;亩&#xff09; 4、范围&#…

MVC、MVP、MVVM区别

MVC、MVP、MVVM区别 MVC&#xff08;Model-View-Controller&#xff09; 。是一种设计模式&#xff0c;通常用于组织与应用程序的数据流。它通常包括三个组件&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&…

【OpenVINO】基于 OpenVINO C++ API 部署 RT-DETR 模型

基于 OpenVINO C API 部署 RT-DETR 模型 1. RT-DETR2. OpenVINO3. 环境配置4. 模型下载与转换4.1 模型导出4.2 模型信息对比 5. C代码实现5.1 模型推理类实现 5.2 模型数据处理类RTDETRProcess6. 预测结果展示7. 总结 RT-DETR是在DETR模型基础上进行改进的&#xff0c;一种基于…

JAR 文件规范详解

介绍 JAR文件是基于ZIP文件格式的一种文件格式&#xff0c;用来将许多文件整合成一个文件。一个JAR文件本质上是包含可选目录META-INF的zip文件&#xff0c;可以通过命令行jar工具或者在Java平台上使用java.util.jar中的API来创建。JAR文件的命名没有严格的要求&#xff0c;可…

Flink SQL Regular Join 、Interval Join、Temporal Join、Lookup Join 详解

Flink ⽀持⾮常多的数据 Join ⽅式&#xff0c;主要包括以下三种&#xff1a; 动态表&#xff08;流&#xff09;与动态表&#xff08;流&#xff09;的 Join动态表&#xff08;流&#xff09;与外部维表&#xff08;⽐如 Redis&#xff09;的 Join动态表字段的列转⾏&#xf…