Cesium使用谷歌google地图带道路信息后解决tileset的偏移和wgs84坐标的偏移


化石原创文章,转载请注明来源并保留原文链接


项目中,倾斜摄影模型从osgb而来,使用3dtile工具转化成了3d tiles格式供Cesium使用。然后服务器会给出一定的坐标。倾斜摄影模型的坐标和服务器给出的坐标都是基于wgs84的。

如果使用google地图,只使用卫星地图( http://mt1.google.cn/vt/lyrs=s&hl=zh-CN&x={x}&y={y}&z={z}&s=Gali )的话,那么倾斜摄影和服务器给的坐标,都能和卫星地图完美配合。无需做任何事情。

然而地图上使用的时候必须看到道路标识,所以给到Cesium的tiles路径就变成了: http://mt1.google.cn/vt/lyrs=y&hl=zh-CN&x={x}&y={y}&z={z}&gl=cn。

可以看出来,请求的api中,参数lyrs从s变成了y,这个决定了从google服务器上请求下来的瓦片图,带有道路合成。参数也多了一个gl=cn,没有这个参数的话,会发现请求到的瓦片图,道路和卫星图是不匹配的,也就是道路有偏差。

所以瓦片请求路径就成了带gl=cn的那个。

不过使用这个瓦片图,其实google是为了符合中国规范,对图做了偏移。所以,所有wgs84的坐标信息(原来的),在这份地图上看起来都有了错位。因而我们需要解决两个问题:

1、tileset在该地图上的位置改动

2、服务器给到wgs84坐标后,我们得换算成现在地图上的坐标

下面是相关的方式:

1、tileset

所涉项目tileset数量很少,所以采用手工方式改动经纬度,看位置信息。最后记录下合适的经纬度。最后配合下面的代码,使tileset在加载准备好以后,自动放置到最后的位置。

var params = {
    tx: 120.7521311337607,    //longitude
    ty: 31.19968924358735,    //latitude
    tz: 0.1,                  //height
    rx: 0,                    //degree
    ry: 0,                    //degree
    rz: 0                     //degree
};
	
function update3dtilesMaxtrix(tileset, params) {
    // rotation maxtrix construct, first we get matrix3, then matrix4 from matrix3
    var mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx));
    var my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry));
    var mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz));
    var rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
    var rotationY = Cesium.Matrix4.fromRotationTranslation(my);
    var rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);

    // translation matrix4
    var position = Cesium.Cartesian3.fromDegrees(params.tx, params.ty, params.tz);
    var m = Cesium.Transforms.eastNorthUpToFixedFrame(position);

    // concate translation and all rotations
    Cesium.Matrix4.multiply(m, rotationX, m);
    Cesium.Matrix4.multiply(m, rotationY, m);
    Cesium.Matrix4.multiply(m, rotationZ, m);

    // update tileset's matrix4
    tileset._root.transform = m;
}

viewer.scene.primitives.add(tileset).readyPromise.then(function(t) {
	update3dtilesMaxtrix(t, params);
});

viewer.zoomTo(tileset);

2、服务器给的wgs84坐标信息

使用gcoord库,把每个wgs84坐标转化成gcj02坐标即可。示例代码:

var result = gcoord.transform(
  [116.403988, 39.914266],    // 经纬度坐标
  gcoord.WGS84,               // 当前坐标系
  gcoord.GCJ02                // 目标坐标系
);

化石原创文章,转载请注明来源并保留原文链接


发表评论

电子邮件地址不会被公开。 必填项已用*标注