我搜索了很多次寻找答案&我无法想象这样的方法不存在!我有一个MKTileOverlayPath (x,y& z),也能得到这个矩形中心的经度/纬度。现在我需要得到每个rect的跨度,这是可能的吗?
发布于 2014-12-12 04:40:16
是的,尽管只使用MapKit并不是很明显。
瓦片和覆盖路径是在网格系统中定义的,因为默认的屏幕瓦片大小是正方形( 256px 2^z * 256 ),所以(正方形)地图一侧的点数等于正方形。z0是一个256px正方形瓦片,z1是一个512px正方形世界的四个瓦片,等等。这个系统中的瓦片坐标是线性的(一个正方形地图中的所有正方形)。
MKMapPoint是从z20派生而来的,因此MKMapSizeWorld是一侧的268,435,456映射点。如果你算一算,2^20 * 256 = 268,435,456。地图点也是线性的(正方形地图中的像素/点)。
纬度和经度当然不是线性的,因为这是一个投影表示,这就是为什么你有像MKMetersPerMapPointAtLatitude()这样的函数。
如果您有以下MKTileOverlayPath:
z = 10x = 12y = 8您知道,世界的点大小是2^10 * 256 = 262,144,世界是边的2^10 = 1,024块。
磁贴的左边缘是向下的点,顶部边缘是向下的点( 256 * 8 = 2,048 points 256 * 12 = 3,072 )。这些都与z10有关,它的规模是z20的268,435,456 / 262,144 = 1,024倍。
这是{ x: (3,072 * 1,024 = 3,145,728), y: (2,048 * 1,024 = 2,097,152) }的MKMapPoint。
右下角也是类似的{ x: 3,407,872, y: 2,359,296 } (将256 * 1,024 = 262,144的大小加到每个图块上)。
您可以在每个函数上使用MKCoordinateForMapPoint()来提取CLLocationCoordinate2D,也可以减去它们之间的差异来获得MKCoordinateSpan。
右上角:{ latitude: 84.8024737243345, longitude: -175.78125 }
{ latitude: 84.7705283207591, longitude: -175.4296875 }
{ latitudeDelta: 0.0319454035754205, longitudeDelta: 0.3515625 }:
是的,这些点非常接近地图的左上角阿拉斯加区域,但考虑到1,024 tiles中的x = 12和y = 8从左上角开始编号,这是合乎逻辑的。
@interface GridTileOverlay : MKTileOverlay
@end
@implementation GridTileOverlay
-(void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *, NSError *))result {
NSLog(@"Loading tile x/y/z: %ld/%ld/%ld",(long)path.x,(long)path.y,(long)path.z);
int worldPointSize = pow(2,(int)path.z)*256; // 2^10 * 256 = 262,144
int tilesOnASide = pow(2,(int)path.z); // 2^10 = 1,024
long leftEdge = path.x *256; // 256 * 12 = 3,072 points
long topEdge = path.y *256; // 256 * 8 = 2,048
int w = self.boundingMapRect.size.width; // 2^20 * 256 = 268,435,456
int zScale = w / worldPointSize; // 268,435,456 / 262,144 = 1,024
int tileSize = 256 * zScale; // 256 * 1,024 = 262,144
long x0 = leftEdge*zScale; // 3,072 * 1,024 = 3,145,728
long y0 = topEdge*zScale; // 2,048 * 1,024 = 3,145,728
long x1 = x0 + tileSize;
long y1 = y0 + tileSize;
MKMapPoint ul = MKMapPointMake(x0, y0); // upper left
MKMapPoint lr = MKMapPointMake(x1, y1); // lower right
MKMapRect mapRect = MKMapRectMake (fmin(ul.x, lr.x),
fmin(ul.y, lr.y),
fabs(ul.x - lr.x),
fabs(ul.y - lr.y));
}
@end 发布于 2016-12-14 10:21:11
主题的变体
+ (MKMapRect)mapRectForTilePath:(MKTileOverlayPath)path
{
CGFloat xScale = (double)path.x / [self worldTileWidthForZoomLevel:path.z];
CGFloat yScale = (double)path.y / [self worldTileWidthForZoomLevel:path.z];
MKMapRect world = MKMapRectWorld;
return MKMapRectMake(world.size.width * xScale,
world.size.height * yScale,
world.size.width / [self worldTileWidthForZoomLevel:path.z],
world.size.height / [self worldTileWidthForZoomLevel:path.z]);
}
/*
Determine the number of tiles wide *or tall* the world is, at the given zoomLevel.
(In the Spherical Mercator projection, the poles are cut off so that the resulting 2D map is "square".)
*/
+ (NSUInteger)worldTileWidthForZoomLevel:(NSUInteger)zoomLevel
{
return (NSUInteger)(pow(2,zoomLevel));
}https://stackoverflow.com/questions/27418144
复制相似问题