作为一个新手,代码写多了才发现最基础的东西都不懂。
记录一下各种坐标转换。 这篇写了挺久,但是感觉写的还是不好,如果有大神指教,非常感谢!
Cesium中几种常用坐标
1. 平面坐标系(Cartesian2)
也就是2D笛卡尔点
2. 世界坐标系(Cartesian3)
也就是3D笛卡尔点,相比于2D,多一条Z轴
3. 弧度(Cartographic)
有API可以看到,这里的经纬度其实是弧度的意思。
长度为半径长的弧,所对的圆心角是 1 弧度(Radian),用符号rad表示。
弧度←→角度转换公式
角度转弧度:π/180 × 角度
弧度转角度:180 / π × 弧度
4. 经纬度
常用的地理坐标系的经纬度,在cesium中是没有直接体现的。需要通过弧度进行转换计算。
Cesium中几种常用坐标之间的转换
1. 屏幕坐标转换为经纬度
这里给地球添加了一个点击事件,将屏幕坐标转换为经纬度输出。
var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(function (movement) {
var pick = movement.position;
var cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(pick), viewer.scene);
var ellipsoid = viewer.scene.globe.ellipsoid;
var cartographic = ellipsoid.cartesianToCartographic(cartesian);
var lat = Cesium.Math.toDegrees(cartographic.latitude);
var lon = Cesium.Math.toDegrees(cartographic.longitude);
var alt = cartographic.height;
console.log('经度:' + lon + '\n纬度:' + lat + '\n高度:' + alt);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
点击地球上某一点运行结果:
分开来看这一部分代码
-
首先看一下movement是什么
var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); handler.setInputAction(function (movement) { console.log(movement); }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
运行结果:
可以看到,movement输出一个对象,其实position是一个2D笛卡尔点,是我们的屏幕坐标。
那么很简单的可知,pick 是屏幕坐标。 -
那么,cartesian是什么呢?这里面用到了几个API
扫描二维码关注公众号,回复: 9621007 查看本文章- 首先是这个
viewer.camera.getPickRay(pick)
(这个看英文的API只是因为中文的翻译过来那个我没看明白= =)
大概意思是,在世界坐标系中,从相机位置到windowsPosition创建一个光线。
如果运行console.log(viewer.camera.getPickRay(pick));
运行结果为:
可以看出,返回一条折线对象。
- 然后呢,是这个
viewer.scene.globe.pick();
也就是根据折线,返回与地球的交点。- 这两个结合起来就是
var cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(pick), viewer.scene); console.log(cartesian);
运行结果为:
也就是说,通过这一系列操作,屏幕坐标已经变为了世界坐标。 - 首先是这个
-
ellipsoid又是啥?
var ellipsoid = viewer.scene.globe.ellipsoid;
由此可见,这一句话把地球得到了= =。
-
最后的cartographic?
var cartographic = ellipsoid.cartesianToCartographic(cartesian);
这个的中文API我又没看明白,但结果应该就是将世界坐标转换为弧度。
console.log(cartographic);
运行结果为:
-
最后只需要将弧度转换为经纬度了❤❤❤
在cesium中Math对象中的函数可以用来完成经纬度和弧度之间的换算。
经纬度转为弧度:弧度值 = Cesium.Math.toRadians(角度值);
弧度转为经纬度:角度值 = Cesium.Math.toDegrees(弧度值);
这两个方法是单纯的将二者进行换算,另外cesium中很多的对象中是有专用的换算函数的。最终,我们也得到了如下运行结果:
其实在这一段代码中,已经包含了一些其他坐标相互转换的方法了.
2. 经纬度转换为其他坐标
1. 经纬度转换为世界坐标
Cesium.Cartesian3.fromDegrees (longitude, latitude, height , ellipsoid , result )
举例:这是上面代码中的一个demo,利用这个进行试验.
console.log(Cesium.Cartesian3.fromDegrees(103.5244736955307, 38.95679115163814, -12727.07286718901));
执行结果为:
2. 经纬度转换为弧度
以如下demo为例。
运行如下代码:
var longitude = Cesium.Math.toRadians(111.56289704608179);
var latitude = Cesium.Math.toRadians(39.55996205199046);
console.log(new Cesium.Cartographic(longitude, latitude));
运行结果为:
3. 经纬度转换为屏幕坐标
要进行两步。经纬度→世界坐标→屏幕坐标
3. 世界坐标转换为其他坐标
1. 世界坐标转换为屏幕坐标
Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position, result)
2. 世界坐标转换为经纬度
参考:其中cartesian为世界坐标
// 2. 世界坐标转换为经纬度
var ellipsoid = viewer.scene.globe.ellipsoid;
var cartographic = ellipsoid.cartesianToCartographic(cartesian);
var lat = Cesium.Math.toDegrees(cartographic.latitude);
var lon = Cesium.Math.toDegrees(cartographic.longitude);
var alt = cartographic.height;
console.log('经度:' + lon + '\n纬度:' + lat + '\n高度:' + alt);