PHP Classes

File: dir/webgps.c.txt

Recommend this page to a friend!
  Classes of Uku-Kaarel Jo~esaar   finfo   dir/webgps.c.txt   Download  
File: dir/webgps.c.txt
Role: Documentation
Content type: text/plain
Description: Documentation
Class: finfo
Determine the type of files analyzing its contents
Author: By
Last change:
Date: 7 years ago
Size: 13,709 bytes
 

Contents

Class file image Download
/* Makes a simple HTML and SVG layout for GPSD */ /* (C)2007 Jason Hecker v0.03*/ /* This is a severely mangled version of xgps.c */ /* To use call: webgps [server] [port] [path] [period] */ /* server: the gpsd server you are connecting to */ /* port: the port number of the gpsd server */ /* path: the destination path for gpsd.svg/html */ /* period: time period in seconds for webgps to update */ #include <stdio.h> #include <math.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <time.h> #include <math.h> /* v2.33 */ #include "config.h" /* v2.34+ */ //#include "gpsd_config.h" #include "gps.h" #define TRACKMAX 1024 #define SATMAX 20 #define STALECOUNT 3 typedef struct trackloc_s{ int x; int y; } trackloc_t; typedef struct trackloc_head_s{ int PRN; int count; int stale; trackloc_t posn[TRACKMAX]; } trackloc_head_t; trackloc_head_t sattrack[SATMAX]; static enum deg_str_type deg_type = deg_dd; static struct gps_data_t *gpsdata; static time_t timer; /* time of last state change */ static int state = 0; /* or MODE_NO_FIX=1, MODE_2D=2, MODE_3D=3 */ void do_html(FILE *fh); void do_svg(FILE *fs); void polartocart(int *x, int *y, int el, int az){ #define DEG2RAD PI/180.0 #define DIAMETER 200 #define XYOFFSET 10 float radius, theta; radius = DIAMETER * cos(((float)(el)) * DEG2RAD); theta = ((float)(az - 90) * DEG2RAD); *x = (int)(radius * cos(theta) + 0.5) + DIAMETER + XYOFFSET; *y = (int)(radius * sin(theta) + 0.5) + DIAMETER + XYOFFSET; } void do_html(FILE *fh){ int i, newstate; char s[128], *latlon; const char pageheader[] = "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" \ "\t<head>\n\t<title>GPSD Satellite Positions and Readings</title>\n\t</head>\n<body>\n" \ "<table border=\"1\">\n\t<td>\n\t\t<table border=\"0\">\n" "\t\t\t<tr>\n\t\t\t\t<td><b>PRN:</b></td><td><b>Elev:</b></td><td><b>Azim:</b></td>" "<td><b>SNR:</b></td><td><b>Used:</b></td>\n\t\t\t</tr>\n"; const char rowhead[] = "\t\t\t<tr>\n\t\t\t\t<td><b>%s</b></d><td>%s</td>\n\t\t\t</tr>\n"; fprintf(fh,pageheader); if (gpsdata->satellites) { for (i = 0; i < MAXCHANNELS; i++) { if (i < (unsigned int)gpsdata->satellites) { fprintf(fh,"\t\t\t<tr>\n\t\t\t\t<td>%3d</td><td>%2d</td><td>%3d</td><td>%2d</td><td>%c</td>\n\t\t\t</tr>\n", gpsdata->PRN[i], gpsdata->elevation[i], gpsdata->azimuth[i], gpsdata->ss[i], gpsdata->used[i] ? 'Y' : 'N'); } } } fprintf(fh,"\t\t</table>\n"); fprintf(fh,"\t\t<table border=\"0\">\n"); if (isnan(gpsdata->fix.time)==0) { (void)unix_to_iso8601(gpsdata->fix.time, s, (int)sizeof(s)); } else (void)strcpy(s,"n/a"); fprintf(fh,rowhead,"Time:",s); if (gpsdata->fix.mode >= MODE_2D) { latlon = deg_to_str(deg_type, fabs(gpsdata->fix.latitude)); (void)snprintf(s, sizeof(s), "%s %c", latlon, (gpsdata->fix.latitude < 0) ? 'S' : 'N'); } else (void)strcpy(s, "n/a"); fprintf(fh,rowhead,"Latitude:",s); if (gpsdata->fix.mode >= MODE_2D) { latlon = deg_to_str(deg_type, fabs(gpsdata->fix.longitude)); (void)snprintf(s, sizeof(s), "%s %c", latlon, (gpsdata->fix.longitude < 0) ? 'W' : 'E'); } else (void)strcpy(s, "n/a"); fprintf(fh,rowhead,"Longitude:",s); if (gpsdata->fix.mode == MODE_3D) { (void)snprintf(s, sizeof(s), "%f metres", gpsdata->fix.altitude); } else (void)strcpy(s, "n/a"); fprintf(fh,rowhead,"Altitude:",s); if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track)==0) { (void)snprintf(s, sizeof(s), "%f metres/sec", gpsdata->fix.speed); } else (void)strcpy(s, "n/a"); fprintf(fh,rowhead,"Speed:",s); if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track)==0) { (void)snprintf(s, sizeof(s), "%f degrees", gpsdata->fix.track); } else (void)strcpy(s, "n/a"); fprintf(fh,rowhead,"Course:",s); if (isnan(gpsdata->fix.eph)==0) { (void)snprintf(s, sizeof(s), "%f metres", gpsdata->fix.eph); } else (void)strcpy(s, "n/a"); fprintf(fh,rowhead,"EPH:",s); if (isnan(gpsdata->fix.epv)==0) { (void)snprintf(s, sizeof(s), "%f metres", gpsdata->fix.epv); } else (void)strcpy(s, "n/a"); fprintf(fh,rowhead,"EPV:",s); if (gpsdata->fix.mode == MODE_3D && isnan(gpsdata->fix.climb)==0) { (void)snprintf(s, sizeof(s), "%f metres/sec", gpsdata->fix.climb); } else (void)strcpy(s, "n/a"); fprintf(fh,rowhead,"Climb:",s); if (gpsdata->online == 0) { newstate = 0; (void)snprintf(s, sizeof(s), "OFFLINE"); } else { newstate = gpsdata->fix.mode; switch (gpsdata->fix.mode) { case MODE_2D: (void)snprintf(s, sizeof(s), "2D %sFIX",(gpsdata->status==STATUS_DGPS_FIX)?"DIFF ":""); break; case MODE_3D: (void)snprintf(s, sizeof(s), "3D %sFIX",(gpsdata->status==STATUS_DGPS_FIX)?"DIFF ":""); break; default: (void)snprintf(s, sizeof(s), "NO FIX"); break; } } if (newstate != state) { timer = time(NULL); state = newstate; } (void)snprintf(s+strlen(s), sizeof(s)-strlen(s), " (%d secs)", (int) (time(NULL) - timer)); fprintf(fh,"\t\t\t<tr>\n\t\t\t\t<td><b>State</b></d><td>%s</td>\n\t\t\t</tr>\n",s); fprintf(fh,"\t\t</table>\n\t</td>\n"); /* SVG Stuff */ fprintf(fh,"\t<td>\n\t\t<embed src=\"gpsd.svg\" width=\"425\" height=\"425\" type=\"image/svg+xml\">\n"); //fprintf(fh,"\t<td>\n\t\t<object data=\"gpsd.svg\" width=\"425\" height=\"425\" align=\"center\"\n"); //fprintf(fh,"\t\t\ttype=\"image/svg+xml\"\n\t\t\tcodebase=\"http://www.adobe.com/svg/viewer/install/\" />\n\t</td>\n"); fprintf(fh,"</table>\n\n</body>\n</html>"); } void do_svg(FILE *fs){ int i, j, x, y, offset; char *fill; const char svghead[] = "<?xml version=\"1.0\" standalone=\"no\"?>\n" \ "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n" \ "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n" \ "<svg width=\"100%%\" height=\"100%%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n" \ "\t<g transform=\"translate(00,0)\">\n" \ "\t\t<circle cx=\"210\" cy=\"210\" r=\"200\" stroke=\"black\"\n" \ "\t\tstroke-width=\"1\" fill=\"white\"/>\n" \ "\t\t<circle cx=\"210\" cy=\"210\" r=\"100\" stroke=\"grey\"\n" \ "\t\tstroke-width=\"1\" fill=\"white\"/>\n" \ "\t\t<circle cx=\"210\" cy=\"210\" r=\"2\" stroke=\"grey\"\n" \ "\t\tstroke-width=\"1\" fill=\"white\"/>\n" \ "\t\t<line x1=\"210\" y1=\"10\" x2=\"210\" y2=\"410\" stroke=\"lightgrey\" />\n" \ "\t\t<line x1=\"10\" y1=\"210\" x2=\"410\" y2=\"210\" stroke=\"lightgrey\" />\n" \ "\t\t<line x1=\"68.578644\" y1=\"68.578644\" x2=\"351.42136\" y2=\"351.42136\" stroke=\"lightgrey\" />\n" \ "\t\t<line x1=\"68.578644\" y1=\"351.42136\" x2=\"351.42136\" y2=\"68.578644\" stroke=\"lightgrey\" />\n" \ "\t\t<g font-size=\"10\" stroke=\"black\" stroke-width=\"0.5\">\n" \ "\t\t\t<text x=\"206\" y=\"8\">N</text>\n" \ "\t\t\t<text x=\"0\" y=\"214\">W</text>\n" \ "\t\t\t<text x=\"412\" y=\"214\">E</text>\n" \ "\t\t\t<text x=\"206\" y=\"420\">S</text>\n"; /* Draw the chart axes */ fprintf(fs, svghead); /* Draw the skid marks */ //printf("Skidin\n"); for(i=0;i<SATMAX;i++){ if(sattrack[i].PRN != -1){ if(sattrack[i].count > 1){ fprintf(fs,"\t\t\t<polyline stroke-width=\"0.6\" stroke=\"red\" fill=\"none\" points=\""); for(j=0;j <= sattrack[i].count-1;j++){ x = sattrack[i].posn[j].x; y = sattrack[i].posn[j].y; fprintf(fs,"%d,%d ", x, y); } fprintf(fs,"\"/>\n"); } } } //printf("Skidout\n"); /* Draw the birdies */ if (gpsdata->satellites) { for (i = 0; i < MAXCHANNELS; i++) { if (i < (unsigned int)gpsdata->satellites) { polartocart(&x , &y, gpsdata->elevation[i], gpsdata->azimuth[i]); if(gpsdata->ss[i] < 30) fill = "\"silver\""; else if (gpsdata->ss[i] < 40) fill = "\"yellow\""; else fill = "\"lime\""; /* Centre single digits PRNs in the circle */ if(gpsdata->PRN[i] < 10) offset = 3; else offset = 0; fprintf(fs,"\t\t\t<circle cx=\"%d\" cy=\"%d\" r=\"8\" stroke=\"black\"\n",x,y); fprintf(fs,"\t\t\t\tstroke-width=\"1\" fill=%s/>\n",fill); fprintf(fs,"\t\t\t<text x=\"%d\" y=\"%d\" stroke=\"black\" fill=\"black\" " \ "font-size=\"10\">%d</text>\n",x-6+offset,y+4,gpsdata->PRN[i]); } } } fprintf(fs,"\t\t</g>\n"); fprintf(fs,"\t</g>\n"); fprintf(fs,"</svg>\n"); } /* Initialise the track table */ void init_track_table(void){ int i; //printf("ITT\n"); for (i=0; i<SATMAX; i++){ sattrack[i].PRN = -1; sattrack[i].count = 0; sattrack[i].stale = 0; } } /* Make all tracks stale */ void make_tracks_stale(void){ int i; //printf("MTS\n"); for(i=0; i<SATMAX; i++){ if(sattrack[i].stale != 0) sattrack[i].stale--; } } /* Returns the index the PRN is in - -1 is a fail*/ int exists_in_table(int prn){ int i; //printf("EIT\n"); for(i=0; i< SATMAX; i++){ if (sattrack[i].PRN == prn) return(i); } return -1; } /* Inserts a new sat xy entry into the table */ void insert_sat(int prn, int x, int y){ int i, idx; idx = exists_in_table(prn); if (idx == -1){ for(i=0; i<SATMAX; i++){ if(sattrack[i].PRN == -1){ sattrack[i].PRN = prn; sattrack[i].posn[0].x = x; sattrack[i].posn[0].y = y; sattrack[i].count = 1; sattrack[i].stale = STALECOUNT; } } } else{ if(sattrack[idx].count < (TRACKMAX-1)){ if(sattrack[idx].posn[sattrack[idx].count-1].x != x || \ sattrack[idx].posn[sattrack[idx].count-1].y != y){ sattrack[idx].posn[sattrack[idx].count].x = x; sattrack[idx].posn[sattrack[idx].count].y = y; sattrack[idx].count++; } sattrack[idx].stale = STALECOUNT; } } //printf("IS %d %d %d\n",idx,prn,sattrack[idx].count); } /* Deletes stale sats */ void delete_stale_sats(void){ int i; //printf("DSS\n"); for(i=0; i<SATMAX; i++){ if (sattrack[i].stale == 0){ sattrack[i].PRN = -1; sattrack[i].count = 0; } } //printf("DSSO\n"); } void update_track_table(void){ int i, x, y; //printf("UTT\n"); make_tracks_stale(); if (gpsdata->satellites) { for (i = 0; i < MAXCHANNELS; i++) { if (i < (unsigned int)gpsdata->satellites) { polartocart(&x , &y, gpsdata->elevation[i], gpsdata->azimuth[i]); insert_sat(gpsdata->PRN[i],x,y); } } } delete_stale_sats(); } int main(int argc, char *argv[]) { FILE *fh,*fs = NULL; char *err_str = NULL; //char server[] = "gpsd.mainframe.cx"; //char port[] = "2947"; char *server; char *port; char *path; int period; char name1[256], name2[256]; //printf("argc %d\n",argc); if (argc != 5){ fprintf(stderr,"Not enough arguments: <server> <port> <path> <period>\n"); exit(2); } server = argv[1]; port = argv[2]; path = argv[3]; period = atoi(argv[4]); gpsdata = gps_open(server, port); if (!gpsdata) { switch ( errno ) { case NL_NOSERVICE: err_str = "can't get service entry"; break; case NL_NOHOST: err_str = "can't get host entry"; break; case NL_NOPROTO: err_str = "can't get protocol entry"; break; case NL_NOSOCK: err_str = "can't create socket"; break; case NL_NOSOCKOPT: err_str = "error SETSOCKOPT SO_REUSEADDR"; break; case NL_NOCONNECT: err_str = "can't connect to host"; break; default: err_str = "Unknown"; break; } (void)fprintf( stderr, "xgps: no gpsd running or network error: %d, %s\n", errno, err_str); exit(2); } init_track_table(); (void)gps_query(gpsdata, "w+x"); (void)gps_query(gpsdata, "j=1"); for(;;){ (void)gps_poll(gpsdata); update_track_table(); sprintf(name1,"%s/gpsd.html",path); sprintf(name2,"%s/gpsd.svg",path); if((fh=fopen(name1,"w")) != NULL ){ do_html(fh); fclose(fh); } if((fs=fopen(name2,"w")) != NULL ){ do_svg(fs); fclose(fs); } sleep(period); } return(0); }