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>
相关推荐
uhakadotcom16 分钟前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom20 分钟前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom21 分钟前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom30 分钟前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom40 分钟前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试
LaoZhangAI2 小时前
2025最全GPT-4o图像生成API指南:官方接口配置+15个实用提示词【保姆级教程】
前端
ONE_Gua2 小时前
chromium魔改——CDP(Chrome DevTools Protocol)检测01
前端·后端·爬虫
LaoZhangAI2 小时前
2025最全Cherry Studio使用MCP指南:8种强大工具配置方法与实战案例
前端
咖啡教室2 小时前
前端开发日常工作每日记录笔记(2019至2024合集)
前端·javascript
溪饱鱼2 小时前
Nuxt3能上生产吗?
前端