You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

490 lines
16 KiB

//
// MAGeometry.h
// MAMapKit
//
// Created by AutoNavi.
// Copyright (c) 2013年 Amap. All rights reserved.
//
#import "MAConfig.h"
#import <CoreGraphics/CoreGraphics.h>
#import <CoreLocation/CoreLocation.h>
#import <UIKit/UIKit.h>
#ifdef __cplusplus
extern "C" {
#endif
///东北、西南两个点定义的四边形经纬度范围
typedef struct MACoordinateBounds{
CLLocationCoordinate2D northEast; ///< 东北角经纬度
CLLocationCoordinate2D southWest; ///< 西南角经纬度
} MACoordinateBounds;
///经度、纬度定义的经纬度跨度范围
typedef struct MACoordinateSpan{
CLLocationDegrees latitudeDelta; ///< 纬度跨度
CLLocationDegrees longitudeDelta; ///< 经度跨度
} MACoordinateSpan;
///中心点、跨度范围定义的四边形经纬度范围
typedef struct MACoordinateRegion{
CLLocationCoordinate2D center; ///< 中心点经纬度
MACoordinateSpan span; ///< 跨度范围
} MACoordinateRegion;
///平面投影坐标结构定义
typedef struct MAMapPoint{
double x; ///<x坐标
double y; ///<y坐标
} MAMapPoint;
///平面投影大小结构定义
typedef struct MAMapSize{
double width; ///<宽度
double height; ///<高度
} MAMapSize;
///平面投影矩形结构定义
typedef struct MAMapRect{
MAMapPoint origin; ///<左上角坐标
MAMapSize size; ///<大小
} MAMapRect;
typedef NS_OPTIONS(NSUInteger, MAMapRectCorner) {
MAMapRectCornerTopLeft = 1 << 0,
MAMapRectCornerTopRight = 1 << 1,
MAMapRectCornerBottomLeft = 1 << 2,
MAMapRectCornerBottomRight = 1 << 3,
MAMapRectCornerAllCorners = ~0UL
};
///比例关系:MAZoomScale = Screen Point / MAMapPoint, 当MAZoomScale = 1时, 1 screen point = 1 MAMapPoint, 当MAZoomScale = 0.5时, 1 screen point = 2 MAMapPoints
typedef double MAZoomScale;
///世界范围大小
extern const MAMapSize MAMapSizeWorld;
///世界范围四边形
extern const MAMapRect MAMapRectWorld;
///(MAMapRect){{INFINITY, INFINITY}, {0, 0}};
extern const MAMapRect MAMapRectNull;
///(MAMapRect){{0, 0}, {0, 0}}
extern const MAMapRect MAMapRectZero;
static inline MACoordinateBounds MACoordinateBoundsMake(CLLocationCoordinate2D northEast,CLLocationCoordinate2D southWest)
{
return (MACoordinateBounds){northEast, southWest};
}
static inline MACoordinateSpan MACoordinateSpanMake(CLLocationDegrees latitudeDelta, CLLocationDegrees longitudeDelta)
{
return (MACoordinateSpan){latitudeDelta, longitudeDelta};
}
static inline MACoordinateRegion MACoordinateRegionMake(CLLocationCoordinate2D centerCoordinate, MACoordinateSpan span)
{
return (MACoordinateRegion){centerCoordinate, span};
}
/**
* @brief 生成一个新的MACoordinateRegion
* @param centerCoordinate 中心点坐标
* @param latitudinalMeters 垂直跨度(单位 米)
* @param longitudinalMeters 水平跨度(单位 米)
* @return 新的MACoordinateRegion
*/
extern MACoordinateRegion MACoordinateRegionMakeWithDistance(CLLocationCoordinate2D centerCoordinate, CLLocationDistance latitudinalMeters, CLLocationDistance longitudinalMeters);
/**
* @brief 经纬度坐标转平面投影坐标
* @param coordinate 要转化的经纬度坐标
* @return 平面投影坐标
*/
extern MAMapPoint MAMapPointForCoordinate(CLLocationCoordinate2D coordinate);
/**
* @brief 平面投影坐标转经纬度坐标
* @param mapPoint 要转化的平面投影坐标
* @return 经纬度坐标
*/
extern CLLocationCoordinate2D MACoordinateForMapPoint(MAMapPoint mapPoint);
/**
* @brief 平面投影矩形转region
* @param rect 要转化的平面投影矩形
* @return region
*/
extern MACoordinateRegion MACoordinateRegionForMapRect(MAMapRect rect);
/**
* @brief region转平面投影矩形
* @param region region 要转化的region
* @return 平面投影矩形
*/
extern MAMapRect MAMapRectForCoordinateRegion(MACoordinateRegion region);
/**
* @brief 单位投影的距离
* @param latitude 经纬度
* @return 距离
*/
extern CLLocationDistance MAMetersPerMapPointAtLatitude(CLLocationDegrees latitude);
/**
* @brief 1米对应的投影
* @param latitude 经纬度
* @return 1米对应的投影
*/
extern double MAMapPointsPerMeterAtLatitude(CLLocationDegrees latitude);
/**
* @brief 投影两点之间的距离
* @param a a点
* @param b b点
* @return 距离
*/
extern CLLocationDistance MAMetersBetweenMapPoints(MAMapPoint a, MAMapPoint b);
/**
* @brief 经纬度间的面积(单位 平方米)
* @param northEast 东北经纬度
* @param southWest 西南经纬度
* @return 面积
*/
extern double MAAreaBetweenCoordinates(CLLocationCoordinate2D northEast, CLLocationCoordinate2D southWest);
/**
* @brief 获取Inset后的MAMapRect
* @param rect rect
* @param dx x点
* @param dy y点
* @return MAMapRect
*/
extern MAMapRect MAMapRectInset(MAMapRect rect, double dx, double dy);
/**
* @brief 合并两个MAMapRect
* @param rect1 rect1
* @param rect2 rect2
* @return 合并后的rect
*/
extern MAMapRect MAMapRectUnion(MAMapRect rect1, MAMapRect rect2);
/**
* @brief 判断size1是否包含size2
* @param size1 size1
* @param size2 size2
* @return 判断结果
*/
extern BOOL MAMapSizeContainsSize(MAMapSize size1, MAMapSize size2);
/**
* @brief 判断点是否在矩形内
* @param rect 矩形rect
* @param point 点
* @return 判断结果
*/
extern BOOL MAMapRectContainsPoint(MAMapRect rect, MAMapPoint point);
/**
* @brief 判断两矩形是否相交
* @param rect1 rect1
* @param rect2 rect2
* @return 判断结果
*/
extern BOOL MAMapRectIntersectsRect(MAMapRect rect1, MAMapRect rect2);
/**
* @brief 判断矩形rect1是否包含矩形rect2
* @param rect1 rect1
* @param rect2 rect2
* @return 判断结果
*/
extern BOOL MAMapRectContainsRect(MAMapRect rect1, MAMapRect rect2);
/**
* @brief 判断点是否在圆内
* @param point 点
* @param center 圆的中心点
* @param radius 圆的半径,单位米
* @return 判断结果
*/
extern BOOL MACircleContainsPoint(MAMapPoint point, MAMapPoint center, double radius);
/**
* @brief 判断经纬度点是否在圆内
* @param point 经纬度
* @param center 圆的中心经纬度
* @param radius 圆的半径,单位米
* @return 判断结果
*/
extern BOOL MACircleContainsCoordinate(CLLocationCoordinate2D point, CLLocationCoordinate2D center, double radius);
/**
* @brief 获取某坐标点距线上最近的坐标点
* @param point 点
* @param polyline 线
* @param count 线里点的数量
* @return 某点到线上最近的点
*/
extern MAMapPoint MAGetNearestMapPointFromPolyline(MAMapPoint point, MAMapPoint *polyline, NSUInteger count);
/**
* @brief 判断点是否在多边形内
* @param point 点
* @param polygon 多边形
* @param count 多边形点的数量
* @return 判断结果
*/
extern BOOL MAPolygonContainsPoint(MAMapPoint point, MAMapPoint *polygon, NSUInteger count);
/**
* @brief 判断经纬度点是否在多边形内
* @param point 经纬度点
* @param polygon 多边形
* @param count 多边形点的数量
* @return 判断结果
*/
extern BOOL MAPolygonContainsCoordinate(CLLocationCoordinate2D point, CLLocationCoordinate2D *polygon, NSUInteger count);
/**
* @brief 取在lineStart和lineEnd组成的线段上距离point距离最近的点
* @param lineStart 线段起点
* @param lineEnd 线段终点
* @param point 测试点
* @return 距离point最近的点坐标
*/
extern MAMapPoint MAGetNearestMapPointFromLine(MAMapPoint lineStart, MAMapPoint lineEnd, MAMapPoint point);
/**
* @brief 获取墨卡托投影切块回调block,如果是无效的映射,则返回(-1, -1, 0, 0, 0, 0)
* @param offsetX 左上点距离所属tile的位移X, 单位像素
* @param offsetY 左上点距离所属tile的位移Y, 单位像素
* @param minX 覆盖tile的最小x
* @param maxX 覆盖tile的最大x
* @param minY 覆盖tile的最小y
* @param maxY 覆盖tile的最大y
*/
typedef void (^AMapTileProjectionBlock)(int offsetX, int offsetY, int minX, int maxX, int minY, int maxY);
/**
* @brief 根据所给经纬度区域获取墨卡托投影切块信息
* @param bounds 经纬度区域
* @param levelOfDetails 对应缩放级别, 取值0-20
* @param tileProjection 返回的切块信息block
*/
extern void MAGetTileProjectionFromBounds(MACoordinateBounds bounds, int levelOfDetails, AMapTileProjectionBlock tileProjection);
/**
* @brief 计算多边形面积,点与点之间按顺序尾部相连, 第一个点与最后一个点相连
* @param coordinates 指定的经纬度坐标点数组,C数组,调用者负责内存管理
* @param count 坐标点的个数
* @return 多边形的面积
*/
extern double MAAreaForPolygon(CLLocationCoordinate2D *coordinates, int count);
static inline MAMapPoint MAMapPointMake(double x, double y)
{
return (MAMapPoint){x, y};
}
static inline MAMapSize MAMapSizeMake(double width, double height)
{
return (MAMapSize){width, height};
}
static inline MAMapRect MAMapRectMake(double x, double y, double width, double height)
{
return (MAMapRect){MAMapPointMake(x, y), MAMapSizeMake(width, height)};
}
static inline double MAMapRectGetMinX(MAMapRect rect)
{
return rect.origin.x;
}
static inline double MAMapRectGetMinY(MAMapRect rect)
{
return rect.origin.y;
}
static inline double MAMapRectGetMidX(MAMapRect rect)
{
return rect.origin.x + rect.size.width / 2.0;
}
static inline double MAMapRectGetMidY(MAMapRect rect)
{
return rect.origin.y + rect.size.height / 2.0;
}
static inline double MAMapRectGetMaxX(MAMapRect rect)
{
return rect.origin.x + rect.size.width;
}
static inline double MAMapRectGetMaxY(MAMapRect rect)
{
return rect.origin.y + rect.size.height;
}
static inline double MAMapRectGetWidth(MAMapRect rect)
{
return rect.size.width;
}
static inline double MAMapRectGetHeight(MAMapRect rect)
{
return rect.size.height;
}
static inline BOOL MAMapPointEqualToPoint(MAMapPoint point1, MAMapPoint point2) {
return point1.x == point2.x && point1.y == point2.y;
}
static inline BOOL MAMapSizeEqualToSize(MAMapSize size1, MAMapSize size2) {
return size1.width == size2.width && size1.height == size2.height;
}
static inline BOOL MAMapRectEqualToRect(MAMapRect rect1, MAMapRect rect2) {
return
MAMapPointEqualToPoint(rect1.origin, rect2.origin) &&
MAMapSizeEqualToSize(rect1.size, rect2.size);
}
static inline BOOL MAMapRectIsNull(MAMapRect rect) {
return isinf(rect.origin.x) || isinf(rect.origin.y);
}
static inline BOOL MAMapRectIsEmpty(MAMapRect rect) {
return MAMapRectIsNull(rect) || (rect.size.width == 0.0 && rect.size.height == 0.0);
}
static inline NSString *MAStringFromMapPoint(MAMapPoint point) {
return [NSString stringWithFormat:@"{%.1f, %.1f}", point.x, point.y];
}
static inline NSString *MAStringFromMapSize(MAMapSize size) {
return [NSString stringWithFormat:@"{%.1f, %.1f}", size.width, size.height];
}
static inline NSString *MAStringFromMapRect(MAMapRect rect) {
return [NSString stringWithFormat:@"{%@, %@}", MAStringFromMapPoint(rect.origin), MAStringFromMapSize(rect.size)];
}
///坐标系类型枚举
typedef NS_ENUM(NSUInteger, MACoordinateType)
{
MACoordinateTypeBaidu = 0, ///< Baidu
MACoordinateTypeMapBar, ///< MapBar
MACoordinateTypeMapABC, ///< MapABC
MACoordinateTypeSoSoMap, ///< SoSoMap
MACoordinateTypeAliYun, ///< AliYun
MACoordinateTypeGoogle, ///< Google
MACoordinateTypeGPS, ///< GPS
};
/**
* @brief 转换目标经纬度为高德坐标系
* @param coordinate 待转换的经纬度
* @param type 坐标系类型
* @return 高德坐标系经纬度
*/
extern CLLocationCoordinate2D MACoordinateConvert(CLLocationCoordinate2D coordinate, MACoordinateType type) __attribute((deprecated("已废弃,使用AMapFoundation中关于坐标转换的接口")));
/**
* @brief 获取矢量坐标方向
* @param fromCoord 矢量坐标起点
* @param toCoord 矢量坐标终点
* @return 方向,详情参考系统 CLLocationDirection
*/
extern CLLocationDirection MAGetDirectionFromCoords(CLLocationCoordinate2D fromCoord, CLLocationCoordinate2D toCoord);
/**
* @brief 获取矢量坐标方向
* @param fromPoint 矢量坐标起点
* @param toPoint 矢量坐标终点
* @return 方向,详情参考系统 CLLocationDirection
*/
extern CLLocationDirection MAGetDirectionFromPoints(MAMapPoint fromPoint, MAMapPoint toPoint);
/**
* @brief 获取点到线的垂直距离
* @param point 起点
* @param lineBegin 线的起点
* @param lineEnd 线的终点
* @return 距离,单位米
*/
extern double MAGetDistanceFromPointToLine(MAMapPoint point, MAMapPoint lineBegin, MAMapPoint lineEnd);
/**
* @brief 判断线是否被点击选中
* @param linePoints 构成线的点
* @param count 点的个数
* @param tappedPoint 点击点
* @param lineWidth 线宽,单位:MAMapPoint点
* @return 是否选中
*/
extern BOOL MAPolylineHitTest(MAMapPoint *linePoints, NSUInteger count, MAMapPoint tappedPoint, CGFloat lineWidth);
#ifdef __cplusplus
}
#endif
///utils方法,方便c结构体对象和NSValue对象间相互转化
@interface NSValue (NSValueMAGeometryExtensions)
/**
* @brief 创建 MAMapPoint 的NSValue对象
* @param mapPoint MAMapPoint结构体对象
* @return NSValue对象
*/
+ (NSValue *)valueWithMAMapPoint:(MAMapPoint)mapPoint;
/**
* @brief 创建 MAMapSize 的NSValue对象
* @param mapSize MAMapSize结构体对象
* @return NSValue对象
*/
+ (NSValue *)valueWithMAMapSize:(MAMapSize)mapSize;
/**
* @brief 创建 MAMapRect 的NSValue对象
* @param mapRect MAMapRect结构体对象
* @return NSValue对象
*/
+ (NSValue *)valueWithMAMapRect:(MAMapRect)mapRect;
/**
* @brief 创建 CLLocationCoordinate2D 的NSValue对象
* @param coordinate CLLocationCoordinate2D结构体对象
* @return NSValue对象
*/
+ (NSValue *)valueWithMACoordinate:(CLLocationCoordinate2D)coordinate;
/**
@brief 返回NSValue对象包含的MAMapPoint结构体对象
@return 当前对象包含的MAMapPoint结构体对象
*/
- (MAMapPoint)MAMapPointValue;
/**
@brief 返回NSValue对象包含的MAMapSize结构体对象
@return 当前对象包含的MAMapSize结构体对象
*/
- (MAMapSize)MAMapSizeValue;
/**
@brief 返回NSValue对象包含的MAMapRect结构体对象
@return 当前对象包含的MAMapRect结构体对象
*/
- (MAMapRect)MAMapRectValue;
/**
@brief 返回NSValue对象包含的CLLocationCoordinate2D结构体对象
@return 当前对象包含的CLLocationCoordinate2D结构体对象
*/
- (CLLocationCoordinate2D)MACoordinateValue;
@end