60#include <gdk/gdkkeysyms.h>
62#include <osm-gps-map.h>
123#define UNCLASSIFIED -1
127#define NOT_CORE_POINT 0
167 const int32_t imgid,
const int count);
185 GtkSelectionData *selection_data, guint target_type, guint time,
189 GtkSelectionData *selection_data, guint target_type, guint time,
206 unsigned int minpts);
218 const gboolean
main);
233 switch(event->keyval)
255#ifndef HAVE_OSMGPSMAP_110_OR_NEWER
262 #define LOG2(x) (ilogb(x))
264 #define LOG2(x) ((int)floor(log2(abs(x))))
271 return (deg *
M_PI / 180.0);
274static int latlon2zoom(
int pix_height,
int pix_width,
float lat1,
float lat2,
float lon1,
float lon2)
276 const float lat1_m = atanh(sinf(lat1));
277 const float lat2_m = atanh(sinf(lat2));
278 const int zoom_lon =
LOG2((
double)(2 * pix_width *
M_PI) / (
TILESIZE * (lon2 - lon1)));
279 const int zoom_lat =
LOG2((
double)(2 * pix_height *
M_PI) / (
TILESIZE * (lat2_m - lat1_m)));
280 return MIN(zoom_lon, zoom_lat);
295 GtkAllocation allocation;
296 gtk_widget_get_allocation(GTK_WIDGET (map), &allocation);
297 const int zoom =
latlon2zoom(allocation.height, allocation.width,
300 osm_gps_map_set_center(map, (latitude1 + latitude2) / 2, (longitude1 + longitude2) / 2);
301 osm_gps_map_set_zoom(map, zoom);
315 double *count_width,
double *count_height)
317 gchar *text = g_strdup_printf(
"%d", nb_images);
321 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
322 cairo_t *cr = cairo_create(cst);
330 cairo_text_extents_t te;
331 cairo_text_extents(cr, text, &te);
332 *count_width = te.width + 4 * te.x_bearing;
333 *count_height = te.height + 2;
334 cairo_move_to(cr, te.x_bearing, te.height + 1);
336 cairo_show_text(cr, text);
338 uint8_t *data = cairo_image_surface_get_data(cst);
340 const size_t size = (size_t)w * h * 4;
341 uint8_t *buf = (uint8_t *)malloc(
size);
342 memcpy(buf, data,
size);
343 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB,
TRUE, 8, w, h, w * 4,
344 (GdkPixbufDestroyNotify)free, NULL);
345 cairo_surface_destroy(cst);
354 g_return_val_if_fail(w > 0 && h > 0, NULL);
362 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
363 cairo_t *cr = cairo_create(cst);
364 cairo_set_source_rgba(cr,
r,
g, b, a);
367 uint8_t *data = cairo_image_surface_get_data(cst);
369 const size_t size = (size_t)w * h * 4;
370 uint8_t *buf = (uint8_t *)malloc(
size);
371 memcpy(buf, data,
size);
372 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB,
TRUE, 8, w, h, w * 4,
373 (GdkPixbufDestroyNotify)free, NULL);
374 cairo_surface_destroy(cst);
382 g_return_val_if_fail(w > 0 && h > 0, NULL);
386 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
387 cairo_t *cr = cairo_create(cst);
394 cairo_set_source_rgba(cr,
r,
g, b, a);
395 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));
396 cairo_line_to(cr, 0.5 * w, h - 2);
397 cairo_close_path(cr);
398 cairo_fill_preserve(cr);
404 cairo_set_source_rgba(cr,
r,
g, b, a);
413 cairo_set_source_rgba(cr,
r,
g, b, a);
414 cairo_arc(cr, 0.5 * w, 0.333 * h, 0.17 * h, 0, 2.0 *
M_PI);
418 uint8_t *data = cairo_image_surface_get_data(cst);
420 size_t size = (size_t)w * h * 4;
421 uint8_t *buf = (uint8_t *)malloc(
size);
422 memcpy(buf, data,
size);
423 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB,
TRUE, 8, w, h, w * 4,
424 (GdkPixbufDestroyNotify)free, NULL);
425 cairo_surface_destroy(cst);
429static GdkPixbuf *
_draw_ellipse(
const float dlongitude,
const float dlatitude,
436 const gboolean landscape = dlon > dlat ?
TRUE :
FALSE;
437 const float ratio = dlon > dlat ? (float)dlat / (
float)dlon : (float)dlon / (
float)dlat;
442 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
443 cairo_t *cr = cairo_create(cst);
445 cairo_set_line_width(cr,
d);
451 cairo_matrix_t save_matrix;
452 cairo_get_matrix(cr, &save_matrix);
453 cairo_translate(cr, 0.5 * w, 0.5 * h);
454 cairo_scale(cr, landscape ? 1 : ratio, landscape ? ratio : 1);
455 cairo_translate(cr, -0.5 * w, -0.5 * h);
458 cairo_arc(cr, 0.5 * w, 0.5 * h, 0.5 * h -
d -
d, 0, 2.0 *
M_PI);
460 cairo_set_matrix(cr, &save_matrix);
462 cairo_move_to(cr, 0.5 * w +
d, 0.5 * h - cross);
463 cairo_line_to(cr, 0.5 * w +
d, 0.5 * h + cross);
464 cairo_move_to(cr, 0.5 * w - cross, 0.5 * h -
d);
465 cairo_line_to(cr, 0.5 * w + cross, 0.5 * h -
d);
468 cairo_get_matrix(cr, &save_matrix);
469 cairo_translate(cr, 0.5 * w, 0.5 * h);
470 cairo_scale(cr, landscape ? 1 : ratio, landscape ? ratio : 1);
471 cairo_translate(cr, -0.5 * w, -0.5 * h);
474 cairo_arc(cr, 0.5 * w, 0.5 * h, 0.5 * h -
d, 0, 2.0 *
M_PI);
476 cairo_set_matrix(cr, &save_matrix);
479 cairo_move_to(cr, 0.5 * w, 0.5 * h - cross);
480 cairo_line_to(cr, 0.5 * w, 0.5 * h + cross);
481 cairo_move_to(cr, 0.5 * w - cross, 0.5 * h );
482 cairo_line_to(cr, 0.5 * w + cross, 0.5 * h );
486 uint8_t *data = cairo_image_surface_get_data(cst);
488 size_t size = (size_t)w * h * 4;
489 uint8_t *buf = (uint8_t *)malloc(
size);
490 memcpy(buf, data,
size);
491 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB,
TRUE, 8, w, h, w * 4,
492 (GdkPixbufDestroyNotify)free, NULL);
493 cairo_surface_destroy(cst);
508 cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
509 cairo_t *cr = cairo_create(cst);
511 cairo_set_line_width(cr,
d);
513 cairo_move_to(cr,
d +
d,
d +
d);
514 cairo_line_to(cr, w -
d -
d,
d +
d);
515 cairo_line_to(cr, w -
d -
d, h -
d -
d);
516 cairo_line_to(cr,
d +
d, h -
d -
d);
517 cairo_line_to(cr,
d +
d,
d +
d);
518 cairo_move_to(cr, 0.5 * w +
d, 0.5 * h - cross);
519 cairo_line_to(cr, 0.5 * w +
d, 0.5 * h + cross);
520 cairo_move_to(cr, 0.5 * w - cross, 0.5 * h -
d);
521 cairo_line_to(cr, 0.5 * w + cross, 0.5 * h -
d);
529 cairo_move_to(cr,
d,
d);
530 cairo_line_to(cr, w -
d,
d);
531 cairo_line_to(cr, w -
d, h -
d);
532 cairo_line_to(cr,
d, h -
d);
533 cairo_line_to(cr,
d,
d);
534 cairo_move_to(cr, 0.5 * w, 0.5 * h - cross);
535 cairo_line_to(cr, 0.5 * w, 0.5 * h + cross);
536 cairo_move_to(cr, 0.5 * w - cross, 0.5 * h );
537 cairo_line_to(cr, 0.5 * w + cross, 0.5 * h );
541 uint8_t *data = cairo_image_surface_get_data(cst);
543 size_t size = (size_t)w * h * 4;
544 uint8_t *buf = (uint8_t *)malloc(
size);
545 memcpy(buf, data,
size);
546 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB,
TRUE, 8, w, h, w * 4,
547 (GdkPixbufDestroyNotify)free, NULL);
548 cairo_surface_destroy(cst);
562 cairo_set_source_rgb(cri, 0, 0, 0);
593 OsmGpsMapSource_t map_source
594 = OSM_GPS_MAP_SOURCE_OPENSTREETMAP;
596 if(old_map_source && old_map_source[0] !=
'\0')
599 for(
int i = 0;
i <= OSM_GPS_MAP_SOURCE_LAST;
i++)
601 const gchar *new_map_source = osm_gps_map_source_get_friendly_name(
i);
602 if(!g_strcmp0(old_map_source, new_map_source))
604 if(osm_gps_map_source_is_valid(
i)) map_source =
i;
610 dt_conf_set_string(
"plugins/map/map_source", osm_gps_map_source_get_friendly_name(map_source));
614 lib->
map = g_object_new(OSM_TYPE_GPS_MAP,
"map-source", OSM_GPS_MAP_SOURCE_NULL,
"proxy-uri",
615 g_getenv(
"http_proxy"), NULL);
617 g_object_ref(lib->
map);
619 lib->
osd = g_object_new(OSM_TYPE_GPS_MAP_OSD,
"show-scale",
TRUE,
"show-coordinates",
TRUE,
"show-dpad",
621#ifdef HAVE_OSMGPSMAP_NEWER_THAN_110
622 "show-copyright",
TRUE,
628 osm_gps_map_layer_add(OSM_GPS_MAP(lib->
map), lib->
osd);
631 gtk_drag_dest_set(GTK_WIDGET(lib->
map), GTK_DEST_DEFAULT_ALL,
639 g_signal_connect_after(G_OBJECT(lib->
map),
"button-press-event",
641 g_signal_connect_after(G_OBJECT(lib->
map),
"button-release-event",
682 g_object_unref(G_OBJECT(lib->
image_pin));
683 g_object_unref(G_OBJECT(lib->
place_pin));
684 g_object_unref(G_OBJECT(lib->
osd));
685 osm_gps_map_image_remove_all(lib->
map);
702 for(GList *other = lib->
loc.
others; other; other = g_list_next(other))
714 g_object_unref(G_OBJECT(lib->
map));
784 g_signal_emit_by_name(lib->
map,
"changed");
789 const float lon,
float *dlat_min,
float *dlon_min)
791 OsmGpsMapPoint *pt0 = osm_gps_map_point_new_degrees(
lat,
lon);
792 OsmGpsMapPoint *pt1 = osm_gps_map_point_new_degrees(0.0, 0.0);
793 gint pixel_x = 0, pixel_y = 0;
794 osm_gps_map_convert_geographic_to_screen(lib->
map, pt0, &pixel_x, &pixel_y);
795 osm_gps_map_convert_screen_to_geographic(lib->
map, pixel_x + pixels,
796 pixel_y + pixels, pt1);
797 float lat1 = 0.0, lon1 = 0.0;
798 osm_gps_map_point_get_degrees(pt1, &lat1, &lon1);
799 osm_gps_map_point_free(pt0);
800 osm_gps_map_point_free(pt1);
801 *dlat_min =
lat - lat1;
802 *dlon_min = lon1 -
lon;
808 float *dlat_min,
float *dlon_min)
811 if(*dlat_min > 0.0 && *dlon_min > 0.0)
824 const float lon0,
const float angle)
826 OsmGpsMapPoint *pt0 = osm_gps_map_point_new_degrees(lat0, lon0);
827 OsmGpsMapPoint *pt1 = osm_gps_map_point_new_degrees(lat0 + angle, lon0 + angle);
828 gint px0 = 0, py0 = 0;
829 gint px1 = 0, py1 = 0;
830 osm_gps_map_convert_geographic_to_screen(lib->
map, pt0, &px0, &py0);
831 osm_gps_map_convert_geographic_to_screen(lib->
map, pt1, &px1, &py1);
832 osm_gps_map_point_free(pt0);
833 osm_gps_map_point_free(pt1);
834 return abs(px1 - px0);
840 OsmGpsMapPoint *pt0 = osm_gps_map_point_new_degrees(lat0, lon0);
841 OsmGpsMapPoint *pt1 = osm_gps_map_point_new_degrees(lat0 + 2.0, lon0 + 2.0);
842 gint px0 = 0, py0 = 0;
843 gint px1 = 0, py1 = 0;
844 osm_gps_map_convert_geographic_to_screen(lib->
map, pt0, &px0, &py0);
845 osm_gps_map_convert_geographic_to_screen(lib->
map, pt1, &px1, &py1);
846 osm_gps_map_point_free(pt0);
847 osm_gps_map_point_free(pt1);
850 ratio = (float)abs(py1 - py0) / (float)(px1 - px0);
860 GdkPixbuf *draw = NULL;
864 if(pixel_lon > pixel_lat)
865 pixel_lat = pixel_lon;
867 pixel_lon = pixel_lat;
879 for(GList *other = lib->
loc.
others; other; other = g_list_next(other))
890 for(GList *other = others; other; other = g_list_next(other))
905 OsmGpsMapImage *location = NULL;
908 location = osm_gps_map_image_add_with_alignment(lib->
map, ld->
data.
lat, ld->
data.
lon, draw, 0.5, 0.5);
909 g_object_unref(draw);
927 return (OsmGpsMapImage *)location;
938 osm_gps_map_polygon_remove(lib->
map, (OsmGpsMapPolygon *)ld->
location);
990 for(GList *other = lib->
loc.
others; other; other = g_list_next(other))
1000 for(GList *other = others; other; other = g_list_next(other))
1046 const int group_count,
const gboolean group_same_loc,
1047 const uint32_t frame,
const int thumbnail,
dt_view_t *self)
1051 GdkPixbuf *thumb = NULL, *source = NULL, *count = NULL;
1062 const int raw_w = cairo_image_surface_get_width(entry->
surface);
1063 const int raw_h = cairo_image_surface_get_height(entry->
surface);
1064 double sx = 1.0, sy = 1.0;
1065 cairo_surface_get_device_scale(entry->
surface, &sx, &sy);
1070 const int w =
MAX(1, (
int)round((
double)raw_w / sx));
1071 const int h =
MAX(1, (
int)round((
double)raw_h / sy));
1072 if(raw_w == w && raw_h == h)
1074 source = gdk_pixbuf_get_from_surface(entry->
surface, 0, 0, w, h);
1079 cairo_surface_t *logical = cairo_image_surface_create(CAIRO_FORMAT_RGB24, w, h);
1080 cairo_t *cr = cairo_create(logical);
1081 cairo_set_source_surface(cr, entry->
surface, 0, 0);
1082 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST);
1085 source = gdk_pixbuf_get_from_surface(logical, 0, 0, w, h);
1086 cairo_surface_destroy(logical);
1090 thumb = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
TRUE, 8, w + 2 * _thumb_border,
1091 h + 2 * _thumb_border + _pin_size);
1093 gdk_pixbuf_fill(thumb, frame);
1094 gdk_pixbuf_copy_area(source, 0, 0, w, h, thumb, _thumb_border, _thumb_border);
1095 gdk_pixbuf_copy_area(lib->
image_pin, 0, 0, w + 2 * _thumb_border,
1096 _pin_size, thumb, 0, h + 2 * _thumb_border);
1099 double count_height, count_width;
1101 gdk_pixbuf_copy_area(count, 0, 0, count_width, count_height, thumb,
1102 _thumb_border, h - count_height + _thumb_border);
1109 double count_height, count_width;
1111 &count_width, &count_height);
1112 if(!count)
goto map_changed_failure;
1113 const int w = count_width + 2 * _thumb_border;
1114 const int h = count_height + 2 * _thumb_border + _pin_size;
1115 thumb = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
TRUE, 8, w, h);
1117 gdk_pixbuf_fill(thumb, frame);
1118 gdk_pixbuf_copy_area(count, 0, 0, count_width, count_height, thumb,
1119 _thumb_border, _thumb_border);
1120 gdk_pixbuf_copy_area(lib->
image_pin, 0, 0, w, _pin_size, thumb,
1121 0, count_height + 2 * _thumb_border);
1126 if(source) g_object_unref(source);
1127 if(count) g_object_unref(count);
1132 const gboolean group_same_loc,
const uint32_t frame,
1136 GdkPixbuf *thumb = NULL, *source = NULL, *count = NULL;
1137 cairo_surface_t *surface = NULL;
1147 const int raw_w = cairo_image_surface_get_width(surface);
1148 const int raw_h = cairo_image_surface_get_height(surface);
1149 double sx = 1.0, sy = 1.0;
1150 cairo_surface_get_device_scale(surface, &sx, &sy);
1151 const int w =
MAX(1, (
int)round((
double)raw_w / sx));
1152 const int h =
MAX(1, (
int)round((
double)raw_h / sy));
1153 if(raw_w == w && raw_h == h)
1155 source = gdk_pixbuf_get_from_surface(surface, 0, 0, w, h);
1160 cairo_surface_t *logical = cairo_image_surface_create(CAIRO_FORMAT_RGB24, w, h);
1161 cairo_t *cr = cairo_create(logical);
1162 cairo_set_source_surface(cr, surface, 0, 0);
1163 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST);
1166 source = gdk_pixbuf_get_from_surface(logical, 0, 0, w, h);
1167 cairo_surface_destroy(logical);
1171 thumb = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
TRUE, 8, w + 2 * _thumb_border,
1172 h + 2 * _thumb_border + _pin_size);
1174 gdk_pixbuf_fill(thumb, frame);
1175 gdk_pixbuf_copy_area(source, 0, 0, w, h, thumb, _thumb_border, _thumb_border);
1176 gdk_pixbuf_copy_area(lib->
image_pin, 0, 0, w + 2 * _thumb_border,
1177 _pin_size, thumb, 0, h + 2 * _thumb_border);
1180 double count_height, count_width;
1182 gdk_pixbuf_copy_area(count, 0, 0, count_width, count_height, thumb,
1183 _thumb_border, h - count_height + _thumb_border);
1190 double count_height, count_width;
1192 if(!count)
goto map_changed_failure;
1193 const int w = count_width + 2 * _thumb_border;
1194 const int h = count_height + 2 * _thumb_border + _pin_size;
1195 thumb = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
TRUE, 8, w, h);
1197 gdk_pixbuf_fill(thumb, frame);
1198 gdk_pixbuf_copy_area(count, 0, 0, count_width, count_height, thumb, _thumb_border, _thumb_border);
1199 gdk_pixbuf_copy_area(lib->
image_pin, 0, 0, w, _pin_size, thumb, 0, count_height + 2 * _thumb_border);
1205 if(surface) cairo_surface_destroy(surface);
1206 if(source) g_object_unref(source);
1207 if(count) g_object_unref(count);
1214 gboolean needs_redraw =
FALSE;
1217 osm_gps_map_image_remove(lib->
map, entry->
image);
1218 entry->
image = NULL;
1229 entry->
image = osm_gps_map_image_add_with_alignment(lib->
map, entry->
latitude,
1232 g_object_unref(thumb);
1235 needs_redraw =
TRUE;
1237 return needs_redraw;
1246 gboolean needs_redraw =
FALSE;
1248 for(GSList *iter = lib->
images; iter; iter = g_slist_next(iter))
1258 return needs_redraw;
1263 OsmGpsMapPoint bb[2];
1264 osm_gps_map_get_bbox(lib->
map, &bb[0], &bb[1]);
1267 osm_gps_map_point_get_degrees(&bb[0], &box.
lat1, &box.
lon1);
1268 osm_gps_map_point_get_degrees(&bb[1], &box.
lat2, &box.
lon2);
1269 box.
lat1 = CLAMP(box.
lat1, -90.0, 90.0);
1270 box.
lat2 = CLAMP(box.
lat2, -90.0, 90.0);
1271 box.
lon1 = CLAMP(box.
lon1, -180.0, 180.0);
1272 box.
lon2 = CLAMP(box.
lon2, -180.0, 180.0);
1280 gboolean all_good =
TRUE;
1281 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);
1312 float center_lat, center_lon;
1313 g_object_get(G_OBJECT(lib->
map),
"zoom", &zoom,
"latitude", ¢er_lat,
"longitude", ¢er_lon, NULL);
1330 while(sqlite3_step(lib->
main_query) == SQLITE_ROW)
1348 while(sqlite3_step(lib->
main_query) == SQLITE_ROW && all_good &&
i < img_count)
1357 const float epsilon_factor =
dt_conf_get_int(
"plugins/map/epsilon_factor");
1358 const int min_images =
dt_conf_get_int(
"plugins/map/min_images_per_group");
1364 double epsilon =
thumb_size * (((
unsigned int)(156412000 >> zoom))
1365 * epsilon_factor * 0.01 * 0.000001 /
R);
1369 _dbscan(
p, img_count, epsilon, min_images);
1375 for(
i = 0;
i< img_count;
i++)
1382 entry->
group =
p[
i].cluster_id;
1389 GINT_TO_POINTER(entry->
imgid))
1393 else if(
p[
i].cluster_id > group)
1395 group =
p[
i].cluster_id;
1399 entry->
group =
p[
i].cluster_id;
1402 GINT_TO_POINTER(
p[
i].imgid)))
1405 for(
int j = 0; j < img_count; j++)
1407 if(
p[j].cluster_id == group)
1418 if(g_list_find((GList *)sel_imgs, GINT_TO_POINTER(
p[j].imgid)))
1428 g_list_free(sel_imgs);
1485 for(
const GSList *iter = lib->
images; iter; iter = g_slist_next(iter))
1488 OsmGpsMapImage *image = entry->
image;
1491 OsmGpsMapPoint *pt = (OsmGpsMapPoint *)osm_gps_map_image_get_point(image);
1492 gint img_x = 0, img_y = 0;
1493 osm_gps_map_convert_geographic_to_screen(lib->
map, pt, &img_x, &img_y);
1495 if(
x >= img_x && x <= img_x + entry->
width && y <= img_y && y >= img_y - entry->
height)
1505 int *offset_x,
int *offset_y,
const gboolean first_on)
1512 for(
const GSList *iter = lib->
images; iter; iter = g_slist_next(iter))
1515 OsmGpsMapImage *image = entry->
image;
1518 OsmGpsMapPoint *pt = (OsmGpsMapPoint *)osm_gps_map_image_get_point(image);
1519 gint img_x = 0, img_y = 0;
1520 osm_gps_map_convert_geographic_to_screen(lib->
map, pt, &img_x, &img_y);
1522 if(
x >= img_x && x <= img_x + entry->
width && y <= img_y && y >= img_y - entry->
height)
1524 imgid = entry->
imgid;
1525 *offset_x = (int)
x - img_x;
1538 if(
p[
i].cluster_id == entry->
group &&
p[
i].imgid != imgid)
1540 imgs = g_list_prepend(imgs, GINT_TO_POINTER(
p[
i].imgid));
1551 imgs = g_list_prepend(imgs, GINT_TO_POINTER(imgid));
1558 return entry->
imgid == GPOINTER_TO_INT(b) ? 0 : 1;
1570 osm_gps_map_image_remove(lib->
map, entry->
image);
1571 entry->
image = NULL;
1582 if(
p[
i].imgid == GPOINTER_TO_INT(entry->
imgid))
1588 if(
p[j].cluster_id == entry->
group)
1596 for(
int j = 0; j <
i; j++)
1598 if(
p[j].cluster_id == entry->
group)
1608 for(
int j =
i - 1; j >= 0; j--)
1610 if(
p[j].cluster_id == entry->
group)
1620 if(
p[j].cluster_id == entry->
group)
1631 if(index == -1)
return FALSE;
1632 entry->
imgid =
p[index].imgid;
1635 osm_gps_map_image_remove(lib->
map, entry->
image);
1636 entry->
image = NULL;
1644 const int32_t imgid,
const int count)
1652 GtkWidget *image = gtk_image_new_from_pixbuf(thumb);
1654 gtk_widget_show(image);
1657 g_object_unref(thumb);
1665 OsmGpsMapPoint *
p = osm_gps_map_point_new_degrees(0.0, 0.0);
1666 osm_gps_map_convert_screen_to_geographic(lib->
map,
x, y,
p);
1668 osm_gps_map_point_get_degrees(
p, &
lat, &
lon);
1669 osm_gps_map_point_free(
p);
1677 OsmGpsMapPoint *
p = osm_gps_map_get_event_location(lib->
map, (GdkEventButton *)e);
1679 osm_gps_map_point_get_degrees(
p, &
lat, &
lon);
1690 GdkDragContext *context =
1691 gtk_drag_begin_with_coordinates(GTK_WIDGET(lib->
map), targets,
1693 (GdkEvent *)e, -1, -1);
1700 GtkWidget *image = gtk_image_new_from_pixbuf(location);
1701 gtk_widget_set_name(image,
"map-drag-icon");
1702 gtk_widget_show(image);
1703 gtk_drag_set_icon_widget(context, image,
1706 g_object_unref(location);
1708 gtk_target_list_unref(targets);
1717 for(
const GSList *iter = lib->
images; iter; iter = g_slist_next(iter))
1723 if(entry->
imgid == GPOINTER_TO_INT(sel_img->data))
1727 osm_gps_map_image_remove(lib->
map, entry->
image);
1728 entry->
image = NULL;
1741 GdkDragContext *context = gtk_drag_begin_with_coordinates(GTK_WIDGET(lib->
map), targets,
1743 (GdkEvent *)e, -1, -1);
1746 gtk_target_list_unref(targets);
1782 g_object_get(G_OBJECT(lib->
map),
"zoom", &zoom,
"max-zoom", &max_zoom, NULL);
1784 OsmGpsMapPoint bb[2];
1785 osm_gps_map_get_bbox(lib->
map, &bb[0], &bb[1]);
1786 gint x0, x1, y0, y1;
1787 osm_gps_map_convert_geographic_to_screen(lib->
map, &bb[0], &x0, &y0);
1788 osm_gps_map_convert_geographic_to_screen(lib->
map, &bb[1], &x1, &y1);
1791 if(direction == GDK_SCROLL_UP && zoom < max_zoom)
1794 nx = (x0 + x1 + 2 *
x) / 4;
1795 ny = (y0 + y1 + 2 * y) / 4;
1797 else if(direction == GDK_SCROLL_DOWN && zoom > 0)
1805 OsmGpsMapPoint *pt = osm_gps_map_point_new_degrees(0.0, 0.0);
1806 osm_gps_map_convert_screen_to_geographic(lib->
map, nx, ny, pt);
1808 osm_gps_map_point_get_degrees(pt, &nlat, &nlon);
1809 osm_gps_map_point_free(pt);
1810 osm_gps_map_set_center_and_zoom(lib->
map, nlat, nlon, zoom);
1826 OsmGpsMapPoint *
p = osm_gps_map_get_event_location(lib->
map, (GdkEventButton *)event);
1828 osm_gps_map_point_get_degrees(
p, &
lat, &
lon);
1835 if(event->direction == GDK_SCROLL_DOWN)
1842 if(event->direction == GDK_SCROLL_DOWN)
1849 if(event->direction == GDK_SCROLL_DOWN)
1894 OsmGpsMapPoint *
p = osm_gps_map_get_event_location(lib->
map, e);
1896 osm_gps_map_point_get_degrees(
p, &
lat, &
lon);
1912 OsmGpsMapPoint *
p = osm_gps_map_get_event_location(lib->
map, e);
1914 osm_gps_map_point_get_degrees(
p, &
lat, &
lon);
1915 for(GList *other = lib->
loc.
others; other; other = g_list_next(other))
1941 if(e->type == GDK_BUTTON_PRESS)
1955 if(e->type == GDK_2BUTTON_PRESS)
1967 float longitude, latitude;
1968 OsmGpsMapPoint *pt = osm_gps_map_point_new_degrees(0.0, 0.0);
1969 osm_gps_map_convert_screen_to_geographic(lib->
map, e->x, e->y, pt);
1970 osm_gps_map_point_get_degrees(pt, &latitude, &longitude);
1971 osm_gps_map_point_free(pt);
1973 g_object_get(G_OBJECT(lib->
map),
"zoom", &zoom,
"max-zoom", &max_zoom, NULL);
1974 zoom =
MIN(zoom + 1, max_zoom);
1997 gboolean done =
FALSE;
2005 double max_longitude = -INFINITY;
2006 double max_latitude = -INFINITY;
2007 double min_longitude = INFINITY;
2008 double min_latitude = INFINITY;
2011 for(
const GList *iter = active; iter; iter = g_list_next((GList *)iter))
2013 const int32_t imgid = GPOINTER_TO_INT(iter->data);
2018 max_longitude = fmax(max_longitude, geoloc.
longitude);
2019 min_longitude = fmin(min_longitude, geoloc.
longitude);
2020 max_latitude = fmax(max_latitude, geoloc.
latitude);
2021 min_latitude = fmin(min_latitude, geoloc.
latitude);
2027 max_longitude = CLAMP(max_longitude, -180, 180);
2028 min_longitude = CLAMP(min_longitude, -180, 180);
2029 max_latitude = CLAMP(max_latitude, -90, 90);
2030 min_latitude = CLAMP(min_latitude, -90, 90);
2047 lon = CLAMP(
lon, -180, 180);
2049 lat = CLAMP(
lat, -90, 90);
2051 osm_gps_map_set_center_and_zoom(lib->
map,
lat,
lon, zoom);
2085 if(!gtk_widget_get_parent(GTK_WIDGET(lib->
map)))
2089 gtk_widget_show_all(GTK_WIDGET(lib->
map));
2141 gtk_widget_hide(GTK_WIDGET(lib->
map));
2186 osm_gps_map_set_center_and_zoom(lib->
map,
lat,
lon, zoom);
2200 osm_gps_map_layer_add(OSM_GPS_MAP(lib->
map), lib->
osd);
2202 osm_gps_map_layer_remove(OSM_GPS_MAP(lib->
map), lib->
osd);
2204 g_signal_emit_by_name(lib->
map,
"changed");
2214 g_value_init(&
value, G_TYPE_INT);
2215 g_value_set_int(&
value, map_source);
2216 g_object_set_property(G_OBJECT(lib->
map),
"map-source", &
value);
2217 g_value_unset(&
value);
2227 dt_conf_set_string(
"plugins/map/map_source", osm_gps_map_source_get_friendly_name(map_source));
2235 return osm_gps_map_image_add_with_alignment(lib->
map,
p->lat,
p->lon, lib->
place_pin, 0.5, 1);
2241 return osm_gps_map_image_remove(lib->
map, pin);
2246 float lat,
lon, prev_lat, prev_lon;
2248 osm_gps_map_point_get_degrees(prev_point, &prev_lat, &prev_lon);
2250 gboolean short_distance =
TRUE;
2254 short_distance =
FALSE;
2262 osm_gps_map_track_add_point(track,
point);
2267 OsmGpsMapPoint *ith_point;
2268 double f, ith_lat, ith_lon;
2270 gboolean first_time =
TRUE;
2271 for(
int i = 1;
i <= n_segments;
i ++)
2279 &ith_lat, &ith_lon);
2281 ith_point = osm_gps_map_point_new_degrees (ith_lat, ith_lon);
2282 osm_gps_map_track_add_point(track, ith_point);
2283 osm_gps_map_point_free(ith_point);
2289#ifdef HAVE_OSMGPSMAP_110_OR_NEWER
2290static OsmGpsMapPolygon *_view_map_add_polygon(
const dt_view_t *
view, GList *points)
2293 OsmGpsMapPolygon *poly = osm_gps_map_polygon_new();
2294 OsmGpsMapTrack* track = osm_gps_map_track_new();
2301 float prev_lat = 0.0;
2302 float prev_lon = 0.0;
2303 for(GList *iter = points; iter; iter = g_list_next(iter))
2306 if((fabs(
p->lat - prev_lat) > dlat) || (fabs(
p->lon - prev_lon) > dlon))
2308 OsmGpsMapPoint*
point = osm_gps_map_point_new_degrees(
p->lat,
p->lon);
2309 osm_gps_map_track_add_point(track,
point);
2315 g_object_set(poly,
"track", track, (gchar *)0);
2316 g_object_set(poly,
"editable",
FALSE, (gchar *)0);
2317 g_object_set(poly,
"shaded",
FALSE, (gchar *)0);
2319 osm_gps_map_polygon_add(lib->
map, poly);
2326 OsmGpsMapPolygon *poly = osm_gps_map_polygon_new();
2327 OsmGpsMapTrack* track = osm_gps_map_track_new();
2328 g_object_set(track,
"line-width" , 2.0,
"alpha", 0.9, (gchar *)0);
2334 g_object_get(G_OBJECT(lib->
map),
"zoom", &zoom, NULL);
2336 const int mod2 = zoom + 1;
2349 float prev_lat = 0.0;
2350 float prev_lon = 0.0;
2351 for(GList *iter = ld->
data.
polygons; iter; iter = g_list_next(iter),
i++)
2357 if((fabs(
p->lat - prev_lat) > dlat) || (fabs(
p->lon - prev_lon) > dlon))
2359 OsmGpsMapPoint*
point = osm_gps_map_point_new_degrees(
p->lat,
p->lon);
2360 osm_gps_map_track_add_point(track,
point);
2365 else if(!(
i % mod2))
2367 OsmGpsMapPoint*
point = osm_gps_map_point_new_degrees(
p->lat,
p->lon);
2368 osm_gps_map_track_add_point(track,
point);
2372 g_object_set(poly,
"track", track, (gchar *)0);
2373 g_object_set(poly,
"editable",
FALSE, (gchar *)0);
2374 g_object_set(poly,
"shaded",
FALSE, (gchar *)0);
2376 osm_gps_map_polygon_add(lib->
map, poly);
2384 return osm_gps_map_polygon_remove(lib->
map, polygon);
2392 OsmGpsMapTrack* track = osm_gps_map_track_new();
2394 OsmGpsMapPoint* prev_point;
2395 gboolean first_point =
TRUE;
2396 for(GList *iter = points; iter; iter = g_list_next(iter))
2399 OsmGpsMapPoint*
point = osm_gps_map_point_new_degrees(
p->lat,
p->lon);
2402 osm_gps_map_track_add_point(track,
point);
2407 osm_gps_map_point_free(prev_point);
2409 prev_point = &(*point);
2410 if(!g_list_next(iter))
2411 osm_gps_map_point_free(prev_point);
2412 first_point =
FALSE;
2415 g_object_set(track,
"editable",
FALSE, (gchar *)0);
2417 osm_gps_map_track_add(lib->
map, track);
2425 return osm_gps_map_track_remove(lib->
map, track);
2431 struct {int32_t imgid;
float latitude;
float longitude;
int count;} *
p;
2435 OsmGpsMapImage *image = NULL;
2438 image = osm_gps_map_image_add_with_alignment(lib->
map,
p->latitude,
p->longitude, thumb, 0, 1);
2439 g_object_unref(thumb);
2450#ifdef HAVE_OSMGPSMAP_110_OR_NEWER
2454 default:
return NULL;
2467#ifdef HAVE_OSMGPSMAP_110_OR_NEWER
2471 default:
return FALSE;
2479 loc_main.
id = locid;
2482 if(
g->delta1 != 0.0 &&
g->delta2 != 0.0)
2486 const double max_lon = CLAMP(
g->lon +
g->delta1, -180, 180);
2487 const double min_lon = CLAMP(
g->lon -
g->delta1, -180, 180);
2488 const double max_lat = CLAMP(
g->lat +
g->delta2, -90, 90);
2489 const double min_lat = CLAMP(
g->lat -
g->delta2, -90, 90);
2490 if(max_lon > min_lon && max_lat > min_lat)
2518 g_object_get(G_OBJECT(lib->
map),
"latitude", &
lat,
"longitude", &
lon, NULL);
2592 g_signal_emit_by_name(lib->
map,
"changed");
2618 g_object_get(G_OBJECT(lib->
map),
"zoom", &zoom, NULL);
2627 double max_longitude = -INFINITY;
2628 double max_latitude = -INFINITY;
2629 double min_longitude = INFINITY;
2630 double min_latitude = INFINITY;
2634 gchar *query = g_strdup_printf(
"SELECT MIN(latitude), MAX(latitude),"
2635 " MIN(longitude), MAX(longitude), COUNT(*)"
2636 " FROM main.images AS i "
2637 " JOIN %s AS l ON l.imgid = i.id "
2638 " WHERE latitude NOT NULL AND longitude NOT NULL",
2643 if(sqlite3_step(stmt) == SQLITE_ROW)
2645 min_latitude = sqlite3_column_double(stmt, 0);
2646 max_latitude = sqlite3_column_double(stmt, 1);
2647 min_longitude = sqlite3_column_double(stmt, 2);
2648 max_longitude = sqlite3_column_double(stmt, 3);
2649 count = sqlite3_column_int(stmt, 4);
2651 sqlite3_finalize(stmt);
2656 max_longitude = CLAMP(max_longitude, -180, 180);
2657 min_longitude = CLAMP(min_longitude, -180, 180);
2658 max_latitude = CLAMP(max_latitude, -90, 90);
2659 min_latitude = CLAMP(min_latitude, -90, 90);
2664 max_longitude = CLAMP(max_longitude + 1.0 * lib->
thumb_lon_angle, -180, 180);
2665 min_longitude = CLAMP(min_longitude - 0.2 * lib->
thumb_lon_angle, -180, 180);
2666 max_latitude = CLAMP(max_latitude + 1.0 * lib->
thumb_lat_angle, -90, 90);
2667 min_latitude = CLAMP(min_latitude - 0.2 * lib->
thumb_lat_angle, -90, 90);
2693 GtkSelectionData *selection_data, guint target_type, guint time,
2698 gboolean success =
FALSE;
2701 const int imgs_nb = gtk_selection_data_get_length(selection_data) /
sizeof(uint32_t);
2704 uint32_t *imgt = (uint32_t *)gtk_selection_data_get_data(selection_data);
2705 if(imgs_nb == 1 && imgt[0] == -1)
2708 OsmGpsMapPoint *pt = osm_gps_map_point_new_degrees(0.0, 0.0);
2709 osm_gps_map_convert_screen_to_geographic(lib->
map,
x, y, pt);
2711 osm_gps_map_point_get_degrees(pt, &
lat, &
lon);
2717 osm_gps_map_point_free(pt);
2726 for(
int i = 0;
i < imgs_nb;
i++)
2728 imgs = g_list_prepend(imgs, GINT_TO_POINTER(imgt[
i]));
2730 float longitude, latitude;
2731 OsmGpsMapPoint *pt = osm_gps_map_point_new_degrees(0.0, 0.0);
2734 osm_gps_map_point_get_degrees(pt, &latitude, &longitude);
2735 osm_gps_map_point_free(pt);
2743 g_signal_emit_by_name(lib->
map,
"changed");
2748 gtk_drag_finish(context, success,
FALSE, time);
2752 GtkSelectionData *selection_data, guint target_type, guint time,
2767 uint32_t *imgs = malloc(
sizeof(uint32_t) * imgs_nb);
2771 imgs[
i++] = GPOINTER_TO_INT(l->data);
2773 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
2774 _DWORD, (guchar *)imgs, imgs_nb *
sizeof(uint32_t));
2781 uint32_t *imgs = malloc(
sizeof(uint32_t));
2783 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
2784 _DWORD, (guchar *)imgs,
sizeof(uint32_t));
2796 gboolean from_cache =
TRUE;
2798 gchar *uri = g_strdup_printf(
"file://%s", pathname);
2799 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
_BYTE,
2800 (guchar *)uri, strlen(uri));
2812 g_signal_emit_by_name(lib->
map,
"changed");
2819 gboolean prefs_changed =
FALSE;
2824 gboolean filter_images_drawn =
dt_conf_get_bool(
"plugins/map/filter_images_drawn");
2831 return prefs_changed;
2841 geo_query = g_strdup_printf(
"SELECT * FROM"
2842 " (SELECT i.id, i.longitude, i.latitude "
2843 " FROM main.images i INNER JOIN memory.collected_images c ON i.id = c.imgid"
2844 " WHERE longitude >= ?1 AND longitude <= ?2"
2845 " AND latitude <= ?3 AND latitude >= ?4 "
2846 " AND longitude NOT NULL AND latitude NOT NULL)"
2847 " ORDER BY longitude ASC");
2859typedef struct epsilon_neighbours_t
2861 unsigned int num_members;
2862 unsigned int index[];
2863} epsilon_neighbours_t;
2865typedef struct dt_dbscan_t
2868 unsigned int num_points;
2870 unsigned int minpts;
2871 epsilon_neighbours_t *seeds;
2872 epsilon_neighbours_t *spreads;
2874 unsigned int cluster_id;
2877static dt_dbscan_t db;
2879static void _get_epsilon_neighbours(epsilon_neighbours_t *en,
unsigned int index)
2884 for(
int i = index;
i < db.num_points; ++
i)
2886 if(
i == index || db.points[
i].cluster_id >= 0)
2888 if((db.points[
i].x - db.points[index].x) > db.epsilon)
2890 if(fabs(db.points[
i].y - db.points[index].y) > db.epsilon)
2894 en->index[en->num_members] =
i;
2899 for(
int i = index;
i >= 0; --
i)
2901 if(
i == (
int)index || db.points[
i].cluster_id >= 0)
2903 if((db.points[index].x - db.points[
i].x) > db.epsilon)
2905 if(fabs(db.points[index].y - db.points[
i].y) > db.epsilon)
2909 en->index[en->num_members] =
i;
2915static void _dbscan_spread(
unsigned int index)
2917 db.spreads->num_members = 0;
2918 _get_epsilon_neighbours(db.spreads, index);
2920 for(
unsigned int i = 0;
i < db.spreads->num_members;
i++)
2925 db.seeds->index[db.seeds->num_members] = db.spreads->index[
i];
2926 db.seeds->num_members++;
2927 d->cluster_id = db.cluster_id;
2932static int _dbscan_expand(
unsigned int index)
2935 db.seeds->num_members = 0;
2936 _get_epsilon_neighbours(db.seeds, index);
2938 if (db.seeds->num_members < db.minpts)
2939 db.points[index].cluster_id =
NOISE;
2942 db.points[index].cluster_id = db.cluster_id;
2943 for(
int i = 0;
i < db.seeds->num_members;
i++)
2945 db.points[db.seeds->index[
i]].cluster_id = db.cluster_id;
2948 for(
int i = 0;
i < db.seeds->num_members;
i++)
2950 _dbscan_spread(db.seeds->index[
i]);
2954 return return_value;
2958 double epsilon,
unsigned int minpts)
2961 db.num_points = num_points;
2962 db.epsilon = epsilon;
2964 db.minpts = minpts > 1 ? minpts - 1 : minpts;
2966 db.seeds = (epsilon_neighbours_t *)malloc(
sizeof(db.seeds->num_members)
2967 + num_points *
sizeof(db.seeds->index[0]));
2968 db.spreads = (epsilon_neighbours_t *)malloc(
sizeof(db.spreads->num_members)
2969 + num_points *
sizeof(db.spreads->index[0]));
2971 if(db.seeds && db.spreads)
2973 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.
GList * dt_act_on_get_images()
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
dt_collection_properties_t
const dt_aligned_pixel_t f
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.
gboolean dt_map_location_update_images(dt_location_draw_t *ld)
GList * dt_map_location_convert_polygons(void *polygons, dt_map_box_t *bbox, int *nb_pts)
void dt_map_location_set_data(const guint locid, const dt_map_location_data_t *g)
void dt_map_location_get_polygons(dt_location_draw_t *ld)
gboolean dt_map_location_included(const float lon, const float lat, dt_map_location_data_t *g)
void dt_map_location_free_polygons(dt_location_draw_t *ld)
GList * dt_map_location_get_locations_on_map(const dt_map_box_t *const bbox)
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)
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
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)
void dt_show_times(const dt_times_t *start, const char *prefix)
#define DT_MODULE(MODVER)
static void dt_free_gpointer(gpointer ptr)
static void dt_get_times(dt_times_t *t)
static const dt_aligned_pixel_simd_t value
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
sqlite3 * dt_database_get(const dt_database_t *db)
#define DT_DEBUG_SQLITE3_RESET(a)
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_CLEAR_BINDINGS(a)
#define DT_DEBUG_SQLITE3_BIND_DOUBLE(a, b, c)
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 dtgtk_cairo_paint_map_pin(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
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
void dt_gui_gtk_set_source_rgb(cairo_t *cr, dt_gui_color_t color)
@ DT_GUI_COLOR_MAP_LOC_SHAPE_HIGH
@ DT_GUI_COLOR_MAP_COUNT_BG
@ DT_GUI_COLOR_MAP_LOC_SHAPE_LOW
@ DT_GUI_COLOR_MAP_COUNT_SAME_LOC
@ DT_GUI_COLOR_MAP_COUNT_DIFF_LOC
@ DT_GUI_COLOR_MAP_LOC_SHAPE_DEF
#define DT_PIXEL_APPLY_DPI(value)
GtkWidget * dt_ui_center_base(dt_ui_t *ui)
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 gboolean _view_map_center_on_image_list(dt_view_t *self, const char *table)
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)
uint32_t view(const dt_view_t *self)
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_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 void _view_map_build_main_query(dt_map_t *lib)
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
int32_t dt_selection_get_first_id(struct dt_selection_t *selection)
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,...)
@ 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)
struct _GtkWidget GtkWidget
struct dt_gui_gtk_t * gui
struct dt_selection_t * selection
const struct dt_database_t * db
struct dt_control_signal_t * signals
struct dt_view_manager_t * view_manager
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
sqlite3_stmt * main_query
dt_thumbtable_t * thumbtable_filmstrip
Track one asynchronous Cairo surface fetch request for a GUI widget.
struct dt_view_manager_t::@67 proxy
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.
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()