Bootstrap

Cesium中的几种坐标和相互转换

 一、坐标分为三类

        地理坐标、世界坐标、屏幕坐标。通常用地理坐标来进行位置表达,比如经纬度、弧度;世界坐标也就是笛卡尔坐标系来做一些空间位置变换,比如平移旋转和缩放;屏幕坐标用来和用户交互。

1、地理坐标

        默认使用的是WGS84作为空间参考,分为弧度和经纬度两种表达方式,但是在cesium中没有具体的经纬度对象。

1)弧度Cartographic

        作用:Cesium中的地理坐标单位默认是弧度制,用Cartographic变量表示。

        获取:通过new Cesium.Cartographic(longitude, latitude, height)创建,其中这里的参数是用弧度表示的经纬度弧度(Cartographic)

        

        new Cesium.Cartographic(longitude, latitude, height) :计算方法:弧度= π/180×经纬度角度。

        这里的经纬度是用弧度表示的,经纬度其实就是角度。弧度即角度对应弧长是半径的倍数。

        角度转弧度: π / 180 × 角度

        弧度变角度: 180 / π × 弧度

2)经纬度(WGS84)

        由于Cesuim中没有具体的经纬度对象,要得到经纬度首先需要计算为弧度,再进行转换。

        地理坐标系,坐标原点在椭球的质心。

        经度:参考椭球面上某点的大地子午面与本初子午面间的两面角。东正西负。

        纬度:参考椭球面上某点的法线与赤道平面的夹角。北正南负。

        World Geodetic System 1984,是为GPS全球定位系统使用而建立的坐标系统,坐标原点为地球质心,其地心空间直角坐标系的Z轴指向BIH (国际时间服务机构)1984.O定义的协议地球极(CTP)方向,X轴指向BIH 1984.0的零子午面和CTP赤道的交点,Y轴与Z轴、X轴垂直构成右手坐标系。我们平常手机上的指南针显示的经纬度就是这个坐标系下当前的坐标,进度范围[-180,180],纬度范围[-90,90]。

        Cesium目前支持两种坐标系WGS84和WebMercator,但是在Cesium中没有实际的对象来描述WGS84坐标,都是以弧度的方式来进行运用的也就是Cartographic类

2.世界坐标

        是一个三维空间中的点,单位是米,原点在椭球中心

1)三维笛卡尔空间坐标(Cartesian3)

        以椭球中心为原点的空间直角坐标系中的一个点的坐标。用来做空间位置的变化如平移、旋转和缩放等等。

        获取:

        (1)通过new Cesium.Cartesian3(x, y, z)创建

3.屏幕坐标像素

        屏幕显示的二维坐标,原点在屏幕左上角,向右是x正方向,向下是y正方向。

1)二维笛卡尔平面坐标(Cartesian2)

        介绍:  屏幕左上角为原点(0,0),单位为像素值,屏幕水平方向为X轴,向右为正,垂直方向为Y轴,向下为正。

        获取:

           (1)通过鼠标点击直接获取的坐标就是屏幕坐标了,单位是像素值;

       (2)通过new Cesium.Cartesian2(x, y)创建平面坐标系也就是平面直角坐标系,与Cartesian3相比少了一个z的分量;

二、坐标系分为两类

        地理坐标系:单位是度,WGS84、CGCS2000。在精度不高的要求下,CGCS2000可以定义为WGS84。

        投影坐标系:单位是米,按照投影带划分。

        一份数据一定有坐标系,但不一定有投影。地理坐标系没有投影,只有投影坐标系有投影。

1.投影坐标系

1) 墨卡托投影(Mercator projection)

        墨卡托投影以其创立者荷兰地图学家墨卡托命名,其学名为“正轴等角圆柱投影”,假设地球被包围在圆柱体中,地球的赤道与圆柱相接触,然后再假想地球中心有一个光源,光源把地球表面上的图像投影到圆柱体上,再将圆柱体展开,展开后的地图就是墨卡托投影的世界地图

2) UTM投影(Universal Transverse Mercator)

        UTM投影,其全称为“通用横轴墨卡托投影”,UTM投影与高斯-克吕格投影十分相似,但圆柱体并不是与地球相切,而是穿过地球

3)网络墨卡托投影(Web Mercator)

        网络墨卡托投影由Google Map发明,借鉴于墨卡托投影,但在投影时并不是把地球当作一个椭球体,而是当作一个正球体。

4)高斯-克吕格投影(Gauss-Kruger)

        高斯-克吕格投影以其创立者高斯和克吕格命名,其学名为“横轴墨卡托投影”,以中央经线与圆柱体相切,再进行投影

2.地理坐标系

        1)3D笛卡尔空间直角坐标系

        2)2D笛卡尔平面直角坐标系

        3) WGS84经纬度坐标弧度制

3.基于WGS84测量系统的坐标系为两种

         1)4326

        是基于wgs84椭球的经纬度坐标系,是地理坐标系。单位是度。

        优点:利于存储,可读性高。

        缺点:会导致页面变形。

        2)3857

        是基于球体的、web墨卡托投影(伪墨卡托投影)的投影坐标系,把 WGS84坐标系投影到正方形。单位是米。

        优点:用于显示、分析数据。

        缺点:可读性差,存储占内存。

        通常使用4326存储数据,使用3857显示数据

4、常见的坐标系

        WGS-84:gps原始坐标系

        GCJ-02:国测局坐标,火星坐标系,是一种对经纬度数据的加密算法

        CGCS2000:国家大地坐标系

        BD-09:百度中国地图采用的坐标系,在GCJ-02的基础上再加密得到

5、常见的地图使用的坐标系

        天地图:全球统一CGCS2000

        百度地图:BD-09,在GCJ-02坐标系基础上再次加密

        高德地图:GCJ-02

        google地图:GCJ-02,数据来自高德,两者互通

        腾讯地图:GCJ-02

三、坐标转换

1.弧度经纬度

        var radians=Cesium.CesiumMath.toRadians(degrees) ;//经纬度转弧度

        var degrees=Cesium.CesiumMath.toDegrees(radians); //弧度转经纬度

2.WGS84(经纬度)-->笛卡尔坐标(Cartesian3

  1. 通过经纬度或弧度进行转换

Cesium.Cartesian3.fromDegrees(longitude, latitude, height, ellipsoid, result)

注意:上述转换函数中最后均有一个默认参数ellipsoid(默认值为Ellipsoid.WGS84)。

// 格式:[113.21, 25.61, 100.0],高度默认为0,可以不写,longitude和latitude为角度

var Cartesian3= Cesium.Cartesian3.fromDegrees(longitude, latitude, height);

//其中,高度默认值为0,可以不用填写;longitude和latitude为角度

// 格式:[113.21, 25.61, 113.54, 25.24],不带高度格式的数组

var Cartesian3s= Cesium.Cartesian3.fromDegreesArray(coordinates);

// 格式:[113.21, 25.61, 100.0, 113.54, 25.24, 200.0],带高度格式的数组

var Cartesian3s= Cesium.Cartesian3.fromDegreesArrayHeights(coordinates);

//同理,通过弧度转换,用法相同,具体有Cesium.Cartesian3.fromRadians,Cesium.Cartesian3.fromRadiansArray,Cesium.Cartesian3.fromRadiansArrayHeights等方法

  1. 通过过度进行转换先转换成弧度再转换

// 获取椭球体对象

var ellipsoid = viewer.scene.globe.ellipsoid;

// 创建Cartographic对象,角度转弧度

var cartographic = Cesium.Cartographic.fromDegrees(lng,lat,alt);

// 将Cartographic对象转换为笛卡尔坐标

var cartesian3 = ellipsoid.cartographicToCartesian(cartographic);

var position = Cesium.Cartographic.fromDegrees(longitude, latitude, height);

//角度转弧度

var positions = Cesium.Ellipsoid.WGS84.cartographicToCartesian(position);

//弧度转Cartesian3

var positions =

Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray([position1,position2,position3]);

3.笛卡尔空坐标(Cartesian3)-->WGS84经纬度坐标

  1. 直接转换

var cartographic= Cesium.Cartographic.fromCartesian(cartesian3);//笛卡尔转换为弧度

//使用经纬度和弧度的转换,将WGS84弧度坐标系转换到目标值,弧度转度

var longitude = Cesium.Math.toDegrees(cartographic.longitude);

var latitude = Cesium.Math.toDegrees(cartographic.latitude);

var height = cartographic.height;

  1. 间接转换

var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian3);

var cartographics = Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray([cartesian1,cartesian2,cartesian3]);

// 获取椭球体对象

var ellipsoid = viewer.scene.globe.ellipsoid;

// 定义笛卡尔坐标

var cartesian3 = new Cesium.cartesian3(x,y,z);

// 将Cartographic对象转换为笛卡尔坐标

var cartographic = ellipsoid.cartesianToCartographic(cartesian3);

// 获取经度、纬度和高度值

var lat = Cesium.Math.toDegrees(cartograhphic.latitude);

var lng = Cesium.Math.toDegrees(cartograhpinc.longitude);

var alt = cartographic.height;

4.平面坐标系(Cartesian2)-->笛卡尔直角坐标系(Cartesian3)

注:当前点(Cartesian2)必须在三维球上,否则返回的是undefined;通过ScreenSpaceEventHandler回调 movement.position获取的坐标都是Cartesian2,即屏幕坐标。

屏幕转世界坐标:

var pick1= new Cesium.Cartesian2(0,0);

var cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(pick1),viewer.scene);    

注意这里屏幕坐标一定要在球上,否则生成出的cartesian对象是undefined

世界坐标转屏幕坐标

Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, Cartesian3);

结果是Cartesian2对象,取出X,Y即为屏幕坐标。

1、屏幕坐标-->场景坐标(世界坐标)

获取倾斜摄影或模型场中,任意点击处对应的世界坐标。

       这里的场景坐标是包含了地形、倾斜摄影表面、模型的坐标。

      通过viewer.scene.pickPosition(movement.position)获取,根据窗口坐标,从场景的深度缓冲区中拾取相应的位置,返回笛卡尔坐标。

var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

handler.setInputAction(function (movement) {

    var position = viewer.scene.pickPosition(movement.position);

    console.log(position);

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        注:若屏幕坐标处没有倾斜摄影表面、模型时,获取的笛卡尔坐标不准,此时要开启地形深度检测(viewer.scene.globe.depthTestAgainstTerrain = true; //默认为false)。

2、屏幕坐标-->地表坐标(世界坐标)

        获取加载地形后对应的经纬度和高程

       这里是地球表面的世界坐标,包含地形,不包括模型、倾斜摄影表面。

  通过viewer.scene.globe.pick(ray, scene)获取,

其中ray=viewer.camera.getPickRay(movement.position)。

var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

handler.setInputAction(function (movement) {

    var ray = viewer.camera.getPickRay(movement.position);

    var position = viewer.scene.globe.pick(ray, viewer.scene);

    console.log(position);

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        注:通过测试,此处得到的坐标通过转换成wgs84后,height的为该点的地形高程值。

3、屏幕坐标-->椭球面坐标

        获取鼠标点的对应椭球面位置

        这里的椭球面坐标是参考椭球的WGS84坐标(Ellipsoid.WGS84),不包含地形、模型、倾斜摄影表面。

        通过 viewer.scene.camera.pickEllipsoid(movement.position, ellipsoid)获取,可以获取当前点击视线与椭球面相交处的坐标,其中ellipsoid是当前地球使用的椭球对象:viewer.scene.globe.ellipsoid,默认为Ellipsoid.WGS84。

        var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

        handler.setInputAction(function (movement)

        var position = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);

            console.log(position);

        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        注:通过测试,此处得到的坐标通过转换成wgs84后,height的为0(此值应该为地表坐标减去地形的高程)。

  1. 笛卡尔坐标系(Cartesian3)-->平面坐标系(Cartesian2)

        var cartesian2=         Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene,cartesian3)

        //结果是Cartesian2对象,取出X,Y即为屏幕坐标。

5.Cartesian2

        Cesium.Cartesian2.fromCartesian3(cartesian, result)→ Cartesian2

6.Cartesian3

        经纬度坐标(WGS84)→ Cartesian3

        Cesium.Cartesian3.fromDegrees(longitude, latitude, height, ellipsoid, result) → Cartesian3

        弧度坐标(WGS84)→ Cartesian3

        Cesium.Cartesian3.fromRadians(longitude, latitude, height, ellipsoid, result) → Cartesian3

7.Cartographic

        Cartesian3→ Cartographic

        Cesium.Cartographic.fromCartesian(cartesian, ellipsoid, result) → Cartographic

        经纬度坐标(WGS84)→ Cartographic

        Cesium.Cartographic.fromDegrees(longitude, latitude, height, result) → Cartographic   

        另外,经纬度坐标和弧度坐标也可以通过Cesium.Math来转换

        Cesium.CesiumMath.toDegrees(radians) → Number

        另外,经纬度坐标和弧度坐标也可以通过Cesium.Math来转换

        Cesium.CesiumMath.toDegrees(radians) → Number

        Cesium.CesiumMath.toRadians(degrees) → Number        

;