瓦片地图
简单点来讲,我们可以把一张地图看成有很多张正方形图片组成的,就像瓦片一样排放,但是这个排放是有一定的规律的.当然地图的缩放等级决定了图片的数量.
举个��
以世界地图为例,那么在缩放等级为0的情况下,就需要一个地图就能显示完.如果放大一个等级,在缩放等级为1的情况下,那么就需要4张图片.
那么我们假设地图缩放等级为n,那么一幅地图就需要(4^n)张图片.
下图就是当缩放等级为1时候的世界地图.
解释下上图上面的一些信息
- 通过各个瓦片地址下载下来的图片都是256*256大小的正方形图片.
- 箭头左边的小图片是通过它下面的地址下载下来的,箭头右边是经过拼接后组成的世界地图.
- 下载地址中的链接可以接单做下介绍,这里我使用的是Google的瓦片地图地址.
- 其中
mt2
是服务器地址,为了缓解压力Google提供了3台服务器,前缀分别为mt1
,mt2
,mt3
-
lyrs
个人猜测是layers
的缩写,就是图层的意思,更换不同的图层会获取不一样的地图.-
lyrs = m
就是常规的Google地图. -
lyrs = s
是Google的卫星图. -
lyrs = p
是Google的地形图.
-
-
x和y
就是把地球通过墨卡托投影到平面上后的坐标.关于这个墨卡托投影没必要深究,大概明白是怎么回事就可以了.
-
z
就是地图的缩放等级,z值越大,比例尺越大,但地图精确度越小.
- 其中
瓦片地图地址
这里我简单介绍几种.
- OpenStreetMap
- OpenCycleMap
- Mapquest
-
Google开源地图
下面这些只是例子
http://mt2.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&x=0&y=0&z=1 - 高德地图
http://wprd02.is.autonavi.com/appmaptile?style=7&x=0&y=0&z=1
各个瓦片地图格式
NSString * const googleStandard = @"http://mt0.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}";
NSString * const googleSatellite = @"http://mt0.google.cn/vt/lyrs=s&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}";
NSString * const googleTerrain = @"http://mt0.google.cn/vt/lyrs=p&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}";
NSString * const opencyclemap = @"http://b.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png";
NSString * const openstreetmap = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png";
NSString * const landscape = @"http://a.tile.opencyclemap.org/landscape/{z}/{x}/{y}.png";
NSString * const gaodeMap = @"http://wprd02.is.autonavi.com/appmaptile?style=7&x={x}&y={y}&z={z}.png";
瓦片地图在iOS项目中使用
瓦片地图拼接完之后,是依托于MapKit
中mapView
这个控件的,需要在mapView
上添加一个图层.在MapKit
中这个图层也有个类叫做MKTileOverlay
.把这个图层添加到mapView
中之后,通过重新渲染描绘替换掉MapKit
中自带的高德地图.
下面是把OpenStreetMap
添加到mapView
上
#import "ViewController.h"
#import <MapKit/MapKit.h>
NSString * const openstreetmap = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png";
@interface ViewController ()<MKMapViewDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (strong,nonatomic) MKTileOverlay *customOverlay;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.mapView.delegate = self;
[self.mapView addOverlay:self.customOverlay];
}
- (MKTileOverlay *)customOverlay{
if (!_customOverlay) {
_customOverlay = [[MKTileOverlay alloc]initWithURLTemplate:openstreetmap];
_customOverlay.canReplaceMapContent = YES;
}
return _customOverlay;
}
#pragma mark - MKMapViewDelegate
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
if ([overlay isKindOfClass:[MKTileOverlay class]]) {
return [[MKTileOverlayRenderer alloc]initWithTileOverlay:overlay];
}else{
return nil;
}
}
@end
原地址:https://heisenbean.me/2016/02/OSM-in-iOS/