0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Apple MapKitのMKTileOverlayを使ってタイル座標のズームレベルを取得する

Last updated at Posted at 2024-07-07

概要

Apple MapKitのMKTileOverlayを使ってタイル座標のズームレベルを取得します

背景

地理情報システム(GIS)を作成するときタイル座標およびタイル画像は欠かせない概念かと思います。タイル座標は z/x/y の形式で表現されます。

しかしながら、Apple MapKitにはズームレベルという概念がなく、よくregionを操作・計算してズームレベルを計算します。

しかし調査をしたところ、MKTileOverlayというタイル画像を読み込むためのクラスを用いることで簡単にズームレベルを取得できることがわかりました!

このことについての解説記事が自分が調査した範囲では見つけることができなかったので、この記事を作成した次第です。同じケースでお悩みの方の参考になれば嬉しいです🙏

サンプルコード

import UIKit
import MapKit

class ViewController: UIViewController {
    // 国土地理院のTileOverlayを作成する
    lazy var mapTile = MKTileOverlay(urlTemplate: "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png")
    // タイル座標のカスタムTileOverlayを作成する
    lazy var gridTile = GridOverlay()

    lazy var mapView: MKMapView = {
        let mapView = MKMapView()
        mapView.delegate = self
        // 地理院のタイルを追加
        mapView.addOverlay(mapTile)
        // カスタムタイルを追加
        mapView.addOverlay(gridTile)
        return mapView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        mapView.frame = view.bounds
        view.addSubview(mapView)
        
        // Mapの初期化
        let coordinate = CLLocationCoordinate2D(latitude: 35.681236, longitude: 139.767125)
        let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
        let region = MKCoordinateRegion(center: coordinate, span: span)
        mapView.setRegion(region, animated: false)
    }
}

extension ViewController: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        // TileOverlayの描画
        return MKTileOverlayRenderer(overlay: overlay)
    }
}

class GridOverlay: MKTileOverlay {
    override func loadTile(at path:MKTileOverlayPath, result:@escaping (Data?, Error?) -> Void) {
        UIGraphicsBeginImageContext(CGSize(width: 256,height: 256))

        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }
        
        // 格子を描画する
        context.setStrokeColor(UIColor.black.cgColor)
        context.stroke(CGRect(x: 0, y: 0, width: 256,height: 256))
    
        // タイル座標(z/x/y)をテキストを描画する
        UIGraphicsPushContext(context)
        let font = UIFont.systemFont(ofSize: 20)
        let text = "\(path.z) / \(path.x) / \(path.y)"
        let string = NSAttributedString(string: text, attributes: [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: UIColor.red])
        string.draw(at: CGPoint(x: 0, y: 118))
        UIGraphicsPopContext()


        let tileImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        result(tileImage?.pngData(), nil)
    }
}

キャプチャ画像

準備中

国土地理院の座標確認ページとぜひ比較してみてください!

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?