summaryrefslogtreecommitdiff
path: root/src/GipfelWidget.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/GipfelWidget.cxx')
-rw-r--r--src/GipfelWidget.cxx822
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;
-}