1 /*
2  # This file is part of the Astrometry.net suite.
3  # Licensed under a 3-clause BSD style license - see LICENSE
4  */
5 #include <string.h>
6 #include <math.h>
7 #include <assert.h>
8 
9 #include "plotoutline.h"
10 #include "cairoutils.h"
11 #include "ioutils.h"
12 #include "log.h"
13 #include "errors.h"
14 #include "sip-utils.h"
15 #include "sip_qfits.h"
16 #include "starutil.h"
17 
18 DEFINE_PLOTTER(outline);
19 
plot_outline_get(plot_args_t * pargs)20 plotoutline_t* plot_outline_get(plot_args_t* pargs) {
21     return plotstuff_get_config(pargs, "outline");
22 }
23 
plot_outline_init(plot_args_t * plotargs)24 void* plot_outline_init(plot_args_t* plotargs) {
25     plotoutline_t* args = calloc(1, sizeof(plotoutline_t));
26     args->stepsize = 10;
27     return args;
28 }
29 
walk_callback(const anwcs_t * wcs,double ix,double iy,double ra,double dec,void * token)30 static void walk_callback(const anwcs_t* wcs, double ix, double iy,
31                           double ra, double dec, void* token) {
32     dl* radecs = (dl*)token;
33     dl_append(radecs, ra);
34     dl_append(radecs, dec);
35 }
36 
plot_outline_plot(const char * command,cairo_t * cairo,plot_args_t * pargs,void * baton)37 int plot_outline_plot(const char* command,
38                       cairo_t* cairo, plot_args_t* pargs, void* baton) {
39     plotoutline_t* args = (plotoutline_t*)baton;
40     dl* rd;
41     int i;
42     pl* lists;
43 
44     assert(args->stepsize > 0);
45     assert(args->wcs);
46     assert(pargs->wcs);
47 
48     plotstuff_builtin_apply(cairo, pargs);
49 
50     logverb("Plotting outline of WCS: image size is %g x %g\n",
51             anwcs_imagew(args->wcs), anwcs_imageh(args->wcs));
52 
53     rd = dl_new(256);
54     anwcs_walk_image_boundary(args->wcs, args->stepsize, walk_callback, rd);
55     logverb("Outline: walked in %zu steps\n", dl_size(rd)/2);
56 
57     if (dl_size(rd) == 0) {
58         printf("plot_outline: empty WCS outline.\n");
59         anwcs_print(args->wcs, stdout);
60         dl_free(rd);
61         return 0;
62     }
63 
64     // avoid special case when there is a break between
65     // the beginning and end of the list.
66     dl_append(rd, dl_get(rd, 0));
67     dl_append(rd, dl_get(rd, 1));
68 
69     lists = anwcs_walk_outline(pargs->wcs, rd, args->fill);
70     dl_free(rd);
71     for (i=0; i<pl_size(lists); i++) {
72         dl* xy = pl_get(lists, i);
73         int j;
74         for (j=0; j<dl_size(xy)/2; j++) {
75             double x,y;
76             x = dl_get(xy, j*2+0);
77             y = dl_get(xy, j*2+1);
78             if (j == 0) {
79                 cairo_move_to(cairo, x, y);
80             } else {
81                 cairo_line_to(cairo, x, y);
82             }
83         }
84         cairo_close_path(cairo);
85         if (args->fill)
86             cairo_fill(cairo);
87         else
88             cairo_stroke(cairo);
89         dl_free(xy);
90     }
91     pl_free(lists);
92     return 0;
93 }
94 
plot_outline_set_wcs_size(plotoutline_t * args,int W,int H)95 int plot_outline_set_wcs_size(plotoutline_t* args, int W, int H) {
96     if (!args->wcs) {
97         ERROR("No WCS is currently set.");
98         return -1;
99     }
100     anwcs_set_size(args->wcs, W, H);
101     return 0;
102 }
103 
plot_outline_set_wcs_file(plotoutline_t * args,const char * filename,int ext)104 int plot_outline_set_wcs_file(plotoutline_t* args, const char* filename, int ext) {
105     anwcs_t* wcs = anwcs_open(filename, ext);
106     if (!wcs) {
107         ERROR("Failed to read WCS file \"%s\"", filename);
108         return -1;
109     }
110     logverb("Read WCS file %s\n", filename);
111     if (args->wcs)
112         anwcs_free(args->wcs);
113     args->wcs = wcs;
114     //anwcs_print(args->wcs, stdout);
115     return 0;
116 }
117 
plot_outline_set_wcs(plotoutline_t * args,const sip_t * wcs)118 int plot_outline_set_wcs(plotoutline_t* args, const sip_t* wcs) {
119     if (args->wcs)
120         anwcs_free(args->wcs);
121     args->wcs = anwcs_new_sip(wcs);
122     return 0;
123 }
124 
plot_outline_set_tan_wcs(plotoutline_t * args,const tan_t * wcs)125 int plot_outline_set_tan_wcs(plotoutline_t* args, const tan_t* wcs) {
126     if (args->wcs)
127         anwcs_free(args->wcs);
128     args->wcs = anwcs_new_tan(wcs);
129     return 0;
130 }
131 
plot_outline_set_fill(plotoutline_t * args,anbool fill)132 int plot_outline_set_fill(plotoutline_t* args, anbool fill) {
133     args->fill = fill;
134     return 0;
135 }
136 
plot_outline_command(const char * cmd,const char * cmdargs,plot_args_t * pargs,void * baton)137 int plot_outline_command(const char* cmd, const char* cmdargs,
138                          plot_args_t* pargs, void* baton) {
139     plotoutline_t* args = (plotoutline_t*)baton;
140     if (streq(cmd, "outline_wcs")) {
141         if (plot_outline_set_wcs_file(args, cmdargs, 0)) {
142             return -1;
143         }
144     } else if (streq(cmd, "outline_fill")) {
145         if (streq(cmdargs, "0"))
146             args->fill = FALSE;
147         else
148             args->fill = TRUE;
149     } else if (streq(cmd, "outline_step")) {
150         args->stepsize = atof(cmdargs);
151     } else {
152         ERROR("Did not understand command \"%s\"", cmd);
153         return -1;
154     }
155     return 0;
156 }
157 
plot_outline_free(plot_args_t * plotargs,void * baton)158 void plot_outline_free(plot_args_t* plotargs, void* baton) {
159     plotoutline_t* args = (plotoutline_t*)baton;
160     free(args);
161 }
162 
163