2 * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "gis-marshal.h"
21 #include "gis-viewer.h"
42 static guint signals[NUM_SIGNALS];
46 static void _gis_viewer_fix_location(GisViewer *self)
48 while (self->location[0] < -90) self->location[0] += 180;
49 while (self->location[0] > 90) self->location[0] -= 180;
50 while (self->location[1] < -180) self->location[1] += 360;
51 while (self->location[1] > 180) self->location[1] -= 360;
52 self->location[2] = ABS(self->location[2]);
56 static void _gis_viewer_emit_location_changed(GisViewer *self)
58 g_signal_emit(self, signals[SIG_LOCATION_CHANGED], 0,
63 static void _gis_viewer_emit_rotation_changed(GisViewer *self)
65 g_signal_emit(self, signals[SIG_ROTATION_CHANGED], 0,
70 static void _gis_viewer_emit_time_changed(GisViewer *self)
72 g_signal_emit(self, signals[SIG_TIME_CHANGED], 0,
75 static void _gis_viewer_emit_site_changed(GisViewer *self)
77 g_signal_emit(self, signals[SIG_SITE_CHANGED], 0,
80 static void _gis_viewer_emit_refresh(GisViewer *self)
82 g_signal_emit(self, signals[SIG_REFRESH], 0);
84 static void _gis_viewer_emit_offline(GisViewer *self)
86 g_signal_emit(self, signals[SIG_OFFLINE], 0,
94 GisViewer *gis_viewer_new()
96 g_debug("GisViewer: new");
97 return g_object_new(GIS_TYPE_VIEWER, NULL);
100 void gis_viewer_set_time(GisViewer *self, const char *time)
102 g_assert(GIS_IS_VIEWER(self));
103 g_debug("GisViewer: set_time - time=%s", time);
105 self->time = g_strdup(time);
106 _gis_viewer_emit_time_changed(self);
109 gchar *gis_viewer_get_time(GisViewer *self)
111 g_assert(GIS_IS_VIEWER(self));
112 g_debug("GisViewer: get_time");
116 void gis_viewer_set_location(GisViewer *self, gdouble lat, gdouble lon, gdouble elev)
118 g_assert(GIS_IS_VIEWER(self));
119 g_debug("GisViewer: set_location");
120 self->location[0] = lat;
121 self->location[1] = lon;
122 self->location[2] = elev;
123 _gis_viewer_fix_location(self);
124 _gis_viewer_emit_location_changed(self);
127 void gis_viewer_get_location(GisViewer *self, gdouble *lat, gdouble *lon, gdouble *elev)
129 g_assert(GIS_IS_VIEWER(self));
130 //g_debug("GisViewer: get_location");
131 *lat = self->location[0];
132 *lon = self->location[1];
133 *elev = self->location[2];
136 void gis_viewer_pan(GisViewer *self, gdouble lat, gdouble lon, gdouble elev)
138 g_assert(GIS_IS_VIEWER(self));
139 g_debug("GisViewer: pan - lat=%8.3f, lon=%8.3f, elev=%8.3f", lat, lon, elev);
140 self->location[0] += lat;
141 self->location[1] += lon;
142 self->location[2] += elev;
143 _gis_viewer_fix_location(self);
144 _gis_viewer_emit_location_changed(self);
147 void gis_viewer_zoom(GisViewer *self, gdouble scale)
149 g_assert(GIS_IS_VIEWER(self));
150 g_debug("GisViewer: zoom");
151 self->location[2] *= scale;
152 _gis_viewer_emit_location_changed(self);
155 void gis_viewer_set_rotation(GisViewer *self, gdouble x, gdouble y, gdouble z)
157 g_assert(GIS_IS_VIEWER(self));
158 g_debug("GisViewer: set_rotation");
159 self->rotation[0] = x;
160 self->rotation[1] = y;
161 self->rotation[2] = z;
162 _gis_viewer_emit_rotation_changed(self);
165 void gis_viewer_get_rotation(GisViewer *self, gdouble *x, gdouble *y, gdouble *z)
167 g_assert(GIS_IS_VIEWER(self));
168 g_debug("GisViewer: get_rotation");
169 *x = self->rotation[0];
170 *y = self->rotation[1];
171 *z = self->rotation[2];
174 void gis_viewer_rotate(GisViewer *self, gdouble x, gdouble y, gdouble z)
176 g_assert(GIS_IS_VIEWER(self));
177 g_debug("GisViewer: rotate - x=%.0f, y=%.0f, z=%.0f", x, y, z);
178 self->rotation[0] += x;
179 self->rotation[1] += y;
180 self->rotation[2] += z;
181 _gis_viewer_emit_rotation_changed(self);
184 /* To be deprecated, use {get,set}_location */
185 void gis_viewer_set_site(GisViewer *self, const gchar *site)
187 g_assert(GIS_IS_VIEWER(self));
188 g_debug("GisViewer: set_site");
190 self->site = g_strdup(site);
191 _gis_viewer_emit_site_changed(self);
194 gchar *gis_viewer_get_site(GisViewer *self)
196 g_assert(GIS_IS_VIEWER(self));
197 g_debug("GisViewer: get_site - %s", self->site);
201 void gis_viewer_refresh(GisViewer *self)
203 g_debug("GisViewer: refresh");
204 _gis_viewer_emit_refresh(self);
207 void gis_viewer_set_offline(GisViewer *self, gboolean offline)
209 g_assert(GIS_IS_VIEWER(self));
210 g_debug("GisViewer: set_offline - %d", offline);
211 self->offline = offline;
212 _gis_viewer_emit_offline(self);
215 gboolean gis_viewer_get_offline(GisViewer *self)
217 g_assert(GIS_IS_VIEWER(self));
218 g_debug("GisViewer: get_offline - %d", self->offline);
219 return self->offline;
226 G_DEFINE_TYPE(GisViewer, gis_viewer, G_TYPE_OBJECT);
227 static void gis_viewer_init(GisViewer *self)
229 g_debug("GisViewer: init");
231 self->time = g_strdup("");
232 self->site = g_strdup("");
233 self->location[0] = 40;
234 self->location[1] = -100;
235 self->location[2] = 1.5*EARTH_R;
236 self->rotation[0] = 0;
237 self->rotation[1] = 0;
238 self->rotation[2] = 0;
240 static void gis_viewer_dispose(GObject *gobject)
242 g_debug("GisViewer: dispose");
243 /* Drop references to other GObjects */
244 G_OBJECT_CLASS(gis_viewer_parent_class)->dispose(gobject);
246 static void gis_viewer_finalize(GObject *gobject)
248 g_debug("GisViewer: finalize");
249 GisViewer *self = GIS_VIEWER(gobject);
252 G_OBJECT_CLASS(gis_viewer_parent_class)->finalize(gobject);
254 static void gis_viewer_set_property(GObject *object, guint property_id,
255 const GValue *value, GParamSpec *pspec)
257 g_debug("GisViewer: set_property");
258 GisViewer *self = GIS_VIEWER(object);
259 switch (property_id) {
260 case PROP_TIME: gis_viewer_set_time (self, g_value_get_string (value)); break;
261 case PROP_SITE: gis_viewer_set_site (self, g_value_get_string (value)); break;
262 case PROP_OFFLINE: gis_viewer_set_offline(self, g_value_get_boolean(value)); break;
263 default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
266 static void gis_viewer_get_property(GObject *object, guint property_id,
267 GValue *value, GParamSpec *pspec)
269 g_debug("GisViewer: get_property");
270 GisViewer *self = GIS_VIEWER(object);
271 switch (property_id) {
272 case PROP_TIME: g_value_set_string (value, gis_viewer_get_time (self)); break;
273 case PROP_SITE: g_value_set_string (value, gis_viewer_get_site (self)); break;
274 case PROP_OFFLINE: g_value_set_boolean(value, gis_viewer_get_offline(self)); break;
275 default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
278 static void gis_viewer_class_init(GisViewerClass *klass)
280 g_debug("GisViewer: class_init");
281 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
282 gobject_class->dispose = gis_viewer_dispose;
283 gobject_class->finalize = gis_viewer_finalize;
284 gobject_class->get_property = gis_viewer_get_property;
285 gobject_class->set_property = gis_viewer_set_property;
286 g_object_class_install_property(gobject_class, PROP_TIME,
287 g_param_spec_pointer(
289 "time of the current frame",
292 g_object_class_install_property(gobject_class, PROP_SITE,
293 g_param_spec_pointer(
295 "site seen by the viewerport",
296 "Site of the viewerport. "
297 "Currently this is the name of the radar site.",
299 g_object_class_install_property(gobject_class, PROP_OFFLINE,
300 g_param_spec_pointer(
302 "whether the viewer should access the network",
303 "Offline state of the viewer. "
304 "If set to true, the viewer will not access the network",
306 signals[SIG_TIME_CHANGED] = g_signal_new(
308 G_TYPE_FROM_CLASS(gobject_class),
313 g_cclosure_marshal_VOID__STRING,
317 signals[SIG_SITE_CHANGED] = g_signal_new(
319 G_TYPE_FROM_CLASS(gobject_class),
324 g_cclosure_marshal_VOID__STRING,
328 signals[SIG_LOCATION_CHANGED] = g_signal_new(
330 G_TYPE_FROM_CLASS(gobject_class),
335 gis_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE,
341 signals[SIG_ROTATION_CHANGED] = g_signal_new(
343 G_TYPE_FROM_CLASS(gobject_class),
348 gis_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE,
354 signals[SIG_REFRESH] = g_signal_new(
356 G_TYPE_FROM_CLASS(gobject_class),
361 g_cclosure_marshal_VOID__VOID,
364 signals[SIG_OFFLINE] = g_signal_new(
366 G_TYPE_FROM_CLASS(gobject_class),
371 g_cclosure_marshal_VOID__BOOLEAN,