WGS84大地水准面高度海拔高度偏移量用于IOS上的外部GPS数据 [英] WGS84 Geoid Height Altitude Offset for external GPS data on IOS

查看:483
本文介绍了WGS84大地水准面高度海拔高度偏移量用于IOS上的外部GPS数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我正在编写的应用程序,我们将IOS设备与通过本地WiFi网络输出GPS数据的外部传感器相连接。这些数据在相对于高度的原始格式中出现。一般来说,所有GPS高度需要根据当前位置,应用与WGS84大地水准面高度有关的修正系数。

例如,在以下地理控制点( http://www.ngs.noaa.gov/cgi-bin/ds_mark.prl?PidBox=HV9830 )位于Lat 38 56 36.77159 和一个Lon 077 01 08.34929

  HV9830 * NAD 83(2011)POSITION- 38 56 36.77159(N)077 01 08.34929(W)ADJUSTED 
HV9830 * NAD 83(2011)椭球HT- 42.624(米)(12年6月27日)来调整
HV9830 * NAD 83(2011)EPOCH - 2010.00
HV9830 * NAVD 88 ORTHO高度 - 74.7(米)245(英尺)VERTCON
HV9830 ______________________________________________________________________
HV9830大地水准面 - -32.02(米)GEOID12A
HV9830 NAD 83 (2011)X - 1,115,795.966(米)COMP
HV9830 NAD 83(2011)Y - -4,840,360.447(米)COMP
HV9830 NAD 83(2011)Z - 3,987,471.457(米)COMP
HV9830 LAPLACE CORR - -2.38(秒)DEFLEC12A

您可以看到大地水准面高度<-32米。因此,如果在这一点附近获得原始GPS读数,则必须应用-32米的修正值才能计算出正确的海拔高度。 (注意:更正是负值,所以你实际上会减去一个负值,从而将读数向上移动32米)。



与Android相反我们的理解是,关于coreLocation,这个GeoidHeight信息是由IOS自动计算的。我们遇到困难的地方在于,我们使用本地WiFi网络和传感器来计算未校正的GPS,并收集外部传感器数据以及GPS的coreLocation读数。我想知道是否有人知道有一个具有大地水准面信息的图书馆(C / Objective-C),并且可以在我从我们的传感器包中读取原始GPS信号时帮助我进行这些计算。



感谢您的帮助。

边注:请不要建议我看以下帖子: 通过Android中的经度和纬度获取高度 这是一个很好的解决方案,但我们没有互联网连接,因此我们无法对Goole或USGS进行实时查询。

>解决方案

我已经提前解决了我的问题。我所做的就是创建一个fortran代码的c实现的ObjectiveC实现来完成我所需要的。原始的c可以在这里找到: http://sourceforge.net/projects/egm96-f477- c /



您需要从source forge下载项目才能访问此代码所需的输入文件: CORCOEF EGM96



我的objective-c实现如下:

GeoidCalculator.h

  #import< Foundation / Foundation.h> 

@interface GeoidCalculator:NSObject
+(GeoidCalculator *)instance;


- (double)getHeightFromLat:(double)lat和lon:(double)lon;
- (double)getCurrentHeightOffset;
- (void)updatePositionWithLatitude:(double)lat和Longitude:(double)lon;

@end

GeoidCalculator.m

  #importGeoidCalculator.h
#import< stdio.h>
#import< math.h>


#define l_value(65341)
#define _361(361)

@implementation GeoidCalculator

static int nmax ;

static double currentHeight;

静态双CC [l_value + 1],CS [l_value + 1],HC [l_value + 1],HS [l_value + 1],
P [l_value + 1],sinml [_361 + 1],cosml [_361 + 1],rleg [_361 + 1];

+(GeoidCalculator *)实例{
static GeoidCalculator * _instance = nil;

@synchronized(self){
if(_instance == nil){
_instance = [[self alloc] init];
init_arrays();
currentHeight = -9999;
}
}

return _instance;
}


- (双)getHeightFromLat:(双)LAT andLon:(双)LON {
[自updatePositionWithLatitude:LAT andLongitude:LON];
return [self getCurrentHeightOffset];
}


- (double)getCurrentHeightOffset {
return currentHeight;
}

- (void)updatePositionWithLatitude:(double)lat和Longitude:(double)lon {
const double rad = 180 / M_PI;
double flat,flon,u;
flat = lat; flon = lon;

/ *计算地心自由度,地心半径,正常重力* /
u =波动(平坦/弧度,flon / rad,nmax,nmax + 1);

/ * u是来自egm96潜在系数模型
的大地水准面波动,包括​​高度异常对大地水准面波动校正项
和一个修正项以使波动参考
wgs84椭圆体。大地水准面波动单位是米。* /
currentHeight = u;
}


双hundu(无符号n最大,双P [l_value + 1],
双HC [l_value + 1],双HS [l_value + 1],
双sinml [_361 + 1],双cosml [_361 + 1],双GR,双重,
双CC [l_value + 1],双CS [l_value + 1]){/ *为WGS84(g873)常数;克,单位为m ** 3 / s ** 2 * /
const double gm = .3986004418e15,ae = 6378137。
double arn,ar,ac,a,b,sum,sumc,sum2,tempc,temp;
int k,n,m;
ar = ae / re;
arn = ar;
ac = a = b = 0;
k = 3;
for(n = 2; n <= nmax; n ++){
arn * = ar;
k ++;
sum = p [k] * hc [k];
sumc = p [k] * cc [k];
sum2 = 0; (m = 1; m <= n; m ++){
k ++;
tempc = cc [k] * cosml [m] + cs [k] * sinml [m];
temp = hc [k] * cosml [m] + hs [k] * sinml [m];
sumc + = p [k] * tempc;
sum + = p [k] * temp;
}
ac + = sumc;
a + = sum * arn;
}
ac + = cc [1] + p [2] * cc [2] + p [3] *(cc [3] * cosml [1] + cs [3] * sinml [ 1]);
/ *添加haco = ac / 100将椭圆体上的高度异常转换为波动
add -0.53m使波动参考wgs84椭圆体* /
return a * gm / (gr * re)+ ac / 100 - .53;
}

void dscml(double rlon,unsigned nmax,double sinml [_361 + 1],double cosml [_361 + 1]){
double a,b;
int m;
a = sin(rlon);
b = cos(rlon);
sinml [1] = a;
cosml [1] = b;
sinml [2] = 2 * b * a;
cosml [2] = 2 * b * b - 1; (m = 3; m <= nmax; m ++){
sinml [m] = 2 * b * sinml [m-1] - sinml [m-2];
cosml [m] = 2 * b * cosml [m - 1] - cosml [m - 2];



void dhcsin(unsigned nmax,double hc [l_value + 1],double hs [l_value + 1]){


//潜在系数文件
// f_12 = fopen(EGM96,rb);
NSString * path2 = [[NSBundle mainBundle] pathForResource:@EGM96ofType:@];
FILE * f_12 = fopen(path2.UTF8String,rb);
if(f_12 == NULL){
NSLog([path2 stringByAppendingString:@not found]);
}



int n,m;
double j2,j4,j6,j8,j10,c,s,ec,es;
/ *以下给出的偶数度带状系数是针对常数
wgs84(g873)系统计算的,与NIMA网格化程序中使用的
值相同。使用N.K编写的子程序
grs计算。 PAVLIS * /
j2 = 0.108262982131e-2;
j4 = -.237091120053e-05;
j6 = 0.608346498882e-8;
j8 = -0.142681087920e-10;
j10 = 0.121439275882e-13;
m =((nmax + 1)*(nmax + 2))/ 2; (n = 1; n <= m; n ++)hc [n] = hs [n] = 0的
;
,而(6 == fscanf(f_12,%i%i%lf%lf%lf%lf,& n,& m,& c,& s,& e,& )如果(n> nmax)继续,则{
);
n =(n *(n + 1))/ 2 + m + 1;
hc [n] = c;
hs [n] = s;
}
hc [4] + = j2 / sqrt(5);
hc [11] + = j4 / 3;
hc [22] + = j6 / sqrt(13);
hc [37] + = j8 / sqrt(17);
hc [56] + = j10 / sqrt(21);


fclose(f_12);


$ b void legfdn(unsigned m,double theta,double rleg [_361 + 1],unsigned nmx)
/ *这个子程序计算所有标准化的legendre函数$ bbinrleg。订单总是
m,而且colatitude始终是theta(弧度)。最大度数
是nmx。所有计算都以双精度进行。
ir必须在第一次调用此子之前设置为零。
数组rleg的大小必须至少等于nmx + 1。
原程序员:Oscar L. Colombo,大地测量科学系
俄亥俄州立大学,1980年8月
ineiev:我删除了衍生产品,因为它们从未在这里计算* /
{
static double drts [1301],dirt [1301],cothet,sithet,rlnn [_361 + 1];
static int ir;
int nmx1 = nmx + 1,nmx2p = 2 * nmx + 1,m1 = m + 1,m2 = m + 2,m3 = m + 3,n,n1,n2;
if(!ir){
ir = 1; (n = 1; n< = nmx2p; n ++){
drts [n] = sqrt(n);
dirt [n] = 1 / drts [n];
}
}
cothet = cos(θ);
sithet = sin(theta);
/ *计算legendre函数* /
rlnn [1] = 1;
rlnn [2] = sithet * drts [3]; (n1 = 3; n1 <= m1; n1 ++){
n = n1-1;
n2 = 2 * n;
rlnn [n1] = drts [n2 + 1] * dirt [n2] * sithet * rlnn [n];
}
switch(m){
case 1:
rleg [2] = rlnn [2];
rleg [3] = drts [5] * cothet * rleg [2];
休息;
案例0:
rleg [1] = 1;
rleg [2] = cothet * drts [3];
休息;
}
rleg [m1] = rlnn [m1];如果(m2 <= nm×1){
rleg [m2] = drts [m1 * 2 + 1] * cothet * rleg [m1]; (n1 = m3; n1 <= nmx1; n1 ++){
n = n1-1;(m1 <= nmx1) ((!m& n< 2)||(m == 1& n< 3))继续时为
;
n2 = 2 * n;
rleg [n1] = drts [n2 + 1] * dirt [n + m] * dirt [n - m] *
(drts [n2 - 1] * cothet * rleg [n1 - 1] - drts [n + m - 1] * drts [n - m - 1] * dirt [n2 - 3] * rleg [n1 - 2]);
}
}
}

void radgra(double lat,double lon,double * rlat,double * gr,double * re)
/ *这个子程序计算以地心为中心的距离,
是地心自由度,
是基于
点的正常重力的近似值,使用wgs84(g873)系统的常量* /
{
const double a = 6378137.,e2 = .00669437999013,geqt = 9.7803253359,k = .00193185265246;
double n,t1 = sin(lat)* sin(lat),t2,x,y,z;
n = a / sqrt(1 - e2 * t1);
t2 = n * cos(lat);
x = t2 * cos(lon);
y = t2 * sin(lon);
z =(n *(1-e2))* sin(lat);
* re = sqrt(x * x + y * y + z * z); / *计算地心半径* /
* rlat = atan(z / sqrt(x * x + y * y )); / *计算地心自由度* /
* gr = geqt *(1 + k * t1)/ sqrt(1-e2 * t1); / *计算正常重力:单位是m / sec ** 2 * /
}


双波动(double lat,double lon,int nmax,int k){
double rlat,gr,re;
int i,j,m;
radgra(lat,lon,& rlat,& gr,& re);
rlat = M_PI / 2 - rlat; (j = 1; j <= k; j ++){
m = j-1;
legfdn(m,rlat,rleg,nmax); (i = j; i <= k; i ++)p [(i-1)* i / 2 + m + 1] = rleg [i]的

}
dscml(lon,nmax,sinml,cosml);
return hundu(nmax,p,hc,hs,sinml,cosml,gr,re,cc,cs);
}

void init_arrays(void){
int ig,i,n,m;
double t1,t2;






NSString * path1 = [[NSBundle mainBundle] pathForResource:@CORCOEFofType:@];


//校正系数文件:用'sed -e's / D / e / g''修改并用fscanf读取
FILE * f_1 = fopen([ path1 cStringUsingEncoding:1],rb);
if(f_1 == NULL){
NSLog([path1 stringByAppendingString:@not found]);
}


nmax = 360; (i = 1; i <= 1_value; i ++)cc [i] = cs [i] = 0;

while(4 == fscanf(f_1,%i%i%lg%lg,& n,& m,& t1,& t2)){
ig =(n *(n + 1))/ 2 + m + 1;
cc [ig] = t1;
cs [ig] = t2;
}
/ *校正系数现在读入* /
/ *现在读入潜在系数,并且参考
偶数度数带域谐波系数被去除到6 * /
dhcsin(nmax,hc,hs);
fclose(f_1);
}


@end



'I'我们已经针对大地水准面高度计算器( http:// www。 unavco.org/community_science/science-support/geoid/geoid.html ),看起来像是一切都是匹配的


更新iOS8或更高版本



截至IOS8此代码可能无法正常工作。您可能需要更改软件包的加载方式:

[[NSBundle mainBundle] pathForResource:@EGM96ofType:@];



做一些Google搜索或在这里添加评论。


For an application I'm writing we are interfacing IOS devices with an external sensor which outputs GPS data over a local wifi network. This data comes across in a "raw" format with respect to altitude. In general all GPS altitude needs to have a correction factor applied related to the WGS84 geoid height based on the current location.

For example, in the following Geo Control Point (http://www.ngs.noaa.gov/cgi-bin/ds_mark.prl?PidBox=HV9830) which resides at Lat 38 56 36.77159 and a Lon 077 01 08.34929

HV9830* NAD 83(2011) POSITION- 38 56 36.77159(N) 077 01 08.34929(W)   ADJUSTED  
HV9830* NAD 83(2011) ELLIP HT-    42.624 (meters)        (06/27/12)   ADJUSTED
HV9830* NAD 83(2011) EPOCH   -  2010.00
HV9830* NAVD 88 ORTHO HEIGHT -    74.7    (meters)     245.    (feet) VERTCON   
HV9830  ______________________________________________________________________
HV9830  GEOID HEIGHT    -        -32.02  (meters)                     GEOID12A
HV9830  NAD 83(2011) X  -  1,115,795.966 (meters)                     COMP
HV9830  NAD 83(2011) Y  - -4,840,360.447 (meters)                     COMP
HV9830  NAD 83(2011) Z  -  3,987,471.457 (meters)                     COMP
HV9830  LAPLACE CORR    -         -2.38  (seconds)                    DEFLEC12A

You can see that the Geoid Height is -32 meters. So given a RAW GPS reading near this point one would have to apply a correction of -32 meters in order to calculate the correct altitude. (Note:corrections are negative so you would actually be subtracting a negative and thus shifting the reading up 32 meters).

As opposed to Android it is our understanding that with regards to coreLocation this GeoidHeight information is automagically calculated internally by IOS. Where we are running into difficulty is that we are using a local wifi network with a sensor that calculates uncorrected GPS and collecting both the external sensor data as well as coreLocation readings for GPS. I was wondering if anybody was aware of a library (C/Objective-C) which has the Geoid information and can help me do these calculations on the fly when I'm reading the raw GPS signal from our sensor package.

Thank you for your help.

Side note: Please don't suggest I look at the following post: Get altitude by longitude and latitude in Android This si a good solution however we do not have a live internet connection so we cannot make a live query to Goole or USGS.

解决方案

I've gone ahead and solved my problems here. What I did was create an ObjectiveC implementation of a c implementation of fortran code to do what I needed. The original c can be found here: http://sourceforge.net/projects/egm96-f477-c/

You would need to download the project from source forge in order to access the input files required for this code: CORCOEF and EGM96

My objective-c implementation is as follows:

GeoidCalculator.h

#import <Foundation/Foundation.h>

@interface GeoidCalculator : NSObject
+ (GeoidCalculator *)instance;


-(double) getHeightFromLat:(double)lat    andLon:(double)lon;
-(double) getCurrentHeightOffset;
-(void) updatePositionWithLatitude:(double)lat andLongitude:(double)lon;

@end

GeoidCalculator.m

#import "GeoidCalculator.h"
#import <stdio.h>
#import <math.h>


#define l_value    (65341)
#define _361    (361)

@implementation GeoidCalculator

static int nmax;

static double currentHeight;

static double cc[l_value+ 1], cs[l_value+ 1], hc[l_value+ 1], hs[l_value+ 1],
        p[l_value+ 1], sinml[_361+ 1], cosml[_361+ 1], rleg[_361+ 1];

+ (GeoidCalculator *)instance {
    static GeoidCalculator *_instance = nil;

    @synchronized (self) {
        if (_instance == nil) {
            _instance = [[self alloc] init];
            init_arrays();
            currentHeight = -9999;
        }
    }

    return _instance;
}


- (double)getHeightFromLat:(double)lat andLon:(double)lon {
    [self updatePositionWithLatitude:lat andLongitude:lon];
    return [self getCurrentHeightOffset];
}


- (double)getCurrentHeightOffset {
    return currentHeight;
}

- (void)updatePositionWithLatitude:(double)lat andLongitude:(double)lon {
    const double rad = 180 / M_PI;
    double flat, flon, u;
    flat = lat; flon = lon;

    /*compute the geocentric latitude,geocentric radius,normal gravity*/
    u = undulation(flat / rad, flon / rad, nmax, nmax + 1);

    /*u is the geoid undulation from the egm96 potential coefficient model
       including the height anomaly to geoid undulation correction term
       and a correction term to have the undulations refer to the
       wgs84 ellipsoid. the geoid undulation unit is meters.*/
    currentHeight = u;
}


double hundu(unsigned nmax, double p[l_value+ 1],
        double hc[l_value+ 1], double hs[l_value+ 1],
        double sinml[_361+ 1], double cosml[_361+ 1], double gr, double re,
        double cc[l_value+ 1], double cs[l_value+ 1]) {/*constants for wgs84(g873);gm in units of m**3/s**2*/
    const double gm = .3986004418e15, ae = 6378137.;
    double arn, ar, ac, a, b, sum, sumc, sum2, tempc, temp;
    int k, n, m;
    ar = ae / re;
    arn = ar;
    ac = a = b = 0;
    k = 3;
    for (n = 2; n <= nmax; n++) {
        arn *= ar;
        k++;
        sum = p[k] * hc[k];
        sumc = p[k] * cc[k];
        sum2 = 0;
        for (m = 1; m <= n; m++) {
            k++;
            tempc = cc[k] * cosml[m] + cs[k] * sinml[m];
            temp = hc[k] * cosml[m] + hs[k] * sinml[m];
            sumc += p[k] * tempc;
            sum += p[k] * temp;
        }
        ac += sumc;
        a += sum * arn;
    }
    ac += cc[1] + p[2] * cc[2] + p[3] * (cc[3] * cosml[1] + cs[3] * sinml[1]);
/*add haco=ac/100 to convert height anomaly on the ellipsoid to the undulation
add -0.53m to make undulation refer to the wgs84 ellipsoid.*/
    return a * gm / (gr * re) + ac / 100 - .53;
}

void dscml(double rlon, unsigned nmax, double sinml[_361+ 1], double cosml[_361+ 1]) {
    double a, b;
    int m;
    a = sin(rlon);
    b = cos(rlon);
    sinml[1] = a;
    cosml[1] = b;
    sinml[2] = 2 * b * a;
    cosml[2] = 2 * b * b - 1;
    for (m = 3; m <= nmax; m++) {
        sinml[m] = 2 * b * sinml[m - 1] - sinml[m - 2];
        cosml[m] = 2 * b * cosml[m - 1] - cosml[m - 2];
    }
}

void dhcsin(unsigned nmax, double hc[l_value+ 1], double hs[l_value+ 1]) {


    // potential coefficient file
    //f_12 = fopen("EGM96", "rb");
    NSString* path2 = [[NSBundle mainBundle] pathForResource:@"EGM96" ofType:@""];
    FILE* f_12 = fopen(path2.UTF8String, "rb");
    if (f_12 == NULL) {
        NSLog([path2 stringByAppendingString:@" not found"]);
    }



    int n, m;
    double j2, j4, j6, j8, j10, c, s, ec, es;
/*the even degree zonal coefficients given below were computed for the
 wgs84(g873) system of constants and are identical to those values
 used in the NIMA gridding procedure. computed using subroutine
 grs written by N.K. PAVLIS*/
    j2 = 0.108262982131e-2;
    j4 = -.237091120053e-05;
    j6 = 0.608346498882e-8;
    j8 = -0.142681087920e-10;
    j10 = 0.121439275882e-13;
    m = ((nmax + 1) * (nmax + 2)) / 2;
    for (n = 1; n <= m; n++)hc[n] = hs[n] = 0;
    while (6 == fscanf(f_12, "%i %i %lf %lf %lf %lf", &n, &m, &c, &s, &ec, &es)) {
        if (n > nmax)continue;
        n = (n * (n + 1)) / 2 + m + 1;
        hc[n] = c;
        hs[n] = s;
    }
    hc[4] += j2 / sqrt(5);
    hc[11] += j4 / 3;
    hc[22] += j6 / sqrt(13);
    hc[37] += j8 / sqrt(17);
    hc[56] += j10 / sqrt(21);


    fclose(f_12);

}

void legfdn(unsigned m, double theta, double rleg[_361+ 1], unsigned nmx)
/*this subroutine computes  all normalized legendre function
in "rleg". order is always
m, and colatitude is always theta  (radians). maximum deg
is  nmx. all calculations in double precision.
ir  must be set to zero before the first call to this sub.
the dimensions of arrays  rleg must be at least equal to  nmx+1.
Original programmer :Oscar L. Colombo, Dept. of Geodetic Science
the Ohio State University, August 1980
ineiev: I removed the derivatives, for they are never computed here*/
{
    static double drts[1301], dirt[1301], cothet, sithet, rlnn[_361+ 1];
    static int ir;
    int nmx1 = nmx + 1, nmx2p = 2 * nmx + 1, m1 = m + 1, m2 = m + 2, m3 = m + 3, n, n1, n2;
    if (!ir) {
        ir = 1;
        for (n = 1; n <= nmx2p; n++) {
            drts[n] = sqrt(n);
            dirt[n] = 1 / drts[n];
        }
    }
    cothet = cos(theta);
    sithet = sin(theta);
    /*compute the legendre functions*/
    rlnn[1] = 1;
    rlnn[2] = sithet * drts[3];
    for (n1 = 3; n1 <= m1; n1++) {
        n = n1 - 1;
        n2 = 2 * n;
        rlnn[n1] = drts[n2 + 1] * dirt[n2] * sithet * rlnn[n];
    }
    switch (m) {
        case 1:
            rleg[2] = rlnn[2];
            rleg[3] = drts[5] * cothet * rleg[2];
            break;
        case 0:
            rleg[1] = 1;
            rleg[2] = cothet * drts[3];
            break;
    }
    rleg[m1] = rlnn[m1];
    if (m2 <= nmx1) {
        rleg[m2] = drts[m1 * 2 + 1] * cothet * rleg[m1];
        if (m3 <= nmx1)
            for (n1 = m3; n1 <= nmx1; n1++) {
                n = n1 - 1;
                if ((!m && n < 2) || (m == 1 && n < 3))continue;
                n2 = 2 * n;
                rleg[n1] = drts[n2 + 1] * dirt[n + m] * dirt[n - m] *
                        (drts[n2 - 1] * cothet * rleg[n1 - 1] - drts[n + m - 1] * drts[n - m - 1] * dirt[n2 - 3] * rleg[n1 - 2]);
            }
    }
}

void radgra(double lat, double lon, double *rlat, double *gr, double *re)
/*this subroutine computes geocentric distance to the point,
the geocentric latitude,and
an approximate value of normal gravity at the point based
the constants of the wgs84(g873) system are used*/
{
    const double a = 6378137., e2 = .00669437999013, geqt = 9.7803253359, k = .00193185265246;
    double n, t1 = sin(lat) * sin(lat), t2, x, y, z;
    n = a / sqrt(1 - e2 * t1);
    t2 = n * cos(lat);
    x = t2 * cos(lon);
    y = t2 * sin(lon);
    z = (n * (1 - e2)) * sin(lat);
    *re = sqrt(x * x + y * y + z * z);/*compute the geocentric radius*/
    *rlat = atan(z / sqrt(x * x + y * y));/*compute the geocentric latitude*/
    *gr = geqt * (1 + k * t1) / sqrt(1 - e2 * t1);/*compute normal gravity:units are m/sec**2*/
}


double undulation(double lat, double lon, int nmax, int k) {
    double rlat, gr, re;
    int i, j, m;
    radgra(lat, lon, &rlat, &gr, &re);
    rlat = M_PI / 2 - rlat;
    for (j = 1; j <= k; j++) {
        m = j - 1;
        legfdn(m, rlat, rleg, nmax);
        for (i = j; i <= k; i++)p[(i - 1) * i / 2 + m + 1] = rleg[i];
    }
    dscml(lon, nmax, sinml, cosml);
    return hundu(nmax, p, hc, hs, sinml, cosml, gr, re, cc, cs);
}

void init_arrays(void) {
    int ig, i, n, m;
    double t1, t2;






    NSString* path1 = [[NSBundle mainBundle] pathForResource:@"CORCOEF" ofType:@""];


    //correction coefficient file:  modified with 'sed -e"s/D/e/g"' to be read with fscanf
    FILE* f_1 = fopen([path1 cStringUsingEncoding:1], "rb");
    if (f_1 == NULL) {
        NSLog([path1 stringByAppendingString:@" not found"]);
    }


    nmax = 360;
    for (i = 1; i <= l_value; i++)cc[i] = cs[i] = 0;

    while (4 == fscanf(f_1, "%i %i %lg %lg", &n, &m, &t1, &t2)) {
        ig = (n * (n + 1)) / 2 + m + 1;
        cc[ig] = t1;
        cs[ig] = t2;
    }
/*the correction coefficients are now read in*/
/*the potential coefficients are now read in and the reference
 even degree zonal harmonic coefficients removed to degree 6*/
    dhcsin(nmax, hc, hs);
    fclose(f_1);
}


@end

I've done some limited testing against the Geoid Height Calculator (http://www.unavco.org/community_science/science-support/geoid/geoid.html) and looks like everything is a match

UPDATE iOS8 or Greater

As of IOS8 This code might not work correctly. You may need to change how the bundle is loaded:

[[NSBundle mainBundle] pathForResource:@"EGM96" ofType:@""];

Do some googling or add a comment here.

这篇关于WGS84大地水准面高度海拔高度偏移量用于IOS上的外部GPS数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆