MKTileOverlayPath返回X/Y/Z值异常 如何转换为谷歌瓦片格式
问题根因
你拿到的超大异常X/Y/Z值不是MapKit原生返回的合法瓦片坐标,是Xamarin.iOS对MKTileOverlayPath结构体的绑定存在内存偏移bug导致的。
原生MKTileOverlayPath实际包含x、y、z、contentScaleFactor四个字段,部分版本的Xamarin.iOS绑定没有正确对齐字段内存位置,直接读取公开的X/Y/Z属性时会读到内存错位后的垃圾值,和瓦片坐标系转换逻辑无关。
修复方法
不要直接调用path.X/path.Y/path.Z属性,通过键值编码直接读取原生对象存储的真实坐标值即可,实现代码如下:
public override NSUrl URLForTilePath(MKTileOverlayPath path, NSUrlCallback callback) { // 直接读取原生字段的正确值 int tileZ = (int)path.ValueForKey(new NSString("z")); int tileX = (int)path.ValueForKey(new NSString("x")); int tileY = (int)path.ValueForKey(new NSString("y")); // 拼接谷歌瓦片体系的文件路径 string tileFilePath = $"{tileZ}/{tileX}/{tileY}.jpg"; // 按你自己的存储逻辑拼接完整路径返回即可 return NSUrl.FromFilename(Path.Combine(yourTileLibraryRootPath, tileFilePath)); }
适配说明
拿到正确的z/x/y值后不需要额外做坐标系转换:MapKit的瓦片Y轴方向和谷歌地图瓦片体系一致,不需要做TMS瓦片常见的Y轴翻转操作,z值会落在你预期的1-19缩放区间,x、y值在对应缩放等级下也会符合谷歌瓦片的取值范围(z级下x/y取值为0到2^z - 1)。
验证参考:当地图缩放到对应谷歌19级时,x、y的取值范围应该在0到524287之间,不会再出现十亿级别的异常数值。
内容的提问来源于stack exchange,提问作者Bouapha
相关产品推荐
相关产品推荐

