Logo Search packages:      
Sourcecode: tucnak2 version File versions  Download package

loc.c

/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2006  Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or                                                        
    modify it under the terms of the GNU General Public License                                                          
    version 2 as published by the Free Software Foundation.

*/


#ifndef MAIN
#include "header.h"
#else
#define R_EARTH 6371.2907
#define MY_PI 3.14159265358979323846
#endif

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

#define LOCDEBUGx

char *tostr(char *s,double x){
    int a,b;

    x=x*180/MY_PI;
    /*fprintf(stderr, "%6.2f\n",x);*/
    a=x;
    if (x>0)
        x-=a;
    else
        x=a-x;
    x*=60;
    b=x;
    if (x>0)
        x-=b;
    else
        x=b-x;
    x*=60;

    sprintf(s,"%d.%d'%3.1f\"",a,b,x);
  /*  fprintf(stderr,"%s\n",s);*/
    return(s);
}


/******************* QRB **************************/

double qth(char *qth,int width) {
    char *c,d;
    double res;
    
    /*dbg("qth('%s',%d)\n", qth, width);*/
    c=qth;
    while (1){
        d=lowcase(*c);
        if (!d) return(-100);
        if (d>='a' || d<='r') break;
        c++;
    }
    if (width&1) c++;
    d=lowcase(*c);
    if (strlen(c)<3) return(-100);
    
    res=(d-106)*MY_PI/9.0;
    c+=2;

    
    if (!isdigit(*c)) return(-100);
    res+=(*c-'0')*MY_PI/90.0;
    c+=2;
    
    /*dbg("strlen(c)=%d, strlen(qth)=%d\n", strlen(c), strlen(qth));  */
    
    if (strlen(qth)>=6){
        d=lowcase(*c);
        if (d<'a' || d>'x') return(-100);
        res+=(d-97)*MY_PI/2160.0;
    }else{
        if (width&2) res+=MY_PI/180;
    }
    
    res+=MY_PI/4320.0;
    
    /*if (strlen(c)>=8){
        c+=2;
        if (isdigit(*c))
            res+=(*c-'0')*MY_PI/21600.0;
        if (width&2) res+=MY_PI/43200.0;
    }else{
        if (width&2) res+=MY_PI/4320.0;
    } */
    
    if (width&1) res/=2;

    
    return(res);
}

/* compute QRB, not QSO points! */
int qrbqtf(char *myqth,char *recqth,double *qrb,double *qtf,char *str, int flags){
    double h1,w1,h2,w2;
    char s1[20],s2[20],s3[20],s4[20];
    int ret;
    
    *qrb=-1;
    *qtf=-1;

    if ((h1=qth(myqth,0|flags))<-10) return(-1);
    if ((w1=qth(myqth,1|flags))<-10) return(-1);
    if ((h2=qth(recqth,0|flags))<-10) return(-1);
    if ((w2=qth(recqth,1|flags))<-10) return(-1);

    /*dbg("h1=%7.4f w1=%7.4f h2=%7.4f  w2=%7.4f \n",h1,w1,h2,w2);*/
#ifdef LOCDEBUG    
    fprintf(stderr, "%s->%s, h1=%7.9f w1=%7.9f h2=%7.9f  w2=%7.9f \n",myqth,recqth,h1,w1,h2,w2);
#endif    

    if (str!=NULL){
        sprintf(str,"From: %s E  %s N  to %s E  %s N",tostr(s1,h1),tostr(s2,w1),tostr(s3,h2),tostr(s4,w2));
    }

    ret = hw2qrbqtf(h1, w1, h2, w2, qrb, qtf);
    *qtf=*qtf * 180.0/MY_PI;
      /*dbg("qrbqtf(%s->%s %5.3fkm %3.0fdeg\n", myqth, recqth, *qrb, *qtf);*/
    return ret;
}

/* compute QRB, not QSO points! */
int hw2qrbqtf(double h1, double w1, double h2, double w2, double *qrb, double *qtf){
    double dh,dw;
#ifdef LOCDEBUG    
    dbg("h1=%7.9f w1=%7.9f h2=%7.9f w2=%7.9f ",h1,w1,h2,w2);
#endif    

    dh=h2-h1;
    *qrb=R_EARTH*acos( sin(w1)*sin(w2)+cos(w1)*cos(w2)*cos(dh) );
    dw=tan(w2)*cos(w1)-sin(w1)*cos(dh);
    
#ifdef LOCDEBUG
    fprintf(stderr, "dh=%7.9f qrb=%7.9f dw=%7.9f\n", dh, *qrb, dw);
#endif    
    *qtf=atan2(sin(dh),dw);
    if (*qtf<0) *qtf+=2*MY_PI;
    return 0;
}

/*************** REVERSE QRB ***************************/
#define EPSILON 0.00000000005 
/* qtf in radian */
int qrbqtf2hw(double h1, double w1, double qrb, double qtf, double *h2, double *w2){
    double dh,  d;

    if (qrb>R_EARTH*MY_PI) return -1;
    d = qrb/R_EARTH;
    
    *w2 = asin (sin(w1)*cos(d) + cos(w1)*sin(d)*cos(qtf));
    if (fabs(cos(*w2))< EPSILON) {
        *h2 = 0;
    }else{
        dh = atan2(sin(qtf)*sin(d)*cos(w1), 
                   cos(d)-sin(w1)*sin(*w2) );
        *h2 = fmod (MY_PI +h1+dh, 2*MY_PI)-MY_PI;
    }
    return 0;
}

#ifdef HAVE_GFX
int xy2qrbqtf(struct gfx *gfx, int x, int y, double *qrb, double *qtf){
    int dx, dy;
    
    dx=x - gfx->o_x - gfx->m_x;
    dy=y - gfx->o_y - gfx->m_y;
    
    *qrb=gfx->zoom->value*sqrt(sqr(dx)+sqr(dy));
    *qtf=atan2(dx,-dy);   
    if (*qtf<0) *qtf+=2*MY_PI;
    return 0;
}

int xy2hw(struct gfx *gfx, int x, int y, double *h, double *w){
    double qrb, qtf;
    int ret;
    
    xy2qrbqtf(gfx, x, y, &qrb, &qtf);
    ret=qrbqtf2hw(gfx->myh, gfx->myw, qrb, qtf, h, w);
    return ret;
}

#endif

/*************** WWL RING *****************************/

int qthwr(char *qth,int width) {
    char *c,d;
    int res;
    
    c=qth;
    while (1){
        d=lowcase(*c);
        if (!d) return(-1000);
        if (d>='a' || d<='r') break;
        c++;
    }
    if (width) c++;
    d=lowcase(*c);
    if (strlen(c)<5) return(-1000);
    
    res=(d-106)*10;
    c+=2;

    if (!isdigit(*c)) return(-1000);
    res+=(*c-'0');
    
    return(res);
}

char *mkwwl4(char *buf, int w, int h){
/*   dbg("mkwwl4(%d, %d)\n", w, h);*/
   w+=90;
   h+=90;
   while (w<0) w+=180;
   while (h<0) h+=180;
   w%=180;
   h%=180;

   buf[0]='A'+ h/10;
   buf[1]='A'+ w/10;
   buf[2]='0'+ h%10;
   buf[3]='0'+ w%10;
   buf[4]='\0';
   
   return buf;
}

/* grad */
char *hw2loc(char *buf, double h, double w){
    h+=180;
    w+=90;
    
    h=fmod(h,360.0);
    w=fmod(w,180.0);

    buf[0]='A'+ h/20.0;
    buf[1]='A'+ w/10.0;
    h=fmod(h,20);
    w=fmod(w,10);
    buf[2]='0'+ h/2;
    buf[3]='0'+ w;
    h=fmod(h,2);
    w=fmod(w,1);
    h*=12;
    w*=24;
    buf[4]='A'+ h;
    buf[5]='A'+ w;
    buf[6]='\0';
   
    return buf;
}


char *x2gramin(char *buf, double x, char *signs){
    double xx;
    char sign;

    sign=x<0?signs[1]:signs[0];
    x = fabs(fmod(x, 360)); 
    xx = fmod(x, 1)*60.0;
    sprintf(buf, "%3d%c%02d", (int)x, sign, (int)xx);    
    return buf;
}


int qsopwr( char *myqth, char *recqth){
    int h1, h2, w1, w2, dh1, dh2, dh, dw, d;
    
    if ((h1=qthwr(myqth,0))<=-1000) return(-1);
    if ((w1=qthwr(myqth,1))<=-1000) return(-1);
    if ((h2=qthwr(recqth,0))<=-1000) return(-1);
    if ((w2=qthwr(recqth,1))<=-1000) return(-1);

    /*dbg("h1=%d  w1=%d  h2=%d  %w2=%d \n",h1,w1,h2,w2);*/

    
    dh1 = h1 - h2; if (dh1 < 0) dh1 += 180; 
    dh2 = h2 - h1; if (dh2 < 0) dh2 += 180; 
/*    dw1 = w1 - w2; if (dw1 < 0) dw1 += 180; 
    dw2 = w2 - w1; if (dw2 < 0) dw2 += 180; */

    dh = dh1 < dh2 ? dh1 : dh2;
/*    dw = dw1 < dw2 ? dw1 : dw2;*/
    dw = w2 - w1;
    if (dw < 0) dw = -dw;

    d = dh < dw ? dw : dh;
    
    return d+2;
}


char *compute_wwl4(char *s, double h, double w){
    int hi, wi;
    
    if (h < -180.0 ||
        h >  180.0 ||
        w <  -90.0 ||
        w >   90.0) {
            strcpy(s,"");
            return s;
    }
      
    h += 180.0;
    w +=  90.0;
    
    hi = h/20;
    s[0] = 'A' + hi;

    wi = w/10;
    s[1] = 'A' + wi;
        
    hi = h/2; hi %= 10;
    wi = w;   wi %= 10;
    
    s[2] = '0' + hi;
    s[3] = '0' + wi;
    s[4] = '\0';
    
    return s;
}
#ifndef MAIN
void qrb_qtf_int(gchar *wwl, int *qrb_int, int *qtf_int){
    double qrb, qtf;

    qrbqtf(ctest ? ctest->pwwlo : cfg->pwwlo, wwl, &qrb, &qtf, NULL, 0); 
    *qrb_int=qrb;
    *qtf_int=qtf;
      /*dbg("qrb_qtf_int(%s->%s %5dkm %3ddeg\n", ctest->pwwlo, wwl, *qrb_int, *qtf_int);*/
}
#endif


/* Compute points from QRB */
int iaru_round(double qrb){
    return ((int)(qrb+1.0));
}

#ifdef MAIN

int main(int argc,char *argv[]){
    char s[100],my[100]="jn69pv",rec[100]="jo60lj";
    double qrb,qtf;

    while (1) {
        printf("\n zadej svuj lokator (%s) :",my);
        fgets(s,90,stdin);
        s[strlen(s)-1]='\0';
        if (strcmp(s,"k")==0) return(1);
        if (strlen(s)>0) strcpy(my,s);
        printf(" zadej prijaty lokator (%s) :",rec);
        fgets(s,90,stdin);
        s[strlen(s)-1]='\0';
        if (strcmp(s,"k")==0) return(1);
        if (strlen(s)>0) strcpy(rec,s);
        qrbqtf(my,rec,&qrb,&qtf,s);
        printf(" %s \n qrb:%8.1f km   qtf:%6.2f \n",s,qrb,qtf);
        printf("WWL ring: %d ", qsopwr(my,rec));
    }
} 

#endif

Generated by  Doxygen 1.6.0   Back to index