QTH számoló program C

Innen: HamWiki
Ugrás a navigációhoz Ugrás a kereséshez

C forrásnyelvű függvénykészlet

  • földrajzi koordináták és QTH lokátor oda-vissza konvertálására,
  • földrajzi koordináták ás APRS formátum oda-vissza konvertálására,
  • távolság és irány számolására.
 /* ul.h */
 /* gg630504 */

#define _dEarthr   6371200.0            /* Föld sugara m */
#define cchAprsLim 19                   /* APRS mező hossza chEos-sal */
#define cchUlLim   9                    /* UL mező hossza chEos-sal */
#define chEos           '\0'           /* szöveg vége karakter */
#define DegFromRad ( 180.0/M_PI )
#define dEps            1.0e-100
#define RadFromSec ( M_PI/648000.0 )
#define rFail           ( -2)          /* sikertelen */
#define rSucced         0              /* sikeres */

typedef double                     _A;  /* szög          rad radián    qte */
typedef double                     _D;  /* távolság      m méter       qrb */
typedef double                     D;   /* duplapontos                     */
typedef signed         int         R;   /* visszatérési kód                */
typedef signed         int         W;   /* előjeles egész                  */
typedef signed   long  int         LW;  /* előjeles hosszú egész           */
typedef unsigned       char        CH;  /* karakter                        */
typedef unsigned       char        F;   /* logikai                         */
typedef unsigned       char      * SZ;  /* szöveg chEos-sal                */
typedef unsigned       int         U;   /* előjel nélküli egész            */
typedef unsigned long  int         LU;  /* előjel nélküli hosszú egész     */

typedef struct     {
 W                 wSig;  /* előjel   -1 0 1 */
 LU                luDeg; /* fok       0 ... */
 U                 uMin;  /* perc      0..60 */
 U                 uSec;  /* másodperc 0..60 */
 }                 _DMS;

typedef struct     {
 W                 wSig;  /* előjel    -1 0 1 */
 LU                luDeg; /* fok       0 ...  */
 D                 dMin;  /* perc      0.0 ...*/
 }                 _DM;

typedef struct     {
 _A                _aLon;     /* hosszúság + kelet; - nyugat */
 _A                _aLat;     /* szélesség + észak; - dél    */
 }                 _GEOA;     /* földrajzi koordináták radiánban */

typedef struct     {
 _DMS              _dmsLon;     /* hosszúság */
 _DMS              _dmsLat;     /* szélesség */
 }                 _GEODMS;     /* földrajzi koordináták */

typedef struct     {
 _DM               _dmLon;     /* hosszúság */
 _DM               _dmLat;     /* szélesség */
 }                 _GEODM;     /* földrajzi koordináták */

typedef struct     {           /* UL koordináták */
 _GEOA             _geoaMp[4]; /* sarkok: dny, dk, ény, ék */
 _GEOA             _geoa;      /* középpont */
 }                 _GEOAUL0;

typedef struct     {
 CH                chType; /* ' ' 'a' 'u' */
 _GEOA  *          p_geoa;

 CH                szAprs[cchAprsLim]; /* ellenőrzött APRS */
 R                 rAprs;          /* ellenőrzés eredménye */
 _GEOA             _geoaAprs;      /* koordináták */

 CH                szUl[cchUlLim]; /* ellenőrzött UL */
 W                 wUl;            /* UL ellenőrzés eredménye */
 _GEOAUL0          _geoaulMp[4];   /* koordináták klf pontossággal */
 }                 _GEOX;

typedef _DM *      P_DM;
typedef _DMS *     P_DMS;
typedef _GEOA *    P_GEOA;
typedef _GEOX *    P_GEOX;
typedef _GEODM *   P_GEODM;
typedef _GEODMS *  P_GEODMS;

 /* szög átszámolás */
_A                 _AFromPdm( P_DM );
_A                 _AFromPdms( P_DMS );
P_DM               PdmAdjPdmF( P_DM, F );
P_DM               PdmFromPdmA( P_DM, _A );
P_DM               PdmFromPdmPdms( P_DM, P_DMS );
P_DMS              PdmsAdjPdmsF( P_DMS, F );
P_DMS              PdmsFromPdmsA( P_DMS, _A );
P_DMS              PdmsFromPdmsPdm( P_DMS, P_DM );

 /* QRB - Földrajzi távolság */
_D                 _DQrbPgeoaPgeoa( P_GEOA, P_GEOA );

 /* QTE - Földrajzi irány */
_A                 _AQtePgeoaPgeoa( P_GEOA, P_GEOA );

 /* UL */
SZ                 SzUlSzPgeoa( SZ, P_GEOA );

 /* APRS */
SZ                 SzAprsSzPgeoa( SZ, P_GEOA );

 /* UL & APRS */
R                  RFromPgeoxSz( P_GEOX, SZ );
R                  RPosPgeox2( P_GEOX, P_GEOX );
 /* ul.c */
 /* gg630504 */

#include <math.h>
#include <stdio.h>

#include "ul.h"

 /*--------------------------------------------------------------------*/
 /* APRS formátumú koordináták <- radián
    ddmm.mmN/dddmm.mmE
    012345678901234567
 */

SZ                 SzAprsSzPgeoa( sz_, pgeo_ )
 SZ                sz_;   /* ki; APRS; cchAprsLim hosszú */
 P_GEOA            pgeo_; /* be; radián */

 {
 W                 wSig;
 D                 dDeg;
 D                 dMin;
 D                 dFloor;
 CH                szDeg[12];
 CH                szMin[12];
 _A                a;

 a = pgeo_->_aLat;

 if( a<0.0 )
      {
      a = -a;
      wSig = 1;
      }
 else wSig = 0;

 dDeg = DegFromRad * a;
 dFloor = floor(dDeg);
 dMin = (dDeg-dFloor)*60.0;
 dDeg = dFloor;
 sprintf( szMin, "%05.2lf", dMin );
 if( szMin[0]=='6' )
      {
      dMin = 0.0;
      dDeg += 1.0;
      sprintf( szMin, "%05.2lf", dMin );
      }
 sprintf( szDeg, "%02.0lf", dDeg );
 sprintf( sz_, "%s%s%s/", szDeg, szMin, wSig ? "S" : "N" );

 a = pgeo_->_aLon;

 if( a<0.0 )
      {
      a = -a;
      wSig = 1;
      }
 else wSig = 0;

 dDeg = DegFromRad * a;
 dFloor = floor(dDeg);
 dMin = (dDeg-dFloor)*60.0;
 dDeg = dFloor;
 sprintf( szMin, "%05.2lf", dMin );
 if( szMin[0]=='6' )
      {
      dMin = 0.0;
      dDeg += 1.0;
      sprintf( szMin, "%05.2lf", dMin );
      }
 sprintf( szDeg, "%03.0lf", dDeg );
 sprintf( sz_+9, "%s%s%s", szDeg, szMin, wSig ? "W" : "E" );

 return( sz_ );
 }

 /*--------------------------------------------------------------------*/
 /* radián <- fok, tizedes perc */

_A                 _AFromPdm( p_ )
 P_DM              p_; /* be; fok, tizedes perc */

 {
 _A                a;

 a  = p_->luDeg*(M_PI/180.0);
 a += p_->dMin*(M_PI/10800.0);
 return( p_->wSig>=0 ? a : -a );
 }

 /*--------------------------------------------------------------------*/
 /* radián <- fok, perc, másodperc */

_A                 _AFromPdms( p_ )
 P_DMS             p_; /* be; fok, perc, másodperc */

 {
 _A                a;

 a  = p_->luDeg*(M_PI/180.0);
 a += p_->uMin*(M_PI/10800.0);
 a += p_->uSec*(M_PI/648000.0);
 return( p_->wSig>=0 ? a : -a );
 }

 /*--------------------------------------------------------------------*/
 /* fok, tizedes perc <- radián */

P_DM               PdmFromPdmA( p_, a_ )
 P_DM              p_; /* ki; fok, tizedes perc */
 _A                a_; /* be; radián */

 {
 D                 dDeg;
 D                 dMin;

 if( a_<0.0 )
      {
      p_->wSig = -1;
      a_ = -a_;
      }
 else if( a_>0.0 )
           p_->wSig = 1;
      else p_->wSig = 0;

 dDeg = a_*180.0/M_PI;
 dMin = modf( dDeg, &dDeg );
 p_->luDeg = dDeg;
 p_->dMin = dMin*60.0;
 return( p_ );
 }

 /*--------------------------------------------------------------------*/
 /* fok, perc, másodperc <- radián */

P_DMS              PdmsFromPdmsA( p_, a_ )
 P_DMS             p_; /* ki; fok, perc, másodperc */
 _A                a_; /* be; radián */

 {
 D                 dDeg;
 D                 dMin;
 D                 dSec;

 if( a_<0.0 )
      {
      p_->wSig = -1;
      a_ = -a_;
      }
 else if( a_>0.0 )
           p_->wSig = 1;
      else p_->wSig = 0;

 dDeg = a_*180.0/M_PI;
 dMin = modf( dDeg, &dDeg );
 p_->luDeg = dDeg;
 dMin *= 60.0;
 dSec = modf( dMin, &dMin );
 p_->uMin = dMin;
 dSec *= 60.0;
 modf( dSec, &dSec );
 p_->uSec = dSec;
 return( p_ );
 }

 /*--------------------------------------------------------------------*/
 /* fok, perc, másodperc <- fok, tizedes perc */

P_DMS              PdmsFromPdmsPdm( pdms_, pdm_ )
 P_DMS             pdms_; /* ki; fok, perc, másodperc */
 P_DM              pdm_; /* be; fok, tizedes perc */

 {
 D                 dMin;
 D                 dSec;

 pdms_->wSig  = pdm_->wSig;
 pdms_->luDeg = pdm_->luDeg;
 dSec = modf( pdm_->dMin, &dMin );
 pdms_->uMin = dMin;
 dSec *= 60.0;
 modf( dSec, &dSec );
 pdms_->uSec = dSec;
 return( pdms_ );
 }

 /*--------------------------------------------------------------------*/
 /* fok, tizedes perc <- fok, perc, másodperc */

P_DM               PdmFromPdmPdms( pdm_, pdms_ )
 P_DM              pdm_; /* ki; fok, tizedes perc */
 P_DMS             pdms_; /* be; fok, perc, másodperc */

 {
 pdm_->wSig  = pdms_->wSig;
 pdm_->luDeg = pdms_->luDeg;
 pdm_->dMin  = pdms_->uMin + pdms_->uSec/60.0;
 return( pdm_ );
 }

 /*--------------------------------------------------------------------*/
 /* fok, tizedes percet állít
    f_: fFalse -> -360 .. +360
    f_: fTrue  ->    0 .. +360 közé */

P_DM               PdmAdjPdmF( pdm_, f_ )
 P_DM              pdm_; /* be&ki: fok, tizedes perc */
 F                 f_;   /* be; */

 {
 LU                luDeg;
 D                 dMin;

 luDeg  = pdm_->luDeg;
 dMin   = fabs(pdm_->dMin);

 luDeg  = luDeg+(dMin / 3600.0);
 luDeg %= 360l;
 dMin   = fmod( dMin, 3600.0 );
 if( dMin<dEps )
      dMin = 0.0;

 if( f_ && pdm_->wSig<0 )
      {
      if( dMin==0.0 )
           {
           if( luDeg>0l )
                luDeg = 360l - luDeg;
           }
      else {
           dMin   = 60.0-dMin;
           if( dMin<dEps )
                dMin = 0.0;
           luDeg  = 359l-luDeg;
           }
      }

 if( luDeg!=0 || dMin>0.0 )
      {
      if( !f_ )
           pdm_->wSig = 1;
      }
 else pdm_->wSig = 0;

 pdm_->luDeg = luDeg;
 pdm_->dMin  = dMin;

 return( pdm_ );
 }

 /*--------------------------------------------------------------------*/
 /* fok, perc, másodpercet állít
    f_: fFalse -> -360 .. +360
    f_: fTrue  ->    0 .. +360 közé */

P_DMS              PdmsAdjPdmsF( pdms_, f_ )
 P_DMS             pdms_; /* be&ki; fok, perc, másodperc */
 F                 f_;    /* be; */

 {
 LU                luDeg;
 LU                luMin;
 LU                luSec;

 luSec = ((pdms_->luDeg%360l)*3600l+(LU)pdms_->uMin*60l+(LU)pdms_->uSec)%1296000l;

 if( f_ && pdms_->wSig<0 )
      {
      luSec  = 1296000l-luSec;
      luSec %= 1296000l;
      }

 luDeg  = luSec / 3600l;
 luSec %= 3600l;
 luMin  = luSec / 60l;
 luSec %= 60l;

 if( luDeg!=0 || luMin!=0 || luSec!=0 )
      {
      if( !f_ )
           pdms_->wSig = 1;
      }
 else pdms_->wSig = 0;

 pdms_->luDeg = luDeg;
 pdms_->uMin  = (U)luMin;
 pdms_->uSec  = (U)luSec;

 return( pdms_ );
 }

 /*-------------------------------------------------------------------*/
 /* segédtáblázat UL típusú szöveg karaktereinek ellenőrzéséhez */

#define bbUlDig 0x01
#define bbUlar  0x10
#define bbUlAR  0x20
#define bbUlax  0x40
#define bbUlAX  0x80

CH                  bbUlMp[] = {
/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 30 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 38 */ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 40 */ 0x00, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
/* 48 */ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
/* 50 */ 0xa0, 0xa0, 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80,
/* 58 */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 60 */ 0x00, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
/* 68 */ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
/* 70 */ 0x50, 0x50, 0x50, 0x40, 0x40, 0x40, 0x40, 0x40,
/* 78 */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 88 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 98 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* a0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* a8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* b0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* b8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* c0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* c8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* d0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* d8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* e0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* e8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* f0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* f8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

 /*-------------------------------------------------------------------*/
 /* Radiános koordináták ( GEOX ) <- UL vagy APRS szöveg

    p_->chType
    'u'                          UL típusú szöveg volt
    'a'                          APRS típusú szöveg volt
    ' '                          hibás bemenő adat

    p_->wUl                      UL pontossága
    3                            RR99XX99
    2                            RR99XX??
    1                            RR99????
    0                            RR??????
    -1                           ????????
 */

R                  RFromPgeoxSz( p_, sz_ )
 P_GEOX            p_; /* ki; típus, radiános koordináták, stb. */
 SZ                sz_; /* be; UL vagy APRS szöveg */

 {
 _GEOAUL0 *        pgeo;
 CH                ch0;
 CH                ch1;
 CH                ch;
 LW                lw0;
 LW                lw1;
 LW                lw;
 LW                lwc;

 /* UL szerinti ellenőrzés --------------------------------------------*/
 ch0 = sz_[0];
 ch1 = sz_[1];

 if( bbUlMp[ch0] & bbUlar )
      ch0 -= 'a'-'A';
 else if( !(bbUlMp[ch0] & bbUlAR) )
           { p_->wUl = -1; goto L0; }

 if( bbUlMp[ch1] & bbUlar )
      ch1 -= 'a'-'A';
 else if( !(bbUlMp[ch1] & bbUlAR) )
           { p_->wUl = -1; goto L0; }

 p_->szUl[0] = ch0;
 p_->szUl[1] = ch1;

 ch0 = sz_[2];
 ch1 = sz_[3];

 if( !(bbUlMp[ch0] & bbUlDig) )
      { p_->wUl = 0; goto L1; }

 if( !(bbUlMp[ch1] & bbUlDig) )
      { p_->wUl = 0; goto L1; }

 p_->szUl[2] = ch0;
 p_->szUl[3] = ch1;

 ch0 = sz_[4];
 ch1 = sz_[5];

 if( bbUlMp[ch0] & bbUlax )
      ch0 -= 'a'-'A';
 else if( !(bbUlMp[ch0] & bbUlAX) )
           { p_->wUl = 1; goto L2; }

 if( bbUlMp[ch1] & bbUlax )
      ch1 -= 'a'-'A';
 else if( !(bbUlMp[ch1] & bbUlAX) )
           { p_->wUl = 1; goto L2; }

 p_->szUl[4] = ch0;
 p_->szUl[5] = ch1;

 ch0 = sz_[6];
 ch1 = sz_[7];

 if( !(bbUlMp[ch0] & bbUlDig) )
      { p_->wUl = 2; goto L3; }

 if( !(bbUlMp[ch1] & bbUlDig) )
      { p_->wUl = 2; goto L3; }

 p_->szUl[6] = ch0;
 p_->szUl[7] = ch1;
 p_->wUl = 3; goto L4;

 L0: p_->szUl[0] = p_->szUl[1] = '?';
 L1: p_->szUl[2] = p_->szUl[3] = '?';
 L2: p_->szUl[4] = p_->szUl[5] = '?';
 L3: p_->szUl[6] = p_->szUl[7] = '?';
 L4: p_->szUl[8] = chEos;

 if( p_->wUl>=0 )
      { /* geoa <- UL konvertálás -------------------------------------*/
      if( p_->wUl >= 0 )
           {
           pgeo = &p_->_geoaulMp[0];
           lw0 = 72000l*(p_->szUl[0]-'A') - 648000l;
           lw1 = lw0+72000l;
           lwc = lw0+36000l;
           pgeo->_geoaMp[0]._aLon = pgeo->_geoaMp[2]._aLon = RadFromSec*lw0;
           pgeo->_geoaMp[1]._aLon = pgeo->_geoaMp[3]._aLon = RadFromSec*lw1;
           pgeo->_geoa._aLon = RadFromSec*lwc;
           lw0 = 36000l*(p_->szUl[1]-'A') - 324000l;
           lw1 = lw0+36000l;
           lwc = lw0+18000l;
           pgeo->_geoaMp[0]._aLat = pgeo->_geoaMp[1]._aLat = RadFromSec*lw0;
           pgeo->_geoaMp[2]._aLat = pgeo->_geoaMp[3]._aLat = RadFromSec*lw1;
           pgeo->_geoa._aLat = RadFromSec*lwc;
           }
      if( p_->wUl >= 1 )
           {
           pgeo = &p_->_geoaulMp[1];
           lw0 = 72000l*(p_->szUl[0]-'A')+ 7200l*(p_->szUl[2]-'0') - 648000l;
           lw1 = lw0+7200l;
           lwc = lw0+3600l;
           pgeo->_geoaMp[0]._aLon = pgeo->_geoaMp[2]._aLon = RadFromSec*lw0;
           pgeo->_geoaMp[1]._aLon = pgeo->_geoaMp[3]._aLon = RadFromSec*lw1;
           pgeo->_geoa._aLon = RadFromSec*lwc;
           lw0 = 36000l*(p_->szUl[1]-'A')+ 3600l*(p_->szUl[3]-'0') - 324000l;
           lw1 = lw0+3600l;
           lwc = lw0+1800l;
           pgeo->_geoaMp[0]._aLat = pgeo->_geoaMp[1]._aLat = RadFromSec*lw0;
           pgeo->_geoaMp[2]._aLat = pgeo->_geoaMp[3]._aLat = RadFromSec*lw1;
           pgeo->_geoa._aLat = RadFromSec*lwc;
           }
      if( p_->wUl >= 2 )
           {
           pgeo = &p_->_geoaulMp[2];
           lw0 = 72000l*(p_->szUl[0]-'A')+ 7200l*(p_->szUl[2]-'0')+
                 300l*(p_->szUl[4]-'A')- 648000l;
           lw1 = lw0+300l;
           lwc = lw0+150l;
           pgeo->_geoaMp[0]._aLon = pgeo->_geoaMp[2]._aLon = RadFromSec*lw0;
           pgeo->_geoaMp[1]._aLon = pgeo->_geoaMp[3]._aLon = RadFromSec*lw1;
           pgeo->_geoa._aLon = RadFromSec*lwc;
           lw0 = 36000l*(p_->szUl[1]-'A')+ 3600l*(p_->szUl[3]-'0')+ 
                 150l*(p_->szUl[5]-'A') - 324000l;
           lw1 = lw0+150l;
           lwc = lw0+75l;
           pgeo->_geoaMp[0]._aLat = pgeo->_geoaMp[1]._aLat = RadFromSec*lw0;
           pgeo->_geoaMp[2]._aLat = pgeo->_geoaMp[3]._aLat = RadFromSec*lw1;
           pgeo->_geoa._aLat = RadFromSec*lwc;
           }
      if( p_->wUl >= 3 )
           {
           pgeo = &p_->_geoaulMp[3];
           lw0 = 72000l*(p_->szUl[0]-'A')+ 7200l*(p_->szUl[2]-'0')+ 
                 300l*(p_->szUl[4]-'A')+ 30l*(p_->szUl[6]-'0')- 648000l;
           lw1 = lw0+30l;
           lwc = lw0+15l;
           pgeo->_geoaMp[0]._aLon = pgeo->_geoaMp[2]._aLon = RadFromSec*lw0;
           pgeo->_geoaMp[1]._aLon = pgeo->_geoaMp[3]._aLon = RadFromSec*lw1;
           pgeo->_geoa._aLon = RadFromSec*lwc;
           lw0 = 36000l*(p_->szUl[1]-'A')+ 3600l*(p_->szUl[3]-'0')+ 
                 150l*(p_->szUl[5]-'A')+ 15l*(p_->szUl[7]-'0') - 324000l;
           lw1 = lw0+15l;
           lwc = lw0+7l;
           pgeo->_geoaMp[0]._aLat = pgeo->_geoaMp[1]._aLat = RadFromSec*lw0;
           pgeo->_geoaMp[2]._aLat = pgeo->_geoaMp[3]._aLat = RadFromSec*lw1;
           pgeo->_geoa._aLat = RadFromSec*(lwc+0.5);
           }
      p_->chType = 'u';
      p_->p_geoa = &p_->_geoaulMp[p_->wUl]._geoa;
      return( rSucced );
      }

 /* APRS szerinti ellenőrzés ------------------------------------------*/
 p_->rAprs = rSucced;
 ch = sz_[ 0]; if( ch< '0' || ch> '9' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[ 0] = ch;
 ch = sz_[ 1]; if( ch< '0' || ch> '9' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[ 1] = ch;
 ch = sz_[ 2]; if( ch< '0' || ch> '5' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[ 2] = ch;
 ch = sz_[ 3]; if( ch< '0' || ch> '9' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[ 3] = ch;
 ch = sz_[ 4]; if( ch!='.'            )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[ 4] = ch;
 ch = sz_[ 5]; if( ch< '0' || ch> '9' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[ 5] = ch;
 ch = sz_[ 6]; if( ch< '0' || ch> '9' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[ 6] = ch;
 /* max. 90 00 00 */
 if( sz_[0]=='9' )
      {
      if( sz_[1]!='0' || sz_[2]!='0' ||  sz_[3]!='0' ||  sz_[5]!='0' ||  sz_[6]!='0' )
           p_->rAprs = rFail;
      }
 ch = sz_[ 7]; if( ch=='n'            )       ch = 'N'; else
                  if( ch=='s'            )       ch = 'S'; else
                  if( ch!='N' && ch!='S' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[ 7] = ch;
 ch = sz_[ 8]; if( ch=='\\'           )       ch = '/'; else
                  if( ch!='/'            )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[ 8] = ch;
 ch = sz_[ 9]; if( ch< '0' || ch> '1' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[ 9] = ch;
 ch = sz_[10]; if( ch< '0' || ch> '8' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[10] = ch;
 ch = sz_[11]; if( ch< '0' || ch> '9' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[11] = ch;
 ch = sz_[12]; if( ch< '0' || ch> '5' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[12] = ch;
 ch = sz_[13]; if( ch< '0' || ch> '9' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[13] = ch;
 ch = sz_[14]; if( ch!='.'            )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[14] = ch;
 ch = sz_[15]; if( ch< '0' || ch> '9' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[15] = ch;
 ch = sz_[16]; if( ch< '0' || ch> '9' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[16] = ch;
 /* max 180 00 00 */
 if( sz_[9]=='1' && sz_[10]=='8' )
      {
      if( sz_[11]!='0' || sz_[12]!='0' || sz_[12]!='0' ||
          sz_[15]!='0' || sz_[16]!='0' )
           p_->rAprs = rFail;
      }
 ch = sz_[17]; if( ch=='e'            )       ch = 'E'; else
                  if( ch=='w'            )       ch = 'W'; else
                  if( ch!='E' && ch!='W' )       { ch = '?'; p_->rAprs = rFail; }
 p_->szAprs[17] = ch;


 p_->szAprs[18] = chEos;

 if( p_->rAprs == rSucced )
      { /* geoa <- APRS konvertálás -----------------------------------*/
      lw =      10l *(p_->szAprs[ 0]-'0')+  (p_->szAprs[ 1]-'0');
      lw *= 6000;
      lw +=   1000l *(p_->szAprs[ 2]-'0')+ 100l *(p_->szAprs[ 3]-'0')+ 
              10l *(p_->szAprs[ 5]-'0')+ (p_->szAprs[ 6]-'0');
      if( p_->szAprs[7] !='N' )
           lw = -lw;
      p_->_geoaAprs._aLat = lw*(M_PI/1080000.0);
      lw =  100l *(p_->szAprs[ 9]-'0')+  10l *(p_->szAprs[10]-'0')+(p_->szAprs[11]-'0');
      lw *= 6000;
      lw += 1000l *(p_->szAprs[12]-'0')+ 100l *(p_->szAprs[13]-'0')+ 
            10l *(p_->szAprs[15]-'0')+ (p_->szAprs[16]-'0');
      if( p_->szAprs[17] !='E' )
           lw = -lw;
      p_->_geoaAprs._aLon = lw*(M_PI/1080000.0);
      p_->chType = 'a';
      p_->p_geoa = &p_->_geoaAprs;
      return( rSucced );
      }

 p_->chType = ' ';
 return( rFail );
 }

 /* -------------------------------------------------------------------
    Távolság és irányszámoláshoz
    geox formátumból összeválogat koordinátákat,
    hogy azonos pontosságúak legyenek.
    Előtte: 2*RFromPgeoaxSz() kell.
    ki; p0_->p_geoa, p1_->p_geoa
 */

R                  RPosPgeox2( p0_, p1_ )
 P_GEOX            p0_; /* be&ki; */
 P_GEOX            p1_; /* be&ki; */

 {
 W                 w;

 switch( p0_->chType ) {
 case 'a':
      switch( p1_->chType ) {
      case 'a':
           p0_->p_geoa = &p0_->_geoaAprs;
           p1_->p_geoa = &p1_->_geoaAprs;
           break;
      case 'u':
           p0_->p_geoa = &p0_->_geoaAprs;
           p1_->p_geoa = &p1_->_geoaulMp[p1_->wUl]._geoa;
           break;
      default: return( rFail );
      }
      break;
 case 'u':
      switch( p1_->chType ) {
      case 'a':
           p0_->p_geoa = &p0_->_geoaulMp[p0_->wUl]._geoa;
           p1_->p_geoa = &p1_->_geoaAprs;
           break;
      case 'u': /* közös pontosság */
           w = p0_->wUl;
           if( p1_->wUl<w )
                w = p1_->wUl;
           p0_->p_geoa = &p0_->_geoaulMp[w]._geoa;
           p1_->p_geoa = &p1_->_geoaulMp[w]._geoa;
           break;
      default: return( rFail );
      }
      break;
 default: return( rFail );
      }

 return( rSucced );
 }

 /*--------------------------------------------------------------------*/
 /* QRB <- radiános koordináták
    ki; távolság: méter */

_D                 _DQrbPgeoaPgeoa( pgeo0_, pgeo1_ )
 P_GEOA            pgeo0_; /* be; radiános koordináták */
 P_GEOA            pgeo1_; /* be; radiános koordináták */

 {
 return acos ( sin(pgeo0_->_aLat) * sin(pgeo1_->_aLat) +
               cos(pgeo0_->_aLat) * cos(pgeo1_->_aLat) *
               cos(pgeo1_->_aLon-pgeo0_->_aLon) ) * _dEarthr;
 }

 /*--------------------------------------------------------------------*/
 /* QTE <- radiános koordináták
    ki; irány: radián */

_A                 _AQtePgeoaPgeoa( pgeo0_, pgeo1_ )
 P_GEOA            pgeo0_; /* be; saját radiános koordináták */
 P_GEOA            pgeo1_; /* be; másik radiános koordináták */

 {
 _A                _aLonD;
 double            dTmp0;
 double            dTmp1;

 _aLonD = pgeo1_->_aLon - pgeo0_->_aLon;

 if( _aLonD <= -M_PI )
      _aLonD += 2.0*M_PI;

 dTmp0 = tan(pgeo1_->_aLat) * cos(pgeo0_->_aLat) -
         sin(pgeo0_->_aLat) * cos(_aLonD);

 if( fabs( dTmp0 ) < dEps )
      return 0.0;

 dTmp1 = fabs(atan( sin(_aLonD)/dTmp0 ));

 if( dTmp0<0.0 )
      dTmp1 = M_PI - dTmp1;

 if( _aLonD<0.0 )
      dTmp1 = (2.0*M_PI) - dTmp1;

 return( dTmp1 );
 }

 /*--------------------------------------------------------------------*/
 /* UL formátumú koordináták <- radián */

SZ                 SzUlSzPgeoa( szul_, pgeo_ )
 SZ                szul_; /* ki; UL; cchUlLim hosszú */
 P_GEOA            pgeo_; /* be; radián */

 {
 LW                lw;

 lw = (648000.0/M_PI)*pgeo_->_aLon+648000.5;
 lw %= 1296000l;
 szul_[0] = 'A' + (CH)( lw / 72000l );
 lw %= 72000l;
 szul_[2] = '0' + (CH)( lw / 7200l );
 lw %= 7200l;
 szul_[4] = 'A' + (CH)( lw / 300l );
 lw %= 300;
 szul_[6] = '0' + (CH)( lw / 30l );

 lw  = (648000.0/M_PI)*pgeo_->_aLat+ 324000.5;
 lw %= 1296000l;
 szul_[1] = 'A' + (CH)( lw / 36000l );
 lw %= 36000l;
 szul_[3] = '0' + (CH)( lw / 3600l );
 lw %= 3600l;
 szul_[5] = 'A' + (CH)( lw / 150l );
 lw %= 150;
 szul_[7] = '0' + (CH)( lw / 15l );

 szul_[8] = chEos;
 return( szul_ );
 }

Példaprogram: a paraméterként megadott két QTH lokátorból és/vagy APRS koordinátából távolságot és irányt számol.

 /* main.c */
 /* gg630504 */

#include <stdio.h>
#include <math.h>
#include "ul.h"

typedef SZ       * PSZ;

_GEOX              _geoxMp[2];

R cdecl            main( cv_, pszv_, psze_ )
 W                 cv_;
 PSZ               pszv_; /* két QTH lokátor és/vagy APRS koordináta */
 PSZ               psze_;

 {
 /* Ellenőrzések és konvertálások */
 if( cv_>=3 &&
     RFromPgeoxSz( &_geoxMp[0], pszv_[1] )==rSucced &&
     RFromPgeoxSz( &_geoxMp[1], pszv_[2] )==rSucced
     )
     {
     RPosPgeox2( &_geoxMp[0], &_geoxMp[1] ); /* azonos pontosság */
     fprintf( stdout, "QRB %f km\n",
              _DQrbPgeoaPgeoa( _geoxMp[0].p_geoa, _geoxMp[1].p_geoa )/1000.0 );
     fprintf( stdout, "QTE %f fok\n",
              DegFromRad*_AQtePgeoaPgeoa( _geoxMp[0].p_geoa, _geoxMp[1].p_geoa ) );
     }
 else fputs( "Hiba.\n", stdout );

 return( 0 );
 }