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