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

能早点看到大佬作品就好了,重复造轮子了,大哭! #2

Open
FengFengmomo opened this issue Jun 19, 2024 · 29 comments

Comments

@FengFengmomo
Copy link

No description provided.

@sxguojf
Copy link
Owner

sxguojf commented Jun 21, 2024

three-tile何尝也不是一个轮子......高兴就好

@red-fire-code
Copy link

你好啊,Three-tile中的map其实是一个平面,请问能否将这个平面放置到实际场景中呢?还有一个问题是,3857坐标系下是一公里为单位,是否可以更加精细呢?

@FengFengmomo
Copy link
Author

你好啊,Three-tile中的map其实是一个平面,请问能否将这个平面放置到实际场景中呢?还有一个问题是,3857坐标系下是一公里为单位,是否可以更加精细呢?

这个平面一般默认坐标是笛卡尔坐标系的(0,0,0),你可以选择把你的模型转换坐标以后放到地图场景里,这样就是地图真实场景了。关于“3857坐标系下是一公里为单位”这个概念不对嗷,不同显示层级代表的精细度是不一样的,可以参考一下天地图给出的元数据信息 http://t0.tianditu.gov.cn/img_w/wmts?request=GetCapabilities&service=wmts

@red-fire-code
Copy link

red-fire-code commented Jul 11, 2024

你好啊,三块地图其实是一个平面,请问能否将这个平面放置在实际场景中呢? 另外还有一个问题,3857坐标系下是一公里为单位,周边更加精细呢?

这个平面一般默认坐标是笛卡尔坐标系的(0,0,0),你可以选择把你的模型转换坐标以后放到地图场景里,这样就是地图真实场景了。关于“3857坐标系下是一公里为单位”这个概念不对嗷,不同显示层级代表的精细度是不一样的,可以参考一下天地图给出的元数据信息http://t0.tianditu.gov.cn/img_w/wmts?request=GetCapabilities&service=wmts

你好,大佬,我想做的事精细的地图编辑,但是会在已有的瓦片上进行,,所以需要想cesium一样能够放大到很大,并且后端传输的数据也要能显示在场景中,请问我借助于tileMap这个面是否可行呢?我尝试了引用你的map作为面,然后添加到threejs场景中,瓦片是出来了,但是我获取的坐标还是后端传给我的经纬度都没能放置到准确的位置上

@FengFengmomo
Copy link
Author

cesium的地图是球体的,如果是经纬度数据不管是球体还是平面都是有个经纬度转换规则的。平面的一般都是采用google的web mecator投影,和WGS84坐标系是很接近。首先需要确定你的数据里面经纬度数据是哪种投影才能选定合适的转换规则。如果你的数据在cesium里面显示正常,那就是这边经纬度数据转换的问题了。

@red-fire-code
Copy link

Cesium的地图是球体的,如果是经纬度数据不管是球体还是平面都是有个经纬度转换的规则的。平面的一般都是采用google的web mecator投影,和WGS84坐标系是很接近的。首先需要确定你的数据里面经纬度数据是哪种投影才能选定合适的转换规则。如果你的数据在cesium里面显示正常,那就是这边经纬度数据转换的问题了。

我只需要一小块,所以还是适用web mecator投影,请问,我可以把map那个mesh宽高都放大1000倍吗?然后还是想获取到正确的经纬度,请问有可行的方法吗?

@FengFengmomo
Copy link
Author

Cesium的地图是球体的,如果是经纬度数据不管是球体还是平面都是有个经纬度转换的规则的。平面的一般都是采用google的web mecator投影,和WGS84坐标系是很接近的。首先需要确定你的数据里面经纬度数据是哪种投影才能选定合适的转换规则。如果你的数据在cesium里面显示正常,那就是这边经纬度数据转换的问题了。

我只需要一小块,所以还是适用web mecator投影,请问,我可以把map那个mesh宽高都放大1000倍吗?然后还是想获取到正确的经纬度,请问有可行的方法吗?

参考一下首页的这个介绍,调整一下。
image

三种方法:1、直接把镜头离那个mesh近一点即可,但是真个地图因为厂商提供的地图精细度不够,所以会糊掉。
2、自己把那个mesh的贴图拿下来,然后根据(zoom,x,y),可以计算出来每个图片上像素点的实际经纬度,有相应的转换方法。
3、自己有无人机扫描出来高精度数据,比如无人机雷达。把扫描出来的数据放到正确位置,同样可以达到放大1000倍的效果且是非常清晰的。

@red-fire-code
Copy link

Cesium的地图是球体的,如果是经纬度数据不管是球体还是平面都是有个经纬度转换的规则的。平面的一般都是采用google的web mecator投影,和WGS84坐标系是很接近的。首先需要确定你的数据里面经纬度数据是哪种投影才能选定合适的转换规则。如果你的数据在cesium里面显示正常,那就是这边经纬度数据转换的问题了。

我只需要一小块,所以还是适用web mecator投影,请问,我可以把map那个mesh宽高都放大1000倍吗?然后还是想获取到正确的经纬度,请问有可行的方法吗?

参考一下首页的这个介绍,调整一下。 image

三种方法:1、直接把镜头离那个mesh近一点即可,但是真个地图因为厂商提供的地图精细度不够,所以会糊掉。 2、自己把那个mesh的贴图拿下来,然后根据(zoom,x,y),可以计算出来每个图片上像素点的实际经纬度,有相应的转换方法。 3、自己有无人机扫描出来高精度数据,比如无人机雷达。把扫描出来的数据放到正确位置,同样可以达到放大1000倍的效果且是非常清晰的。

谢谢,我要去试试看!

@sxguojf
Copy link
Owner

sxguojf commented Jul 11, 2024

你好啊,Three-tile中的map其实是一个平面,请问能否将这个平面放置到实际场景中呢?还有一个问题是,3857坐标系下是一公里为单位,是否可以更加精细呢?

1、首先,把three-tile升级到0.6.1,老版本地图水平面放在了xy平面,与webgl不一样,很多用户被坐标系搞糊涂了,所以v0.6.1不再修改模型的默认Up值,与threejs默认坐标系保持一致。
2、three-tile的目标就是让把TileMap当做个平面放在实际场景中,没有问题。v0.6.1版直接用tilemap替换你原有的平面即可。
3、分辨率、地图精度跟投影方式无关,关于3857投影单位的1公里描述,是指模型坐标1个单位,默认情况下是1公里,比如new BoxGeometry(100, 200, 10),显示到地图上就是长宽高分别为100、200、10公里的立方体。如果你要显示100米200米10米的立方体,可以用BoxGeometry(0.1,0.2,0.1),更小的也没问题,多取几位小数。
4、1公里的单位,的确与cesium不一样,主要是大场景下我写嫌坐标值数字太大了,想少些几个零。不过这不影响,正如你想的,把地图拉伸1000倍就可以了。

@red-fire-code
Copy link

20240711-201006
请问,这个偏差上什么问题?是使用获取的世界坐标直接绘制的。

@sxguojf
Copy link
Owner

sxguojf commented Jul 11, 2024

20240711-201006 请问,这个偏差上什么问题?是使用获取的世界坐标直接绘制的。

1、不知道你是否用的TileMap.getLocalInfoFromScreen()函数取得地面坐标?getLocalInfoFromScreen使用射线法取得鼠标点击处的坐标,包括地面模型局部和经纬度高度,应该是准确的,可参考下 (https://github.com/sxguojf/three-tile-example) 项目的中step1.3。
2、关于点击屏幕点,放置物体到该点的方法,可参考 (https://github.com/sxguojf/three-tile-example) 项目的中step3.4,点击地面放置一个士兵模型到地面。

@red-fire-code
Copy link

20240711-201006 请问,这个偏差上什么问题?是使用获取的世界坐标直接绘制的。

1、不知道你是否用的TileMap.getLocalInfoFromScreen()函数取得地面坐标?getLocalInfoFromScreen使用射线法取得鼠标点击处的坐标,包括地面模型局部和经纬度高度,应该是准确的,可参考下 (https://github.com/sxguojf/three-tile-example) 项目的中step1.3。 2、关于点击屏幕点,放置物体到该点的方法,可参考 (https://github.com/sxguojf/three-tile-example) 项目的中step3.4,点击地面放置一个士兵模型到地面。

是使用的TileMap.getLocalInfofromScreen()获取的坐标。无论是使用location的经纬度,还是point的世界坐标,绘制的线和回回显的线都不在一条线上

@sxguojf
Copy link
Owner

sxguojf commented Jul 12, 2024

20240711-201006 请问,这个偏差上什么问题?是使用获取的世界坐标直接绘制的。

1、不知道你是否用的TileMap.getLocalInfoFromScreen()函数取得地面坐标?getLocalInfoFromScreen使用射线法取得鼠标点击处的坐标,包括地面模型局部和经纬度高度,应该是准确的,可参考下 (https://github.com/sxguojf/three-tile-example) 项目的中step1.3。 2、关于点击屏幕点,放置物体到该点的方法,可参考 (https://github.com/sxguojf/three-tile-example) 项目的中step3.4,点击地面放置一个士兵模型到地面。

是使用的TileMap.getLocalInfofromScreen()获取的坐标。无论是使用location的经纬度,还是point的世界坐标,绘制的线和回回显的线都不在一条线上

TileMap计算交点有bug,v0.6.2刚修复,( https://sxguojf.github.io/three-tile-example/ ) 中增加了一个示例:step1.13:鼠标点击放置模型到地面

@red-fire-code
Copy link

red-fire-code commented Jul 12, 2024

20240711-201006 请问,这个偏差上什么问题?是使用获取的世界坐标直接绘制的。

1、不知道你是否用的TileMap.getLocalInfoFromScreen()函数取得地面坐标?getLocalInfoFromScreen使用射线法取得鼠标点击处的坐标,包括地面模型局部和经纬度高度,应该是准确的,可参考下 (https://github.com/sxguojf/three-tile-example) 项目的中step1.3。 2、关于点击屏幕点,放置物体到该点的方法,可参考 (https://github.com/sxguojf/three-tile-example) 项目的中step3.4,点击地面放置一个士兵模型到地面。

是使用的TileMap.getLocalInfofromScreen()获取的坐标。无论是使用location的经纬度,还是point的世界坐标,绘制的线和回回显的线都不在一条线上

TileMap计算交点有bug,v0.6.2刚修复,( https://sxguojf.github.io/three-tile-example/ ) 中增加了一个示例:step1.13:鼠标点击放置模型到地面

谢谢,我更新下试试看,我得找机会学习下这套的原理才行。大佬在哪上班?我们现在在招人,地图编辑平台,可有兴趣?

@FengFengmomo
Copy link
Author

一般鼠标点击放置模型应该是直接获取世界xyz坐标,不要做xy到经纬度转换,再转世界坐标,因为float计算会出现误差值,有漂移很正常。

@red-fire-code
Copy link

一般鼠标点击放置模型应该是直接获取世界xyz坐标,不要做xy到经纬度转换,再转世界坐标,因为float计算会出现误差值,有漂移很正常。
更新后getLocalInfoFromScreen无返回值了

@sxguojf
Copy link
Owner

sxguojf commented Jul 12, 2024

一般鼠标点击放置模型应该是直接获取世界xyz坐标,不要做xy到经纬度转换,再转世界坐标,因为float计算会出现误差值,有漂移很正常。
更新后getLocalInfoFromScreen无返回值了

// 鼠标点击地图,放置模型
viewer.container.addEventListener("click", (evt) => {
	const camera = viewer.camera;
	const pointer = new Vector2();
	// 鼠标点击的屏幕坐标(-0.5到+0.5范围)
	pointer.x = (evt.clientX / viewer.container.clientWidth) * 2 - 1;
	pointer.y = 1 - (evt.clientY / viewer.container.clientHeight) * 2;
	// 取得目标点坐标(光标处地面坐标)
	const position = map.getLocalInfoFromScreen(camera, pointer)?.point;
	if (position) {
		// 创建模型
		const model = new Mesh(new BoxGeometry(0.1, 0.1, 0.1), new MeshLambertMaterial());
		model.position.copy(position);
		viewer.scene.add(model);
	}
});

@red-fire-code
Copy link

red-fire-code commented Jul 12, 2024

const camera = viewer.camera;
	const pointer = new Vector2();
	// 鼠标点击的屏幕坐标(-0.5到+0.5范围)
	pointer.x = (evt.clientX / viewer.container.clientWidth) * 2 - 1;
	pointer.y = 1 - (evt.clientY / viewer.container.clientHeight) * 2;
	// 取得目标点坐标(光标处地面坐标)
	const position = map.getLocalInfoFromScreen(camera, pointer)?.point;

我知道问题了,是不是在计算的时候,你这边是以window,的宽高参与计算的啊?我是在一个窗口中,不是全屏,然后算的就有偏差了,我全屏就没偏差。请问有办法解决吗?

@sxguojf
Copy link
Owner

sxguojf commented Jul 12, 2024

我没有用window做宽高,代码中能看到,用的viewer.container.clientWidth。你应该是监听的是window的的click事件,事件参数evt.clientX不是相对于地图容器的,直接用上面的代码,监听viewer.container的click:
viewer.container.addEventListener("click", (evt) => {

@red-fire-code
Copy link

我没有用window做宽高,代码中能看到,用的viewer.container.clientWidth。你应该是监听的是window的的click事件,事件参数evt.clientX不是相对于地图容器的,直接用上面的代码,监听viewer.container的click: viewer.container.addEventListener("click", (evt) => {

我们没发使用你这种,只能用你的地图面,所以我是使用的原始的Threejs监听器,我也觉得你哪个应该没啥问题,我感觉我这边可能需要在调整下,才行。有一个问题就是我吧面缩放1000倍,获取坐标(经纬度)不久不对了嘛?是不是需要改源码了?

@sxguojf
Copy link
Owner

sxguojf commented Jul 12, 2024

我没有用window做宽高,代码中能看到,用的viewer.container.clientWidth。你应该是监听的是window的的click事件,事件参数evt.clientX不是相对于地图容器的,直接用上面的代码,监听viewer.container的click: viewer.container.addEventListener("click", (evt) => {

我们没发使用你这种,只能用你的地图面,所以我是使用的原始的Threejs监听器,我也觉得你哪个应该没啥问题,我感觉我这边可能需要在调整下,才行。有一个问题就是我吧面缩放1000倍,获取坐标(经纬度)不久不对了嘛?是不是需要改源码了?

地图拉伸,不影响取经纬度。但可能会影响示例中的一些功能,有的地方我按公里为单位写的高度,具体没有测试过。

@red-fire-code
Copy link

大佬,请问瓦片的加载能否扩大请求范围,领导需求预加载功能,请问可以设置请求瓦片的范围为屏幕的两倍大嘛?

@sxguojf
Copy link
Owner

sxguojf commented Jul 16, 2024

image

这两属性是改缓存大小的。不过改大了太耗内存和显卡,风扇呜呜响...

本来是想搞个轻量级的,资源用完就释放,需要了再加载。后面考虑加个开关,可以选择把性能拉满。


另外,今天刚改了渲染缓存算法,效率提升不少,还没没发布npm,你可以pull下来试试。

@red-fire-code
Copy link

图像

这两个属性是改变服务器大小的。不过改大了太耗内存和显卡,风扇呜呜响……

本来是想搞个轻量级的,资源用完就释放,需要了再加载。后面考虑加个开关,可以选择把性能拉满。

另外,今天刚改了架构服务器算法,效率提升明显,还没发布npm,大家可以拉下来试试。

好的,我拉下来试试看

@red-fire-code
Copy link

大佬,请问下,我在map上添加的面啊,线啊,闪烁都很严重啊,除了renderOrder、logarithmicDepthBuffer、polygonOffset还有没有好的方法啊?

@FengFengmomo
Copy link
Author

大佬,请问下,我在map上添加的面啊,线啊,闪烁都很严重啊,除了renderOrder、logarithmicDepthBuffer、polygonOffset还有没有好的方法啊?

把你画的面或者线调整一下高度,比如比地图平面高10,闪烁的原因是因为出现深度冲突z-fight。

@red-fire-code
Copy link

大佬,请问下,我在map上添加的面啊,线啊,闪烁都很严重啊,除了renderOrder、logarithmicDepthBuffer、polygonOffset还有没有好的方法啊?

把你画的面或者线调整一下高度,比如比地图平面高10,闪烁的原因是因为出现深度冲突z-fight。

目前上用的这种,感觉不优雅

@FengFengmomo
Copy link
Author

大佬,请问下,我在map上添加的面啊,线啊,闪烁都很严重啊,除了renderOrder、logarithmicDepthBuffer、polygonOffset还有没有好的方法啊?

把你画的面或者线调整一下高度,比如比地图平面高10,闪烁的原因是因为出现深度冲突z-fight。

目前上用的这种,感觉不优雅

可以动态调整一下高度,镜头离的越近,把线和地图平面距离调整的越近就行。或者使用多layer。比较优雅的方法我也不知道,需要guojf大佬出来解答一下了。

@sxguojf
Copy link
Owner

sxguojf commented Jul 18, 2024

大佬,请问下,我在map上添加的面啊,线啊,闪烁都很严重啊,除了renderOrder、logarithmicDepthBuffer、polygonOffset还有没有好的方法啊?

正如 @FengFengmomo 所说,这就是三维开发中常见的Z-Fighting现象,即使不用three-tile,这种情况一样存在。详细解释见threejs官方文档:https://threejs.org/manual/#zh/cameras,threejs也给了解决方案:
image

试试这几种办法:
1、logarithmicDepthBuffer、polygonOffset是threejs官方解决方案,但你大概不想用他们
2、修改camera的near和far,不要让他两差距太大,但图有可能被视锥体错误剪裁。
3、根据地图倾角和与摄像机距离动态调整near、far,GLViewer里有简单算法。
4、如果不想修改near、far,那可以用试试cesium的方法,将地图和地图上叠加物分别渲染到两个目标上,然后将两个渲染结果叠加到一张图上显示。

后面有新问题重新开个主题讨论,这个帖子已经太长了

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

No branches or pull requests

3 participants