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