当前位置:网站首页>Threejs realizes the drawing of the earth, geographical location annotation, longitude and latitude conversion of world coordinates threejs coordinates

Threejs realizes the drawing of the earth, geographical location annotation, longitude and latitude conversion of world coordinates threejs coordinates

2022-07-05 04:00:00 Zuo Ben

1, Introduce

This example uses r95 edition Three.js library .

Main functions : Draw the earth and geographical location for annotation  

The renderings are as follows : 

2, Main description  

Prepare a map , Create a sphere and map it , Convert the longitude and latitude of the geographical location into threejs The world coordinates of , And mark it .

Create the earth , Part of the code is as follows :

//  Create the earth   radius 100
function createEarth() {
	var earthGeo = new THREE.SphereGeometry(radius, 50, 50);
	var earthMater = new THREE.MeshPhongMaterial({
		map: new THREE.TextureLoader().load('assets/earth/earth3.jpg'),
		transparent: true,
		depthWrite: false,
		side: THREE.DoubleSide,
		blending: THREE.AdditiveBlending,
		opacity: 0.8,
		color: 0x03d98e
	});
	var earthMesh = new THREE.Mesh(earthGeo, earthMater);
	scene.add(earthMesh)
}

Longitude and latitude are converted into threejs coordinate ( Also called right-hand coordinate system ) 

 Picture description

 phi It's the azimuth ( level ) The angle inside , Range 0~360 degree ,theta It's the pitch plane ( Vertical plane ) The angle inside , Range 0~180 degree 、 It's two parameters in the space polar coordinate system , And analogy in Cartesian coordinates xyz

threejs Implement transformation , The code is as follows :

//  Coordinate transformation ,
function createPosition(lnglat) {
	let spherical = new THREE.Spherical
	spherical.radius = radius;
	const lng = lnglat[0]
	const lat = lnglat[1]
	const theta = (lng + 90) * (Math.PI / 180)
	const phi = (90 - lat) * (Math.PI / 180)
	spherical.phi = phi; // phi It's the azimuth ( level ) The angle inside , Range 0~360 degree 
	spherical.theta = theta; // theta It's the pitch plane ( Vertical plane ) The angle inside , Range 0~180 degree 
	let position = new THREE.Vector3()
	position.setFromSpherical(spherical)
	return position
}

 3, Source code

<!DOCTYPE html>
<html>
	<head>
		<title>Threejs Realize drawing the earth , Geographical location annotation - Longitude and latitude transform world coordinates </title>
		<script type="text/javascript" src="libs/three.js"></script>
		<script type="text/javascript" src="libs/OrbitControls.js"></script>
		<style>
			body {
				margin: 0;
				overflow: hidden;
			}
		</style>
	</head>
	<body>
		<div id="dom"></div>
		<script type="text/javascript">
			var camera;
			var renderer;
			var radius = 100; //  Earth radius 
			var areas = [{
				name: " China ",
				position: [116.20, 39.55]
			}, {
				name: " Central African Republic ",
				position: [18.35, 4.23]
			}, {
				name: " Chile ",
				position: [-70.40, -33.24]
			}, {
				name: " Chad ",
				position: [14.59, 12.10]
			}, {
				name: " Zambia ",
				position: [28.16, -15.28]
			}, {
				name: " Vietnam ",
				position: [105.55, 21.05]
			}, {
				name: " Jordan ",
				position: [35.52, 31.57]
			}, {
				name: " The British Virgin Islands ",
				position: [-64.37, 18.27]
			}, {
				name: " The British ",
				position: [-0.05, 51.36]
			}];

			function init() {
				//  Create a scene , It will contain all our elements , Like an object , Cameras and lights .
				var scene = new THREE.Scene();

				var urls = [
					'assets/textures/cubemap/flowers/posx.jpg',
					'assets/textures/cubemap/flowers/negx.jpg',
					'assets/textures/cubemap/flowers/posy.jpg',
					'assets/textures/cubemap/flowers/negy.jpg',
					'assets/textures/cubemap/flowers/posz.jpg',
					'assets/textures/cubemap/flowers/negz.jpg'
				];

				var cubeLoader = new THREE.CubeTextureLoader();
				// scene.background = cubeLoader.load(urls);

				//  Create a camera , It defines where we are looking 
				camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
				//  Aim the camera at the center of the scene 
				camera.position.z = 500;
				camera.lookAt(scene.position);
				var orbit = new THREE.OrbitControls(camera);

				//  Create a renderer and set the size ,WebGLRenderer The computer graphics card will be used to render the scene 
				renderer = new THREE.WebGLRenderer({
					antialias: true,
					logarithmicDepthBuffer: true,
				});
				renderer.setSize(window.innerWidth, window.innerHeight);
				// scene.add(new THREE.AmbientLight(0x666666));

				var ambientLight = new THREE.AmbientLight("#ffffff", 1);
				scene.add(ambientLight);

				//  Display the coordinate axis on the screen 
				var axes = new THREE.AxisHelper(radius);
				scene.add(axes);

				//  Add planes to the scene 
				var plane = createPlaneGeometryBasicMaterial();
				// scene.add(plane);

				// initSphere(10, 0, 10);
				createEarth();
				createAreaPoint();

				var rs = coordinateWorldTurnScreen(10, 0, 10);
				var div = document.createElement('div');
				div.innerHTML = ' state ';
				div.style.padding = '5px';
				div.style.position = 'absolute';
				div.style.backgroundColor = 'rgba(155,0,155,0.8)';
				document.body.appendChild(div);
				div.style.left = rs.x + "px";
				div.style.top = rs.y + "px";
				console.log(rs)

				//  Add the output of the renderer to HTML Elements 
				document.getElementById("dom").appendChild(renderer.domElement);

				//  Start animation 
				renderScene();

				/**
				 *  Create the ground and add materials 
				 * wrapS Attributes define the texture along x Axial behavior , and warpT Attributes define the texture along y Axial behavior .
				 * Three.js The following two options are provided for these attributes :
				 * ·THREE.RepeatWrapping Allow the texture to repeat itself .
				 * ·THREE.ClampToEdgeWrapping Is the default value of the attribute .
				 *  The property value is THREE.ClampToEdgeWrapping when , Then the whole texture will not repeat , Only the pixels at the edge of the texture will be repeated to fill the remaining space .
				 */
				function createPlaneGeometryBasicMaterial() {
					var textureLoader = new THREE.TextureLoader();
					var cubeMaterial = new THREE.MeshStandardMaterial({
						map: textureLoader.load("assets/textures/stone/cd.jpg"),
					});
					cubeMaterial.map.wrapS = THREE.RepeatWrapping;
					cubeMaterial.map.wrapT = THREE.RepeatWrapping;
					cubeMaterial.map.repeat.set(8, 8)
					//  Create the ground plane and set the size 
					var planeGeometry = new THREE.PlaneGeometry(100, 100);
					var plane = new THREE.Mesh(planeGeometry, cubeMaterial);

					//  Set the plane position and rotate 
					plane.rotation.x = -0.5 * Math.PI;
					plane.position.x = 0;
					plane.position.z = 0;
					return plane;
				}

				//  World coordinates to screen coordinates 
				function coordinateWorldTurnScreen(x, y, z) {
					let world_vector = new THREE.Vector3(x, y, z);
					let vector = world_vector.project(camera);
					let halfWidth = window.innerWidth / 2,
						halfHeight = window.innerHeight / 2;
					return {
						x: Math.round(vector.x * halfWidth + halfWidth),
						y: Math.round(-vector.y * halfHeight + halfHeight)
					}
				}

				//  Create the earth   radius 100
				function createEarth() {
					var earthGeo = new THREE.SphereGeometry(radius, 50, 50);
					var earthMater = new THREE.MeshPhongMaterial({
						map: new THREE.TextureLoader().load('assets/earth/earth3.jpg'),
						transparent: true,
						depthWrite: false,
						side: THREE.DoubleSide,
						blending: THREE.AdditiveBlending,
						opacity: 0.8,
						color: 0x03d98e
					});
					var earthMesh = new THREE.Mesh(earthGeo, earthMater);
					scene.add(earthMesh)
				}

				function createAreaPoint() {
					//  sphere 
					let sphereGeom = new THREE.SphereGeometry(1, 20, 20),
						sphereMat = new THREE.MeshBasicMaterial({
							color: 0x03d98e,
							wireframe: true
						})
					let sphere = new THREE.Mesh(sphereGeom, sphereMat)
					scene.add(sphere)
					//  Landmarks and light cones 
					for (let i = 0, length = areas.length; i < length; i++) {
						const position = createPosition(this.areas[i].position)
						createHexagon(position); //  landmark 
					}
				}

				//  Coordinate transformation ,
				function createPosition(lnglat) {
					let spherical = new THREE.Spherical
					spherical.radius = radius;
					const lng = lnglat[0]
					const lat = lnglat[1]
					const theta = (lng + 90) * (Math.PI / 180)
					const phi = (90 - lat) * (Math.PI / 180)
					spherical.phi = phi; // phi It's the azimuth ( level ) The angle inside , Range 0~360 degree 
					spherical.theta = theta; // theta It's the pitch plane ( Vertical plane ) The angle inside , Range 0~180 degree 
					let position = new THREE.Vector3()
					position.setFromSpherical(spherical)
					return position
				}

				//  Create landmark markers 
				function createHexagon(position) {
					var hexagon = new THREE.Object3D()
					let hexagonLine = new THREE.CircleGeometry(4, 6)
					let hexagonPlane = new THREE.CircleGeometry(3, 6)
					let vertices = hexagonLine.vertices
					vertices.shift() //  The first node is the central point 
					let material = new THREE.MeshBasicMaterial({
						color: 0xffff00,
						side: THREE.DoubleSide,
						opacity: 0.5
					})
					let circleLine = new THREE.LineLoop(hexagonLine, material)
					let circlePlane = new THREE.Mesh(hexagonPlane, material)
					circleLine.position.copy(position)
					circlePlane.position.copy(position)
					circlePlane.lookAt(new THREE.Vector3(0, 0, 0))
					circleLine.lookAt(new THREE.Vector3(0, 0, 0))

					hexagon.add(circleLine)
					hexagon.add(circlePlane)
					scene.add(hexagon);
				}

				//  Initial sphere 
				function initSphere(x, y, z) {
					var geometry = new THREE.SphereGeometry(1, 100, 100); // Sphere geometry 
					var material = new THREE.MeshBasicMaterial({
						color: 0xffff00
					}); // Grid base material 

					var sphere = new THREE.Mesh(geometry, material);
					sphere.position.x = x;
					sphere.position.y = y;
					sphere.position.z = z;
					scene.add(sphere);
				}

				function renderScene() {
					orbit.update();
					//  Use requestAnimationFrame Function to render 
					requestAnimationFrame(renderScene);
					renderer.render(scene, camera);
				}

				//  Rendered scenes 
				renderer.render(scene, camera);
			}
			window.onload = init;

			//  Modify the scene as the form changes 
			function onResize() {
				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();
				renderer.setSize(window.innerWidth, window.innerHeight);
			}
			//  Listen for form resizing events 
			window.addEventListener('resize', onResize, false);
		</script>
	</body>
</html>

  If you need a complete code, please leave a message or contact me on wechat :1171053128

原网站

版权声明
本文为[Zuo Ben]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140717140947.html