MKMapView笔记


3种坐标系

  • 经度和纬度

    • CLLocationCoordinate2D
    • 以经度和纬度表示的坐标系,原点位于非洲大陆的西部
  • 地图坐标系

    • MK?
    • 墨卡托地图的坐标系,原点在左上方
  • 核心图形坐标系

    • CG?
    • UIView中的坐标系,原点在左上方

纬度和经度

  • CLLocationCoordinate2D
  • 包含经度和纬度值的结构,由WGS84(美国采用的世界大地测量系统)定义的坐标系
  • 纬度:纬度CLLocationDegrees(双精度)类型
  • 经度:经度CLLocationDegrees(双精度)类型
  • 当表示"无效值"时,似乎lat / lon均为NaN,可以通过isnan()函数

  • 由于它是经度和纬度,因此在本初子午线和赤道之间的边界处可能取负值。
  • 日本大约是{35,135}
  • {0,0}在非洲大陆的西部,在赤道和子午线的交点处

    • 当您展开它时,一个奇怪的岛会漂浮。可能是一个神圣的地方(在Google地图上不存在?)
      CF5h3JNUgAAXXDL.png
      CF5h3GrUIAA-Szz.png

地图坐标系

任意调用地图坐标系以区别于其他坐标系。

  • MKMapRect
  • MKMapPoint
  • MKMapSize

墨卡托投影中有MapView的外观。原点在北美大陆的左上方,而日期更改线在{0,0}。在这种情况下,该地图是主要在西方绘制的世界地图。

MKMapPoint通常不具有负值,但是在出现某些错误的情况下可以为{-1,-1}(请参见下文)

目前,应该查看Apple的材料和MKGeometry.h

  • ADC-位置信息编程指南.pdf
  • MapKit.framework / MKGeometry.h

坐标系转换?碰撞检测

将MKMapRect转换为NSString

日志输出为字符串

1
NSLog(MKStringFromMapRect(mapRect));

使用MKMapRect

获取MKMapView的显示范围

获取地图显示范围

1
MKMapRect visibleRect = mapView.visibleMapRect;

从MKMapPoint转换为CLLocationCoordinate2D

从墨卡托投影中的点转换为纬度和经度

1
2
MKMapPoint p = MKMapPointMake(100.0, 200.0);
CLLocationCoordinate2D coordinate = MKCoordinateForMapPoint;

从CLLocationCoordinate2D转换为MKMapPoint

从纬度/经度转换为墨卡托投影中的点

1
2
CLLocationCoordinate2D coordinate = CLLocationCoordinate2D(35.0, 135.0);
MKMapPoint p = MKMapPointForCoordinate(coordinate);

注意

例如,如果您指定了如下所示的不可能的纬度/经度,则{-1,-1}将返回到MKMapPoint。屏幕上不存在此坐标。

没有这样的地方

1
2
CLLocationCoordinate2D coordinate = CLLocationCoordinate2D(999999, 999999);
MKMapPoint p = MKMapPointForCoordinate(coordinate);

MKMapPoint和MKMapRect

之间的冲突检测

如何确定地图坐标是否在地图矩形内。

屏幕上是否有圆点?

1
2
3
4
5
MKMapRect mapRect = mapView.visibleMapRect; // 表示している画面矩形
MKMapPoint point = MKMapPointMake(100, 200.0); // メルカトル図法上での点

// 点が画面内にあれば YES が返る
BOOL isInMapRect = MKMapRectContainsPoint(mapRect, point);

CLLocationCoordinate2D与MKCircle

之间的碰撞检测

如何确定经纬度与MKCircle之间的冲突。确定用户的坐标是否在半径为?M的圆内。

确定用户是否在Yodobashi Camera Umeda附近

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CLLocationCoordinate2D yodobashiUmedaPoint = CLLocationCoordinate2DMake(34.704172, 135.496324); // 中心緯度経度
CLLocationDistance yodobashiUmedaRadius = 100.0; // 半径100m
MKCircle *yodobashiUmedaArea = [MKCircle circleWithCenterCoordinate:yodobashiUmedaPoint radius: yodobashiUmedaRadius];

// ユーザーの座標
CLLocationCoordinate2D userCoordinate = mapView.userLocation.coordinate;
MKMapPoint userLocationMapPoint = MKMapPointForCoordinate(userCoordinate);

// パスをオフスクリーン描画
MKCircleRenderer *yodobashiUmedaRenderer = [[MKCircleRenderer alloc] initWithCircle: yodobashiUmedaArea];
[yodobashiUmedaRenderer createPath];
// ユーザーの座標を CGPoint に変換
CGPoint userLocationPoint = [yodobashiUmedaRenderer pointForMapPoint:userLocationMapPoint];

// ユーザーの座標がパスに含まれるかを判定
if (CGPathContainsPoint(yodobashiUmedaRenderer.path, NULL, userLocationPoint, NO)) {
    // 近くにいるよ
}
else {
    // いないよ
}

计算两点之间的距离(以米为单位)

1
2
3
MKMapPoint point1 = MKMapPointForCoordinate(coordinate1);
MKMapPoint point2 = MKMapPointForCoordinate(coordinate2);
CLLocationDistance distance = MKMetersBetweenMapPoints(point1, point2);

CLLocationDistance以米为单位。