ちからわざで日本地図を描いてみた(swift)

#はじめに
objective-cでつくったはいいけど**使っていない**クラスをswiftに書き換えてgithubにあげてみたので、そのクラスについて紹介したいと思います。自分はまだ使う場面がない（今のところ思いつかない）ので、あわよくばだれかに使ってもらえたらいいなと思います。(第五弾)

[第一弾（時計）](https://qiita.com/am10/items/0222e6966d58062d2eca)

[第二弾（スピードメーター）](https://qiita.com/am10/items/0fe8cffac7dd7659eb2a)

[第三弾（めくるカレンダー）](https://qiita.com/am10/items/2a929ca8196f33cb1d4a)

[第四弾（グラフ）](https://qiita.com/am10/items/aee964a8a7a9712d66f8#_reference-ca2e5485de5acf8eca97)

2019/04/21 せっかくなんでswift5.0対応しました
2019/10/16 せっかくなんでSwiftPM対応しました

#GitHub
今回はこちらのクラスについて紹介します。

[AMJpnMapView](https://github.com/adventam10/AMJpnMapView)

#見た目
## AMJpnMapView
![map1.gif](https://qiita-image-store.s3.amazonaws.com/0/225999/b9f9172e-96ac-8420-fce1-d6b64636f129.gif)
![map2.gif](https://qiita-image-store.s3.amazonaws.com/0/225999/92fb82f0-6469-24c4-aa56-7b9ae50c3932.gif)
<img width="372" alt="map.png" src="https://qiita-image-store.s3.amazonaws.com/0/225999/6c9f6053-5584-7ebe-3938-2e15b24ae317.png">
## AMJpnMapDetailView
<img width="372" alt="map_detail.png" src="https://qiita-image-store.s3.amazonaws.com/0/225999/cee31b92-c38c-c7a1-6856-62bfeb8e1b03.png">

#機能
日本地図を表示するView
## AMJpnMapView
* 各地方ごとに色が設定できる
* 各地方の選択ができる
* 各地方ごとに拡大表示ができる

## AMJpnMapDetailView
* 都道府県ごとに色を設定できる

#使い方
## AMJpnMapView
1. xibにカスタムクラスを設定  
<img width="257" alt="custom_class1.png" src="https://qiita-image-store.s3.amazonaws.com/0/225999/f11b3bfb-9445-98c2-7759-d16656d9e7da.png">

2. 初期表示  
色を設定する（全地方共通）  
<img width="255" alt="IBInspectable1.png" src="https://qiita-image-store.s3.amazonaws.com/0/225999/0c915e59-7fc3-265c-c888-fc349003682c.png">

3. デリゲートを設定する  
	
	```swift
	@IBOutlet weak var jpnMapView: AMJpnMapView!
	jpnMapView.delegate = self
	```
	各地方をタップすると下記のデリゲートが呼ばれる
	
	```swift
	protocol AMJpnMapViewDelegate: class {
    
    /// 地方選択時に呼ばれる
    func jpnMapView(jpnMapView: AMJpnMapView, didSelectAtRegion region: AMRegion)
    
    /// 地方選択解除時に呼ばれる
    func jpnMapView(jpnMapView: AMJpnMapView, didDeselectAtRegion region: AMRegion)
}
	```
	
	引数のregionは下記の種類がある
	
	```swift
	enum AMRegion: Int {
    case hokkaido = 0
    case tohoku = 1
    case kanto = 2
    case chubu = 3
    case kinki = 4
    case chugoku = 5
    case shikoku = 6
    case kyushu = 7
    }
    ```

4. 地方ごとに色を設定する  
下記メソッドで色を設定する
	
	```swift
	/// 塗りつぶしの色を設定
	func setFillColor(color: UIColor, region: AMRegion)
	
	/// 枠線の色を設定
	func setStrokeColor(color: UIColor, region: AMRegion)
	```
	
	viewDidLoadではまだ地図を描画していないので色を設定するならviewDidAppearでおこなう必要がある
5. 拡大表示する  
下記メソッドでスケールを設定する

	```swift
	func setScale(scale: CGFloat, region: AMRegion) 
	``` 
	
選択時のデリゲートで下記のように呼べばデモのような動きができる

```swift
/// 地方選択時に呼ばれる
func jpnMapView(_ jpnMapView: AMJpnMapView, didSelectAtRegion region: AMRegion) {
        
        /// 枠線を黒色にする
        jpnMapView.setStrokeColor(color: UIColor.black, region: region)
        /// 拡大する
        jpnMapView.setScale(scale: 3.0, region: region)    
 }

/// 地方選択解除時に呼ばれる
func jpnMapView(_ jpnMapView: AMJpnMapView, didDeselectAtRegion region: AMRegion) {
        
        /// 枠線を緑色にする
        jpnMapView.setStrokeColor(color: UIColor.green, region: region)
        /// 元の大きさにする
        jpnMapView.setScale(scale: 1.0, region: region)
 }
```

## AMJpnMapDetailView
1. xibにカスタムクラスを設定  
<img width="256" alt="custom_class2.png" src="https://qiita-image-store.s3.amazonaws.com/0/225999/40ff90cd-4b53-cc55-b2ca-70c43a4f8d3b.png">

2. 初期表示  
色を設定する（全都道府県共通）  
<img width="254" alt="IBInspectable2.png" src="https://qiita-image-store.s3.amazonaws.com/0/225999/63f4705e-8c68-d8f0-e129-cf7eb84bdbaf.png">

3. 都道府県ごとに色を設定する  
	
	```swift
	/// 枠線の色を設定 
	func setStrokeColor(color: UIColor, prefecture: AMPrefecture)
	
	 /// 塗りつぶしの色を設定      
    func setFillColor(color: UIColor, prefecture: AMPrefecture)
	```

	viewDidLoadではまだ地図を描画していないので色を設定するなviewDidAppearでおこなう必要がある

#つくったきっかけ
ある日、UIBezierPathの勉強をしているときにふと「これ使って部位ごとにレイヤー分ければ、部位ごとに色変更したり、アニメーションつけれるやん！」と思った。その時何を思ったか、とりあえず日本地図を描こうと思いつくった。最初は地方ごとのやつをつくったが、どうせなら都道府県もと思い都道府県のやつもつくった。

#使わなかった理由
1. 細部の描画が雑  
実際に利用するとなると割と形が雑なので、各都道府県の人に怒られそうである。利用するならもう少しクオリティを上げたい。

#つくり方
日本地図の描画方法について少し書いておきます。

1. 正方形の日本地図の画像を用意する
2. xibに正方形のViewを置く
3. 上記のView上にImageViewを置き、日本地図の画像を表示する
4. さらにその上に小さなViewを置く
5. 日本地図の頂点に小さなViewの左上を合わせる
6. 小さなViewのframe.originをメモする
7. 5,6を日本地図の各頂点で繰り返す
8. 日本地図を描画したいViewに上記メモの座標で描画していく  
ex.2で用意したViewのサイズがx:500,y:500で、日本地図を描画したいViewのサイズがx:300,y:300とする。  
下記の計算でメモした座標を描画したいViewのサイズに合わせる
	
	```swift
	/// pointX、pointYはメモした座標
	CGPoint(x: 300 * (pointX/500.0), y: 300 * (pointY/500.0))
	```
	この座標を元に```UIBezierPath```を作成する

5.6.の作業はこんな感じ
<img width="1023" alt="map_memo.png" src="https://qiita-image-store.s3.amazonaws.com/0/225999/00fe3158-d82f-850b-ec92-3efaf01934e9.png">
白いViewが2.のView、赤いViewが4.の小さなViewに当たる。
この例では北海道のえりも岬あたりの座標がx:399,y:130であることがわかる。

簡単である。

アホだと思うが、当時は数時間この作業を嬉々としておこなっていた。無駄な作業のようであるが、充実した日々であったように思う...

当時は、日本地図が描けると思いこんな方法をとったが、複雑なパスを作成する際は、画像編集ソフトとかで作成して、そのファイルを読み込んだ方が断然いいように思う。私は知らないが、きっとそういう方法があるはずである。

#さいごに
以上の理由から今のところは使用していませんが、もしかしたら今後使う場面があるかもしれません。都道府県を選択するときは、tableViewを利用しているが、日本地図で選択した方がおもしろいんじゃないかと思った。もう少しクオリティをあげれば使ってもらえるかもしれない...

私はほぼObjective-Cしか使ったことがないペーペーのプログラマーなので記事内容やgithubのコードにおかしなところがあればご指摘いただければ幸いです。

#つくったのまとめ
* [アナログ時計を描画してみた（swift）](https://qiita.com/am10/items/0222e6966d58062d2eca)
* [スピードメーターをつくってみた（swift）](https://qiita.com/am10/items/0fe8cffac7dd7659eb2a)
* [めくるカレンダーをつくってみた(swift)](https://qiita.com/am10/items/2a929ca8196f33cb1d4a)
* [グラフを描画してみた(swift)](https://qiita.com/am10/items/aee964a8a7a9712d66f8#_reference-ca2e5485de5acf8eca97)
* [ちからわざで日本地図を描いてみた(swift)](https://qiita.com/am10/items/26de3242ee33b4bd4aae)
* [カラーピッカーをつくってみた(swift)](https://qiita.com/am10/items/82a4adb2267979841c9e)
* [面積比がそれっぽいベン図を描いてみた(swift)](https://qiita.com/am10/items/858041f70be4d8de5090)
* [UIViewを燃やしてみた（swift）](https://qiita.com/am10/items/f7b32ea5725feeb1469f)

##動作確認用にまとめたプロジェクト
* [Carthageで入れたやつ](https://github.com/adventam10/TestCarthage)
* [CocoaPodsで入れたやつ](https://github.com/adventam10/TestCocoaPods)
* [SwiftPMで入れたやつ](https://github.com/adventam10/TestSwiftPM)