Google S2 Geometry产生错误Check failed: si = KMaxSiti

为何 Google S2 geometry 产生错误Check failed: si <= kMaxSiTi

  最近在学习Google开源的S2 Geometry库,在学习和使用的过程中,由于理解上的不到位,一个BUG困扰了我将近一周的时间,今天来跟大家分享一下,如果你碰巧也碰到了这个问题,那太好了,真希望能帮到你,那我会很开心,错误的地方,还望指正。

 S2算法填充曲线采用的是Hilbert Curve,代码中默认使用的lKMaxCellLevel = 30(在s2coords.h中),由于我不需要使用这么高的精度,所以我选用了lKMaxCellLevel = 12,然后我进行编译,编译通过,在使用经纬度构造S2CellId的对象时,并没有报错,代码如下:

S2CellId cell_id(S2LatLng::FromDegrees(lat_degrees, lng_degrees));

 构造并没有报错,当然可能得到的S2CellID对象是不符合他应有的数据结构的。
当我通过地图块的id值(数据类型:unsigned long long)来构造S2CellId的对象,然后返回id值对应的经纬度时,却出现了如下的报错信息:
图1
 我的id值转经纬度的主要代码片度如下:

S2CellId cellId(id);
R2Point point;
S2LatLng latlng;
latlng = cellId.ToLatLng();
lat = latlng.lat().degrees();
lon = latlng.lng().degrees();

 一般说来,我从经纬度获得地图块的id值,然后再从地图块的id值获得经纬度,应该会得到和我输入的经纬度一样的结果,但是这里不但得不到正确的结果,反而还会产生上面的报错信息,我根据报错信息中的提示找到了s2coords.h中对应的代码:

inline double SiTitoST(unsigned int si){
	S2_DCHECK_LE(si, kMaxSiTi);
	return (1.0 / kMaxSiTi) * si;
}

 报错就是因为S2_DCHECK_LE(si, kMaxSiTi)这一句,报错产生的原因就是,因为si > kMaxSiTi,如果你已经了解过了Hilbert Curve的原理,那么就应该就知道,si应该对应的就是平面划分为栅格之后在s方向上的第i个栅格,对于level为12的划分精度,面的边长应该是 s i d e = 2 12 − 1 side = 2^{12} - 1 side=2121正常情况下来说si <= side,所以一定是从经纬度构造S2CellId的时候出错了,我在这里折腾了四五天总算找到了一个解决方法(也许这就是S2正确的使用方法吧),依然使用lKMaxCellLevel = 30的默认值,从经纬度求id值的代码修改如下:

S2CellId cell_id(S2LatLng::FromDegrees(lat_degrees, lng_degrees));
id = cell_id.parent(12).id();

这里我还是按照默认的lKMaxCellLevel = 30来划分地图,但是在我需要获得id值的时候,我使用了cell_id.parent(12).id()这个函数,将parent(int)的值设为12,这样我就获得了当前经纬度在level=12时对应的id值了。当我将上述方法获得的id值用到上述求取经纬度的代码中时,原先报的错误不在出现了。然后也得到了我需要的结果了!

 
如果您有更好的方法,请不吝赐教!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值