準備

  1. APIキーからAPIキーを取得する
  2. ダウンロードからframeworkをダウンロードし解凍する
  3. 解凍したディレクトリ内のpin@2x.pngをプロジェクトにコピーする(それ以外のアイコンも自由にお使い下さい)
  4. 解凍したディレクトリをプロジェクトに追加する
  5. CoreLocation.framework,QuartzCore.framework,libsqlite3.dylibをプロジェクトに追加する

地図を表示する

#import <MapionMaps/MapionMaps.h>
...
- (void)viewDidLoad {
  [super viewDidLoad];
  
  MMMapView *mapView = [[MMMapView alloc] initWithFrame:[[self view] bounds] key:@"APIキー"];
  // 地図を指定する場合(以下は3D風地図を表示する例(3D風地図は法人向けのみの機能です))
  // id <MMMap> mapionMap3d = [[MMMapionMap3D alloc] init];
  // MMMapView *mapView = [[MMMapView alloc] initWithFrame:[[self view] bounds] key:@"APIキー" map:mapionMap3d];
  
  [self.view addSubview:mapView];
  
  // 地図を変更したい場合
  // id <MMMap> openStreetMap = [[OpenStreetMap alloc] init];
  // mapView.map = openStreetMap;
}

緯度経度縮尺を指定して地図を表示する

#import <MapionMaps/MapionMaps.h>
...
- (void)viewDidLoad {
  [super viewDidLoad];
  
  MMMapView *mapView = [[MMMapView alloc] initWithFrame:[[self view] bounds] key:@"APIキー"];
  [self.view addSubview:mapView];
  
  [mapView setZoom:12.3 animated:NO]; // animated:YESでアニメーションする
  
  CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(35.3, 139.3);
  [mapView setCenterCoordinate:coordinate animated:NO]; // animated:YESでアニメーションする
}

ピンを立てる

MMAnnotationView *annotationView = [[MMAnnotationView alloc] initWithMapView:mapView coordinate:mapView.centerCoordinate];
// フラットデザインの吹き出しの場合
// MMAnnotationView *annotationView = [[MMFlatAnnotationView alloc] initWithMapView:mapView coordinate:mapView.centerCoordinate];
// 吹き出し内のボタンを表示させたくない場合
// MMAnnotationView *annotationView = [[MMAnnotationView alloc] initWithMapView:mapView coordinate:mapView.centerCoordinate useLeftAccessoryView:NO useRightAccessoryView:NO];

annotationView.title = @"タイトル";
annotationView.subtitle = @"サブタイトル";
annotationView.rightButtonTapped = ^(MMMapView *mapView) {
  // 吹き出し内の詳細ボタンタップ時の挙動をここに書く
};

// 独自アイコンを使いたい場合
// annotationView.image = [UIImage imageNamed:@"myicon.png"];
// annotationView.centerOffset = CGPointMake(-21, -28); // アイコンの中心を設定する

// annotationViewのタッチイベントをオーバーライドしたい場合
// annotationView.tapped = ^(MMMapView *mapView) {
// 
// };

// 吹き出し内の右側viewを適当なviewに切り替えたい場合(左側も同様)
// annotationView.rightAccessoryView = [UIButton buttonWithType:UIButtonTypeInfoDark];
// [annotationView.rightAccessoryView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(test)]];

[mapView addAnnotation:annotationView animated:NO]; // animated:YESでアニメーションする

// [mapView removeAnnotation:annotationView]; // ピンを削除する場合
// [mapView removeAnnotations:mapView.annotations]; // 全てのピンを削除する場合

リスナー

MMMapViewDelegateを実装したクラスを作ってMMMapViewのdelegateプロパティに設定する

#import <MapionMaps/MapionMaps.h>

@interface MapViewDelegate : NSObject <MMMapViewDelegate>

@end

@implementation MapViewDelegate

- (void)doubleTap:(MMMapView *)mapView point:(CGPoint)point {
  // ダブルタップ時
}

- (void)singleTap:(MMMapView *)mapView point:(CGPoint)point {
  // シングルタップ時
}

- (void)singleTapTwoFingers:(MMMapView *)mapView point:(CGPoint)point {
  // 2本指タップ時
}

- (void)longSingleTap:(MMMapView *)mapView point:(CGPoint)point {
  // 長押し時
}

- (void)beforeMapMove:(MMMapView *)mapView {
  // 地図をスクロールする前
}

- (void)afterMapMove:(MMMapView *)mapView {
  // 地図をスクロールした後
}

- (void)beforeMapZoom:(MMMapView *)mapView {
  // ズームチェンジする前
}

- (void)afterMapZoom:(MMMapView *)mapView {
  // ズームチェンジした後
}

@end
mapView.delegate = [[MapViewDelegate alloc] init];

スクリーン座標を緯度経度に変換する

CGPoint point = [touch locationInView:mapView];
CLLocationCoordinate2D coordinate = [mapView pixelToCoordinate:point];

緯度経度をスクリーン座標に変換する

CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(35.3, 139.3);
CGPoint point = [mapView coordinateToPixel:coordinate];

独自地図を表示する


OpenStreetMapのようなデファクトスタンダードな仕様の地図であればMMAbstractEPSG900913Mapクラスを継承することにより容易に実現できます。独自地図にピンを立てたりラインを引くことも可能です。


OpenStreetMapを表示する場合
#import <MapionMaps/MapionMaps.h>

@interface OpenStreetMap : MMAbstractEPSG900913Map

@end

@implementation OpenStreetMap

- (int)tileLength {
  return 512; // ズームにおける1タイルあたりの最大サイズ。デフォルトは256。OpenStreetMapのタイルのサイズは256なので512にすると2倍まで拡大する。
}

- (float)minZoom {
  return 0;
}

- (float)maxZoom {
  return 18;
}

- (NSString *)name {
  return @"OpenStreetMap";
}

- (NSString *)copyright {
  return @"Map data © OpenStreetMap contributors, CC BY-SA";
}

- (NSURL *)URLForTile:(MMTile)tile {
  NSString *urlString = [NSString stringWithFormat:@"http://tile.openstreetmap.org/%d/%d/%d.png", tile.zoom, tile.x, tile.y];
  
  return [NSURL URLWithString:urlString];
}

@end

使い方
#import <MapionMaps/MapionMaps.h>
#import <OpenStreetMap.h>
...
- (void)viewDidLoad {
  [super viewDidLoad];
  
  id <MMMap> openStreetMap = [[OpenStreetMap alloc] init];
  MMMapView *mapView = [[MMMapView alloc] initWithFrame:[[self view] bounds] key:@"APIキー" map:openStreetMap];
  
  [self.view addSubview:mapView];
}
国土地理院の地図を表示する場合
国土地理院の地図データを使用するには国土地理院の許諾が必要です(許諾を得るための申請要領等について
#import <MapionMaps/MapionMaps.h>

@interface GSIMap : MMAbstractEPSG900913Map

@end

@implementation GSIMap

- (int)tileLength {
  return 512; // 国土地理院のタイルのサイズは256なのでこうすると最大2倍表示
}

- (float)minZoom {
  return 5;
}

- (float)maxZoom {
  return 18;
}

- (NSString *)name {
  return @"GSI";
}

- (NSString *)copyright {
  return @"(国土地理院背景地図等データ利用許諾番号)20xx-xxx号"; // 国土地理院から付与される許諾番号を書く
}

- (NSURL *)URLForTile:(MMTile)tile {
  NSString *did;
  switch (tile.zoom) {
    case 5:
    case 6:
    case 7:
    case 8:
      did = @"JAIS";
      break;
    case 9:
    case 10:
    case 11:
      did = @"BAFD1000K";
      break;
    case 12:
    case 13:
    case 14:
      did = @"BAFD200K";
      break;
    case 15:
    case 16:
    case 17:
      did = @"DJBMM";
      break;
    case 18:
      did = @"FGD";
      break;
    default:
      did = @"";
      break;
  }
  
  NSString *xstr = [NSString stringWithFormat:@"%07d", tile.x];
  NSString *ystr = [NSString stringWithFormat:@"%07d", tile.y];
  NSString *path = [self path:xstr y:ystr];
  
  NSString *urlString = [NSString stringWithFormat:@"http://cyberjapandata.gsi.go.jp/sqras/all/%@/latest/%d%@/%@%@.png", did, tile.zoom, path, xstr, ystr];
  
  return [NSURL URLWithString:urlString];
}

#pragma mark - private

- (NSString *)path:(NSString *)x y:(NSString *)y {
  NSString *dir = @"";
  NSString *xi;
  NSString *yi;
  for (int i = 0; i < 6; i++) {
    xi = [x substringWithRange:NSMakeRange(i, 1)];
    yi = [y substringWithRange:NSMakeRange(i, 1)];
    dir = [dir stringByAppendingFormat:@"/%@%@", xi, yi];
  }
  return dir;
}

@end
使い方
#import <MapionMaps/MapionMaps.h>
#import "GSIMap.h"
...
- (void)viewDidLoad {
  [super viewDidLoad];
  
  id <MMMap> gsiMap = [[GSIMap alloc] init];
  MMMapView *mapView = [[MMMapView alloc] initWithFrame:[[self view] bounds] key:@"APIキー" map:gsiMap];
  
  [self.view addSubview:mapView];
}
ローカルに保存したOpenStreetMapを表示する場合
#import <MapionMaps/MapionMaps.h>

@interface LocalStandardMap : MMAbstractEPSG900913Map

@end

@implementation LocalStandardMap

- (float)minZoom {
  return 17;
}

- (float)maxZoom {
  return 18;
}

- (UIImage *)imageForTile:(MMTile)tile {
  // ローカルに{zoom}_{x}_{y}.pngという形式で保存した場合
  return [UIImage imageNamed:[NSString stringWithFormat:@"%d_%d_%d", tile.zoom, tile.x, tile.y]];
}

- (NSString *)copyright {
  return @"Map data © OpenStreetMap contributors, CC BY-SA";
}

@end

使い方
#import <MapionMaps/MapionMaps.h>
#import <LocalStandardMap.h>
...
- (void)viewDidLoad {
  [super viewDidLoad];
  
  id <MMMap> localStandardMap = [[LocalStandardMap alloc] init];
  MMMapView *mapView = [[MMMapView alloc] initWithFrame:[[self view] bounds] key:@"APIキー" map:localStandardMap];
  
  [self.view addSubview:mapView];
}

独自画像を表示する


ローカルやWEBにある独自画像を表示することが可能です。独自画像にピンを立てたりラインを引くことも可能です。例として以下の画像(mapiontown.jpeg)をタイル化してframeworkで表示させる場合を示します。




タイル化手順
  1. GMap Image Cutterをダウンロード&インストール
  2. GMap Image Cutterを起動する
  3. mapiontown.pngを開く
  4. Createを押す
  5. mapiontown-tilesとmapiontown.htmlが出来上がる(必要なのはmapiontown-tiles内のタイルです)
  6. Supporting Filesにタイルをコピーする
MapionTownMapクラス作成
#import <MapionMaps/MapionMaps.h>

@interface MapionTownMap : NSObject <MMMap>

@end

#import "MapionTownMap.h"

@implementation MapionTownMap

#pragma mark - MMMap

- (int)tileLength {
  return 256;
}

- (float)minZoom {
  return 0;
}

- (float)maxZoom {
  return 3;
}

- (NSString *)name {
  return @"MapionTown";
}

- (NSString *)copyright {
  return @"© Mapion";
}

- (MMProjectedRect)projectedRect {
  float maxLength = 256 / [UIScreen mainScreen].scale;
  return MMProjectedRectMake(-maxLength, -maxLength, maxLength * 2, maxLength * 2);
}

- (UIImage *)imageForTile:(MMTile)tile {
  NSString *fileName = [self tileToFileName:tile];
  return [UIImage imageNamed:fileName];
}

- (CLLocationCoordinate2D)projectedPointToCoordinate:(MMProjectedPoint)point {
  CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(point.y, point.x);
  return coordinate;
}

- (MMProjectedPoint)coordinateToProjectedPoint:(CLLocationCoordinate2D)coordinate {
  MMProjectedPoint point;
  point.x = coordinate.longitude;
  point.y = coordinate.latitude;
  return point;
}

#pragma mark - Private

- (NSString *)tileToFileName:(MMTile)tile {
  double p = pow(2.0, tile.zoom);
  int x = tile.x;
  int y = tile.y;
  
  NSMutableString *tileName = [NSMutableString string];
  [tileName appendString:@"t"];
  for (int i = 0; i < tile.zoom; i++) {
    p = p / 2;
    if (y < p) {
      if (x < p) {
        [tileName appendString:@"q"];
      } else {
        [tileName appendString:@"r"];
        x -= p;
      }
    } else {
      if (x < p) {
        [tileName appendString:@"t"];
        y -= p;
      } else {
        [tileName appendString:@"s"];
        x -= p;
        y -= p;
      }
    }
  }
  [tileName appendString:@".jpg"];
  return tileName;
}

@end

使い方
#import <MapionMaps/MapionMaps.h>
#import "MapionTownMap.h"
...
- (void)viewDidLoad {
  [super viewDidLoad];
  
  id <MMMap> mapionTownMap = [[MapionTownMap alloc] init];
  MMMapView *mapView = [[MMMapView alloc] initWithFrame:[[self view] bounds] key:@"APIキー" map:mapionTownMap];
  
  [self.view addSubview:mapView];
}

キャッシュの上限値を設定する

MMMapViewDelegateのcacheCapacityを実装する

- (NSUInteger)cacheCapacity {
  return 1000; // 4000以上を設定することはできません
}

サークルを描画する

MMCircle *circle = [[MMCircle alloc] initWithMapView:mapView centerCoordinate:mapView.centerCoordinate r:10000]; // rは半径(m)
circle.fillColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.8];
[mapView addOverlay:circle];

// [circle setCenterCoordinate:CLLocationCoordinate2DMake(35.3, 139.3) animated:YES]; // 中心位置を変更する場合
// [circle setR:12000 animated:YES]; // 半径を変更する場合
// [mapView removeOverlay:circle]; // 削除

ラインを描画する

MMShape *line = [[MMShape alloc] initWithMapView:mapView];
[line addLineToPoint:CGPointMake(50, 50)]; // 緯度経度を指定したい場合はaddLineToCoordinate:を使う
[line addLineToPoint:CGPointMake(100, 100) flush:YES]; // flush:YESで描画される
[mapView addOverlay:line];

// line.lineColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.6]; // ラインの色を指定する場合
// line.lineCap = kCALineCapRound; // ライン先端の形状 kCALineCapButt(デフォルト) / kCALineCapRound / kCALineCapSquare
// line.lineJoin = kCALineJoinRound; // ライン接続部の形状 kCALineJoinMiter(デフォルト) / kCALineJoinRound / kCALineJoinBevel

// [mapView removeOverlay:line]; // 削除

ポリゴンを描画する

MMShape *polygon = [[MMShape alloc] initWithMapView:mapView];
polygon.fillColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.6];
[polygon addLineToPoint:CGPointMake(100, 100)]; // 緯度経度を指定したい場合はaddLineToCoordinate:を使う
[polygon addLineToPoint:CGPointMake(200, 200)];
[polygon addLineToPoint:CGPointMake(200, 100)];
[polygon addLineToPoint:CGPointMake(100, 100)];
[polygon closePath]; // ポリゴンの場合はこうして明示的に閉じる
[mapView addOverlay:polygon];

// polygon.lineColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.6]; // ラインの色を指定する場合
// polygon.lineCap = kCALineCapRound; // ライン先端の形状 kCALineCapButt(デフォルト) / kCALineCapRound / kCALineCapSquare
// polygon.lineJoin = kCALineJoinRound; // ライン接続部の形状 kCALineJoinMiter(デフォルト) / kCALineJoinRound / kCALineJoinBevel
// polygon.fillColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.6]; // ポリゴンの中身に色を付ける場合

// [mapView removeOverlay:polygon]; // 削除

画像を描画する

// MMFixImageはMMAnnotationViewと違い、地図と共に回転します
MMFixImage *fixImage = [[MMFixImage alloc] initWithMapView:mapView coordinate:kLongBeach image:[UIImage imageNamed:@"kokodene.png"]];
[mapView addOverlay:fixImage];

// 地図の拡大と連動させたい場合はMMFlexImageを使う
// MMFlexImage *flexImage = [[MMFlexImage alloc] initWithMapView:mapView coordinate:kLongBeach image:[UIImage imageNamed:@"kokodene.png"] originZoom:10.415038];
// [_mapView addOverlay:flexImage];

レイヤを追加する

OpenWeatherMapの降水予報のMapを追加する場合

#import <MapionMaps/MapionMaps.h>

@interface OpenStreetMap : MMAbstractEPSG900913Map

@end

@implementation OpenWeatherMap

- (int)tileLength {
  return 384;
}

- (float)minZoom {
  return 0;
}

- (float)maxZoom {
  return 18;
}

- (NSString *)name {
  return @"OpenWeatherMapPrecip";
}

- (NSString *)copyright {
  return @"Data CC-By-SA by Forecast layers from Environment Canada";
}

- (NSURL *)URLForTile:(MMTile)tile {
  NSString *dateParameter;
  
  NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  [formatter setDateFormat:@"YYYYMMddHHmm"];
  NSDate *date = [NSDate date];
  NSString *dateString = [formatter stringFromDate:date];
  [formatter release];
  
  NSString *one = [dateString substringWithRange:NSMakeRange(0, 11)];
  NSString *two = [dateString substringFromIndex:11];
  int twoInt = [two intValue];
  if (twoInt < 5) {
    dateParameter = [NSString stringWithFormat:@"%@0", one];
  } else if (twoInt > 5) {
    dateParameter = [NSString stringWithFormat:@"%@5", one];
  } else {
    dateParameter = dateString;
  }
  
  NSString *urlString = [NSString stringWithFormat:@"http://openweathermap.org/t/tile.cgi/1.0.0/PRECIP/%d/%d/%d.png?date=%@", tile.zoom, tile.x, tile.y, dateParameter];
  
  return [NSURL URLWithString:urlString];
}

@end
id <MMMap> openWeatherMap = [[OpenWeatherMap alloc] init];
[mapView addMap:openWeatherMap];
// [mapView addMap:openWeatherMap atIndex:1]; // indexを指定して追加する場合
// [mapView removeMap:openWeatherMap]; // 削除する場合
// [mapView removeMapAtIndex:1]; // indexを指定して削除する場合

回転する

法人向けのみの機能です

mapView.degrees = 310.0; // 310度回転する
// [mapView setDegrees:50.0 animated:YES]; // アニメーションさせたい場合
// mapView.rotation = 0.872665; // ラジアンで指定も可能
// [mapView setRotation:0.872665 animated:YES]; // ラジアンで指定しアニメーションさせたい場合

回転してもピンは常に上を向く


パノラマを設定する

法人向けのみの機能です

[mapView setPanorama:45.0f animated:YES]; // 0 ... 45

パノラマを設定すると余白が生まれるのでframeを広めに設定している