在图像上绘制lat/lng点

Aug*_*aas 5 gis math trigonometry objective-c map

我有以下内容:

  • 图像 - 手绘地图 - 面积约600x400米.图像绘制在Google地图图块之上.
  • 此图像角落的纬度/经度(来自谷歌地图).或者换句话说,我有北纬和南纬以及图像的东西经度.
  • 来自iPhone的CoreLocation的纬度/经度坐标.

如何在此图像上绘制一个点(如果超出界限,则不显示任何点),表示CoreLocation的坐标?

添加奖励:如果坐标超出图像范围,则在地图边缘绘制箭头,指向坐标.

我想在不使用类似proj的库的情况下这样做,以便不必捆绑大型库,并了解我正在做什么以及为什么.

正如您可能已经知道的那样,我在Objective-C中写这个.不过,你的答案不一定是在Objective-C中.

Aug*_*aas 3

经过一番研究,我编写了自己的库:libPirateMap。它不是很精致,但是很有效。

如果链接失效,我将在此处粘贴相关源代码。

用法:

// .h
PirateMap *pirateMap;
PirateMapPoint *pirateMapPoint;

// .m
- (void)viewDidLoad {
    [super viewDidLoad];
    pirateMap = [[PirateMap alloc] initWithNorthLatitude:59.87822
                                        andSouthLatitude:59.87428
                                        andWestLongitude:10.79847
                                        andEastLongitude:10.80375
                                           andImageWidth:640
                                          andImageHeight:960];

    pirateMapPoint = [[PirateMapPoint alloc] init];
    pirateMapPoint.pirateMap = pirateMap;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    pirateMapPoint.coordinate = PirateMapCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude)    
    PirateMapPoint2D point = [pirateMapPoint pointOnImage];
    // use point.x and point.y to place your view.
}
Run Code Online (Sandbox Code Playgroud)

相关.m代码。

#import "PirateMap.h"

static const double RAD_TO_DEG = 180 / M_PI;
static const double DEG_TO_RAD = M_PI / 180;

PirateMapCoordinate2D PirateMapCoordinate2DMake(double latitude, double longitude) {
    return (PirateMapCoordinate2D) {latitude, longitude};
}

// atan2(y2-y1,x2-x1)

@implementation PirateMap
@synthesize northLatitude, southLatitude, westLongitude, eastLongitude,
imageWidth, imageHeight, latitudeImageToWorldRatio, longitudeImageToWorldRatio;

-(id)initWithNorthLatitude:(double)aNorthLatitude
          andSouthLatitude:(double)aSouthLatitude
          andWestLongitude:(double)aWestLongitude
          andEastLongitude:(double)anEastLongitude
             andImageWidth:(int)anImageWidth
            andImageHeight:(int)anImageHeight{
    if (self = [super init]) {
        self.northLatitude = aNorthLatitude;
        self.southLatitude = aSouthLatitude;
        self.westLongitude = aWestLongitude;
        self.eastLongitude = anEastLongitude;

        self.imageWidth = anImageWidth;
        self.imageHeight = anImageHeight;

        self.latitudeImageToWorldRatio = [self computeLatitudeImageToWorldRatio];
        self.longitudeImageToWorldRatio = [self computeLongitudeImageToWorldRatio];
    }
    return self;
}

-(double)computeLatitudeImageToWorldRatio {
    return fabs(self.northLatitude - self.southLatitude) / self.imageHeight;
}

-(double)computeLongitudeImageToWorldRatio {
    return fabs(self.eastLongitude - self.westLongitude) / self.imageWidth;
}

+(double)latitudeToMercatorY:(double)latitude {
    static const double M_PI_TO_4 = M_PI / 4;

    return RAD_TO_DEG * log(tan(M_PI_TO_4 + latitude * (DEG_TO_RAD / 2)));
}
@end

#import "PirateMapPoint.h"

PirateMapPoint2D PirateMapPoint2DMake(int x, int y) {
    return (PirateMapPoint2D) {x, y};
}

@implementation PirateMapPoint
@synthesize pirateMap, coordinate;

-(id)initWithPirateMap:(PirateMap *)aPirateMap andCoordinate:(PirateMapCoordinate2D)aCoordinate {
    if (self = [super init]) {
        self.pirateMap = aPirateMap;
        self.coordinate = aCoordinate;
    }

    return self;
}

-(PirateMapPoint2D)pointOnImage {
    double xDelta = self.coordinate.longitude - self.pirateMap.westLongitude;
    double yDelta = self.pirateMap.northLatitude - self.coordinate.latitude;
    return PirateMapPoint2DMake(round(xDelta / self.pirateMap.longitudeImageToWorldRatio), round(yDelta / self.pirateMap.latitudeImageToWorldRatio));
}
@end
Run Code Online (Sandbox Code Playgroud)