60#include <gdk/gdkkeysyms.h>
125#define UNCLASSIFIED -1
129#define NOT_CORE_POINT 0
169 const int32_t imgid,
const int count);
187 GtkSelectionData *selection_data, guint target_type, guint time,
191 GtkSelectionData *selection_data, guint target_type, guint time,
208 unsigned int minpts);
219 const gboolean
main);
234 switch(event->keyval)
256#ifndef HAVE_OSMGPSMAP_110_OR_NEWER
263 #define LOG2(x) (ilogb(x))
265 #define LOG2(x) ((int)floor(log2(abs(x))))
272 return (deg *
M_PI / 180.0);
275static int latlon2zoom(
int pix_height,
int pix_width,
float lat1,
float lat2,
float lon1,
float lon2)
277 const float lat1_m = atanh(sinf(lat1));
278 const float lat2_m = atanh(sinf(lat2));
279 const int zoom_lon =
LOG2((
double)(2 * pix_width *
M_PI) / (
TILESIZE * (lon2 - lon1)));
280 const int zoom_lat =
LOG2((
double)(2 * pix_height *
M_PI) / (
TILESIZE * (lat2_m - lat1_m)));
281 return MIN(zoom_lon, zoom_lat);
296 GtkAllocation allocation;
297 gtk_widget_get_allocation(GTK_WIDGET (map), &allocation);
298 const int zoom =
latlon2zoom(allocation.height, allocation.width,
301 osm_gps_map_set_center(map, (latitude1 + latitude2) / 2, (longitude1 + longitude2) / 2);
302 osm_gps_map_set_zoom(map, zoom);
316 double *count_width,
double *count_height)
318 gchar *text = g_strdup_printf(
"%d", nb_images);
322 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
323 cairo_t *cr = cairo_create(cst);
331 cairo_text_extents_t te;
332 cairo_text_extents(cr, text, &te);
333 *count_width = te.width + 4 * te.x_bearing;
334 *count_height = te.height + 2;
335 cairo_move_to(cr, te.x_bearing, te.height + 1);
337 cairo_show_text(cr, text);
339 uint8_t *data = cairo_image_surface_get_data(cst);
341 const size_t size = (size_t)w * h * 4;
342 uint8_t *buf = (uint8_t *)malloc(
size);
343 memcpy(buf, data,
size);
344 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB,
TRUE, 8, w, h, w * 4,
345 (GdkPixbufDestroyNotify)free, NULL);
346 cairo_surface_destroy(cst);
355 g_return_val_if_fail(w > 0 && h > 0, NULL);
363 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
364 cairo_t *cr = cairo_create(cst);
365 cairo_set_source_rgba(cr,
r,
g, b, a);
368 uint8_t *data = cairo_image_surface_get_data(cst);
370 const size_t size = (size_t)w * h * 4;
371 uint8_t *buf = (uint8_t *)malloc(
size);
372 memcpy(buf, data,
size);
373 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB,
TRUE, 8, w, h, w * 4,
374 (GdkPixbufDestroyNotify)free, NULL);
375 cairo_surface_destroy(cst);
383 g_return_val_if_fail(w > 0 && h > 0, NULL);
387 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
388 cairo_t *cr = cairo_create(cst);
395 cairo_set_source_rgba(cr,
r,
g, b, a);
396 cairo_arc(cr, 0.5 * w, 0.333 * h, 0.333 * h - 2, 150.0 * (
M_PI / 180.0), 30.0 * (
M_PI / 180.0));
397 cairo_line_to(cr, 0.5 * w, h - 2);
398 cairo_close_path(cr);
399 cairo_fill_preserve(cr);
405 cairo_set_source_rgba(cr,
r,
g, b, a);
414 cairo_set_source_rgba(cr,
r,
g, b, a);
415 cairo_arc(cr, 0.5 * w, 0.333 * h, 0.17 * h, 0, 2.0 *
M_PI);
419 uint8_t *data = cairo_image_surface_get_data(cst);
421 size_t size = (size_t)w * h * 4;
422 uint8_t *buf = (uint8_t *)malloc(
size);
423 memcpy(buf, data,
size);
424 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB,
TRUE, 8, w, h, w * 4,
425 (GdkPixbufDestroyNotify)free, NULL);
426 cairo_surface_destroy(cst);
430static GdkPixbuf *
_draw_ellipse(
const float dlongitude,
const float dlatitude,
437 const gboolean landscape = dlon > dlat ?
TRUE :
FALSE;
438 const float ratio = dlon > dlat ? (float)dlat / (
float)dlon : (float)dlon / (
float)dlat;
443 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
444 cairo_t *cr = cairo_create(cst);
446 cairo_set_line_width(cr,
d);
452 cairo_matrix_t save_matrix;
453 cairo_get_matrix(cr, &save_matrix);
454 cairo_translate(cr, 0.5 * w, 0.5 * h);
455 cairo_scale(cr, landscape ? 1 : ratio, landscape ? ratio : 1);
456 cairo_translate(cr, -0.5 * w, -0.5 * h);
459 cairo_arc(cr, 0.5 * w, 0.5 * h, 0.5 * h -
d -
d, 0, 2.0 *
M_PI);
461 cairo_set_matrix(cr, &save_matrix);
463 cairo_move_to(cr, 0.5 * w +
d, 0.5 * h - cross);
464 cairo_line_to(cr, 0.5 * w +
d, 0.5 * h + cross);
465 cairo_move_to(cr, 0.5 * w - cross, 0.5 * h -
d);
466 cairo_line_to(cr, 0.5 * w + cross, 0.5 * h -
d);
469 cairo_get_matrix(cr, &save_matrix);
470 cairo_translate(cr, 0.5 * w, 0.5 * h);
471 cairo_scale(cr, landscape ? 1 : ratio, landscape ? ratio : 1);
472 cairo_translate(cr, -0.5 * w, -0.5 * h);
475 cairo_arc(cr, 0.5 * w, 0.5 * h, 0.5 * h -
d, 0, 2.0 *
M_PI);
477 cairo_set_matrix(cr, &save_matrix);
480 cairo_move_to(cr, 0.5 * w, 0.5 * h - cross);
481 cairo_line_to(cr, 0.5 * w, 0.5 * h + cross);
482 cairo_move_to(cr, 0.5 * w - cross, 0.5 * h );
483 cairo_line_to(cr, 0.5 * w + cross, 0.5 * h );
487 uint8_t *data = cairo_image_surface_get_data(cst);
489 size_t size = (size_t)w * h * 4;
490 uint8_t *buf = (uint8_t *)malloc(
size);
491 memcpy(buf, data,
size);
492 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB,
TRUE, 8, w, h, w * 4,
493 (GdkPixbufDestroyNotify)free, NULL);
494 cairo_surface_destroy(cst);
509 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
510 cairo_t *cr = cairo_create(cst);
512 cairo_set_line_width(cr,
d);
514 cairo_move_to(cr,
d +
d,
d +
d);
515 cairo_line_to(cr, w -
d -
d,
d +
d);
516 cairo_line_to(cr, w -
d -
d, h -
d -
d);
517 cairo_line_to(cr,
d +
d, h -
d -
d);
518 cairo_line_to(cr,
d +
d,
d +
d);
519 cairo_move_to(cr, 0.5 * w +
d, 0.5 * h - cross);
520 cairo_line_to(cr, 0.5 * w +
d, 0.5 * h + cross);
521 cairo_move_to(cr, 0.5 * w - cross, 0.5 * h -
d);
522 cairo_line_to(cr, 0.5 * w + cross, 0.5 * h -
d);
530 cairo_move_to(cr,
d,
d);
531 cairo_line_to(cr, w -
d,
d);
532 cairo_line_to(cr, w -
d, h -
d);
533 cairo_line_to(cr,
d, h -
d);
534 cairo_line_to(cr,
d,
d);
535 cairo_move_to(cr, 0.5 * w, 0.5 * h - cross);
536 cairo_line_to(cr, 0.5 * w, 0.5 * h + cross);
537 cairo_move_to(cr, 0.5 * w - cross, 0.5 * h );
538 cairo_line_to(cr, 0.5 * w + cross, 0.5 * h );
542 uint8_t *data = cairo_image_surface_get_data(cst);
544 size_t size = (size_t)w * h * 4;
545 uint8_t *buf = (uint8_t *)malloc(
size);
546 memcpy(buf, data,
size);
547 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB,
TRUE, 8, w, h, w * 4,
548 (GdkPixbufDestroyNotify)free, NULL);
549 cairo_surface_destroy(cst);
563 cairo_set_source_rgb(cri, 0, 0, 0);
594 OsmGpsMapSource_t map_source
595 = OSM_GPS_MAP_SOURCE_OPENSTREETMAP;
597 if(old_map_source && old_map_source[0] !=
'\0')
600 for(
int i = 0;
i <= OSM_GPS_MAP_SOURCE_LAST;
i++)
602 const gchar *new_map_source = osm_gps_map_source_get_friendly_name(
i);
603 if(!g_strcmp0(old_map_source, new_map_source))
605 if(osm_gps_map_source_is_valid(
i)) map_source =
i;
611 dt_conf_set_string(
"plugins/map/map_source", osm_gps_map_source_get_friendly_name(map_source));
615 lib->
map = g_object_new(OSM_TYPE_GPS_MAP,
"map-source", OSM_GPS_MAP_SOURCE_NULL,
"proxy-uri",
616 g_getenv(
"http_proxy"), NULL);
618 g_object_ref(lib->
map);
620 lib->
osd = g_object_new(OSM_TYPE_GPS_MAP_OSD,
"show-scale",
TRUE,
"show-coordinates",
TRUE,
"show-dpad",
622#ifdef HAVE_OSMGPSMAP_NEWER_THAN_110
623 "show-copyright",
TRUE,
629 osm_gps_map_layer_add(OSM_GPS_MAP(lib->
map), lib->
osd);
632 gtk_drag_dest_set(GTK_WIDGET(lib->
map), GTK_DEST_DEFAULT_ALL,
640 g_signal_connect_after(G_OBJECT(lib->
map),
"button-press-event",
642 g_signal_connect_after(G_OBJECT(lib->
map),
"button-release-event",
681 g_object_unref(G_OBJECT(lib->
image_pin));
682 g_object_unref(G_OBJECT(lib->
place_pin));
683 g_object_unref(G_OBJECT(lib->
osd));
684 osm_gps_map_image_remove_all(lib->
map);
701 for(GList *other = lib->
loc.
others; other; other = g_list_next(other))
713 g_object_unref(G_OBJECT(lib->
map));
782 g_signal_emit_by_name(lib->
map,
"changed");
787 const float lon,
float *dlat_min,
float *dlon_min)
789 OsmGpsMapPoint *pt0 = osm_gps_map_point_new_degrees(
lat,
lon);
790 OsmGpsMapPoint *pt1 = osm_gps_map_point_new_degrees(0.0, 0.0);
791 gint pixel_x = 0, pixel_y = 0;
792 osm_gps_map_convert_geographic_to_screen(lib->
map, pt0, &pixel_x, &pixel_y);
793 osm_gps_map_convert_screen_to_geographic(lib->
map, pixel_x + pixels,
794 pixel_y + pixels, pt1);
795 float lat1 = 0.0, lon1 = 0.0;
796 osm_gps_map_point_get_degrees(pt1, &lat1, &lon1);
797 osm_gps_map_point_free(pt0);
798 osm_gps_map_point_free(pt1);
799 *dlat_min =
lat - lat1;
800 *dlon_min = lon1 -
lon;
806 float *dlat_min,
float *dlon_min)
809 if(*dlat_min > 0.0 && *dlon_min > 0.0)
822 const float lon0,
const float angle)
824 OsmGpsMapPoint *pt0 = osm_gps_map_point_new_degrees(lat0, lon0);
825 OsmGpsMapPoint *pt1 = osm_gps_map_point_new_degrees(lat0 + angle, lon0 + angle);
826 gint px0 = 0, py0 = 0;
827 gint px1 = 0, py1 = 0;
828 osm_gps_map_convert_geographic_to_screen(lib->
map, pt0, &px0, &py0);
829 osm_gps_map_convert_geographic_to_screen(lib->
map, pt1, &px1, &py1);
830 osm_gps_map_point_free(pt0);
831 osm_gps_map_point_free(pt1);
832 return abs(px1 - px0);
838 OsmGpsMapPoint *pt0 = osm_gps_map_point_new_degrees(lat0, lon0);
839 OsmGpsMapPoint *pt1 = osm_gps_map_point_new_degrees(lat0 + 2.0, lon0 + 2.0);
840 gint px0 = 0, py0 = 0;
841 gint px1 = 0, py1 = 0;
842 osm_gps_map_convert_geographic_to_screen(lib->
map, pt0, &px0, &py0);
843 osm_gps_map_convert_geographic_to_screen(lib->
map, pt1, &px1, &py1);
844 osm_gps_map_point_free(pt0);
845 osm_gps_map_point_free(pt1);
848 ratio = (float)abs(py1 - py0) / (float)(px1 - px0);
858 GdkPixbuf *draw = NULL;
862 if(pixel_lon > pixel_lat)
863 pixel_lat = pixel_lon;
865 pixel_lon = pixel_lat;
877 for(GList *other = lib->
loc.
others; other; other = g_list_next(other))
888 for(GList *other = others; other; other = g_list_next(other))
903 OsmGpsMapImage *location = NULL;
906 location = osm_gps_map_image_add_with_alignment(lib->
map, ld->
data.
lat, ld->
data.
lon, draw, 0.5, 0.5);
907 g_object_unref(draw);
925 return (OsmGpsMapImage *)location;
936 osm_gps_map_polygon_remove(lib->
map, (OsmGpsMapPolygon *)ld->
location);
988 for(GList *other = lib->
loc.
others; other; other = g_list_next(other))
998 for(GList *other = others; other; other = g_list_next(other))
1044 const int group_count,
const gboolean group_same_loc,
1045 const uint32_t frame,
const int thumbnail,
dt_view_t *self)
1049 GdkPixbuf *thumb = NULL, *source = NULL, *count = NULL;
1060 const int raw_w = cairo_image_surface_get_width(entry->
surface);
1061 const int raw_h = cairo_image_surface_get_height(entry->
surface);
1062 double sx = 1.0, sy = 1.0;
1063 cairo_surface_get_device_scale(entry->
surface, &sx, &sy);
1068 const int w =
MAX(1, (
int)round((
double)raw_w / sx));
1069 const int h =
MAX(1, (
int)round((
double)raw_h / sy));
1070 if(raw_w == w && raw_h == h)
1072 source = gdk_pixbuf_get_from_surface(entry->
surface, 0, 0, w, h);
1077 cairo_surface_t *logical = cairo_image_surface_create(CAIRO_FORMAT_RGB24, w, h);
1078 cairo_t *cr = cairo_create(logical);
1079 cairo_set_source_surface(cr, entry->
surface, 0, 0);
1080 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST);
1083 source = gdk_pixbuf_get_from_surface(logical, 0, 0, w, h);
1084 cairo_surface_destroy(logical);
1088 thumb = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
TRUE, 8, w + 2 * _thumb_border,
1089 h + 2 * _thumb_border + _pin_size);
1091 gdk_pixbuf_fill(thumb, frame);
1092 gdk_pixbuf_copy_area(source, 0, 0, w, h, thumb, _thumb_border, _thumb_border);
1093 gdk_pixbuf_copy_area(lib->
image_pin, 0, 0, w + 2 * _thumb_border,
1094 _pin_size, thumb, 0, h + 2 * _thumb_border);
1097 double count_height, count_width;
1099 gdk_pixbuf_copy_area(count, 0, 0, count_width, count_height, thumb,
1100 _thumb_border, h - count_height + _thumb_border);
1107 double count_height, count_width;
1109 &count_width, &count_height);
1110 if(!count)
goto map_changed_failure;
1111 const int w = count_width + 2 * _thumb_border;
1112 const int h = count_height + 2 * _thumb_border + _pin_size;
1113 thumb = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
TRUE, 8, w, h);
1115 gdk_pixbuf_fill(thumb, frame);
1116 gdk_pixbuf_copy_area(count, 0, 0, count_width, count_height, thumb,
1117 _thumb_border, _thumb_border);
1118 gdk_pixbuf_copy_area(lib->
image_pin, 0, 0, w, _pin_size, thumb,
1119 0, count_height + 2 * _thumb_border);
1124 if(source) g_object_unref(source);
1125 if(count) g_object_unref(count);
1130 const gboolean group_same_loc,
const uint32_t frame,
1134 GdkPixbuf *thumb = NULL, *source = NULL, *count = NULL;
1135 cairo_surface_t *surface = NULL;
1145 const int raw_w = cairo_image_surface_get_width(surface);
1146 const int raw_h = cairo_image_surface_get_height(surface);
1147 double sx = 1.0, sy = 1.0;
1148 cairo_surface_get_device_scale(surface, &sx, &sy);
1149 const int w =
MAX(1, (
int)round((
double)raw_w / sx));
1150 const int h =
MAX(1, (
int)round((
double)raw_h / sy));
1151 if(raw_w == w && raw_h == h)
1153 source = gdk_pixbuf_get_from_surface(surface, 0, 0, w, h);
1158 cairo_surface_t *logical = cairo_image_surface_create(CAIRO_FORMAT_RGB24, w, h);
1159 cairo_t *cr = cairo_create(logical);
1160 cairo_set_source_surface(cr, surface, 0, 0);
1161 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST);
1164 source = gdk_pixbuf_get_from_surface(logical, 0, 0, w, h);
1165 cairo_surface_destroy(logical);
1169 thumb = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
TRUE, 8, w + 2 * _thumb_border,
1170 h + 2 * _thumb_border + _pin_size);
1172 gdk_pixbuf_fill(thumb, frame);
1173 gdk_pixbuf_copy_area(source, 0, 0, w, h, thumb, _thumb_border, _thumb_border);
1174 gdk_pixbuf_copy_area(lib->
image_pin, 0, 0, w + 2 * _thumb_border,
1175 _pin_size, thumb, 0, h + 2 * _thumb_border);
1178 double count_height, count_width;
1180 gdk_pixbuf_copy_area(count, 0, 0, count_width, count_height, thumb,
1181 _thumb_border, h - count_height + _thumb_border);
1188 double count_height, count_width;
1190 if(!count)
goto map_changed_failure;
1191 const int w = count_width + 2 * _thumb_border;
1192 const int h = count_height + 2 * _thumb_border + _pin_size;
1193 thumb = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
TRUE, 8, w, h);
1195 gdk_pixbuf_fill(thumb, frame);
1196 gdk_pixbuf_copy_area(count, 0, 0, count_width, count_height, thumb, _thumb_border, _thumb_border);
1197 gdk_pixbuf_copy_area(lib->
image_pin, 0, 0, w, _pin_size, thumb, 0, count_height + 2 * _thumb_border);
1203 if(surface) cairo_surface_destroy(surface);
1204 if(source) g_object_unref(source);
1205 if(count) g_object_unref(count);
1212 gboolean needs_redraw =
FALSE;
1215 osm_gps_map_image_remove(lib->
map, entry->
image);
1216 entry->
image = NULL;
1227 entry->
image = osm_gps_map_image_add_with_alignment(lib->
map, entry->
latitude,
1230 g_object_unref(thumb);
1233 needs_redraw =
TRUE;
1235 return needs_redraw;
1244 gboolean needs_redraw =
FALSE;
1246 for(GSList *iter = lib->
images; iter; iter = g_slist_next(iter))
1256 return needs_redraw;
1261 OsmGpsMapPoint bb[2];
1262 osm_gps_map_get_bbox(lib->
map, &bb[0], &bb[1]);
1265 osm_gps_map_point_get_degrees(&bb[0], &box.
lat1, &box.
lon1);
1266 osm_gps_map_point_get_degrees(&bb[1], &box.
lat2, &box.
lon2);
1267 box.
lat1 = CLAMP(box.
lat1, -90.0, 90.0);
1268 box.
lat2 = CLAMP(box.
lat2, -90.0, 90.0);
1269 box.
lon1 = CLAMP(box.
lon1, -180.0, 180.0);
1270 box.
lon2 = CLAMP(box.
lon2, -180.0, 180.0);
1278 gboolean needs_redraw =
FALSE;
1290 for(GSList *iter = lib->
images; iter; iter = g_slist_next(iter))
1294 osm_gps_map_image_remove(lib->
map, image->
image);
1309 float center_lat, center_lon;
1310 g_object_get(G_OBJECT(lib->
map),
"zoom", &zoom,
"latitude", ¢er_lat,
"longitude", ¢er_lon, NULL);
1331 for(
i = 0;
p &&
i < img_count;
i++)
1342 const float epsilon_factor =
dt_conf_get_int(
"plugins/map/epsilon_factor");
1343 const int min_images =
dt_conf_get_int(
"plugins/map/min_images_per_group");
1349 double epsilon =
thumb_size * (((
unsigned int)(156412000 >> zoom))
1350 * epsilon_factor * 0.01 * 0.000001 /
R);
1354 _dbscan(
p, img_count, epsilon, min_images);
1360 for(
i = 0;
i< img_count;
i++)
1367 entry->
group =
p[
i].cluster_id;
1374 GINT_TO_POINTER(entry->
imgid))
1378 else if(
p[
i].cluster_id > group)
1380 group =
p[
i].cluster_id;
1384 entry->
group =
p[
i].cluster_id;
1387 GINT_TO_POINTER(
p[
i].imgid)))
1390 for(
int j = 0; j < img_count; j++)
1392 if(
p[j].cluster_id == group)
1403 if(g_list_find((GList *)sel_imgs, GINT_TO_POINTER(
p[j].imgid)))
1413 g_list_free(sel_imgs);
1470 for(
const GSList *iter = lib->
images; iter; iter = g_slist_next(iter))
1473 OsmGpsMapImage *image = entry->
image;
1476 OsmGpsMapPoint *pt = (OsmGpsMapPoint *)osm_gps_map_image_get_point(image);
1477 gint img_x = 0, img_y = 0;
1478 osm_gps_map_convert_geographic_to_screen(lib->
map, pt, &img_x, &img_y);
1480 if(
x >= img_x && x <= img_x + entry->
width && y <= img_y && y >= img_y - entry->
height)
1490 int *offset_x,
int *offset_y,
const gboolean first_on)
1497 for(
const GSList *iter = lib->
images; iter; iter = g_slist_next(iter))
1500 OsmGpsMapImage *image = entry->
image;
1503 OsmGpsMapPoint *pt = (OsmGpsMapPoint *)osm_gps_map_image_get_point(image);
1504 gint img_x = 0, img_y = 0;
1505 osm_gps_map_convert_geographic_to_screen(lib->
map, pt, &img_x, &img_y);
1507 if(
x >= img_x && x <= img_x + entry->
width && y <= img_y && y >= img_y - entry->
height)
1509 imgid = entry->
imgid;
1510 *offset_x = (int)
x - img_x;
1523 if(
p[
i].cluster_id == entry->
group &&
p[
i].imgid != imgid)
1525 imgs = g_list_prepend(imgs, GINT_TO_POINTER(
p[
i].imgid));
1536 imgs = g_list_prepend(imgs, GINT_TO_POINTER(imgid));
1543 return entry->
imgid == GPOINTER_TO_INT(b) ? 0 : 1;
1555 osm_gps_map_image_remove(lib->
map, entry->
image);
1556 entry->
image = NULL;
1567 if(
p[
i].imgid == GPOINTER_TO_INT(entry->
imgid))
1573 if(
p[j].cluster_id == entry->
group)
1581 for(
int j = 0; j <
i; j++)
1583 if(
p[j].cluster_id == entry->
group)
1593 for(
int j =
i - 1; j >= 0; j--)
1595 if(
p[j].cluster_id == entry->
group)
1605 if(
p[j].cluster_id == entry->
group)
1616 if(index == -1)
return FALSE;
1617 entry->
imgid =
p[index].imgid;
1620 osm_gps_map_image_remove(lib->
map, entry->
image);
1621 entry->
image = NULL;
1629 const int32_t imgid,
const int count)
1637 GtkWidget *image = gtk_image_new_from_pixbuf(thumb);
1639 gtk_widget_show(image);
1642 g_object_unref(thumb);
1650 OsmGpsMapPoint *
p = osm_gps_map_point_new_degrees(0.0, 0.0);
1651 osm_gps_map_convert_screen_to_geographic(lib->
map,
x, y,
p);
1653 osm_gps_map_point_get_degrees(
p, &
lat, &
lon);
1654 osm_gps_map_point_free(
p);
1662 OsmGpsMapPoint *
p = osm_gps_map_get_event_location(lib->
map, (GdkEventButton *)e);
1664 osm_gps_map_point_get_degrees(
p, &
lat, &
lon);
1675 GdkDragContext *context =
1676 gtk_drag_begin_with_coordinates(GTK_WIDGET(lib->
map), targets,
1678 (GdkEvent *)e, -1, -1);
1685 GtkWidget *image = gtk_image_new_from_pixbuf(location);
1686 gtk_widget_set_name(image,
"map-drag-icon");
1687 gtk_widget_show(image);
1688 gtk_drag_set_icon_widget(context, image,
1691 g_object_unref(location);
1693 gtk_target_list_unref(targets);
1702 for(
const GSList *iter = lib->
images; iter; iter = g_slist_next(iter))
1708 if(entry->
imgid == GPOINTER_TO_INT(sel_img->data))
1712 osm_gps_map_image_remove(lib->
map, entry->
image);
1713 entry->
image = NULL;
1726 GdkDragContext *context = gtk_drag_begin_with_coordinates(GTK_WIDGET(lib->
map), targets,
1728 (GdkEvent *)e, -1, -1);
1731 gtk_target_list_unref(targets);
1767 g_object_get(G_OBJECT(lib->
map),
"zoom", &zoom,
"max-zoom", &max_zoom, NULL);
1769 OsmGpsMapPoint bb[2];
1770 osm_gps_map_get_bbox(lib->
map, &bb[0], &bb[1]);
1771 gint x0, x1, y0, y1;
1772 osm_gps_map_convert_geographic_to_screen(lib->
map, &bb[0], &x0, &y0);
1773 osm_gps_map_convert_geographic_to_screen(lib->
map, &bb[1], &x1, &y1);
1776 if(direction == GDK_SCROLL_UP && zoom < max_zoom)
1779 nx = (x0 + x1 + 2 *
x) / 4;
1780 ny = (y0 + y1 + 2 * y) / 4;
1782 else if(direction == GDK_SCROLL_DOWN && zoom > 0)
1790 OsmGpsMapPoint *pt = osm_gps_map_point_new_degrees(0.0, 0.0);
1791 osm_gps_map_convert_screen_to_geographic(lib->
map, nx, ny, pt);
1793 osm_gps_map_point_get_degrees(pt, &nlat, &nlon);
1794 osm_gps_map_point_free(pt);
1795 osm_gps_map_set_center_and_zoom(lib->
map, nlat, nlon, zoom);
1811 OsmGpsMapPoint *
p = osm_gps_map_get_event_location(lib->
map, (GdkEventButton *)event);
1813 osm_gps_map_point_get_degrees(
p, &
lat, &
lon);
1820 if(event->direction == GDK_SCROLL_DOWN)
1827 if(event->direction == GDK_SCROLL_DOWN)
1834 if(event->direction == GDK_SCROLL_DOWN)
1879 OsmGpsMapPoint *
p = osm_gps_map_get_event_location(lib->
map, e);
1881 osm_gps_map_point_get_degrees(
p, &
lat, &
lon);
1897 OsmGpsMapPoint *
p = osm_gps_map_get_event_location(lib->
map, e);
1899 osm_gps_map_point_get_degrees(
p, &
lat, &
lon);
1900 for(GList *other = lib->
loc.
others; other; other = g_list_next(other))
1926 if(e->type == GDK_BUTTON_PRESS)
1940 if(e->type == GDK_2BUTTON_PRESS)
1952 float longitude, latitude;
1953 OsmGpsMapPoint *pt = osm_gps_map_point_new_degrees(0.0, 0.0);
1954 osm_gps_map_convert_screen_to_geographic(lib->
map, e->x, e->y, pt);
1955 osm_gps_map_point_get_degrees(pt, &latitude, &longitude);
1956 osm_gps_map_point_free(pt);
1958 g_object_get(G_OBJECT(lib->
map),
"zoom", &zoom,
"max-zoom", &max_zoom, NULL);
1959 zoom =
MIN(zoom + 1, max_zoom);
1982 gboolean done =
FALSE;
1990 double max_longitude = -INFINITY;
1991 double max_latitude = -INFINITY;
1992 double min_longitude = INFINITY;
1993 double min_latitude = INFINITY;
1996 for(
const GList *iter = active; iter; iter = g_list_next((GList *)iter))
1998 const int32_t imgid = GPOINTER_TO_INT(iter->data);
2003 max_longitude = fmax(max_longitude, geoloc.
longitude);
2004 min_longitude = fmin(min_longitude, geoloc.
longitude);
2005 max_latitude = fmax(max_latitude, geoloc.
latitude);
2006 min_latitude = fmin(min_latitude, geoloc.
latitude);
2012 max_longitude = CLAMP(max_longitude, -180, 180);
2013 min_longitude = CLAMP(min_longitude, -180, 180);
2014 max_latitude = CLAMP(max_latitude, -90, 90);
2015 min_latitude = CLAMP(min_latitude, -90, 90);
2032 lon = CLAMP(
lon, -180, 180);
2034 lat = CLAMP(
lat, -90, 90);
2036 osm_gps_map_set_center_and_zoom(lib->
map,
lat,
lon, zoom);
2070 if(!gtk_widget_get_parent(GTK_WIDGET(lib->
map)))
2074 gtk_widget_show_all(GTK_WIDGET(lib->
map));
2127 gtk_widget_hide(GTK_WIDGET(lib->
map));
2172 osm_gps_map_set_center_and_zoom(lib->
map,
lat,
lon, zoom);
2186 osm_gps_map_layer_add(OSM_GPS_MAP(lib->
map), lib->
osd);
2188 osm_gps_map_layer_remove(OSM_GPS_MAP(lib->
map), lib->
osd);
2190 g_signal_emit_by_name(lib->
map,
"changed");
2200 g_value_init(&
value, G_TYPE_INT);
2201 g_value_set_int(&
value, map_source);
2202 g_object_set_property(G_OBJECT(lib->
map),
"map-source", &
value);
2203 g_value_unset(&
value);
2213 dt_conf_set_string(
"plugins/map/map_source", osm_gps_map_source_get_friendly_name(map_source));
2221 return osm_gps_map_image_add_with_alignment(lib->
map,
p->lat,
p->lon, lib->
place_pin, 0.5, 1);
2227 return osm_gps_map_image_remove(lib->
map, pin);
2232 float lat,
lon, prev_lat, prev_lon;
2234 osm_gps_map_point_get_degrees(prev_point, &prev_lat, &prev_lon);
2236 gboolean short_distance =
TRUE;
2240 short_distance =
FALSE;
2248 osm_gps_map_track_add_point(track,
point);
2253 OsmGpsMapPoint *ith_point;
2254 double f, ith_lat, ith_lon;
2256 gboolean first_time =
TRUE;
2257 for(
int i = 1;
i <= n_segments;
i ++)
2265 &ith_lat, &ith_lon);
2267 ith_point = osm_gps_map_point_new_degrees (ith_lat, ith_lon);
2268 osm_gps_map_track_add_point(track, ith_point);
2269 osm_gps_map_point_free(ith_point);
2275#ifdef HAVE_OSMGPSMAP_110_OR_NEWER
2276static OsmGpsMapPolygon *_view_map_add_polygon(
const dt_view_t *
view, GList *points)
2279 OsmGpsMapPolygon *poly = osm_gps_map_polygon_new();
2280 OsmGpsMapTrack* track = osm_gps_map_track_new();
2287 float prev_lat = 0.0;
2288 float prev_lon = 0.0;
2289 for(GList *iter = points; iter; iter = g_list_next(iter))
2292 if((fabs(
p->lat - prev_lat) > dlat) || (fabs(
p->lon - prev_lon) > dlon))
2294 OsmGpsMapPoint*
point = osm_gps_map_point_new_degrees(
p->lat,
p->lon);
2295 osm_gps_map_track_add_point(track,
point);
2301 g_object_set(poly,
"track", track, (gchar *)0);
2302 g_object_set(poly,
"editable",
FALSE, (gchar *)0);
2303 g_object_set(poly,
"shaded",
FALSE, (gchar *)0);
2305 osm_gps_map_polygon_add(lib->
map, poly);
2312 OsmGpsMapPolygon *poly = osm_gps_map_polygon_new();
2313 OsmGpsMapTrack* track = osm_gps_map_track_new();
2314 g_object_set(track,
"line-width" , 2.0,
"alpha", 0.9, (gchar *)0);
2320 g_object_get(G_OBJECT(lib->
map),
"zoom", &zoom, NULL);
2322 const int mod2 = zoom + 1;
2335 float prev_lat = 0.0;
2336 float prev_lon = 0.0;
2337 for(GList *iter = ld->
data.
polygons; iter; iter = g_list_next(iter),
i++)
2343 if((fabs(
p->lat - prev_lat) > dlat) || (fabs(
p->lon - prev_lon) > dlon))
2345 OsmGpsMapPoint*
point = osm_gps_map_point_new_degrees(
p->lat,
p->lon);
2346 osm_gps_map_track_add_point(track,
point);
2351 else if(!(
i % mod2))
2353 OsmGpsMapPoint*
point = osm_gps_map_point_new_degrees(
p->lat,
p->lon);
2354 osm_gps_map_track_add_point(track,
point);
2358 g_object_set(poly,
"track", track, (gchar *)0);
2359 g_object_set(poly,
"editable",
FALSE, (gchar *)0);
2360 g_object_set(poly,
"shaded",
FALSE, (gchar *)0);
2362 osm_gps_map_polygon_add(lib->
map, poly);
2370 return osm_gps_map_polygon_remove(lib->
map, polygon);
2378 OsmGpsMapTrack* track = osm_gps_map_track_new();
2380 OsmGpsMapPoint* prev_point;
2381 gboolean first_point =
TRUE;
2382 for(GList *iter = points; iter; iter = g_list_next(iter))
2385 OsmGpsMapPoint*
point = osm_gps_map_point_new_degrees(
p->lat,
p->lon);
2388 osm_gps_map_track_add_point(track,
point);
2393 osm_gps_map_point_free(prev_point);
2395 prev_point = &(*point);
2396 if(!g_list_next(iter))
2397 osm_gps_map_point_free(prev_point);
2398 first_point =
FALSE;
2401 g_object_set(track,
"editable",
FALSE, (gchar *)0);
2403 osm_gps_map_track_add(lib->
map, track);
2411 return osm_gps_map_track_remove(lib->
map, track);
2417 struct {int32_t imgid;
float latitude;
float longitude;
int count;} *
p;
2421 OsmGpsMapImage *image = NULL;
2424 image = osm_gps_map_image_add_with_alignment(lib->
map,
p->latitude,
p->longitude, thumb, 0, 1);
2425 g_object_unref(thumb);
2436#ifdef HAVE_OSMGPSMAP_110_OR_NEWER
2440 default:
return NULL;
2453#ifdef HAVE_OSMGPSMAP_110_OR_NEWER
2457 default:
return FALSE;
2465 loc_main.
id = locid;
2468 if(
g->delta1 != 0.0 &&
g->delta2 != 0.0)
2472 const double max_lon = CLAMP(
g->lon +
g->delta1, -180, 180);
2473 const double min_lon = CLAMP(
g->lon -
g->delta1, -180, 180);
2474 const double max_lat = CLAMP(
g->lat +
g->delta2, -90, 90);
2475 const double min_lat = CLAMP(
g->lat -
g->delta2, -90, 90);
2476 if(max_lon > min_lon && max_lat > min_lat)
2504 g_object_get(G_OBJECT(lib->
map),
"latitude", &
lat,
"longitude", &
lon, NULL);
2584 g_signal_emit_by_name(lib->
map,
"changed");
2610 g_object_get(G_OBJECT(lib->
map),
"zoom", &zoom, NULL);
2627 int count = bounds.
count;
2631 max_longitude = CLAMP(max_longitude, -180, 180);
2632 min_longitude = CLAMP(min_longitude, -180, 180);
2633 max_latitude = CLAMP(max_latitude, -90, 90);
2634 min_latitude = CLAMP(min_latitude, -90, 90);
2639 max_longitude = CLAMP(max_longitude + 1.0 * lib->
thumb_lon_angle, -180, 180);
2640 min_longitude = CLAMP(min_longitude - 0.2 * lib->
thumb_lon_angle, -180, 180);
2641 max_latitude = CLAMP(max_latitude + 1.0 * lib->
thumb_lat_angle, -90, 90);
2642 min_latitude = CLAMP(min_latitude - 0.2 * lib->
thumb_lat_angle, -90, 90);
2668 GtkSelectionData *selection_data, guint target_type, guint time,
2673 gboolean success =
FALSE;
2676 const int imgs_nb = gtk_selection_data_get_length(selection_data) /
sizeof(uint32_t);
2679 uint32_t *imgt = (uint32_t *)gtk_selection_data_get_data(selection_data);
2680 if(imgs_nb == 1 && imgt[0] == -1)
2683 OsmGpsMapPoint *pt = osm_gps_map_point_new_degrees(0.0, 0.0);
2684 osm_gps_map_convert_screen_to_geographic(lib->
map,
x, y, pt);
2686 osm_gps_map_point_get_degrees(pt, &
lat, &
lon);
2692 osm_gps_map_point_free(pt);
2701 for(
int i = 0;
i < imgs_nb;
i++)
2703 imgs = g_list_prepend(imgs, GINT_TO_POINTER(imgt[
i]));
2705 float longitude, latitude;
2706 OsmGpsMapPoint *pt = osm_gps_map_point_new_degrees(0.0, 0.0);
2709 osm_gps_map_point_get_degrees(pt, &latitude, &longitude);
2710 osm_gps_map_point_free(pt);
2718 g_signal_emit_by_name(lib->
map,
"changed");
2723 gtk_drag_finish(context, success,
FALSE, time);
2727 GtkSelectionData *selection_data, guint target_type, guint time,
2742 uint32_t *imgs = malloc(
sizeof(uint32_t) * imgs_nb);
2746 imgs[
i++] = GPOINTER_TO_INT(l->data);
2748 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
2749 _DWORD, (guchar *)imgs, imgs_nb *
sizeof(uint32_t));
2756 uint32_t *imgs = malloc(
sizeof(uint32_t));
2758 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
2759 _DWORD, (guchar *)imgs,
sizeof(uint32_t));
2771 gboolean from_cache =
TRUE;
2773 gchar *uri = g_strdup_printf(
"file://%s", pathname);
2774 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
_BYTE,
2775 (guchar *)uri, strlen(uri));
2787 g_signal_emit_by_name(lib->
map,
"changed");
2794 gboolean prefs_changed =
FALSE;
2799 gboolean filter_images_drawn =
dt_conf_get_bool(
"plugins/map/filter_images_drawn");
2806 return prefs_changed;
2812typedef struct epsilon_neighbours_t
2814 unsigned int num_members;
2815 unsigned int index[];
2816} epsilon_neighbours_t;
2818typedef struct dt_dbscan_t
2821 unsigned int num_points;
2823 unsigned int minpts;
2824 epsilon_neighbours_t *seeds;
2825 epsilon_neighbours_t *spreads;
2827 unsigned int cluster_id;
2830static dt_dbscan_t db;
2832static void _get_epsilon_neighbours(epsilon_neighbours_t *en,
unsigned int index)
2837 for(
int i = index;
i < db.num_points; ++
i)
2839 if(
i == index || db.points[
i].cluster_id >= 0)
2841 if((db.points[
i].x - db.points[index].x) > db.epsilon)
2843 if(fabs(db.points[
i].y - db.points[index].y) > db.epsilon)
2847 en->index[en->num_members] =
i;
2852 for(
int i = index;
i >= 0; --
i)
2854 if(
i == (
int)index || db.points[
i].cluster_id >= 0)
2856 if((db.points[index].x - db.points[
i].x) > db.epsilon)
2858 if(fabs(db.points[index].y - db.points[
i].y) > db.epsilon)
2862 en->index[en->num_members] =
i;
2868static void _dbscan_spread(
unsigned int index)
2870 db.spreads->num_members = 0;
2871 _get_epsilon_neighbours(db.spreads, index);
2873 for(
unsigned int i = 0;
i < db.spreads->num_members;
i++)
2878 db.seeds->index[db.seeds->num_members] = db.spreads->index[
i];
2879 db.seeds->num_members++;
2880 d->cluster_id = db.cluster_id;
2885static int _dbscan_expand(
unsigned int index)
2888 db.seeds->num_members = 0;
2889 _get_epsilon_neighbours(db.seeds, index);
2891 if (db.seeds->num_members < db.minpts)
2892 db.points[index].cluster_id =
NOISE;
2895 db.points[index].cluster_id = db.cluster_id;
2896 for(
int i = 0;
i < db.seeds->num_members;
i++)
2898 db.points[db.seeds->index[
i]].cluster_id = db.cluster_id;
2901 for(
int i = 0;
i < db.seeds->num_members;
i++)
2903 _dbscan_spread(db.seeds->index[
i]);
2907 return return_value;
2911 double epsilon,
unsigned int minpts)
2914 db.num_points = num_points;
2915 db.epsilon = epsilon;
2917 db.minpts = minpts > 1 ? minpts - 1 : minpts;
2919 db.seeds = (epsilon_neighbours_t *)malloc(
sizeof(db.seeds->num_members)
2920 + num_points *
sizeof(db.seeds->index[0]));
2921 db.spreads = (epsilon_neighbours_t *)malloc(
sizeof(db.spreads->num_members)
2922 + num_points *
sizeof(db.spreads->index[0]));
2924 if(db.seeds && db.spreads)
2926 for(
unsigned int i = 0;
i < db.num_points; ++
i)
void dt_accels_connect_accels(dt_accels_t *accels)
Actually enable accelerators after having loaded user config.
void dt_accels_connect_active_group(dt_accels_t *accels, const gchar *group)
Connect the contextual active accels group to the window. Views can declare their own set of contextu...
void dt_accels_disconnect_active_group(dt_accels_t *accels)
Disconnect the contextual active accels group from the window.
Handle default and user-set shortcuts (accelerators)
GList * dt_act_on_get_images()
struct dt_accels_t * dt_gui_get_accels(void)
struct dt_ui_t * dt_gui_get_ui(void)
dt_collection_properties_t
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
int dt_conf_get_bool(const char *name)
void dt_conf_set_float(const char *name, float val)
float dt_conf_get_float(const char *name)
Float for name, clamped to its declared bounds.
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
Integer for name, clamped to the bounds declared in the XML.
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
Borrow the stored string for name without copying it.
void dt_image_get_location(const int32_t imgid, dt_image_geoloc_t *geoloc)
void dt_image_set_locations(const GList *imgs, const dt_image_geoloc_t *geoloc, const gboolean undo_on)
void dt_image_full_path(const int32_t imgid, char *pathname, size_t pathname_len, gboolean *from_cache, const char *calling_func)
Get the full path of an image out of the database.
void dt_ctl_switch_mode_to(const char *mode)
void dt_toast_log(const char *msg,...)
void dt_control_set_mouse_over_id(int32_t value)
void dt_control_set_keyboard_over_id(int32_t value)
struct dt_view_manager_t * dt_view_manager_get_global(void)
struct dt_gui_gtk_t * dt_gui_get_global(void)
gboolean enabled
–doc was passed on the command line
GtkWidget * view
the tree view
static const GtkTargetEntry target_list_all[]
static const GtkTargetEntry target_list_internal[]
static const guint n_targets_internal
static const guint n_targets_all
static void dt_draw_cairo_to_gdk_pixbuf(uint8_t *data, unsigned int width, unsigned int height)
void dt_gpx_geodesic_intermediate_point(const double lat1, const double lon1, const double lat2, const double lon2, const double delta, const gboolean first_time, double f, double *lat, double *lon)
void dt_gpx_geodesic_distance(double lat1, double lon1, double lat2, double lon2, double *d, double *delta)
#define DT_MINIMUM_DISTANCE_FOR_GEODESIC
#define DT_MINIMUM_ANGULAR_DELTA_FOR_GEODESIC
gboolean dt_image_repository_get_collected_geo_bounds(dt_image_geo_bounds_t *bounds)
Bounding box of every collected image carrying coordinates.
dt_image_geo_point_t * dt_image_repository_get_collected_geo_points(const double lon1, const double lon2, const double lat1, const double lat2, int *count)
Collected images inside the box, ordered by longitude ascending.
Reading and writing one dt_image_t to and from the library database. The SQL half of what used to be ...
_lib_location_type_t type
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static GObject * _view_map_add_marker(const dt_view_t *view, dt_geo_map_display_t type, GList *points)
void init(dt_view_t *self)
static void _view_map_filmstrip_drag_begin_callback(gpointer instance, int32_t imgid, gpointer user_data)
static void _dbscan(dt_geo_position_t *points, unsigned int num_points, double epsilon, unsigned int minpts)
static gboolean _display_next_image(dt_view_t *self, dt_map_image_t *entry, const gboolean next)
static void _view_map_check_preference_changed(gpointer instance, gpointer user_data)
static GdkPixbuf * _draw_image(dt_map_image_t *entry, int *width, int *height, const int group_count, const gboolean group_same_loc, const uint32_t frame, const int thumbnail, dt_view_t *self)
static gboolean _view_map_dnd_failed_callback(GtkWidget *widget, GdkDragContext *drag_context, GtkDragResult result, dt_view_t *self)
static void _view_map_get_bounding_box(dt_map_t *lib, dt_map_box_t *bbox)
GList * _others_location(GList *others, const int locid)
static const uint32_t pin_outer_color
static void _view_map_center_on_image(dt_view_t *self, const int32_t imgid)
static void _view_map_show_osd(const dt_view_t *view)
void leave(dt_view_t *self)
static void _view_map_collection_changed(gpointer instance, dt_collection_change_t query_change, dt_collection_properties_t changed_property, gpointer imgs, int next, gpointer user_data)
static void _view_map_set_map_source(const dt_view_t *view, OsmGpsMapSource_t map_source)
static GdkPixbuf * _draw_ellipse(const float dlongitude, const float dlatitude, const gboolean main)
static gboolean _view_map_changed_callback_wait(gpointer user_data)
static void _view_map_add_location(const dt_view_t *view, dt_map_location_data_t *g, const guint locid)
dt_location_draw_t * _others_location_draw(dt_map_t *lib, const int locid)
static const uint32_t thumb_frame_color
static gboolean _view_map_draw_image(dt_map_image_t *entry, const int thumbnail, dt_view_t *self)
static void _view_map_delete_other_location(dt_map_t *lib, GList *other)
static void _view_map_draw_other_locations(dt_map_t *lib, dt_map_box_t *bbox)
void cleanup(dt_view_t *self)
static gboolean _view_map_remove_marker(const dt_view_t *view, dt_geo_map_display_t type, GObject *marker)
static int latlon2zoom(int pix_height, int pix_width, float lat1, float lat2, float lon1, float lon2)
static gboolean _view_map_drag_motion_callback(GtkWidget *widget, GdkDragContext *dc, gint x, gint y, guint time, dt_view_t *self)
static void _view_map_signal_change_wait(dt_view_t *self, const int time_out)
static gboolean _view_map_remove_track(const dt_view_t *view, OsmGpsMapTrack *track)
static dt_map_image_t * _view_map_get_entry_at_pos(dt_view_t *self, const double x, const double y)
static OsmGpsMapImage * _view_map_draw_single_image(const dt_view_t *view, GList *points)
static gboolean _view_map_button_press_callback(GtkWidget *w, GdkEventButton *e, dt_view_t *self)
static OsmGpsMapImage * _view_map_draw_location(dt_map_t *lib, dt_location_draw_t *ld, const gboolean main)
static GdkPixbuf * _draw_transient_image(const int32_t imgid, int *width, int *height, const int group_count, const gboolean group_same_loc, const uint32_t frame, const int thumbnail, dt_view_t *self)
static gboolean _view_map_motion_notify_callback(GtkWidget *w, GdkEventMotion *e, dt_view_t *self)
static void _view_map_angles(dt_map_t *lib, const gint pixels, const float lat, const float lon, float *dlat_min, float *dlon_min)
static const int thumb_size
static GdkPixbuf * _init_image_pin()
static GdkPixbuf * _view_map_images_count(const int nb_images, const gboolean same_loc, double *count_width, double *count_height)
static const int place_pin_size
static void _view_map_geotag_changed(gpointer instance, GList *imgs, const int locid, gpointer user_data)
static gboolean _view_map_prefs_changed(dt_map_t *lib)
static gboolean _view_map_remove_polygon(const dt_view_t *view, OsmGpsMapPolygon *polygon)
int key_pressed(dt_view_t *self, GdkEventKey *event)
static const uint32_t pin_line_color
static void _track_add_point(OsmGpsMapTrack *track, OsmGpsMapPoint *point, OsmGpsMapPoint *prev_point)
static void _view_map_location_action(const dt_view_t *view, const int action)
static void _view_map_update_location_geotag(dt_view_t *self)
static const int cross_size
static void _toast_log_lat_lon(const float lat, const float lon)
static OsmGpsMapTrack * _view_map_add_track(const dt_view_t *view, GList *points)
void configure(dt_view_t *self, int wd, int ht)
static gboolean _view_map_display_selected(gpointer user_data)
static void _view_map_center_on_bbox(const dt_view_t *view, gdouble lon1, gdouble lat1, gdouble lon2, gdouble lat2)
static void _view_map_drag_set_icon(const dt_view_t *self, GdkDragContext *context, const int32_t imgid, const int count)
static void _view_changed(gpointer instance, dt_view_t *old_view, dt_view_t *new_view, dt_view_t *self)
static void _view_map_draw_main_location(dt_map_t *lib, dt_location_draw_t *ld)
static void osm_gps_map_zoom_fit_bbox(OsmGpsMap *map, float latitude1, float latitude2, float longitude1, float longitude2)
static GdkPixbuf * _draw_rectangle(const float dlongitude, const float dlatitude, const gboolean main)
static double _view_map_get_angles_ratio(const dt_map_t *lib, const float lat0, const float lon0)
static void _view_map_changed_callback_delayed(gpointer user_data)
static const int thumb_border
static float _view_map_angles_to_pixels(const dt_map_t *lib, const float lat0, const float lon0, const float angle)
static const int image_pin_size
static void _view_map_set_map_source_g_object(const dt_view_t *view, OsmGpsMapSource_t map_source)
static void _view_map_thumb_angles(dt_map_t *lib, const float lat, const float lon, float *dlat_min, float *dlon_min)
static void _view_map_signal_change_raise(gpointer user_data)
void enter(dt_view_t *self)
static gboolean _view_map_remove_pin(const dt_view_t *view, OsmGpsMapImage *pin)
static void _view_map_remove_location(dt_map_t *lib, dt_location_draw_t *ld)
static gboolean _view_map_signal_change_delayed(gpointer user_data)
static float deg2rad(float deg)
static void _view_map_changed_callback(OsmGpsMap *map, dt_view_t *self)
static void _drag_and_drop_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint target_type, guint time, gpointer data)
void expose(dt_view_t *self, cairo_t *cri, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
static OsmGpsMapImage * _view_map_add_pin(const dt_view_t *view, GList *points)
static void _view_map_selection_changed(gpointer instance, gpointer user_data)
gint _find_image_in_images(gconstpointer a, gconstpointer b)
static void _free_map_image(gpointer data)
static gboolean _zoom_and_center(const gint x, const gint y, const int direction, dt_view_t *self)
static gboolean _view_map_draw_images(gpointer user_data)
static GdkPixbuf * _draw_location(dt_map_t *lib, int *width, int *height, dt_map_location_data_t *data, const gboolean main)
static const int max_size
static OsmGpsMapPolygon * _view_map_add_polygon_location(dt_map_t *lib, dt_location_draw_t *ld)
static gboolean _view_map_center_on_image_list(dt_view_t *self)
static gboolean _view_map_redraw(gpointer user_data)
static void _view_map_filmstrip_activate_callback(gpointer instance, int32_t imgid, gpointer user_data)
static gboolean _view_map_scroll_event(GtkWidget *w, GdkEventScroll *event, dt_view_t *self)
static GdkPixbuf * _init_place_pin()
static gboolean _view_map_button_release_callback(GtkWidget *w, GdkEventButton *e, dt_view_t *self)
int try_enter(dt_view_t *self)
static const uint32_t pin_inner_color
static void _view_map_dnd_get_callback(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint target_type, guint time, dt_view_t *self)
static const uint32_t thumb_frame_gpx_color
static GList * _view_map_get_imgs_at_pos(dt_view_t *self, const float x, const float y, int *offset_x, int *offset_y, const gboolean first_on)
static void _view_map_center_on_location(const dt_view_t *view, gdouble lon, gdouble lat, gdouble zoom)
static const uint32_t thumb_frame_sel_color
@ MAP_LOCATION_ACTION_REMOVE
@ MAP_LOCATION_SHAPE_POLYGONS
@ MAP_LOCATION_SHAPE_RECTANGLE
@ MAP_LOCATION_SHAPE_ELLIPSE
static void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
#define DT_MODULE(MODVER)
Instantiate the version handshake every module must export. Use once, at file scope,...
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
int32_t dt_selection_get_first_id(struct dt_selection_t *selection)
struct dt_selection_t * dt_selection_get_global(void)
GList * dt_selection_get_list(struct dt_selection_t *selection)
void dt_selection_select_single(dt_selection_t *selection, int32_t imgid)
void dt_control_signal_unblock_by_func(const struct dt_control_signal_t *ctlsig, GCallback cb, gpointer user_data)
void dt_control_signal_block_by_func(const struct dt_control_signal_t *ctlsig, GCallback cb, gpointer user_data)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ DT_SIGNAL_GEOTAG_CHANGED
This signal is raised when a geotag is added/deleted/changed
@ DT_SIGNAL_PREFERENCES_CHANGE
This signal is raised after preferences have been changed no parameters no return.
@ DT_SIGNAL_TAG_CHANGED
This signal is raised when a tag is added/deleted/changed
@ DT_SIGNAL_VIEWMANAGER_FILMSTRIP_ACTIVATE
This signal is raised when a thumb is single-clicked in the filmstrip. Views that want filmstrip clic...
@ DT_SIGNAL_SELECTION_CHANGED
This signal is raised when the selection is changed no param, no returned value.
@ DT_SIGNAL_VIEWMANAGER_FILMSTRIP_DRAG_BEGIN
This signal is raised when a drag starts from the filmstrip. Views that need filmstrip drags to commi...
@ DT_SIGNAL_COLLECTION_CHANGED
This signal is raised when collection changed. To avoid leaking the list, dt_collection_t is connecte...
@ DT_SIGNAL_VIEWMANAGER_VIEW_CHANGED
This signal is raised by viewmanager when a view has changed. 1 : dt_view_t * the old view 2 : dt_vie...
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
static const dt_aligned_pixel_simd_t value
The extent of the collection's geotagged images.
One geotagged image, in degrees as stored.
dt_map_location_data_t data
dt_view_image_surface_fetcher_t fetcher
cairo_surface_t * surface
gboolean selected_in_group
OsmGpsMapSource_t map_source
gboolean drop_filmstrip_activated
dt_map_image_t * last_hovered_entry
gboolean filter_images_drawn
GList * incoming_selection
dt_geo_position_t * points
Track one asynchronous Cairo surface fetch request for a GUI widget.
GObject *(* add_marker)(const dt_view_t *view, dt_geo_map_display_t type, GList *points)
gboolean(* redraw)(gpointer user_data)
void(* center_on_location)(const dt_view_t *view, gdouble lon, gdouble lat, double zoom)
gboolean(* remove_marker)(const dt_view_t *view, dt_geo_map_display_t type, GObject *marker)
void(* add_location)(const dt_view_t *view, dt_map_location_data_t *p, const guint posid)
void(* location_action)(const dt_view_t *view, const int action)
void(* set_map_source)(const dt_view_t *view, OsmGpsMapSource_t map_source)
struct dt_view_manager_t::@60 proxy
struct dt_view_manager_t::@60::@64 map
void(* show_osd)(const dt_view_t *view)
void(* center_on_bbox)(const dt_view_t *view, gdouble lon1, gdouble lat1, gdouble lon2, gdouble lat2)
typedef double((*spd)(unsigned long int wavelength, double TempK))
int dt_thumbtable_scroll_to_selection(dt_thumbtable_t *table)
Scroll to show selected content.
void dt_thumbtable_update_parent(dt_thumbtable_t *table)
A widget to manage and display image thumbnails in Ansel's lighttable and filmstrip views.
static void dt_thumbtable_show(dt_thumbtable_t *table)
Show the thumbnail table widget.
static void dt_thumbtable_hide(dt_thumbtable_t *table)
Hide the thumbnail table widget.
void dt_show_times(const dt_times_t *start, const char *prefix)
static void dt_get_times(dt_times_t *t)
gchar * dt_util_longitude_str(float longitude)
gchar * dt_util_latitude_str(float latitude)
void dt_view_image_surface_fetcher_cleanup(dt_view_image_surface_fetcher_t *fetcher)
void dt_view_image_surface_fetcher_init(dt_view_image_surface_fetcher_t *fetcher)
dt_view_surface_value_t dt_view_image_get_surface_async(dt_view_image_surface_fetcher_t *fetcher, int32_t imgid, int width, int height, cairo_surface_t **target, GtkWidget *widget, int zoom)
void dt_view_active_images_reset(gboolean raise)
GList * dt_view_active_images_get_all()
dt_view_surface_value_t dt_view_image_get_surface(int32_t imgid, int width, int height, cairo_surface_t **surface, int zoom)
void dt_view_active_images_set(GList *images, gboolean raise)
int32_t dt_view_active_images_get_first()
GtkWidget * dt_ui_center_base(dt_ui_t *ui)