标签: mktileoverlay

地图的离线缓存

我非常需要为我的应用做离线地图,因为它主要是为泰国制作的,因为泰国通常很难连接互联网.我现在正在使用OpenStreetMap我的MKTileOverlay但是在实现它以供离线使用时遇到问题.我找到了一个教给子类的教程MKTileOverlay.所以,在我ViewController的地图上我有:

 - (void)viewWillAppear:(BOOL)animated {

    CLLocationCoordinate2D coord = {.latitude =  15.8700320, .longitude =  100.9925410};
    MKCoordinateSpan span = {.latitudeDelta =  3, .longitudeDelta =  3};
    MKCoordinateRegion region = {coord, span};
    [mapView setRegion:region];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"Map";
    NSString *template = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png";
    self.overlay = [[XXTileOverlay alloc] initWithURLTemplate:template];
    self.overlay.canReplaceMapContent = YES;
    [mapView addOverlay:self.overlay level:MKOverlayLevelAboveLabels];
}

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay {

    return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
}
Run Code Online (Sandbox Code Playgroud)

在我的子类中MKTileOverlay,我有:

- (NSURL *)URLForTilePath:(MKTileOverlayPath)path { …
Run Code Online (Sandbox Code Playgroud)

openstreetmap mapkit offline-caching ios mktileoverlay

17
推荐指数
1
解决办法
1297
查看次数

iOS - 某些图块未在自定义 MKTileOverlay 中呈现

我在我的 iOS 项目中使用 MapKit 有一个自定义的 MKTileOverlay,它大部分时间都可以正常工作。但是,在放大/缩小几次并平移地图后,一些图块没有被绘制。

起初我认为这是一个没有加载瓷砖的简单情况,所以我对 MKTileOverlay 进行了子类化并在控制台中添加了日志记录。它表明所有瓷砖都被完美地加载并交付到结果块。

由于我的想法不多了,我创建了一个本地图块生成器,它只返回带有 x/y/z 路径和绘制的框架的图像,以查看缺少哪些图块。

缺少图块示例图像

不幸的是,即使使用本地生成的图块,问题仍然存在,因此它与 Internet 连接无关。另一个奇怪的行为是,如果我有两个自定义叠加层,它们将是完全相同的图块,但不会在两个叠加层上呈现。

我现在能想到的唯一解决方案是将 tile 渲染器子类化并确保显示所有内容,因为无法知道 tile 未呈现。然而,这听起来像是很多工作和“重新发明轮子”的任务......

mapkit ios custom-overlay mktileoverlay

8
推荐指数
1
解决办法
920
查看次数

带有Retina-Tiles的MKTileOverlay

我有问题要在MKMapKit中加载512x512px图块.服务器提供512x512 .jpeg磁贴.

我在MKMapView中找不到自定义视网膜图块的任何解决方案或示例实现.

我所做的:

当我将它们加载到MKMapView中时

 overlay = [[MKTileOverlay alloc] initWithURLTemplate:template];
 overlay.tileSize = CGSizeMake(512.0f, 512.0f);
 [_mapView insertOverlay:overlay atIndex:MAP_OVERLAY_INDEX_TILE level:MKOverlayLevelAboveLabels];
Run Code Online (Sandbox Code Playgroud)

...瓷砖缩放正确但只加载了一半(不仅在视觉上 - 我嗅探了请求并且缺少了瓷砖)

 overlay = [[MKTileOverlay alloc] initWithURLTemplate:template];
 overlay.tileSize = CGSizeMake(256.0f, 256.0f);
 [_mapView insertOverlay:overlay atIndex:MAP_OVERLAY_INDEX_TILE level:MKOverlayLevelAboveLabels];
Run Code Online (Sandbox Code Playgroud)

...显示所有图块但缩放不正确

这是我的绘图方法:

(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay
{
    MKOverlayRenderer *overlayRenderer = nil;

    if([overlay isKindOfClass:MKTileOverlay.class])
    {
        overlayRenderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
    }

    return overlayRenderer;
}
Run Code Online (Sandbox Code Playgroud)

... overlayRenderer.contentScaleFactor总是1 ...无论是什么tileSize(iOS模拟器7.1视网膜)

有什么建议?

最好的问候,史蒂夫

scale mapkit ios retina mktileoverlay

6
推荐指数
1
解决办法
1463
查看次数

另一个MKMapView缩放级别和离线地图

我一直在iOS 7中使用MKMapView尝试设置并以编程方式获取缩放级别,以便在我离线时下载和重用地图图块.

因为我无法将整个地图下载到我的手机中,所以我只是按照适当的缩放级别下载了几个平铺,然后我修复了缩放级别并使用了思想MKTileOverlayMKTileOverlayRenderer的平铺.

我尝试使用Troybrant的算法(http://troybrant.net/blog/2010/01/set-the-zoom-level-of-an-mkmapview),但它对我来说效果不佳.它无法正确建立缩放级别.

所以我创建了一个我自己的工作正常.

关于我自己的方法的一些解释:

  • 在最大地图缩放级别(20),您将看到每个地图点的比例为1:1.整个地图将有256*2 ^ 20点.

  • 在视网膜显示器中,在地图点和像素之间存在2.0比例因子.

  • Apple地图的缩放级别可以从3到19(最小和最大)不等

  • 然后有一个简单的反向规则:

    • 在最大缩放级别,我们的视图将显示与其具有的像素一样多的点(视网膜显示器的点像素比例因子为2.0)
    • 如果缩放级别降低,则显示的地图点数量应增加(反向规则)


有了这些信息,我们的想法是设置MKMapView的visibleRect属性:

visibleRect width points = 2.0 * mapView.bounds.size.width * 2^(20-zoom)
Run Code Online (Sandbox Code Playgroud)

使用该公式,我已经能够将我的地图居中并适当地应用它们缩放级别.


正如Troybrant所做的那样,我使用以下方法创建了一个类别:

@interface MKMapView (ZoomLevel)

- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
                  zoomLevel:(NSUInteger)zoomLevel
                  animated:(BOOL)animated;
@end

@implementation MKMapView (ZoomLevel)

- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
                  zoomLevel:(NSUInteger)zoomLevel
                  animated:(BOOL)animated
{
    MKMapPoint centrePoint = MKMapPointForCoordinate(centreCoord);

    CGFloat rectWidth = 2.0 * self.bounds.size.width * pow(2, 20-zoomLevel);
    CGFloat rectHeight = 2.0 * self.bounds.size.height * pow(2, 20-zoomLevel);

    MKMapRect visibleRect = MKMapRectMake(centrePoint.x-rectWidth/2, centrePoint.y-rectHeight/2, rectWidth, …
Run Code Online (Sandbox Code Playgroud)

offline zoom mkmapview ios mktileoverlay

5
推荐指数
0
解决办法
1975
查看次数

iOS MKMapView加载自定义瓦片优化

我使用自定义 TileOverlay 开发了 iOS 地图应用程序,它从我们自己的服务器加载图块。我扩展了 TileOverlay 类,它获取图块数据如下:

override func loadTile(at path: MKTileOverlayPath, result: @escaping (Data?, Error?) -> Void)
{
    let url = self.url(forTilePath: path)
    if let cachedData = cache.object(forKey: url as AnyObject) as? NSData
    {
        result(cachedData as Data, nil)
    } else {

        let session = URLSession.shared
        let request = NSURLRequest(url: url)
        let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in

            if let data = data {
                self.cache.setObject(data as AnyObject, forKey: url as AnyObject)
            }
            result(data, …
Run Code Online (Sandbox Code Playgroud)

mapkit mkmapview ios mktileoverlay swift

5
推荐指数
0
解决办法
1286
查看次数

MapKit : 添加 MKPolyline 隐藏 MKTileOverlay

MKMapView正在处理MKTileOverlay来自本地数据库的显示图块。它工作正常。
然后我用来MKDirections获得两个坐标之间的方向并绘制这样的路线:

MKRoute *route = response.routes.lastObject;
MKPolyline *polyline = route.polyline;

// Draw path on overlay
[self.mapView insertOverlay:polyline aboveOverlay:self.tileOverlay];
Run Code Online (Sandbox Code Playgroud)

但是当我缩放以查看线条时,它看起来没有平铺背景(通常从MKTileOverlay(存储到self.tileOverlay)加载)。我加入了一个图像以更好地查看。

我还制作了此代码来呈现叠加层:

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
    if ([overlay isKindOfClass:[MKTileOverlay class]]) {
        return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
    }
    else if ([overlay isKindOfClass:[MKPolyline class]]) {
        MKPolylineRenderer *lineView = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
        lineView.strokeColor = [UIColor greenColor];
        lineView.lineWidth = 3;
        return lineView;
    }
    return nil;
}
Run Code Online (Sandbox Code Playgroud)

这就像渲染线的“瓷砖”隐藏从MKTileOverlay. 我怎样才能:
- 指定MKPolyline叠加层必须是透明的?
- …

objective-c mkpolyline mktileoverlay

3
推荐指数
1
解决办法
858
查看次数