Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

倾斜摄影OSGB是基于CGCS2000的,如何转换成GCJ02 的3dtiles #200

Open
yangchao2015 opened this issue Aug 5, 2021 · 15 comments
Open
Labels

Comments

@yangchao2015
Copy link

你好,麻烦问下,倾斜摄影OSGB是基于CGCS2000的,如何转换成GCJ02 的3dtiles

@fanvanzh
Copy link
Owner

fanvanzh commented Aug 6, 2021

不明白你的意思, CGCS2000、GCJ02 应该都是说的基准点坐标。
3dtile 都是 单位是米的 投影数据

@yangchao2015
Copy link
Author

对倾斜摄影不太了解,第三方机构提供的是基于CGCS2000的,通过3dtiles 转换成 3dtiles 文件,需要在高德地图进行加载,空间参考填写 高德的经纬度坐标点?我尝试过,转换过之后是无法正常加载的

@yangchao2015
Copy link
Author

OSGB 倾斜摄影 数据其中的 metadata.xml内容如下:
1628219113(1)

@fanvanzh
Copy link
Owner

fanvanzh commented Aug 7, 2021

高德地图支持加载 3dtiles 了?
你这个 metadata.xml 是 高斯3度带的投影, EPSG=4549

这个项目只支持 EPSG: 4549 这种写法的解析。

@fanvanzh
Copy link
Owner

fanvanzh commented Aug 7, 2021

你注意下 3dtile.exe 执行时的输出里,有没有打印 x -> {}, y -> {} 的日志。 这个坐标就是经纬度坐标。

@yangchao2015
Copy link
Author

1628302675(1)
是的,现在我转换出来直接使用 Cesium 可以加载出来,但是使用高德加载,无法显示,查看得到的titleCenter 坐标 是 {lng: -23.40701687715633, lat: 39.141703930756044},应该是坐标系的问题,导致的显示的问题,不知道如何去进行处理和显示,希望能得到如何去处理的方式,或者可以处理的工具,感谢
1628302714

@yangchao2015
Copy link
Author

输出的 坐标是 118.788434239726, 32.057578129300

@fanvanzh
Copy link
Owner

fanvanzh commented Aug 7, 2021

那你高德地图经纬度填写这个坐标试试呢?
118.788434239726, 32.057578129300

没用过 高德这个功能, 3dtile 里 b3dm 里是不涉及坐标系的, 只有 tileset.json/transform 和坐标有关

@liaozd
Copy link

liaozd commented Sep 4, 2022

问题最后怎么解决的?我们也有同样的3Dtile需要展示在高德地图上

@yangchao2015
Copy link
Author

yangchao2015 commented Sep 4, 2022 via email

@ibandeng
Copy link

你好,麻烦问下,倾斜摄影OSGB是基于CGCS2000的,如何转换成GCJ02 的3dtiles

你好,请问问题最后怎么解决的?

@yangchao2015
Copy link
Author

yangchao2015 commented Oct 27, 2022 via email

@lianzhao
Copy link

lianzhao commented Oct 27, 2022

谈一些我的经验,抛砖引玉。我经历了两套b3dm要转为gcj-02坐标系。

(PS,我的b3dm文件不是通过本项目生成的,而是从别的软件导出的。所以如果是跟本项目相关的特定问题,那下面的描述帮不到您)

Case 1

这套文件,有多个树状结构的tileset.json,每个文件有两种方式决定对应模型所在的位置

Case 1.1

有些文件通过boundingVolume.box来决定,结构为

"boundingVolume": {
  "box": [
    0,   0,   10,
    100, 0,   0,
    0,   100, 0,
    0,   0,   10
  ]
}

根据文档,前三个值就是中心点坐标。使用类似如下的代码来变更box前三个值

import { Ellipsoid } from '@math.gl/geospatial';

const updateBox = boundingVolume => {
  const center = Ellipsoid.WGS84.cartesianToCartographic(boundingVolume.box.slice(0, 3));
  const { lng, lat } = toGCJ02(center[0], center[1]);
  const transformed = Ellipsoid.WGS84.cartographicToCartesian([lng, lat, center[2]]);
  boundingVolume.box[0] = transformed[0];
  boundingVolume.box[1] = transformed[1];
  boundingVolume.box[2] = transformed[2];
}

Case 1.2

有些文件通过transform来决定相对父元素的transform。解决方法是:

  • 这个工具中输入root节点的经纬度(经过变换为gcj-02之后的),就会得到一个新的matrix,赋值给那些transform不为空的对象即可。
if (obj.transform) obj.transform = newTransform;

Case 2

这是我拿到的另一套b3dm文件。这次关键的位置信息在b3dm文件的FeatureTable里,而非tileset.json中。使用类似如下的代码来变更b3dm文件

import { promises as fs } from "fs";
import path from "path";
import { Ellipsoid } from '@math.gl/geospatial';

const handleFile = async (file) => {
  const fullPath = path.resolve(file);
  const content = (await fs.readFile(fullPath));
  const jsonStart = 28; // 按照协议,feature table从28开始
  const jsonLength = content[12]; // 按照协议,这里是json的长度
  const jsonObj = JSON.parse(content.slice(jsonStart, jsonStart + jsonLength));
  const center = Ellipsoid.WGS84.cartesianToCartographic(jsonObj.RTC_CENTER);
  const { lng, lat } = toGCJ02(center[0], center[1]);
  const transformed = Ellipsoid.WGS84.cartographicToCartesian([lng, lat, center[2]]);
  const buffer = Buffer.alloc(jsonLength, 32); // 结果中需要保持jsonLength的长度不变,如果长度不足,用'32'填充(不知道为什么,但原数据就是这样)
  Buffer.from(`{"BATCH_LENGTH":1,"RTC_CENTER":[${transformed.map(val => val.toFixed(6)).join()}]}`).copy(buffer);
  for (let i = 0; i < jsonLength; i++) {
    content[jsonStart + i] = buffer[i];
  }
  await fs.writeFile(fullPath, content);
}

上述代码是处理一个b3dm文件的过程。你需要按照你的目录结构遍历所有b3dm文件。

@fanvanzh
Copy link
Owner

@lianzhao 需要您这样有分享精神的人

@lianzhao
Copy link

@lianzhao 需要您这样有分享精神的人

像您学习😁

顺便再分享下处理boundingVolume.region的方法,根据文档,region里的经纬度是“角度”,因此先把角度转化为经纬度,再转gcj-02,再转回角度就行了。处理一个tileset.json的代码大概是这样的

import { promises as fs } from "fs";
import path from "path";
import { degrees, radians } from '@math.gl/core';

const updateRegion = boundingVolume => {
  const [west, south, east, north, minHeight, maxHeight] = boundingVolume.region;
  const northWest = toGCJ02(degrees(west), degrees(north));
  const southEast = toGCJ02(degrees(east), degrees(south));
  boundingVolume.region[0] = radians(northWest.lng);
  boundingVolume.region[1] = radians(southEast.lat);
  boundingVolume.region[2] = radians(southEast.lng);
  boundingVolume.region[3] = radians(northWest.lat);
  // console.log(west, south, east, north);
  // console.log(boundingVolume.region.slice(0, 4));
}

const handleObject = obj => {
  updateRegion(obj.boundingVolume);
  obj.children?.forEach(handleObject);
}

const handleFile = async file => {
  const fullPath = path.resolve(file);
  const obj = JSON.parse(await fs.readFile(fullPath));
  handleObject(obj.root);
  await fs.writeFile(fullPath, JSON.stringify(obj));
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants