CesiumJS 案例 P15:检测标记、鼠标点击移动标记、鼠标拖动标记

CesiumJS


一、检测标记

html 复制代码
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Billboard - 检测标记</title>
		<link rel="stylesheet" href="../js/Cesium-1.112/Build/Cesium/Widgets/widgets.css" />
		<style>
			* {
				margin: 0;
				padding: 0;
				box-sizing: border-box;
			}

			html,
			body {
				width: 100%;
				height: 100%;
			}

			.container {
				width: 100%;
				height: 100%;
			}

			.btn-remove-marker {
				position: fixed;
				left: 0px;
				top: 0px;
			}

			.btn-check-marker {
				position: fixed;
				left: 0px;
				top: 50px;
			}
		</style>
	</head>

	<body>
		<div id="container"></div>
		<button class="btn-remove-marker">删除标记</button>
		<button class="btn-check-marker">检测标记</button>
	</body>

	<script src="../js/Cesium-1.112/Build/Cesium/Cesium.js"></script>
	<script>
		const viewer = new Cesium.Viewer("container");

		const billboards = viewer.scene.primitives.add(new Cesium.BillboardCollection());

		const billboard = billboards.add({
			image: "../img/marker-icon.png",
			position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
			verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
		});

		const btnRemoveMarker = document.querySelector(".btn-remove-marker");
		const btnCheckMarker = document.querySelector(".btn-check-marker");

		btnRemoveMarker.addEventListener("click", () => {
			billboards.remove(billboard);
		});

		btnCheckMarker.addEventListener("click", () => {
			console.log(billboards.contains(billboard));
		});
	</script>
</html>

二、鼠标点击移动标记

html 复制代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Billboard - 鼠标点击移动标记</title>
        <link rel="stylesheet" href="../js/Cesium-1.112/Build/Cesium/Widgets/widgets.css" />
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }

            html,
            body {
                width: 100%;
                height: 100%;
            }

            .container {
                width: 100%;
                height: 100%;
            }
        </style>
    </head>

    <body>
        <div id="container"></div>
    </body>

    <script src="../js/Cesium-1.112/Build/Cesium/Cesium.js"></script>
    <script>
        const viewer = new Cesium.Viewer("container");

        const billboards = viewer.scene.primitives.add(new Cesium.BillboardCollection());

        const billboard = billboards.add({
            id: "billboard-test",
            image: "../img/marker-icon.png",
            position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        });

        let isSelect = false;

        viewer.screenSpaceEventHandler.setInputAction((click) => {
            if (isSelect) {
                // 获取左击位置的射线
                const pickRay = viewer.camera.getPickRay(click.position);

                // 在地球表面找到与射线相交的点
                const pickPosition = viewer.scene.globe.pick(pickRay, viewer.scene);

                if (Cesium.defined(pickPosition)) {
                    // 如果找到了交点,将其转换为地理弧度坐标(Cartographic)
                    const cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(pickPosition);

                    // 这里转换成直观的地理度数坐标
                    console.log("落点在地球球面,地理坐标为:", Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude));

                    // 将地理弧度坐标(Cartographic)转换为笛卡尔坐标(Cartesian3)
                    const cartesian3 = Cesium.Ellipsoid.WGS84.cartographicToCartesian(cartographic);

                    billboard.position = cartesian3;
                } else {
                    console.log("落点不在地球球面");

                    alert("落点不在地球球面,请重新操作");
                }
                
                isSelect = false;

                return;
            }

            const pickedObject = viewer.scene.pick(click.position);

            if (Cesium.defined(pickedObject) && pickedObject.id === "billboard-test") {
                console.log("点击了标记!!!");
                isSelect = true;
            } else {
                console.log("未点击标记");
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    </script>
</html>

三、鼠标拖动标记

html 复制代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Billboard - 鼠标拖动标记</title>
        <link rel="stylesheet" href="../js/Cesium-1.112/Build/Cesium/Widgets/widgets.css" />
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }

            html,
            body {
                width: 100%;
                height: 100%;
            }

            .container {
                width: 100%;
                height: 100%;
            }
        </style>
    </head>

    <body>
        <div id="container"></div>
    </body>

    <script src="../js/Cesium-1.112/Build/Cesium/Cesium.js"></script>
    <script>
        const viewer = new Cesium.Viewer("container");

        const billboards = viewer.scene.primitives.add(new Cesium.BillboardCollection());

        const billboard = billboards.add({
            id: "billboard-test",
            image: "../img/marker-icon.png",
            position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        });

        let isSelect = false;
        let originPositon;

        viewer.screenSpaceEventHandler.setInputAction((click) => {
            if (isSelect) {
                // 获取左击位置的射线
                const pickRay = viewer.camera.getPickRay(click.position);

                // 在地球表面找到与射线相交的点
                const pickPosition = viewer.scene.globe.pick(pickRay, viewer.scene);

                if (Cesium.defined(pickPosition)) {
                    // 如果找到了交点,将其转换为地理弧度坐标(Cartographic)
                    const cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(pickPosition);

                    // 这里转换成直观的地理度数坐标
                    console.log("落点在地球球面,地理坐标为:", Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude));

                    // 将地理弧度坐标(Cartographic)转换为笛卡尔坐标(Cartesian3)
                    const cartesian3 = Cesium.Ellipsoid.WGS84.cartographicToCartesian(cartographic);

                    billboard.position = cartesian3;
                } else {
                    console.log("落点不在地球球面");

                    alert("落点不在地球球面,请重新操作");

                    billboard.position = originPositon;
                }

                isSelect = false;

                return;
            }

            const pickedObject = viewer.scene.pick(click.position);

            if (Cesium.defined(pickedObject) && pickedObject.id === "billboard-test") {
                console.log("点击了标记!!!");
                isSelect = true;
                originPositon = billboard.position.clone();
            } else {
                console.log("未点击标记");
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        viewer.screenSpaceEventHandler.setInputAction((movement) => {
            if (!isSelect) return;

            const pickRay = viewer.camera.getPickRay(movement.endPosition);
            const pickPosition = viewer.scene.globe.pick(pickRay, viewer.scene);
            if (Cesium.defined(pickPosition)) {
                const cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(pickPosition);
                console.log("移动位置在地球球面,地理坐标为:", Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude));
                const cartesian3 = Cesium.Ellipsoid.WGS84.cartographicToCartesian(cartographic);
                billboard.position = cartesian3;
            } else {
                console.log("移动位置不在地球球面");
                alert("移动位置不在地球球面,请重新操作");
                billboard.position = originPositon;
                isSelect = false;
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    </script>
</html>
相关推荐
辰风沐阳6 分钟前
JavaScript 的宏任务和微任务
javascript
夏幻灵1 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星1 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_1 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝1 小时前
RBAC前端架构-01:项目初始化
前端·架构
程序员agions1 小时前
2026年,微前端终于“死“了
前端·状态模式
万岳科技系统开发1 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
程序员猫哥_2 小时前
HTML 生成网页工具推荐:从手写代码到 AI 自动生成网页的进化路径
前端·人工智能·html
龙飞052 小时前
Systemd -systemctl - journalctl 速查表:服务管理 + 日志排障
linux·运维·前端·chrome·systemctl·journalctl
我爱加班、、2 小时前
Websocket能携带token过去后端吗
前端·后端·websocket