#include #include #include #include #include #include #include using namespace std; #include "findFile.h" #include "keywords.h" #include "Options.h" #include "parse.h" #include "PlanetProperties.h" #include "sphericalToPixel.h" #include "xpUtil.h" #include "drawArc.h" #include "libannotate/libannotate.h" #include "libplanet/Planet.h" #include "libprojection/ProjectionBase.h" class View; static void readArcFile(const char *line, Planet *planet, View *view, ProjectionBase *projection, unsigned char *color, const double magnify, multimap &annotationMap) { int i = 0, j = 0, k = 0; while (isDelimiter(line[i])) { i++; if (static_cast (i) > strlen(line)) return; } if (isEndOfLine(line[i])) return; Options *options = Options::getInstance(); double coords[4]; double radius[2] = { -1, -1 }; double spacing = options->ArcSpacing(); bool syntaxError = false; while (static_cast (i) < strlen(line)) { char *returnString = NULL; int val = parse(i, line, returnString); switch (val) { case COLOR: { int r, g, b; if (sscanf(returnString, "%d,%d,%d", &r, &g, &b) == 3) { color[0] = static_cast (r & 0xff); color[1] = static_cast (g & 0xff); color[2] = static_cast (b & 0xff); } else { xpWarn("Need three values for color\n", __FILE__, __LINE__); syntaxError = true; } } break; case LATLON: checkLocale(LC_NUMERIC, "C"); if (j < 4) { sscanf(returnString, "%lf", &coords[j]); if (j%2 == 0) { if (coords[j] < -90 || coords[j] > 90) { ostringstream errMsg; errMsg << "Latitude value must be between -90 " << "and 90 degrees\n"; xpWarn(errMsg.str(), __FILE__, __LINE__); syntaxError = true; } } else { if (coords[j] < -360 || coords[j] > 360) { ostringstream errMsg; errMsg << "Longitude value must be between -360 " << "and 360 degrees\n"; xpWarn(errMsg.str(), __FILE__, __LINE__); syntaxError = true; } } coords[j] *= deg_to_rad; j++; } else { syntaxError = true; } checkLocale(LC_NUMERIC, ""); break; case RADIUS: checkLocale(LC_NUMERIC, "C"); if (k < 2) { sscanf(returnString, "%lf", &radius[k]); if (radius[k] < 0) { xpWarn("Radius value must be positive\n", __FILE__, __LINE__); radius[k] = -1; syntaxError = true; } else { k++; } } checkLocale(LC_NUMERIC, ""); break; case SPACING: checkLocale(LC_NUMERIC, "C"); sscanf(returnString, "%lf", &spacing); if (spacing < 0) { xpWarn("spacing must be positive\n", __FILE__, __LINE__); spacing = 0.1; syntaxError = true; } checkLocale(LC_NUMERIC, ""); break; case UNKNOWN: syntaxError = true; default: case DELIMITER: break; } if (val != DELIMITER && options->Verbosity() > 3) { ostringstream msg; msg << "value is " << keyWordString[val - '?']; if (returnString != NULL) msg << ", returnString is " << returnString; msg << endl; xpMsg(msg.str(), __FILE__, __LINE__); } delete [] returnString; if (syntaxError) { ostringstream errStr; errStr << "Syntax error in arc file\n" << "line is \"" << line << "\"\n"; xpWarn(errStr.str(), __FILE__, __LINE__); return; } if (val == ENDOFLINE) break; } if (j != 4) { ostringstream errStr; errStr << "Incomplete entry in arc file\n" << "line is \"" << line << "\"\n"; xpWarn(errStr.str(), __FILE__, __LINE__); return; } if (k == 0) radius[1] = radius[0]; for (i = 0; i < 2; i++) { if (radius[i] < 0) { if (planet != NULL) { radius[i] = planet->Radius(coords[2*i]); } else { radius[i] = 1; } } } if (planet == NULL) { double X1, Y1, Z1; double X2, Y2, Z2; sphericalToPixel(coords[0], coords[1], 1.0, X1, Y1, Z1, NULL, view, NULL); sphericalToPixel(coords[2], coords[3], 1.0, X2, Y2, Z2, NULL, view, NULL); LineSegment *ls = new LineSegment(color, X2, Y2, X1, Y1); double avgZ = 0.5 * (Z1 + Z2); if (Z1 > 0 && Z2 > 0) annotationMap.insert(pair(avgZ, ls)); } else { drawArc(coords[0], coords[1], radius[0], coords[2], coords[3], radius[1], color, spacing * deg_to_rad, magnify, planet, view, projection, annotationMap); } } void addArcs(PlanetProperties *planetProperties, Planet *planet, View *view, ProjectionBase *projection, multimap &annotationMap) { vector arcfiles = planetProperties->ArcFiles(); vector::iterator ii = arcfiles.begin(); unsigned char color[3]; memcpy(color, planetProperties->ArcColor(), 3); while (ii != arcfiles.end()) { string arcFile(*ii); bool foundFile = findFile(arcFile, "arcs"); if (foundFile) { ifstream inFile(arcFile.c_str()); char *line = new char[MAX_LINE_LENGTH]; while (inFile.getline (line, MAX_LINE_LENGTH, '\n') != NULL) readArcFile(line, planet, view, projection, color, planetProperties->Magnify(), annotationMap); inFile.close(); delete [] line; } else { ostringstream errStr; errStr << "Can't load arc file " << arcFile << endl; xpWarn(errStr.str(), __FILE__, __LINE__); } ii++; } } void addArcs(View *view, multimap &annotationMap) { Options *options = Options::getInstance(); vector arcfiles = options->ArcFiles(); vector::iterator ii = arcfiles.begin(); unsigned char color[3]; memset(color, 128, 3); while (ii != arcfiles.end()) { string arcFile(*ii); bool foundFile = findFile(arcFile, "arcs"); if (foundFile) { ifstream inFile(arcFile.c_str()); char *line = new char[256]; while (inFile.getline (line, 256, '\n') != NULL) readArcFile(line, NULL, view, NULL, color, 1.0, annotationMap); inFile.close(); delete [] line; } else { ostringstream errStr; errStr << "Can't load arc file " << arcFile << endl; xpWarn(errStr.str(), __FILE__, __LINE__); } ii++; } }