1,介绍

该示例使用的是 r95版本Three.js库。

主要实现功能:绘制地球和地理位置进行标注

效果图如下:

2,主要说明

准备一张地图,创建一个球体并进行贴图,把地理位置经纬度转换成threejs的世界坐标,并进行标注。

创建地球,部分代码如下:

// 创建地球 半径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)
}

经纬度转换成threejs坐标(也叫右手坐标系)

phi是方位面(水平面)内的角度,范围0~360度,theta是俯仰面(竖直面)内的角度,范围0~180度、就是空间极坐标系中的两个参数,和类比直角坐标系里的xyz

threejs实现转换,代码如下:

// 坐标转换,
function createPosition(lnglat) {let spherical = new THREE.Sphericalspherical.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是方位面(水平面)内的角度,范围0~360度spherical.theta = theta; // theta是俯仰面(竖直面)内的角度,范围0~180度let position = new THREE.Vector3()position.setFromSpherical(spherical)return position
}

3,源码

<!DOCTYPE html>
<html><head><title>Threejs实现绘制地球,地理位置标注-经纬度转换世界坐标</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; // 地球半径var areas = [{name: "中国",position: [116.20, 39.55]}, {name: "中非共和国",position: [18.35, 4.23]}, {name: "智利",position: [-70.40, -33.24]}, {name: "乍得",position: [14.59, 12.10]}, {name: "赞比亚",position: [28.16, -15.28]}, {name: "越南",position: [105.55, 21.05]}, {name: "约旦",position: [35.52, 31.57]}, {name: "英属维尔京群岛",position: [-64.37, 18.27]}, {name: "英国",position: [-0.05, 51.36]}];function init() {// 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。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);// 创建一个摄像机,它定义了我们正在看的地方camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);// 将摄像机对准场景的中心camera.position.z = 500;camera.lookAt(scene.position);var orbit = new THREE.OrbitControls(camera);// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景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);// 在屏幕上显示坐标轴var axes = new THREE.AxisHelper(radius);scene.add(axes);// 将平面添加到场景中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 = '立';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)// 将呈现器的输出添加到HTML元素document.getElementById("dom").appendChild(renderer.domElement);// 启动动画renderScene();/*** 创建地面并添加材质* wrapS属性定义的是纹理沿x轴方向的行为,而warpT属性定义的是纹理沿y轴方向的行为。* Three.js为这些属性提供了如下两个选项:* ·THREE.RepeatWrapping允许纹理重复自己。* ·THREE.ClampToEdgeWrapping是属性的默认值。* 属性值为THREE.ClampToEdgeWrapping时,那么纹理的整体不会重复,只会重复纹理边缘的像素来填满剩下的空间。*/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)// 创建地平面并设置大小var planeGeometry = new THREE.PlaneGeometry(100, 100);var plane = new THREE.Mesh(planeGeometry, cubeMaterial);// 设置平面位置并旋转plane.rotation.x = -0.5 * Math.PI;plane.position.x = 0;plane.position.z = 0;return plane;}// 世界坐标转屏幕坐标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)}}// 创建地球 半径100function 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() {// 球面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)// 地标及光锥for (let i = 0, length = areas.length; i < length; i++) {const position = createPosition(this.areas[i].position)createHexagon(position); // 地标}}// 坐标转换,function createPosition(lnglat) {let spherical = new THREE.Sphericalspherical.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是方位面(水平面)内的角度,范围0~360度spherical.theta = theta; // theta是俯仰面(竖直面)内的角度,范围0~180度let position = new THREE.Vector3()position.setFromSpherical(spherical)return position}// 创建地标标记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.verticesvertices.shift() // 第一个节点是中心点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);}// 初始球体function initSphere(x, y, z) {var geometry = new THREE.SphereGeometry(1, 100, 100); //球体几何var material = new THREE.MeshBasicMaterial({color: 0xffff00}); //网格基础材料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();// 使用requestAnimationFrame函数进行渲染requestAnimationFrame(renderScene);renderer.render(scene, camera);}// 渲染的场景renderer.render(scene, camera);}window.onload = init;// 随着窗体的变化修改场景function onResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}// 监听窗体调整大小事件window.addEventListener('resize', onResize, false);</script></body>
</html>

在线预览:左本的博客 (zuoben.top)

Threejs实现绘制地球,地理位置标注、经纬度转换世界坐标threejs坐标相关推荐

  1. oracle经纬度换算成xy坐标,谁有全套经纬度转换成XY坐标的好的软件?

    用的实施么地图?标准地形图吗? 如果是标准地形图,还是有办法转化的,因为用的是高斯-克吕格投影 该投影按照投影带中央子午线投影为直线且长度不变和赤道投影为直线的条件,确定函数的形式,从而得到高斯一克吕 ...

  2. threejs-经纬度转换成xyz坐标的方法

    用threejs做3D应用时,很经常会接触到球状物体,比如说地球,要定义球上的一点,用经纬度是常用的办法.现在,我们要在北京这个地方标一个点,北京的坐标为--北纬39.9",东经116. 3 ...

  3. threejs 绘制球体_实战:用 threejs 创建一个地球

    原标题:实战:用 threejs 创建一个地球 提示: 讲座 前端大型免费公开课讲座 教程 从零基础学前端教程,都在这~ 上个月底,在朋友圈看到一个号称"这可能是地球上最美的h5" ...

  4. 经纬度转换成地理位置

    项目有一个需求,就是把经纬度转换成具体的地理位置.开始准备用百度地图的jar方式去,不过这种方式有一个缺陷,会给app带来很大的增量.于是研究了下放弃了这种方式. 于是采用第二种方式,通过百度地图提供 ...

  5. PHP3d地球,three.js绘制地球、飞机与轨迹的效果示例

    对于three.js不太熟悉的朋友们可以参考这篇文章,threejs官网:https://threejs.org/ 首先我们来看下要实现的效果 这个缩小后的图片,下面我们来看下近距离的动态效果.. 效 ...

  6. js 封装经纬度成json_R实现地理位置与经纬度相互转换

    原标题:R实现地理位置与经纬度相互转换 本实例要实现目标通过输入城市名或者地名,然后找出其经度纬度值,以及通过可视化展现其线路流向以及周边地图展示 address_list数据: 山西省太原市小店区亲 ...

  7. SPARK 笔记 (五) 经纬度转换地址

    经纬度转换地址 anssin用的是高德地图,实现逆地理位置,首先需要去高德地图开放平台(https://lbs.amap.com/)获取key 我的key就不分享给大家了 逆地理位置用的是http请求 ...

  8. 经纬度转换成屏幕坐标

    学期projet总结: 当把点的数据和线的数据读进来之后,为了画出地图还有最重要的一步就是把实际的经纬度转换成屏幕像素点的坐标.在找老师讨论之前,我在网上查资料,找到了下边链接的文章,并按照这个方法画 ...

  9. 1、地球图 - 绘制地球、轮廓流光效果、添加光晕轮廓效果并自转

    我们实现标题中的效果基本分为接下来的这些功能点,如果看过"Threejs项目实战 - 省市图",会对这些功能有一定的了解,特别是开启辉光效果和后续的飞线效果. 地球 绘制地球实体 ...

最新文章

  1. Webix 1.5发布:一个强大的JavaScript UI组件库
  2. mysql行转列和列转行_mysql 行转列和列转行实例详解
  3. Jessica's Reading Problem
  4. 非常实用的Windows7进阶功能
  5. LinDaiDai的 2019 面试准备
  6. 第四范式@2020 WAIC世界人工智能大会
  7. Windows.form增删改查
  8. beyond compare类似软件_BIM工作是什么?需要哪些BIM软件来完成?
  9. android 自定义海报,Android仿海报工厂(完)
  10. endnotex9如何导入caj中文文献_EndNote X9常用方法汇总
  11. 我的世界服务器怎么修改矿物,我的世界怎么设置自定义矿物
  12. 6.2创建Docker镜像文件
  13. 服务器上找不到iis,Web服务器打开IIS7管理器看不到站点解决方法
  14. 如何把word ppt 思维导图这类文件转化为高清晰度的图片(要干货只看粗体黑字)
  15. 浅析EDA技术应用于电子设计竞赛的可行性
  16. 五胡十六国、东晋南北朝这280年历史,你知道多少?5000字带你看个清楚明白
  17. 充电桩,成了新能源汽车发展的“拦路虎”?
  18. 使用arduino驱动光驱步进电机
  19. 投资组合风险收益率公式_投资组合分析的基础收益和亏损
  20. java 中文转码_java 下载文件中文名称转码详解

热门文章

  1. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java大学生比赛信息管理系统38iiq
  2. win7 python_win7自带python吗
  3. 使用java来实现阻塞队列
  4. 2020年自考计算机应用基础都考什么题型,2019年10月自考计算机应用基础试题和答案...
  5. 齿轮和轴的介绍 外文翻译
  6. 织梦mysql安装教程_新手教程:DedeCmsV5.7 SP1详细安装步骤(2)
  7. flutter实现条形码二维码扫描
  8. 安鸾靶场之XSS漏洞_交友平台
  9. 常用的自动化管理软件及Ansible安装
  10. Excel批量导入图片并在右侧单元格备注名称