#include #include #include #include #define X 0 #define Y 1 #define numCorners 256 #define border 50 typedef float XY_t[2]; typedef enum {NS, ANGLE_INT, ANGLE_FRAC, WHITESPACE, LENGTH_INT, LENGTH_FRAC} stage_t; typedef unsigned char bool_t; /************************************************* Code starts here *************************************************/ void usage(char* argv[]) { printf("\nUsage: \"%s [Switches] [< filename]\"\n", argv[0]); printf("Switches (optional) begin with '-', followed in any order by\n"); printf(" v: verbose, shows intermediate results for each entered line\n"); printf(" f: input is from a file. The program needs this to manage the display.\n"); printf(" o: Overlay mode. You'll be prompted for origin and scale factor.\n"); printf(" a: Angle offset, useful in overlay mode. You'll be prompted for a value.\n"); printf(" \"< filename\" is standard Posix command line syntax. It tells the operating\n"); printf(" system to get input from the file rather than the keyboard.\n\n"); printf("Example: \"%s -v\" runs interactively in verbose mode.\n", argv[0]); printf("Example: \"%s -f < myfile\" gets input from a file named \"myfile\".\n", argv[0]); printf("Input format is standard deed shorthand, e.g. \"N74E 33.68\"\n"); } /************************************************* Store or check command line switches *************************************************/ unsigned char switches (char *inval) { static char switchval[32]; int i; switchval[31]=0; if (inval[0]=='-') strncpy(switchval, inval, 31); else { for (i=0;i1) { for (i=0;i='0') && (buffer[i]<='9')) { if (gotdot) { frac*=10; frac+=(buffer[i]-'0'); fracDigits++; } else { integer*=10; integer+=(buffer[i]-'0'); } } } if (buffer[0]=='-') return (-1.0*(integer+frac/pow(10,fracDigits))); else return (integer+frac/pow(10,fracDigits)); } else return 0.0; } /************************************************* In: vector, deed shorthand format, e.g. N43W 45.2 Out: dx and dy, real floating point numbers *************************************************/ void parse (char *buffer, size_t len, float angleOffset, XY_t XY) { int input_num, frac_denom; float length=0.0, angle=0.0; char north=0, west=0; size_t i; stage_t stage; XY[X]=0.0; XY[Y]=0.0; stage=NS; /************************************************* Go through the input left to right, gathering up - North (-) vs. south (+) - Angle, in degrees - East (+) vs. west (-) - Length, in chains *************************************************/ for (i=0;i='0') && (buffer[i]<='9')) { input_num*=10; input_num+=(buffer[i]-'0'); } else if (buffer[i]=='.') { angle=(float)input_num; input_num=0; frac_denom=1; stage=ANGLE_FRAC; } else if ((buffer[i]=='E') || (buffer[i]=='e') || (buffer[i]=='W') || (buffer[i]=='w')) { angle=(float)input_num; input_num=0; if ((buffer[i]=='W') || (buffer[i]=='w')) west=1; stage=WHITESPACE; // Handle the cases of due N or S } else if (buffer[1]==' ') { angle=0.0; input_num=0; stage=WHITESPACE; } else return; break; case ANGLE_FRAC: if ((buffer[i]>='0') && (buffer[i]<='9')) { input_num*=10; input_num+=(buffer[i]-'0'); frac_denom*=10; } else if ((buffer[i]=='E') || (buffer[i]=='e') || (buffer[i]=='W') || (buffer[i]=='w')) { angle+=((float)input_num/(float)frac_denom); input_num=0; if ((buffer[i]=='w') || (buffer[i]=='W')) west=1; stage=WHITESPACE; } else return; break; case WHITESPACE: while (buffer[i]<=' '){ i++; if (i>=len) return; } i--; input_num=0; stage=LENGTH_INT; break; case LENGTH_INT: if ((buffer[i]>='0') && (buffer[i]<='9')) { input_num*=10; input_num+=(buffer[i]-'0'); } else if (buffer[i]=='.') { length=(float)input_num; input_num=0; frac_denom=1; stage=LENGTH_FRAC; } else if (buffer[i]<=' ') { length=(float)input_num; i=len; } else return; break; case LENGTH_FRAC: if ((buffer[i]>='0') && (buffer[i]<='9')) { input_num*=10; input_num+=(buffer[i]-'0'); frac_denom*=10; } else if (buffer[i]<=' ') { length+=((float)input_num/(float)frac_denom); i=len; } else return; break; default: return; } } /************************************************** Convert north, west and the angle to positive radians from due south, calculate the deltas **************************************************/ if (north && west) angle+=180; else if (north) angle=180-angle; else if (west) angle=360-angle; angle-=angleOffset; // Convert to radians @ pi radians per 180 degrees angle*=(acos(-1.0)/180); XY[X]=length*sinf(angle); XY[Y]=length*cosf(angle); } /* MAIN */ int main(int argc, char *argv[]) { size_t bufsize=64, len; char i, n=0, keepGoing=1, *buffer; float corners[numCorners][2], xmin=0.0, ymin=0.0, xmax=0.0, ymax=0.0, scale=10.0; float angleOffset=0.0, ftemp; XY_t XY; corners[0][X]=0.0; corners[0][Y]=0.0; buffer=(char*)malloc(bufsize); /************************************************** Parse the command line **************************************************/ if (argc<2) { switches("-"); printf("\"%s ?\" for help.\n\n", argv[0]); } else if (argv[1][0] == '-') switches(argv[1]); else { switches("-"); if (argv[1][0] == '?') { usage(argv); return 0; } } if (switches("o")) { printf("Overlay mode selected.\nEnter scale factor in feet per pixel: "); ftemp=getReal(buffer); if (ftemp>0.1) scale=66.0/ftemp; printf("scale, pixels per chain %f\n", scale); printf("Enter X offset of starting point: "); corners[0][X]=getReal(buffer); printf("Enter Y offset of starting point: "); corners[0][Y]=getReal(buffer); } if (switches("a")) { printf("Enter angle offset in clockwise degrees: "); angleOffset=getReal(buffer); } /************************************************** Collect the X and Y deltas for each user entry. Scale and accumulate them to get corner locations, tracking the most negative X and Y value **************************************************/ while (keepGoing) { printf("Enter boundary #%d, or empty line if you're done: ", n+1); len=getline(&buffer, &bufsize, stdin); if (switches("f")) printf("%s", buffer); if (len==-1) keepGoing=0; else if (buffer[0]<' ') keepGoing=0; else { parse(buffer, len, angleOffset, XY); if ((fabsf(XY[X])<0.1) && (fabsf(XY[Y])<0.1)) { printf("Defective input, please try again.\n", buffer); } else { n++; if (switches("v")) printf("%f %f\n", XY[X], XY[Y]); corners[n][X]=XY[X]*scale+corners[n-1][X]; corners[n][Y]=XY[Y]*scale+corners[n-1][Y]; if (corners[n][X]xmax) xmax=corners[i][X]; if (corners[i][Y]>ymax) ymax=corners[i][Y]; } printf("Set canvas size to %d x %d. Corners:\n", (int)xmax+border, (int)ymax+border); } for (i=0;i<=n;i++) { printf("%d. (%d %d)\n", i+1, (int)(corners[i][X]), (int)(corners[i][Y])); } return 0; }