1 /*
2 # This file is part of the Astrometry.net suite.
3 # Licensed under a 3-clause BSD style license - see LICENSE
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <math.h>
10 #include <sys/types.h>
11 #include <sys/mman.h>
12 #include <string.h>
13 #include <ctype.h>
14
15 #include "starutil.h"
16 #include "bl.h"
17 #include "mathutil.h"
18 #include "an-endian.h"
19
20 const char* OPTIONS = "h";
21
22 // size of entries in Stellarium's hipparcos.fab file.
23 static int HIP_SIZE = 15;
24 // byte offset to the first element in Stellarium's hipparcos.fab file.
25 static int HIP_OFFSET = 4;
26
print_help(char * progname)27 void print_help(char* progname) {
28 //BOILERPLATE_HELP_HEADER(stdout);
29 printf("\nUsage: %s\n"
30 "\n", progname);
31 }
32
33 static char* const_dirs[] = {
34 ".",
35 "/usr/share/stellarium/data/sky_cultures/western", // Debian
36 "/home/gmaps/usnob-map/execs" // FIXME
37 };
38
39 static char* hipparcos_fn = "hipparcos.fab";
40 static char* constfn = "constellationship.fab";
41 static char* hip_dirs[] = {
42 ".",
43 "/usr/share/stellarium/data", // Debian
44 "/home/gmaps/usnob-map/execs"
45 };
46
47 typedef union {
48 uint32_t i;
49 float f;
50 } intfloat;
51
hip_get_radec(unsigned char * hip,int star1,double * ra,double * dec)52 static void hip_get_radec(unsigned char* hip, int star1,
53 double* ra, double* dec) {
54 intfloat ifval;
55 ifval.i = *((uint32_t*)(hip + HIP_SIZE * star1));
56 v32_letoh(&ifval.i);
57 *ra = ifval.f;
58 // Stellarium stores RA in hours...
59 *ra *= (360.0 / 24.0);
60 ifval.i = *((uint32_t*)(hip + HIP_SIZE * star1 + 4));
61 v32_letoh(&ifval.i);
62 *dec = ifval.f;
63 }
64
65
main(int argc,char ** args)66 int main(int argc, char** args) {
67 int c;
68 FILE* fconst = NULL;
69 uint32_t nstars;
70 size_t mapsize;
71 void* map;
72 unsigned char* hip;
73 FILE* fhip = NULL;
74 int i;
75 pl* cstars;
76 il* alluniqstars;
77 sl* shortnames;
78
79 while ((c = getopt(argc, args, OPTIONS)) != -1) {
80 switch (c) {
81 case 'h':
82 print_help(args[0]);
83 exit(0);
84 }
85 }
86
87 if (optind != argc) {
88 print_help(args[0]);
89 exit(-1);
90 }
91
92 for (i=0; i<sizeof(const_dirs)/sizeof(char*); i++) {
93 char fn[256];
94 snprintf(fn, sizeof(fn), "%s/%s", const_dirs[i], constfn);
95 fprintf(stderr, "render_constellation: Trying file: %s\n", fn);
96 fconst = fopen(fn, "rb");
97 if (fconst)
98 break;
99 }
100 if (!fconst) {
101 fprintf(stderr, "render_constellation: couldn't open any constellation files.\n");
102 return -1;
103 }
104
105 for (i=0; i<sizeof(hip_dirs)/sizeof(char*); i++) {
106 char fn[256];
107 snprintf(fn, sizeof(fn), "%s/%s", hip_dirs[i], hipparcos_fn);
108 fprintf(stderr, "render_constellation: Trying hip file: %s\n", fn);
109 fhip = fopen(fn, "rb");
110 if (fhip)
111 break;
112 }
113 if (!fhip) {
114 fprintf(stderr, "render_constellation: unhip\n");
115 return -1;
116 }
117
118 // first 32-bit int:
119 if (fread(&nstars, 4, 1, fhip) != 1) {
120 fprintf(stderr, "render_constellation: failed to read nstars.\n");
121 return -1;
122 }
123 v32_letoh(&nstars);
124 fprintf(stderr, "render_constellation: Found %i Hipparcos stars\n", nstars);
125
126 mapsize = nstars * HIP_SIZE + HIP_OFFSET;
127 map = mmap(0, mapsize, PROT_READ, MAP_SHARED, fileno(fhip), 0);
128 hip = ((unsigned char*)map) + HIP_OFFSET;
129
130 // for each constellation, its il* of lines.
131 cstars = pl_new(16);
132 alluniqstars = il_new(16);
133 shortnames = sl_new(16);
134
135 for (c=0;; c++) {
136 char shortname[16];
137 int nlines;
138 int i;
139 il* stars;
140
141 if (feof(fconst))
142 break;
143
144 if (fscanf(fconst, "%s %d ", shortname, &nlines) != 2) {
145 fprintf(stderr, "failed to parse name+nlines (constellation %i)\n", c);
146 fprintf(stderr, "file offset: %i (%x)\n",
147 (int)ftello(fconst), (int)ftello(fconst));
148 return -1;
149 }
150 //fprintf(stderr, "Name: %s. Nlines %i.\n", shortname, nlines);
151
152 stars = il_new(16);
153
154 sl_append(shortnames, shortname);
155 pl_append(cstars, stars);
156
157 for (i=0; i<nlines; i++) {
158 int star1, star2;
159
160 if (fscanf(fconst, " %d %d", &star1, &star2) != 2) {
161 fprintf(stderr, "failed parse star1+star2\n");
162 return -1;
163 }
164
165 il_insert_unique_ascending(alluniqstars, star1);
166 il_insert_unique_ascending(alluniqstars, star2);
167
168 il_append(stars, star1);
169 il_append(stars, star2);
170 }
171 fscanf(fconst, "\n");
172 }
173 fprintf(stderr, "render_constellations: Read %i constellations.\n", c);
174
175 printf("static const int constellations_N = %i;\n", sl_size(shortnames));
176
177 /*
178 for (c=0; c<sl_size(shortnames); c++) {
179 printf("static const char* shortname_%i = \"%s\";\n", c, sl_get(shortnames, c));
180 }
181 printf("static const char* shortnames[] = {");
182 for (c=0; c<sl_size(shortnames); c++) {
183 printf("shortname_%i,", c);
184 }
185 printf("};\n");
186 */
187 printf("static const char* shortnames[] = {");
188 for (c=0; c<sl_size(shortnames); c++) {
189 printf("\"%s\",", sl_get(shortnames, c));
190 }
191 printf("};\n");
192
193 printf("static const int constellation_nlines[] = {");
194 for (c=0; c<pl_size(cstars); c++) {
195 il* stars = pl_get(cstars, c);
196 printf("%i,", il_size(stars)/2);
197 }
198 printf("};\n");
199
200 for (c=0; c<pl_size(cstars); c++) {
201 il* stars = pl_get(cstars, c);
202 printf("static const int constellation_lines_%i[] = {", c);
203 for (i=0; i<il_size(stars); i++) {
204 int s = il_get(stars, i);
205 int ms = il_index_of(alluniqstars, s);
206 printf("%s%i", (i?",":""), ms);
207 }
208 printf("};\n");
209 }
210
211 printf("static const int* constellation_lines[] = {");
212 for (c=0; c<pl_size(cstars); c++) {
213 printf("constellation_lines_%i,", c);
214 }
215 printf("};\n");
216
217 printf("static const int stars_N = %i;\n", il_size(alluniqstars));
218
219 printf("static const double star_positions[] = {");
220 for (i=0; i<il_size(alluniqstars); i++) {
221 int s = il_get(alluniqstars, i);
222 double ra, dec;
223 hip_get_radec(hip, s, &ra, &dec);
224 printf("%g,%g,", ra, dec);
225 }
226 printf("};\n");
227
228 munmap(map, mapsize);
229
230 fclose(fconst);
231 fclose(fhip);
232
233 return 0;
234 }
235