/tags/xplanet-1.1.0/src/libannotate/addArcs.cpp

# · C++ · 286 lines · 260 code · 26 blank · 0 comment · 48 complexity · 942f2c9a45dd4f2f68b99e1495743060 MD5 · raw file

  1. #include <clocale>
  2. #include <cstdio>
  3. #include <fstream>
  4. #include <sstream>
  5. #include <map>
  6. #include <string>
  7. #include <vector>
  8. using namespace std;
  9. #include "findFile.h"
  10. #include "keywords.h"
  11. #include "Options.h"
  12. #include "parse.h"
  13. #include "PlanetProperties.h"
  14. #include "sphericalToPixel.h"
  15. #include "xpUtil.h"
  16. #include "drawArc.h"
  17. #include "libannotate/libannotate.h"
  18. #include "libplanet/Planet.h"
  19. #include "libprojection/ProjectionBase.h"
  20. class View;
  21. static void
  22. readArcFile(const char *line, Planet *planet,
  23. View *view, ProjectionBase *projection,
  24. unsigned char *color,
  25. const double magnify,
  26. multimap<double, Annotation *> &annotationMap)
  27. {
  28. int i = 0, j = 0, k = 0;
  29. while (isDelimiter(line[i]))
  30. {
  31. i++;
  32. if (static_cast<unsigned int> (i) > strlen(line)) return;
  33. }
  34. if (isEndOfLine(line[i])) return;
  35. Options *options = Options::getInstance();
  36. double coords[4];
  37. double radius[2] = { -1, -1 };
  38. double spacing = 0.1;
  39. bool syntaxError = false;
  40. while (static_cast<unsigned int> (i) < strlen(line))
  41. {
  42. char *returnString = NULL;
  43. int val = parse(i, line, returnString);
  44. switch (val)
  45. {
  46. case COLOR:
  47. {
  48. int r, g, b;
  49. if (sscanf(returnString, "%d,%d,%d", &r, &g, &b) == 3)
  50. {
  51. color[0] = static_cast<unsigned char> (r & 0xff);
  52. color[1] = static_cast<unsigned char> (g & 0xff);
  53. color[2] = static_cast<unsigned char> (b & 0xff);
  54. }
  55. else
  56. {
  57. xpWarn("Need three values for color\n", __FILE__, __LINE__);
  58. syntaxError = true;
  59. }
  60. }
  61. break;
  62. case LATLON:
  63. checkLocale(LC_NUMERIC, "C");
  64. if (j < 4)
  65. {
  66. sscanf(returnString, "%lf", &coords[j]);
  67. if (j%2 == 0)
  68. {
  69. if (coords[j] < -90 || coords[j] > 90)
  70. {
  71. ostringstream errMsg;
  72. errMsg << "Latitude value must be between -90 "
  73. << "and 90 degrees\n";
  74. xpWarn(errMsg.str(), __FILE__, __LINE__);
  75. syntaxError = true;
  76. }
  77. }
  78. else
  79. {
  80. if (coords[j] < -360 || coords[j] > 360)
  81. {
  82. ostringstream errMsg;
  83. errMsg << "Longitude value must be between -360 "
  84. << "and 360 degrees\n";
  85. xpWarn(errMsg.str(), __FILE__, __LINE__);
  86. syntaxError = true;
  87. }
  88. }
  89. coords[j] *= deg_to_rad;
  90. j++;
  91. }
  92. else
  93. {
  94. syntaxError = true;
  95. }
  96. checkLocale(LC_NUMERIC, "");
  97. break;
  98. case RADIUS:
  99. checkLocale(LC_NUMERIC, "C");
  100. if (k < 2)
  101. {
  102. sscanf(returnString, "%lf", &radius[k]);
  103. if (radius[k] < 0)
  104. {
  105. xpWarn("Radius value must be positive\n",
  106. __FILE__, __LINE__);
  107. radius[k] = -1;
  108. syntaxError = true;
  109. }
  110. else
  111. {
  112. k++;
  113. }
  114. }
  115. checkLocale(LC_NUMERIC, "");
  116. break;
  117. case SPACING:
  118. checkLocale(LC_NUMERIC, "C");
  119. sscanf(returnString, "%lf", &spacing);
  120. if (spacing < 0)
  121. {
  122. xpWarn("spacing must be positive\n", __FILE__, __LINE__);
  123. spacing = 0.1;
  124. syntaxError = true;
  125. }
  126. checkLocale(LC_NUMERIC, "");
  127. break;
  128. case UNKNOWN:
  129. syntaxError = true;
  130. default:
  131. case DELIMITER:
  132. break;
  133. }
  134. if (val != DELIMITER && options->Verbosity() > 3)
  135. {
  136. ostringstream msg;
  137. msg << "value is " << keyWordString[val - '?'];
  138. if (returnString != NULL)
  139. msg << ", returnString is " << returnString;
  140. msg << endl;
  141. xpMsg(msg.str(), __FILE__, __LINE__);
  142. }
  143. delete [] returnString;
  144. if (syntaxError)
  145. {
  146. ostringstream errStr;
  147. errStr << "Syntax error in arc file\n"
  148. << "line is \"" << line << "\"\n";
  149. xpWarn(errStr.str(), __FILE__, __LINE__);
  150. return;
  151. }
  152. if (val == ENDOFLINE) break;
  153. }
  154. if (j != 4)
  155. {
  156. ostringstream errStr;
  157. errStr << "Incomplete entry in arc file\n"
  158. << "line is \"" << line << "\"\n";
  159. xpWarn(errStr.str(), __FILE__, __LINE__);
  160. return;
  161. }
  162. if (k == 0) radius[1] = radius[0];
  163. for (i = 0; i < 2; i++)
  164. {
  165. if (radius[i] < 0)
  166. {
  167. if (planet != NULL)
  168. {
  169. radius[i] = planet->Radius(coords[2*i]);
  170. }
  171. else
  172. {
  173. radius[i] = 1;
  174. }
  175. }
  176. }
  177. if (planet == NULL)
  178. {
  179. double X1, Y1, Z1;
  180. double X2, Y2, Z2;
  181. sphericalToPixel(coords[0], coords[1], 1.0,
  182. X1, Y1, Z1, NULL, view, NULL);
  183. sphericalToPixel(coords[2], coords[3], 1.0,
  184. X2, Y2, Z2, NULL, view, NULL);
  185. LineSegment *ls = new LineSegment(color, X2, Y2, X1, Y1);
  186. double avgZ = 0.5 * (Z1 + Z2);
  187. if (Z1 > 0 && Z2 > 0)
  188. annotationMap.insert(pair<const double, Annotation*>(avgZ, ls));
  189. }
  190. else
  191. {
  192. drawArc(coords[0], coords[1], radius[0], coords[2], coords[3],
  193. radius[1], color, spacing * deg_to_rad,
  194. magnify, planet, view, projection, annotationMap);
  195. }
  196. }
  197. void
  198. addArcs(PlanetProperties *planetProperties, Planet *planet,
  199. View *view, ProjectionBase *projection,
  200. multimap<double, Annotation *> &annotationMap)
  201. {
  202. vector<string> arcfiles = planetProperties->ArcFiles();
  203. vector<string>::iterator ii = arcfiles.begin();
  204. unsigned char color[3];
  205. memcpy(color, planetProperties->ArcColor(), 3);
  206. while (ii != arcfiles.end())
  207. {
  208. string arcFile(*ii);
  209. bool foundFile = findFile(arcFile, "arcs");
  210. if (foundFile)
  211. {
  212. ifstream inFile(arcFile.c_str());
  213. char *line = new char[MAX_LINE_LENGTH];
  214. while (inFile.getline (line, MAX_LINE_LENGTH, '\n') != NULL)
  215. readArcFile(line, planet, view, projection,
  216. color, planetProperties->Magnify(),
  217. annotationMap);
  218. inFile.close();
  219. delete [] line;
  220. }
  221. else
  222. {
  223. ostringstream errStr;
  224. errStr << "Can't load arc file " << arcFile << endl;
  225. xpWarn(errStr.str(), __FILE__, __LINE__);
  226. }
  227. ii++;
  228. }
  229. }
  230. void
  231. addArcs(View *view, multimap<double, Annotation *> &annotationMap)
  232. {
  233. Options *options = Options::getInstance();
  234. vector<string> arcfiles = options->ArcFiles();
  235. vector<string>::iterator ii = arcfiles.begin();
  236. unsigned char color[3];
  237. memset(color, 128, 3);
  238. while (ii != arcfiles.end())
  239. {
  240. string arcFile(*ii);
  241. bool foundFile = findFile(arcFile, "arcs");
  242. if (foundFile)
  243. {
  244. ifstream inFile(arcFile.c_str());
  245. char *line = new char[256];
  246. while (inFile.getline (line, 256, '\n') != NULL)
  247. readArcFile(line, NULL, view, NULL,
  248. color, 1.0, annotationMap);
  249. inFile.close();
  250. delete [] line;
  251. }
  252. else
  253. {
  254. ostringstream errStr;
  255. errStr << "Can't load arc file " << arcFile << endl;
  256. xpWarn(errStr.str(), __FILE__, __LINE__);
  257. }
  258. ii++;
  259. }
  260. }