Cesium 坐标变换 - cytggit/Map-openlayers GitHub Wiki
cesium中常用的坐标有两种WGS84地理坐标系和笛卡尔空间坐标系。我们平时常用的以经纬度来指明一个地点就是用的WGS84坐标,笛卡尔空间坐标系常用来做一些空间位置变换如平移旋转缩放等等。
在实际应用中用的最多的操作就是(lng, lat, alt)<=>(x, y, z)之间的相互转换,cesiumjs为我们提供了这些转换:
<code class="hljs javascript" style=""><span style="font-size:18px"><span class="hljs-keyword" style="">var</span> ellipsoid = viewer.scene.globe.ellipsoid;
<span class="hljs-keyword" style="">var</span> coord_wgs84 = Cesium.Cartographic.fromDegrees(lng, lat, alt);<span class="hljs-comment" style="">//单位:度,度,米</span>
<span class="hljs-keyword" style="">var</span> coord_xyz = ellipsoid.cartographicToCartesian(coord_wgs84);
<span class="hljs-built_in" style="">console</span>.log(<span class="hljs-string" style="">'x='</span> + coord_xyz.x + <span class="hljs-string" style="">',y='</span> + coord_xyz.y + <span class="hljs-string" style="">',z='</span> + coord_xyz.z);<span class="hljs-comment" style="">//单位:米,米,米</span>
<span class="hljs-keyword" style="">var</span> xyz = <span class="hljs-keyword" style="">new</span> Cesium.Cartesian3(x, y, z);
<span class="hljs-keyword" style="">var</span> wgs84 = ellipsoid.cartesianToCartographic(xyz);
<span class="hljs-built_in" style="">console</span>.log(<span class="hljs-string" style="">'lng='</span> + Cesium.Math.toDegrees(wgs84.longitude) + <span class="hljs-string" style="">',lat='</span> + Cesium.Math.toDegrees(wgs84.latitude) + <span class="hljs-string" style="">',alt='</span> + wgs84.height);</span></code>
需要注意cesium内部的角度单位是弧度,因此输入计算或输出显示时需要转换。
转换到笛卡尔坐标系后就能运用计算机图形学中的仿射变换知识进行空间位置变换如平移旋转缩放。
cesiumjs为我们提供了很有用的变换工具类,Cesium.Cartesian3(相当于Point3D)Cesium.Matrix3(3x3矩阵,用于描述旋转变换)Cesium.Matrix4(4x4矩阵,用于描述旋转加平移变换),Cesium.Quaternion(四元数,用于描述围绕某个向量旋转一定角度的变换)。
下面举个例子:
一个局部坐标为p1(x,y,z)的点,将它的局部坐标原点放置到loc(lng,lat,alt)上,局部坐标的z轴垂直于地表,局部坐标的y轴指向正北,并围绕这个z轴旋转d度,求此时p1(x,y,z)变换成全局坐标笛卡尔坐p2(x1,y1,z1)是多少?
<code class="hljs javascript" style=""><span style="font-size:18px"><span class="hljs-keyword" style="">var</span> rotate = Cesium.Math.toRadians(d);<span class="hljs-comment" style="">//转成弧度</span>
<span class="hljs-keyword" style="">var</span> quat = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, rotate); <span class="hljs-comment" style="">//quat为围绕这个z轴旋转d度的四元数</span>
<span class="hljs-keyword" style="">var</span> rot_mat3 = Cesium.Matrix3.fromQuaternion(quat);<span class="hljs-comment" style="">//rot_mat3为根据四元数求得的旋转矩阵</span>
<span class="hljs-keyword" style="">var</span> v = <span class="hljs-keyword" style="">new</span> Cesium.Cartesian3(x, y, z);<span class="hljs-comment" style="">//p1的局部坐标</span>
<span class="hljs-keyword" style="">var</span> m = Cesium.Matrix4.fromRotationTranslation(rot_mat3, Cesium.Cartesian3.ZERO);m2为旋转加平移的<span class="hljs-number" style="">4</span>x4变换矩阵,这里平移为(<span class="hljs-number" style="">0</span>,<span class="hljs-number" style="">0</span>,<span class="hljs-number" style="">0</span>),故填个Cesium.Cartesian3.ZERO
m = Cesium.Matrix4.multiplyByTranslation(m, v);<span class="hljs-comment" style="">//m = m X v</span>
<span class="hljs-keyword" style="">var</span> cart3 = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(lng, lat, alt)); <span class="hljs-comment" style="">//得到局部坐标原点的全局坐标</span>
<span class="hljs-keyword" style="">var</span> m1 = Cesium.Transforms.eastNorthUpToFixedFrame(cart3);<span class="hljs-comment" style="">//m1为局部坐标的z轴垂直于地表,局部坐标的y轴指向正北的4x4变换矩阵</span>
m = Cesium.Matrix4.multiplyTransformation(m, m1);<span class="hljs-comment" style="">//m = m X m1</span>
<span class="hljs-keyword" style="">var</span> p2 = Cesium.Matrix4.getTranslation(m);<span class="hljs-comment" style="">//根据最终变换矩阵m得到p2</span>
<span class="hljs-built_in" style="">console</span>.log(<span class="hljs-string" style="">'x='</span> + p2.x + <span class="hljs-string" style="">',y='</span> + p2.y + <span class="hljs-string" style="">',z='</span> + p2.z );</span></code>