diff options
Diffstat (limited to 'src/GipfelWidget.cxx')
| -rw-r--r-- | src/GipfelWidget.cxx | 822 |
1 files changed, 0 insertions, 822 deletions
diff --git a/src/GipfelWidget.cxx b/src/GipfelWidget.cxx deleted file mode 100644 index 30172a1..0000000 --- a/src/GipfelWidget.cxx +++ /dev/null @@ -1,822 +0,0 @@ -// -// Copyright 2006-2009 Johannes Hofmann <Johannes.Hofmann@gmx.de> -// -// This software may be used and distributed according to the terms -// of the GNU General Public License, incorporated herein by reference. - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <errno.h> -#include <math.h> -#include <algorithm> - -#include <FL/Fl.H> -#include <FL/Fl_Menu_Item.H> -#include <FL/Fl_Shared_Image.H> -#include <FL/Fl_JPEG_Image.H> -#include <FL/Fl_Preferences.H> -#include <FL/fl_draw.H> - -#include "Fl_Search_Chooser.H" -#include "choose_hill.H" -#include "ScanImage.H" -#include "GipfelWidget.H" - -#define CROSS_SIZE 2 - -static double pi_d, deg2rad; - -GipfelWidget::GipfelWidget(int X,int Y,int W, int H, void (*changed_cb)()): Fl_Group(X, Y, W, H) { - end(); - pi_d = asin(1.0) * 2.0; - deg2rad = pi_d / 180.0; - img = NULL; - pan = new Panorama(); - cur_mountain = NULL; - focused_mountain = NULL; - known_hills = new Hills(); - img_file = NULL; - track_width = 200.0; - show_hidden = false; - have_gipfel_info = false; - md = new ImageMetaData(); - track_points = NULL; - fl_register_images(); - mouse_x = mouse_y = 0; - params_changed_cb = changed_cb; -} - -int -GipfelWidget::load_image(char *file) { - Fl_Image *new_img; - double direction, nick, tilt, fl; - - new_img = new Fl_JPEG_Image(file); - - if (new_img == NULL) - return 1; - - if (img) - delete img; - - img = new_img; - - if (img_file) - free(img_file); - - img_file = strdup(file); - - known_hills->clear(); - - h(img->h()); - w(img->w()); - - // try to retrieve gipfel data from JPEG meta data - md->load_image(file); - set_view_long(md->longitude()); - set_view_lat(md->latitude()); - set_view_height(md->height()); - projection((ProjectionLSQ::Projection_t) md->projection_type()); - - have_gipfel_info = true; - direction = md->direction(); - if (isnan(direction)) { - set_center_angle(0.0); - have_gipfel_info = false; - } else { - set_center_angle(direction); - } - - nick = md->nick(); - if (isnan(nick)) { - set_nick_angle(0.0); - have_gipfel_info = false; - } else { - set_nick_angle(nick); - } - - tilt = md->tilt(); - if (isnan(tilt)) { - set_tilt_angle(0.0); - have_gipfel_info = false; - } else { - set_tilt_angle(tilt); - } - - fl = md->focal_length_35mm(); - if (isnan(fl) || fl == 0.0) { - set_focal_length_35mm(35.0); - have_gipfel_info = false; - } else { - set_focal_length_35mm(fl); - } - - // try to get distortion parameters in the following ordering: - // 1. gipfel data in JPEG comment - // 2. matching distortion profile - // 3. set the to 0.0, 0.0 - md->distortion_params(&pan->parms.k0, &pan->parms.k1, &pan->parms.x0); - if (isnan(pan->parms.k0)) { - char buf[1024]; - if (get_distortion_profile_name(buf, sizeof(buf)) == 0) - load_distortion_params(buf); - - if (isnan(pan->parms.k0)) - pan->parms.k0 = 0.0; - if (isnan(pan->parms.k1)) - pan->parms.k1 = 0.0; - if (isnan(pan->parms.x0)) - pan->parms.x0 = 0.0; - } - - return 0; -} - -const char * -GipfelWidget::get_image_filename() { - return img_file; -} - -int -GipfelWidget::save_image(char *file) { - if (img_file == NULL) { - fprintf(stderr, "Nothing to save\n"); - return 1; - } - - md->longitude(get_view_long()); - md->latitude(get_view_lat()); - md->height(get_view_height()); - md->direction(get_center_angle()); - md->nick(get_nick_angle()); - md->tilt(get_tilt_angle()); - md->focal_length_35mm(get_focal_length_35mm()); - md->projection_type((int) projection()); - md->distortion_params(pan->parms.k0, pan->parms.k1, pan->parms.x0); - - return md->save_image(img_file, file); -} - -int -GipfelWidget::load_data(const char *file) { - int r; - - r = pan->load_data(file); - set_labels(pan->get_visible_mountains()); - - return r; -} - -int -GipfelWidget::load_track(const char *file) { - if (track_points) { - pan->remove_hills(Hill::TRACK_POINT); - track_points->clobber(); - delete track_points; - } - - track_points = new Hills(); - - if (track_points->load(file) != 0) { - delete track_points; - track_points = NULL; - return 1; - } - - for (int i = 0; i < track_points->get_num(); i++) - track_points->get(i)->flags |= Hill::TRACK_POINT; - - pan->add_hills(track_points); - redraw(); - - return 0; -} - -int -GipfelWidget::set_viewpoint(const char *pos) { - int r; - - r = pan->set_viewpoint(pos); - set_labels(pan->get_visible_mountains()); - redraw(); - return r; -} - -void -GipfelWidget::set_viewpoint(const Hill *m) { - pan->set_viewpoint(m); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -static void -draw_flag(int x, int y) { - fl_polygon(x, y - 10, x, y - 20, x + 10, y - 15); - fl_yxline(x, y, y - 10); - fl_circle(x , y, 3); -} - -void -GipfelWidget::draw() { - Hills *mnts; - Hill *m; - int i, height; - - if (img == NULL) - return; - - fl_push_clip(x(), y(), w(), h()); - img->draw(x(),y(),w(),h(),0,0); - - /* hills */ - fl_font(FL_HELVETICA, 8); - mnts = pan->get_visible_mountains(); - - fl_color(FL_YELLOW); - height = fl_height(); - for (i=0; i<mnts->get_num(); i++) { - m = mnts->get(i); - int m_x = w() / 2 + x() + (int) rint(m->x); - int m_y = h() / 2 + y() + (int) rint(m->y); - - if ((m->flags & (Hill::DUPLIC|Hill::TRACK_POINT)) || - (!show_hidden && (m->flags & Hill::HIDDEN)) || - known_hills->contains(m) || m == focused_mountain) - continue; - - if (fabs(m->x) > img->w() / 2 || fabs(m->y) > img->h() / 2) - continue; - - fl_xyline(m_x - CROSS_SIZE, m_y, m_x + CROSS_SIZE); - fl_yxline(m_x, m_y + m->label_y - height, m_y + CROSS_SIZE); - fl_xyline(m_x, m_y + m->label_y - height, m_x + m->label_x); - } - - for (i=0; i<mnts->get_num(); i++) { - m = mnts->get(i); - int m_x = w() / 2 + x() + (int) rint(m->x); - int m_y = h() / 2 + y() + (int) rint(m->y); - - if ((m->flags & (Hill::DUPLIC|Hill::TRACK_POINT)) || - (!show_hidden && (m->flags & Hill::HIDDEN)) || m == focused_mountain) - continue; - - if (fabs(m->x) > img->w() / 2 || fabs(m->y) > img->h() / 2) - continue; - - if (known_hills->contains(m)) { - if (known_hills->get_num() > 3) - fl_color(FL_GREEN); - else - fl_color(FL_RED); - - draw_flag(m_x, m_y); - fl_color(FL_BLACK); - } else if (m->flags & Hill::HIDDEN) { - fl_color(FL_BLUE); - } else { - fl_color(FL_BLACK); - } - - fl_draw(m->name, m_x + 2, m_y + m->label_y); - } - - if (focused_mountain) { - m = focused_mountain; - int m_x = w() / 2 + x() + (int) rint(m->x); - int m_y = h() / 2 + y() + (int) rint(m->y); - - fl_color(FL_YELLOW); - - fl_rectf(m_x, m_y - height, - (int) fl_width(focused_mountain_label) + 2, height + 2); - fl_color(FL_BLACK); - fl_draw(focused_mountain_label, m_x, m_y); - } - - - /* track */ - if (track_points && track_points->get_num() > 0) { - int last_x = 0, last_y = 0, last_initialized = 0; - - for (i=1; i<track_points->get_num(); i++) { - m = track_points->get(i); - int m_x = w() / 2 + x() + (int) rint(m->x); - int m_y = h() / 2 + y() + (int) rint(m->y); - - if (!(track_points->get(i)->flags & Hill::VISIBLE)) - continue; - - if (track_points->get(i)->flags & Hill::HIDDEN) - fl_color(FL_BLUE); - else - fl_color(FL_RED); - - fl_line_style(FL_SOLID | FL_CAP_ROUND | FL_JOIN_ROUND, - get_rel_track_width(track_points->get(i))); - if (last_initialized) { - fl_begin_line(); - fl_vertex(last_x, last_y); - fl_vertex(m_x, m_y); - fl_end_line(); - } - - last_x = m_x; - last_y = m_y; - last_initialized++; - } - fl_line_style(0); - } - - fl_pop_clip(); -} - -static int -overlap(double x1, double l1, double x2, double l2) { - return x1 <= x2 + l2 && x1 + l1 >= x2; -} - -void -GipfelWidget::set_labels(Hills *v) { - int height; - - if (!img) - return; - - - fl_font(FL_HELVETICA, 8); - height = fl_height(); - - for (int i = 0; i < v->get_num(); i++) { - Hill *m = v->get(i); - Hills colliding; - - if (m->flags & (Hill::DUPLIC | Hill::TRACK_POINT)) - continue; - - if (!show_hidden && (m->flags & Hill::HIDDEN)) - continue; - - if (fabs(m->x) > img->w() / 2 || fabs(m->y) > img->h() / 2) - continue; - - m->label_x = (int) fl_width(m->name) + 1; - m->label_y = 0; - - for (int j = i - 1; j >= 0; j--) { - Hill *n = v->get(j); - - if (n->flags & (Hill::DUPLIC | Hill::TRACK_POINT)) - continue; - - if (!show_hidden && (n->flags & Hill::HIDDEN)) - continue; - - if (fabs(m->x) > img->w() / 2 || fabs(m->y) > img->h() / 2) - continue; - - if (overlap(m->x, m->label_x, n->x - CROSS_SIZE, n->label_x)) - colliding.add(n); - else - break; - } - - colliding.sort(Hills::SORT_LABEL_Y); - - for (int j = 0; j < colliding.get_num(); j++) { - Hill *n = colliding.get(j); - - // Check for overlapping labels and - // overlaps between labels and peak markers - if (overlap(m->y + m->label_y - height, height, - n->y + n->label_y - height, height) || - overlap(m->y + m->label_y - height, - height, n->y - CROSS_SIZE, 2 * CROSS_SIZE)) { - - m->label_y = (int) rint(n->y + n->label_y - m->y - height - 2); - } - } - } -} - -Hill * -GipfelWidget::find_mountain(Hills *mnts, int m_x, int m_y) { - Hill *m; - int center_x = w() / 2; - int center_y = h() / 2; - - for (int i = 0; i < mnts->get_num(); i++) { - m = mnts->get(i); - - if (m_x - center_x >= m->x - 2 && m_x - center_x < m->x + 2 && - m_y - center_y >= m->y - 2 && m_y - center_y < m->y + 2) - return m; - } - - return NULL; -} - -int -GipfelWidget::toggle_known_mountain(int m_x, int m_y) { - Hills *mnts = pan->get_visible_mountains(); - int center_x = w() / 2; - int center_y = h() / 2; - - for (int i = 0; i < mnts->get_num(); i++) { - Hill *m = mnts->get(i); - - if (m->flags & (Hill::DUPLIC | Hill::TRACK_POINT)) - continue; - - if (m_x - center_x >= m->x - 2 && m_x - center_x < m->x + 2 && - m_y - center_y >= m->y - 2 && m_y - center_y < m->y + 2) { - - - if (known_hills->contains(m)) - known_hills->remove(m); - else - known_hills->add(m); - - redraw(); - return 0; - } - } - - cur_mountain = NULL; - redraw(); - return 1; -} - -int -GipfelWidget::set_mountain(int m_x, int m_y) { - int old_x, old_y, old_label_y; - int center_x = w() / 2; - int center_y = h() / 2; - - if (!cur_mountain) - return 1; - - old_x = (int) rint(cur_mountain->x); - old_y = (int) rint(cur_mountain->y); - old_label_y = cur_mountain->label_y; - - cur_mountain->x = m_x - center_x; - cur_mountain->y = m_y - center_y; - cur_mountain->label_y = 0; - - damage(4, center_x + x() + old_x - 2*CROSS_SIZE - 1, - center_y + y() + old_y + old_label_y - 2*CROSS_SIZE - 20, - std::max(20, cur_mountain->label_x) + 2*CROSS_SIZE + 4, - std::max(20, old_label_y) + 22 ); - damage(4, - (int) rint(center_x + x() + cur_mountain->x - 2*CROSS_SIZE - 1), - (int) rint(center_y + y() + cur_mountain->y + cur_mountain->label_y - 2*CROSS_SIZE - 20), - std::max(20, cur_mountain->label_x) + 2*CROSS_SIZE + 4, - std::max(20, cur_mountain->label_y) + 22 ); - - return 0; -} - -void -GipfelWidget::set_center_angle(double a) { - pan->set_center_angle(a); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -void -GipfelWidget::set_nick_angle(double a) { - pan->set_nick_angle(a); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -void -GipfelWidget::set_tilt_angle(double a) { - pan->set_tilt_angle(a); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -void -GipfelWidget::set_focal_length_35mm(double s) { - int w = std::max(img->w(), img->h()); // assume sensor is wider than high - pan->set_scale(s * (double) w / 35.0); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -void -GipfelWidget::projection(ProjectionLSQ::Projection_t p) { - pan->set_projection(p); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -void -GipfelWidget::set_distortion_params(double k0, double k1, double x0) { - pan->set_distortion_params(k0, k1, x0); - redraw(); -} - -double -GipfelWidget::get_focal_length_35mm() { - int w; - - if (img == NULL) - return NAN; - - w = std::max(img->w(), img->h()); // assume sensor is wider than high - return pan->get_scale() * 35.0 / (double) w; -} - -void -GipfelWidget::find_peak_cb(Fl_Widget *, void *f) { - GipfelWidget *g = (GipfelWidget*) f; - - Hill *m = choose_hill(g->pan->get_close_mountains(), "Find Peak"); - if (m) { - if (!g->known_hills->contains(m)) - g->known_hills->add(m); - - m->flags |= Hill::VISIBLE; - if (! g->pan->get_visible_mountains()->contains(m)) - g->pan->get_visible_mountains()->add(m); - g->set_labels(g->pan->get_visible_mountains()); - - g->cur_mountain = m; - g->set_mountain(g->mouse_x, g->mouse_y); - g->comp_params(); - } -} - -void -GipfelWidget::toggle_hidden_cb(Fl_Widget *, void *f) { - GipfelWidget *g = (GipfelWidget*) f; - - Hill *m = g->find_mountain(g->pan->get_visible_mountains(), g->mouse_x, g->mouse_y); - if (!m) - return; - - if (m->flags & Hill::HIDDEN) - m->flags &= ~Hill::HIDDEN; - else - m->flags |= Hill::HIDDEN; - - g->set_labels(g->pan->get_visible_mountains()); - g->redraw(); -} - -void -GipfelWidget::set_height_dist_ratio(double r) { - pan->set_height_dist_ratio(r); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -void -GipfelWidget::set_hide_value(double h) { - pan->set_hide_value(h); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -void -GipfelWidget::set_show_hidden(bool h) { - show_hidden = h; - set_labels(pan->get_visible_mountains()); - redraw(); -} - -void -GipfelWidget::set_view_lat(double v) { - pan->set_view_lat(v); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -void -GipfelWidget::set_view_long(double v) { - pan->set_view_long(v); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -void -GipfelWidget::set_view_height(double v) { - pan->set_view_height(v); - set_labels(pan->get_visible_mountains()); - redraw(); -} - -int -GipfelWidget::comp_params() { - int ret; - - fl_cursor(FL_CURSOR_WAIT); - ret = pan->comp_params(known_hills); - set_labels(pan->get_visible_mountains()); - redraw(); - fl_cursor(FL_CURSOR_DEFAULT); - if (params_changed_cb) - params_changed_cb(); - - return ret; -} - -int -GipfelWidget::get_rel_track_width(Hill *m) { - double dist = pan->get_real_distance(m); - - return (int) rint(std::max((pan->get_scale()*track_width)/(dist*10.0), 1.0)); -} - -void -GipfelWidget::set_track_width(double w) { - track_width = w; - redraw(); -} - -int -GipfelWidget::handle(int event) { - Hill *m; - - switch(event) { - case FL_PUSH: - mouse_x = Fl::event_x()-x(); - mouse_y = Fl::event_y()-y(); - if (Fl::event_button() == FL_LEFT_MOUSE) { - m = find_mountain(known_hills, mouse_x, mouse_y); - if (m) - cur_mountain = m; - } else if (Fl::event_button() == FL_MIDDLE_MOUSE) { - toggle_known_mountain(mouse_x, mouse_y); - if (focused_mountain) { - focused_mountain = NULL; - redraw(); - } - } else if (Fl::event_button() == FL_RIGHT_MOUSE) { - focused_mountain = NULL; - - Fl_Menu_Button rclick_menu(Fl::event_x_root(), - Fl::event_y_root(), 80, 1); - Hill *m = find_mountain(pan->get_visible_mountains(), - mouse_x, mouse_y); - char buf[1024]; - - rclick_menu.add("Find Peak", 0, find_peak_cb, this); - if (m) { - if (m->flags & Hill::HIDDEN) - snprintf(buf, sizeof(buf), "Unhide %s", m->name); - else - snprintf(buf, sizeof(buf), "Hide %s", m->name); - - rclick_menu.add(buf, 0, toggle_hidden_cb, this); - } - - rclick_menu.popup(); - } - - Fl::focus(this); - return 1; - case FL_DRAG: - set_mountain(Fl::event_x()-x(), Fl::event_y()-y()); - return 1; - case FL_RELEASE: - cur_mountain = NULL; - if (known_hills->get_num() > 0) - comp_params(); - return 1; - case FL_ENTER: - return 1; - case FL_LEAVE: - return 1; - case FL_MOVE: - m = find_mountain(pan->get_visible_mountains(), Fl::event_x()-x(), Fl::event_y()-y()); - if (m != focused_mountain && (!m || !known_hills->contains(m))) { - if (m) - snprintf(focused_mountain_label, - sizeof(focused_mountain_label) - 1, - "%s (%dm), distance %.2fkm", - m->name, (int) m->height, pan->get_real_distance(m) / 1000.0); - - focused_mountain = m; - redraw(); - } - return 1; - case FL_FOCUS: - return 1; - case FL_UNFOCUS: - return 0; - } - return 0; -} - -int -GipfelWidget::export_hills(const char *file, FILE *fp) { - Hills export_hills, *mnts; - - if (!have_gipfel_info) { - fprintf(stderr, "No gipfel info available for %s.\n", img_file); - return 0; - } - - if (file) { - if (export_hills.load(file) != 0) - return 1; - - for (int i = 0; i < export_hills.get_num(); i++) - export_hills.get(i)->flags |= Hill::EXPORT; - - pan->add_hills(&export_hills); - } - - fprintf(fp, "#\n# name\theight\tx\ty\tdistance\tflags\n#\n"); - - mnts = pan->get_visible_mountains(); - for (int i = 0; i < mnts->get_num(); i++) { - Hill *m = mnts->get(i); - int _x = (int) rint(m->x) + w() / 2; - int _y = (int) rint(m->y) + h() / 2; - - if (m->flags & Hill::DUPLIC || m->flags & Hill::HIDDEN || - (file && !(m->flags & Hill::EXPORT))) { - continue; - } - - if (_x < 0 || _x > w() || _y < 0 || _y > h()) - continue; - - fprintf(fp, "%s\t%d\t%d\t%d\t%d\n", - m->name, (int) rint(m->height), _x, _y, - (int) rint(pan->get_real_distance(m))); - } - - pan->remove_hills(Hill::EXPORT); - - return 0; -} - -int -GipfelWidget::get_pixel(ScanImage::mode_t m, - double a_alph, double a_nick, int *r, int *g, int *b) { - double px, py; - int ret; - - if (img == NULL) - return 1; - - if (pan->get_coordinates(a_alph, a_nick, &px, &py) != 0) - return 1; - - ret = ScanImage::get_pixel(img, m, px + ((double) img->w()) / 2.0, - py + ((double) img->h()) / 2.0, r, g, b); - - return ret; -} - -int -GipfelWidget::get_distortion_profile_name(char *buf, int buflen) { - int n; - - if (md && md->manufacturer() && md->model()) { - n = snprintf(buf, buflen, "%s_%s_%.2f_mm", - md->manufacturer(), md->model(), md->focal_length()); - - return n > buflen; - } else { - return 1; - } -} - -static Fl_Preferences dist_prefs(Fl_Preferences::USER, - "Johannes.HofmannATgmx.de", "gipfel/DistortionProfiles"); - -int -GipfelWidget::load_distortion_params(const char *prof_name) { - int ret = 0; - - Fl_Preferences prof(dist_prefs, prof_name); - ret += prof.get("k0", pan->parms.k0, pan->parms.k0); - ret += prof.get("k1", pan->parms.k1, pan->parms.k1); - ret += prof.get("x0", pan->parms.x0, pan->parms.x0); - - return !ret; -} - -int -GipfelWidget::save_distortion_params(const char *prof_name, int force) { - Fl_Preferences prof(dist_prefs, prof_name); - - if (!force && prof.entryExists("k0")) - return 1; - - prof.set("k0", pan->parms.k0); - prof.set("k1", pan->parms.k1); - prof.set("x0", pan->parms.x0); - - return 0; -} |
