CesiumJS+SuperMap3D.js混用实现可视域分析 S3M图层加载 裁剪区域绘制

news2024/11/17 11:45:02

版本简介:

cesium:1.99;Supermap3D:SuperMap iClient JavaScript 11i(2023);

官方下载文档链家:SuperMap技术资源中心|为您提供全面的在线技术服务

示例参考:support.supermap.com.cn:8090/webgl/Cesium/examples/webgl/examples.html#analysis

support.supermap.com.cn:8090/webgl/examples/webgl/examples.html

Cesium:场景初始化、渲染、Bing地图、S3M图层加载。

SuperMap3D:可视域分析、S3M图层加载、裁剪区域绘制、Knockout绑定等功能。

两者结合:Cesium 提供基础渲染和事件处理,SuperMap3D 提供高级的功能实现。

1. Cesium 部分

场景初始化与配置
Cesium.Ion.defaultAccessToken = '...';
var viewer = new Cesium.Viewer('Container', {
    selectionIndicator: false,
    infoBox: false,
    terrainProvider: Cesium.createWorldTerrain()
});
viewer.resolutionScale = window.devicePixelRatio;
  • 这段代码是使用 Cesium 进行场景渲染的部分。Cesium.Ion.defaultAccessToken 用于访问 Cesium Ion 服务,viewer 是 Cesium Viewer 的实例,它用于创建一个可视化容器,其中指定了Container元素来渲染场景。createWorldTerrain() 设置了全球地形服务,resolutionScale 提高了分辨率,以适应高DPI屏幕。
添加Bing地图图层
viewer.imageryLayers.addImageryProvider(new Cesium.BingMapsImageryProvider({
    url: 'https://dev.virtualearth.net',
    mapStyle: Cesium.BingMapsStyle.AERIAL,
    key: URL_CONFIG.BING_MAP_KEY
}));
  • 这里是Cesium的图层管理部分,使用 BingMapsImageryProvider 添加了 Bing 地图的航拍图层。Cesium 的图层管理方式主要通过 imageryLayers.addImageryProvider() 实现。
事件处理与视口操作
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function (e) {
    //...
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  • 这一部分代码处理的是 Cesium 中的鼠标事件,如屏幕空间事件(ScreenSpaceEventHandler) 和鼠标移动事件 (MOUSE_MOVE)。这是 Cesium 的交互控制,通过捕捉鼠标操作来对场景进行更新。

2. SuperMap3D 部分

可视域分析与裁剪
var viewshed3D = new SuperMap3D.ViewShed3D(scene);
  • 这里是 SuperMap3D 提供的可视域分析功能的初始化。SuperMap3D.ViewShed3D 是用于在 3D 场景中执行可视域分析的类,用于计算某个点是否可见。
加载S3M图层
var promise = scene.open('http://www.supermapol.com/realspace/services/3D-CBD-2/rest/realspace');
SuperMap3D.when(promise, function (layers) {
    // 设置相机位置等操作
}, function (e) {
    // 错误处理
});
  • 这里通过 scene.open() 加载了 SuperMap3D 的 S3M 图层,这个图层是 SuperMap 提供的特定格式,通常用于大规模3D场景的渲染和展示。
裁剪区域操作
var handlerPolygon = new SuperMap3D.DrawHandler(viewer, SuperMap3D.DrawMode.Polygon, 0); 
handlerPolygon.movingEvt.addEventListener(function (windowPosition) {
    if (handlerPolygon.isDrawing) {
        tooltip.showAt(windowPosition, '<p>绘制相交区域(右键结束绘制)</p>'); // 绘制提示
    }
});
handlerPolygon.drawEvt.addEventListener(function (result) {
    var array = [].concat(result.object.positions);
    var positions = [];
    for (var i = 0, len = array.length; i < len; i++) {
        var cartographic = SuperMap3D.Cartographic.fromCartesian(array[i]);
        var longitude = SuperMap3D.Math.toDegrees(cartographic.longitude);
        var latitude = SuperMap3D.Math.toDegrees(cartographic.latitude);
        var h = cartographic.height;
        positions.push(longitude, latitude, h);
    }
    viewshed3D.addClipRegion({name: 'test', position: positions}); // 添加裁剪区域
});
  • 这是 SuperMap3D 的裁剪操作部分。通过 SuperMap3D.DrawHandler 绘制多边形区域,viewshed3D.addClipRegion() 函数则用于将绘制的区域应用到可视域分析对象中,进行裁剪。
  • DrawHandler 用于激活绘制多边形裁剪面的功能。
  • movingEvt 事件在绘制过程中显示提示信息。
  • drawEvt 事件在绘制完成时获取多边形的坐标,并将其设置为可视域的裁剪区域。
Knockout 绑定
SuperMap3D.knockout.track(viewModel);
SuperMap3D.knockout.applyBindings(viewModel, toolbar);
  • 这段代码是使用 SuperMap3D 提供的 Knockout 绑定功能,目的是将数据模型 viewModel 与 UI 绑定。这个功能允许动态更新可视域分析的参数。

3. Cesium 和 SuperMap3D 的结合

Cesium 在整个代码中主要负责场景渲染、基础交互和图层的管理,如初始化 Viewer、处理鼠标事件、添加图层等。而 SuperMap3D 负责具体的功能实现,比如可视域分析、S3M 图层加载、裁剪操作等。

两者通过 viewer.scene 来共享场景,SuperMap3D 的功能在 Cesium 的场景之上实现。例如:

  • var viewshed3D = new SuperMap3D.ViewShed3D(scene); —— 这里的 scene 是 Cesium 场景,而 viewshed3D 是 SuperMap3D 的可视域对象,它依赖于 Cesium 的场景。
  • 加载S3M图层和添加裁剪区域也是在 Cesium 场景中进行操作,二者配合使用

 4.完整代码展示

<!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="../../public/SuperMap3D/Widgets/widgets.css" rel="stylesheet">
    <link rel="stylesheet" href="./css/font-awesome.min.css">
    <link href="../css/pretty.css" rel="stylesheet">
    <link href="../css/style.css" rel="stylesheet">
    <link href="../css/viewshed3D.css" rel="stylesheet">
    <script type="text/javascript" src="../js/jquery.min.js"></script>
    <script src="../js/slider.js"></script>
    <script src="../js/config.js"></script>
    <script src="../js/tooltip.js"></script>
    <script src="../js/spectrum.js"></script>
    <script type="text/javascript" src="../../public/SuperMap3D/SuperMap3D.js"></script>

    <script src="../../../Cesium-1.99/Build/Cesium/Cesium.js"></script>
	<link href="../../../Cesium-1.99/Build/Cesium/Widgets/widgets.css">
</head>

<body>
<div id="Container"></div>
<div id='loadingbar' class="spinner">
    <div class="spinner-container container1">
        <div class="circle1"></div>
        <div class="circle2"></div>
        <div class="circle3"></div>
        <div class="circle4"></div>
    </div>
    <div class="spinner-container container2">
        <div class="circle1"></div>
        <div class="circle2"></div>
        <div class="circle3"></div>
        <div class="circle4"></div>
    </div>
    <div class="spinner-container container3">
        <div class="circle1"></div>
        <div class="circle2"></div>
        <div class="circle3"></div>
        <div class="circle4"></div>
    </div>
</div>
<div id="toolbar" class="param-container tool-bar">
    <button type="button" id="chooseView" class="button black">绘制可视域</button>
    <button type="button" id="cilpRegion" class="button black">绘制裁剪面</button>
    <button type="button" id="clear" class="button black">清除</button>
    <div class="param-item">
        <b>裁剪模式:</b>
        <select id="clip-mode" class="supermap3d-button">
            <option value="keep-inside">保留区域内</option>
            <option value="keep-outside">保留区域外</option>
        </select>
    </div>
</div>

<div id="wrapper" style="display:none">
    <div id="login" class="animate form">
        <span class="close" aria-hidden="true">×</span>
        <form>
            <h1>属性编辑</h1>
            <p>
            <div>
                <label>方向(度)</label>
                <input type="range" id="direction" min="0" max="360" step="1.0" title="方向"
                       data-bind="value: direction, valueUpdate: 'input'">
                <input type="text" size="5" data-bind="value: direction">
            </div>

            <div>
                <label>翻转(度)</label>
                <input type="range" id="pitch" min="-90" max="90" step="1.0" value="1" title="翻转"
                       data-bind="value: pitch, valueUpdate: 'input'">
                <input type="text" size="5" data-bind="value: pitch">
            </div>

            <div>
                <label>距离(米)</label>
                <input type="range" id="distance" min="1" max="500" step="1.0" value="1" title="距离"
                       data-bind="value: distance, valueUpdate: 'input'">
                <input type="text" size="5" data-bind="value: distance">
            </div>

            <div>
                <label>水平视场角(度)</label>
                <input type="range" id="horizonalFov" min="1" max="120" step="1" value="1" title="水平视场角"
                       data-bind="value: horizontalFov, valueUpdate: 'input'">
                <input type="text" size="5" data-bind="value: horizontalFov">
            </div>

            <div>
                <label>垂直视场角(度)</label>
                <input type="range" id="verticalFov" min="1" max="90" step="1.0" value="1" title="垂直视场角"
                       data-bind="value: verticalFov, valueUpdate: 'input'">
                <input type="text" size="5" data-bind="value: verticalFov">
            </div>
            </p>
            <p>
            <div class="square square-left">
                <label>可见区域颜色</label><input class="colorPicker" data-bind="value: visibleAreaColor,valueUpdate: 'input'"
                                            id="colorPicker1"/>
            </div>
            <div class="square square-right">
                <label>不可见区域颜色</label><input class="colorPicker"
                                             data-bind="value: invisibleAreaColor,valueUpdate: 'input'"
                                             id="colorPicker2"/>
            </div>
            </p><br/><br/>
            <p><label>本例中观察者附加高度:1.8 米</label></p>
        </form>
    </div>
</div>

<script type="text/javascript">

    function onload(Cesium) {
        Cesium.Ion.defaultAccessToken = 'your token'
        var viewer = new Cesium.Viewer('Container', {
            selectionIndicator: false,
			infoBox: false,
			terrainProvider: Cesium.createWorldTerrain()
        });
        viewer.resolutionScale = window.devicePixelRatio;

        viewer.scenePromise.then(function(scene){
            init(Cesium, scene, viewer);
        });
    }

    function init(Cesium, scene, viewer) {
        var labelImagery = new Cesium.TiandituImageryProvider({
            mapStyle: Cesium.TiandituMapsStyle.CIA_C,//天地图全球中文注记服务
            token: 'your token' //由天地图官网申请的密钥
        });

        var scene = viewer.scene;
        scene.lightSource.ambientLightColor = new Cesium.Color(0.65, 0.65, 0.65, 1);
        var viewPosition;

        if (!scene.pickPositionSupported) {
            alert('不支持深度纹理,可视域分析功能无法使用(无法添加观测)!');
        }
        // 先将此标记置为true,不激活鼠标移动事件中对可视域分析对象的操作
        scene.viewFlag = true;
        var pointHandler = new Cesium.DrawHandler(viewer, Cesium.DrawMode.Point);

        // 创建可视域分析对象
        var viewshed3D = new SuperMap3D.ViewShed3D(scene);
        var colorStr1 = viewshed3D.visibleAreaColor.toCssColorString();
        var colorStr2 = viewshed3D.hiddenAreaColor.toCssColorString();

        var widget = viewer.Widget;
        try {
            //添加S3M图层
            var promise = scene.open('http://www.supermapol.com/realspace/services/3D-CBD-2/rest/realspace');
            SuperMap3D.when(promise, function (layers) {
                // 图层加载完成,设置相机位置
                scene.camera.setView({
                    destination: SuperMap3D.Cartesian3.fromDegrees(116.44366835831197, 39.907137217792666, 48.237028126511696),
                    orientation: {
                        heading: 1.6310555040487564,
                        pitch: 0.0017367269669030794,
                        roll: 3.007372129104624e-12
                    }
                });
                for (var i = 0; i < layers.length; i++) {
                    layers[i].selectEnabled = false;
                }
            }, function (e) {
                if (widget._showRenderLoopErrors) {
                    var title = '加载SCP失败,请检查网络连接状态或者url地址是否正确?';
                    widget.showErrorPanel(title, undefined, e);
                }
            });
        } catch (e) {
            if (widget._showRenderLoopErrors) {
                var title = '渲染时发生错误,已停止渲染。';
                widget.showErrorPanel(title, undefined, e);
            }
        }

        var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
        // 鼠标移动时间回调
        handler.setInputAction(function (e) {
            // 若此标记为false,则激活对可视域分析对象的操作
            if (!scene.viewFlag) {
                //获取鼠标屏幕坐标,并将其转化成笛卡尔坐标
                var windowPosition = e.endPosition;
                scene.pickPositionAsync(windowPosition).then((last)=>{
                    //计算该点与视口位置点坐标的距离
                    var distance = SuperMap3D.Cartesian3.distance(viewPosition, last);

                    if (distance > 0) {
                        // 将鼠标当前点坐标转化成经纬度
                        var cartographic = Cesium.Cartographic.fromCartesian(last);
                        var longitude = Cesium.Math.toDegrees(cartographic.longitude);
                        var latitude = Cesium.Math.toDegrees(cartographic.latitude);
                        var height = cartographic.height;
                        // 通过该点设置可视域分析对象的距离及方向
                        viewshed3D.setDistDirByPoint([longitude, latitude, height]);
                    }
                })
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        handler.setInputAction(function (e) {
            //鼠标右键事件回调,不再执行鼠标移动事件中对可视域的操作
            scene.viewFlag = true;
            $("#wrapper").show();
            viewModel.direction = viewshed3D.direction;
            viewModel.pitch = viewshed3D.pitch;
            viewModel.distance = viewshed3D.distance;
            viewModel.horizontalFov = viewshed3D.horizontalFov;
            viewModel.verticalFov = viewshed3D.verticalFov;

        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

        var tooltip = createTooltip(document.body);

        //绘制裁剪面
        var handlerPolygon = new SuperMap3D.DrawHandler(viewer, SuperMap3D.DrawMode.Polygon, 0);
        handlerPolygon.activeEvt.addEventListener(function (isActive) {
            if (isActive == true) {
                viewer.enableCursorStyle = false;
                viewer._element.style.cursor = '';
                $('body').removeClass('drawCur').addClass('drawCur');
            } else {
                viewer.enableCursorStyle = true;
                $('body').removeClass('drawCur');
            }
        });
        handlerPolygon.movingEvt.addEventListener(function (windowPosition) {
            if (handlerPolygon.isDrawing) {
                tooltip.showAt(windowPosition, '<p>绘制相交区域(右键结束绘制)</p>');
            }
        });

        handlerPolygon.drawEvt.addEventListener(function (result) {
            tooltip.setVisible(false);

            var array = [].concat(result.object.positions);
            var positions = [];
            for (var i = 0, len = array.length; i < len; i++) {

                var cartographic = SuperMap3D.Cartographic.fromCartesian(array[i]);
                var longitude = SuperMap3D.Math.toDegrees(cartographic.longitude);
                var latitude = SuperMap3D.Math.toDegrees(cartographic.latitude);
                var h = cartographic.height;
                if (positions.indexOf(longitude) == -1 && positions.indexOf(latitude) == -1) {
                    positions.push(longitude);
                    positions.push(latitude);
                    positions.push(h);
                }
            }
            handlerPolygon.polygon.show = false;
            handlerPolygon.polyline.show = false;
            viewshed3D.addClipRegion({name: 'test', position: positions});
            handlerPolygon.deactivate();
        });

        pointHandler.drawEvt.addEventListener(function (result) {
            // var point = result.object;
            var position = result.object.position;
            viewPosition = position;

            // 将获取的点的位置转化成经纬度
            var cartographic = Cesium.Cartographic.fromCartesian(position);
            var longitude = Cesium.Math.toDegrees(cartographic.longitude);
            var latitude = Cesium.Math.toDegrees(cartographic.latitude);
            var height = cartographic.height + 1.8;
            // point.position = SuperMap3D.Cartesian3.fromDegrees(longitude, latitude, height);

            if (scene.viewFlag) {
                // 设置视口位置
                viewshed3D.viewPosition = [longitude, latitude, height];
                viewshed3D.build();
                // 将标记置为false以激活鼠标移动回调里面的设置可视域操作
                scene.viewFlag = false;
            }
        });
       
        var viewModel = {
            direction: 1.0,
            pitch: 1.0,
            distance: 1.0,
            verticalFov: 1.0,
            horizontalFov: 1.0,
            visibleAreaColor: '#ffffffff',
            invisibleAreaColor: '#ffffffff'
        };

        SuperMap3D.knockout.track(viewModel);
        var toolbar = document.getElementById('wrapper');
        SuperMap3D.knockout.applyBindings(viewModel, toolbar);
        SuperMap3D.knockout.getObservable(viewModel, 'direction').subscribe(
            function (newValue) {
                if(viewshed3D.direction !== parseFloat(newValue)){
                    viewshed3D.direction = parseFloat(newValue);
                    viewshed3D.removeClipRegion('test');
                }
            }
        );
        SuperMap3D.knockout.getObservable(viewModel, 'pitch').subscribe(
            function (newValue) {
                if(viewshed3D.pitch !== parseFloat(newValue)){
                    viewshed3D.pitch = parseFloat(newValue);
                    viewshed3D.removeClipRegion('test');
                }
            }
        );
        SuperMap3D.knockout.getObservable(viewModel, 'distance').subscribe(
            function (newValue) {
                if(viewshed3D.distance !== parseFloat(newValue)){
                    viewshed3D.distance = parseFloat(newValue);
                    viewshed3D.removeClipRegion('test');
                }
            }
        );
        SuperMap3D.knockout.getObservable(viewModel, 'verticalFov').subscribe(
            function (newValue) {
                if(viewshed3D.verticalFov !== parseFloat(newValue)){
                    viewshed3D.verticalFov = parseFloat(newValue);
                    viewshed3D.removeClipRegion('test');
                }
            }
        );
        SuperMap3D.knockout.getObservable(viewModel, 'horizontalFov').subscribe(
            function (newValue) {
                if(viewshed3D.horizontalFov !== parseFloat(newValue)){
                    viewshed3D.horizontalFov = parseFloat(newValue);
                    viewshed3D.removeClipRegion('test');
                }
            }
        );
        SuperMap3D.knockout.getObservable(viewModel, 'visibleAreaColor').subscribe(
            function (newValue) {
                var color = SuperMap3D.Color.fromCssColorString(newValue);
                viewshed3D.visibleAreaColor = color;
            }
        );
        SuperMap3D.knockout.getObservable(viewModel, 'invisibleAreaColor').subscribe(
            function (newValue) {
                var color = SuperMap3D.Color.fromCssColorString(newValue);
                viewshed3D.hiddenAreaColor = color;
            }
        );

        $("#colorPicker1").spectrum({
            color: colorStr1,
            showPalette: true,
            showAlpha: true,
            localStorageKey: "spectrum.demo",
            preferredFormat:'rgb'
        });
        $('#colorPicker2').spectrum({
            color: colorStr2,
            showPalette: true,
            showAlpha: true,
            localStorageKey: "spectrum.demo",
            preferredFormat:'rgb'
        });
        $(".close").click(function () {
            $("#wrapper").hide();
        });

        $("#chooseView").click(function (e) {
            if (pointHandler.active) {
                return;
            }
            //先清除之前的可视域分析
            // viewer.entities.removeAll();
            viewshed3D.distance = 0.1;
            scene.viewFlag = true;

            //激活绘制点类
            pointHandler.activate();
        });

        $("#clip-mode").on("input propertychange", function () {
            clipMode = $(this).val() === 'keep-inside' ? SuperMap3D.ClippingType.KeepInside : SuperMap3D.ClippingType.KeepOutside;
            viewshed3D.setClipMode(clipMode);
        });

        $("#cilpRegion").click(function (e) {
            handlerPolygon.deactivate();
            handlerPolygon.activate();
        });

        $("#clear").on("click", function () {
            viewshed3D.removeAllClipRegion();

            // 清除观察点
            pointHandler.clear()

            $("#wrapper").hide();
            viewshed3D.distance = 0.1;
            scene.viewFlag = true;
        })
        $('#loadingbar').remove();
        $("#toolbar").show();
    }

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

</html>

注意替换Cesium.Ion.defaultAccessToken,以及天地图官网申请的密钥 

5.效果展示:

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

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

相关文章

设置 AutoCAD双击 DWG 文件时启动新的程序

1 问题描述 原CAD打开多个文件时&#xff0c;会在该程序打开新的标签&#xff0c;合并显示。 有时想打开新文件时启动新的程序&#xff0c;单独显示&#xff0c;如下&#xff1a; 2 解决办法 2.1 方法1 SDI变量可以将CAD设置成单文档模式&#xff0c;设置为1的时候就能实…

音视频直播应用场景探讨之RTMP推流还是GB28181接入?

技术背景 好多开发者跟我们沟通音视频解决方案的时候&#xff0c;不清楚什么时候用RTMP推送模块&#xff0c;什么时候用GB28181设备接入模块&#xff0c;也不清楚二者差异化。实际上&#xff0c;RTMP推流和GB28181接入模块&#xff0c;在很多方面存在差异&#xff0c;如应用领…

IPC之AIDL从认识到实战

目录 前言 什么是AIDL? 为什么要设计出这样一种语言&#xff1f;它能帮助我们干什么&#xff1f; 还有其他方法能实现跨进程通信吗&#xff1f;相较于别的方法AIDL有什么优势呢&#xff1f; AIDL的相关语法 Java与AIDL的不同之处 AIDL默认支持的数据类型&#xff1a; …

怎么浏览URL的PDF文件呢

最近发现PDF文件网页端打开就是丑&#xff0c;不知道怎么办 1. 看着实在不舒服&#xff0c;用chorm的插件 然后原本本地用的也是2345pdf阅读器 2. 之后也下载了adobe pdf的桌面阅读器 2345打开是这个样子 这个是现在啦 如果要一些安装包什么的&#xff0c;评论见~ 最…

相机光学(三十八)——VCM(Voice Coil Motor)音圈马达

VCM&#xff08;Voice Coil Motor&#xff09;音圈马达 0.参考链接1.什么是音圈马达2.对焦&#xff08;变焦&#xff09;原理3.音圈马达结构4.音圈马达工作原理5.VCM 主要性能指标 0.参考链接 &#xff08;1&#xff09;Camera 模组之 VCM篇 &#xff08;2&#xff09;VCM基本…

08 vue3之认识bem架构及less sass 和scoped

bem架构 他是一种css架构 oocss 实现的一种 &#xff08;面向对象css&#xff09; &#xff0c;BEM实际上是block、element、modifier的缩写&#xff0c;分别为块层、元素层、修饰符层&#xff0c;element UI 也使用的是这种架构 1. BEM架构 1. 介绍 1. BEM是Block Element M…

PowerBI 关于FILTERS函数和VALUES函数

本人是powerbi新手&#xff0c;最近在使用Filters()函数和Values()函数时&#xff0c;有点不太明白它们之间的区别&#xff0c;u有时它们得到的结果是一样的&#xff0c;有时却不一样。 官方文档里&#xff0c;Filters()是表示返回直接作为筛选器应用到 columnName 的值 FILT…

MinIO - macOS上配置、Python调用

文章目录 安装配置 MinIO 服务Python 调用SDK 简介调用示例 安装配置 MinIO 服务 1、使用 brew 安装 MinIO 如果您之前使用 brew install minio 安装了MinIO服务器&#xff0c;那么我们建议您改为从 minio/stable/minio 重新安装。 brew install minio/stable/minio2、创建文…

YOLOv5/v8 + 双目相机测距

yolov5/v8双目相机测距的代码&#xff0c;需要相机标定 可以训练自己的模型并检测测距&#xff0c;都是python代码 已多次实验&#xff0c;代码无报错。 非常适合做类似的双目课题&#xff01; 相机用的是汇博视捷的双目相机&#xff0c;具体型号见下图。 用的yolov5是6.1版本的…

Spring Boot集成Akka remoting快速入门Demo

1.什么是Akka remoting&#xff1f; Akka-Remoting一种ActorSystem之间Actor对Actor点对点的沟通协议.通过Akka-Remoting来实现一个ActorSystem中的一个Actor与另一个ActorSystem中的另一个Actor之间的沟通 Akka Remoting限制&#xff1a; 不支持NAT&#xff08;Network Add…

使用Java实现一个简单的B树

1.B树简介 B树是一个搜索树&#xff0c;数据结构可以抽象成如二叉树一样的树&#xff0c;不过它有平衡、有序、多路的特点。 平衡&#xff1a;所有叶子节点都在同一层。有序&#xff1a;任一元素的左子树都小于它&#xff0c;右子树都大于它。多路&#xff1a;B树的每个节点最多…

深入链表的遍历——快慢指针算法(LeetCode——876题)

今天我们一起来学习一下一个快速遍历链表的方法 我们先来看看一道经典的需要遍历链表的题目 &#xff08;题目来自LeetCode&#xff09; 876. 链表的中间结点https://leetcode.cn/problems/middle-of-the-linked-list/ 给你单链表的头结点 head &#xff0c;请你找出并返回链…

C++多态 学习

目录 一、多态的概念 二、多态的实现 三、纯虚函数和多态类 四、多态的原理 一、多态的概念 多态&#xff1a;多态分为编译时多态(静态多态)和运行时多态(动态多态)。编译时多态主要是我们之前学过的函数重载和函数模板&#xff0c;他们在传不同类型的参数就可以调用不同的函…

diff 命令:文本比较

一、diff 命令简介 ​diff ​命令是一个用于比较两个文件并输出它们之间差异的工具。它是文件比较的基本工具&#xff0c;广泛用于源代码管理、脚本编写和日常的文件维护工作中。 ‍ 二、diff 命令参数 diff [选项] 文件1 文件2选项&#xff1a; ​-b​ 或 --ignore-space…

光伏选址和设计离不开气象分析!

都说光伏选址和设计离不开气象分析&#xff0c;气象条件对太阳能发电影响较大&#xff0c;具体有哪些影响呢&#xff1f;今天我就来讲解下。 - 太阳辐射&#xff1a;太阳辐射的强度是光伏发电的首要因素&#xff0c;对光伏发电有着重要的影响。太阳辐射的强度决定了光伏发电系…

信息安全数学基础(14)欧拉函数

前言 在信息安全数学基础中&#xff0c;欧拉函数&#xff08;Eulers Totient Function&#xff09;是一个非常重要的概念&#xff0c;它与模运算、剩余类、简化剩余系以及密码学中的许多应用紧密相关。欧拉函数用符号 φ(n) 表示&#xff0c;其中 n 是一个正整数。 一、定义 欧…

LVGL学习

注&#xff1a;本文使用的lvgl-release-v8.3版本&#xff0c;其它版本可能稍有不同。 01 LVGL模拟器配置 day01-02_课程介绍_哔哩哔哩_bilibili LVGL开发教程 (yuque.com) 如果按照上述视频和文档中配置不成功的话&#xff0c;直接重装VsCode&#xff0c;我的就是重装以后就…

[Visual Stuidio 2022使用技巧]2.配置及常用快捷键

使用vs2022开发WPF桌面程序时常用配置及快捷键。 语言&#xff1a;C# IDE&#xff1a;Microsoft Visual Studio Community 2022 框架&#xff1a;WPF&#xff0c;.net 8.0 一、配置 1.1 内联提示 未开启时&#xff1a; 开启后&#xff1a; 开启方法&#xff1a; 工具-选…

torch.linspace() torch.arange() torch.stack() 函数详解

1 torch.linspace函数详解 torch.linspace(start, end, steps100, outNone, dtypeNone, layouttorch.strided, deviceNone, requires_gradFalse) → Tensor 函数的作用是&#xff0c;返回一个一维的tensor&#xff08;张量&#xff09;&#xff0c;这个张量包含了从start到end…

【专题】2024新能源企业“出海”系列之驶向中东、东南亚报告合集PDF分享(附原数据表)

原文链接&#xff1a; https://tecdat.cn/?p37698 在“双碳”目标引领下&#xff0c;中国新能源产业近年迅猛发展&#xff0c;新能源企业凭借技术革新、政策支持与市场驱动实现快速增长&#xff0c;在产业链完备、技术领先、生产效能及成本控制等方面优势显著。面对国内外环境…