[PATCH] Show single dives in map.

subsurface at henrik.synth.no subsurface at henrik.synth.no
Tue Jan 15 13:45:18 PST 2013


From: Henrik Brautaset Aronsen <subsurface at henrik.synth.no>

This adds a "Show in map" entry in the dive list context menu.  It will
zoom to the dive location if it exists, otherwise the full map will be
displayed.

I've also switched map tiles from OpenStreetMap to Google Maps just to
show off that we can.

Signed-off-by: Henrik Brautaset Aronsen <subsurface at henrik.synth.no>
---


No rest for the wicked.  This is the third version of this patch,
now sporting av dive flag on the dive site.

Henrik


 dive.h     |   1 +
 divelist.c |  13 +++++++++++
 flag.png   | Bin 0 -> 4314 bytes
 gps.c      |  73 +++++++++++++++++++++++++++++++++++++++++++++++++------------
 4 files changed, 73 insertions(+), 14 deletions(-)
 create mode 100644 flag.png

diff --git a/dive.h b/dive.h
index 28ea799..449092e 100644
--- a/dive.h
+++ b/dive.h
@@ -500,6 +500,7 @@ extern void show_dive_stats(struct dive *);
 extern void clear_stats_widgets(void);
 
 extern void show_gps_locations(void);
+extern void show_gps_location(struct dive *);
 
 extern void show_yearly_stats(void);
 
diff --git a/divelist.c b/divelist.c
index e6fb710..54518dd 100644
--- a/divelist.c
+++ b/divelist.c
@@ -1659,6 +1659,11 @@ void edit_dive_when_cb(GtkWidget *menuitem, struct dive *dive)
 	}
 }
 
+static void show_gps_location_cb(GtkWidget *menuitem, struct dive *dive)
+{
+	show_gps_location(dive);
+}
+
 static void expand_all_cb(GtkWidget *menuitem, GtkTreeView *tree_view)
 {
 	gtk_tree_view_expand_all(tree_view);
@@ -2440,6 +2445,7 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int
 				menuitem = gtk_menu_item_new_with_label(_("Edit dive date/time"));
 				g_signal_connect(menuitem, "activate", G_CALLBACK(edit_dive_when_cb), dive);
 				gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+
 			} else {
 				deletelabel = _(deleteplurallabel);
 				editlabel = _(editplurallabel);
@@ -2470,6 +2476,11 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int
 			g_signal_connect(menuitem, "activate", G_CALLBACK(edit_dive_from_path_cb), path);
 			gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
 		}
+
+		menuitem = gtk_menu_item_new_with_label(_("Show in map"));
+		g_signal_connect(menuitem, "activate", G_CALLBACK(show_gps_location_cb), dive);
+		gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+
 		/* only offer trip editing options when we are displaying the tree model */
 		if (dive_list.model == dive_list.treemodel) {
 			int depth = gtk_tree_path_get_depth(path);
@@ -2503,9 +2514,11 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int
 	menuitem = gtk_menu_item_new_with_label(_("Expand all"));
 	g_signal_connect(menuitem, "activate", G_CALLBACK(expand_all_cb), tree_view);
 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+
 	menuitem = gtk_menu_item_new_with_label(_("Collapse all"));
 	g_signal_connect(menuitem, "activate", G_CALLBACK(collapse_all_cb), tree_view);
 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+
 	gtk_widget_show_all(menu);
 
 	gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
diff --git a/flag.png b/flag.png
new file mode 100644
index 0000000000000000000000000000000000000000..56b3ce421a474a10d111b55dea907a0ef881c63f
GIT binary patch
literal 4314
zcmV<05GC)4P)<h;3K|Lk000e1NJLTq000;O000*V1^@s65h0H)00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000IBNkl<Zc-oAWTWr(k8ODF#|7id1#IX|`a6&=|kiZ~}0Hsur(XqCqU69&!D`Jx>
zA?;>|?q*xZZpN5YG*)Tb#iU8oR83mDQd$OW8KoU0KoUqfmf&#;g&as?C&YGQ`)~Vy
z+65YGX}j at A&&~V2-}iivUg>$onOF95KYWtJh-Eb%na;h at RPc^AEB3yY#nE$RezoY`
zDIv5u5RT#)0#ET!0s-8~BvP at 2H9p1IbdLC)DH3)OC7T$(?|F~B=MgZBjgLpdt)gJH
z`n=MQ`#wC~wRA!KzS%X4y0CoxND_#<{r?Nf(xCe3iU1Uq{!=HPnaCFD_~DO8%Yw7<
z^BWHDczHv|x<{v)m$#jWKD>Uf9Ps}W#Z927Unn5|dfPUPVBixBV$7;)xY6DH(xH8?
z>nmC|QrEVDrsZo$_QvVk|BAnGa;W*z^^4EUOsBSn=EfTIit?h6r4+VPaMLqnixv~6
zNzQeUcRcq3h~R%Ihp-CnxBK4fd^#|iWV(Nx`E6|km(=j3W$WRCI8L&knVW+Q9_uN)
z-hJ|+$(uKxS5>t=sA*M-s^!e0HI~R`$+`~0dozCDgmnfkoICjUoxghWt0j+7Zewoh
z;MqfeK>|`o`uWG^r-<btA}W~lrbv><G{TfOH&MNMRaUR7 at 14-p15<YCu)O2zTfj2!
zvXlp1iCsE!d{^S)DgRP5swvVp&`YY^$D+0C at XxPCn_b6;Z|@<D%K|E>N5`;o%!~~)
za`v(|*gw!XkxoCAm#LL^JpKq+cka at e1T*ukv-{t9PE3vw5*{Jp5TZbTcQ5rD+bOG^
zLsjb%CO#hL%EfNx5J46et_Hf|r^;2R%H`2+4U-*A?3E}u+@%eYpVZa(=Jbuzgk_aU
zRboh1sFA8!leg*p&QB?g<^Xu?w>vSGe~oKou%#fTr<2r5q=F{8RA3oyc3H;!o0Rbk
zragm{2$G(0YA>I>_-L+_C!na<iq41;W>_v~wlp8}Mh~6ae*=J48RE%5?Pgdr7<BR&
zZW%sXBj?&AG?NJ>e_AJVMPAm_!qurMh6 at E|MJhKR>+0SzGC79fK**IbB$bjZFzq5i
zp>X~}C*fEVvsNx4SThS*3et1*05Qs_7Jd|~M48aZQu?DwzDGVimF9!%mpObbjuQ;N
z)ZX4PuW9aLk(`<liBtm9N}^g0iX<>J6~i_e?7F~$%^j%G5V5uuOkB9d^(&`nlqxBA
z9YUU56u8?}<Z-#NZUF&ZM-$TGH+#E&v9@*P*7j}R|J|Ym3+?jy#+rPfyeyfTCS_)D
zZI>t!ils@$&tIkS8y(<RnY*%uf9-ppQaVAIuN=$HpQ?1!T@|i|TpOE*Bm{=8e@~T_
zroX<s=Lb);tQnnG*Kjae6Wg=+iB0kPRjryFsg9=eCErkHh at zKcVB{kh%TfRICbY^B
zu}GAj1Fun(T~O3N2*>To2 at g3or~YoldERbCQO=I$vIkyl|0WU5M=_I`Q9@<sjcD}M
zxhqz^-?VPkP^7KZC&JZrV>4;?96Lxr3DMNHma;E5lbf2MtM{-~Q01Qt`$-P!&OL#J
zz|VnS`ZawZlh3hfelx-Y$?$<~<7M+>vZ0)atXcYMLq~gO>(=KdVoi%@ojh~Avc92~
zaI}hs)ekeB$efrQxc0KFYaXhCSk<~7U^}o=KoCJOZRR=p-Jen0un7DLNCK~5BjgfP
z$`G9c^Qr+Ng_-nY+2rUJO!F(6Er$(@7t^;#cjI{=xaVLO&<nf)P;wlOT>gkhnp>!>
zt_Ifu+eJtY1Z2>CpawvbOhxy_HR0?@jVIr|eBsRPY%cRUhMq3SE=9>h0p<ehfQ|pj
zy9%G5zLAeP96!gx)ephM_~(bc3%Erb$3c?ixCe2oSj5Wbaa<Pw33wJ51G?|s^E^U+
zgOXjs%I83mc at PL85JG&aCIK%1`+?FY4{E|y{QkYSNZh&(p^E>z8ovk<a0z(pGrs|J
zRpZZ{hp?tIhzE4>c>>3Q5k9l}!KbQR9J+~JD#Cr%9~A!{0Ejk~^53%7c>n+a07*qo
IM6N<$f)H^$9{>OV

literal 0
HcmV?d00001

diff --git a/gps.c b/gps.c
index e0771ae..079b2aa 100644
--- a/gps.c
+++ b/gps.c
@@ -2,6 +2,7 @@
 /* Creates the UI displaying the dives locations on a map.
  */
 #include <glib/gi18n.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
 
 #include "osm-gps-map.h"
 
@@ -10,7 +11,10 @@
 #include "display-gtk.h"
 #include "divelist.h"
 
-static OsmGpsMapSource_t opt_map_provider = OSM_GPS_MAP_SOURCE_OPENSTREETMAP;
+/* Several map providers are available, such as OSM_GPS_MAP_SOURCE_OPENSTREETMAP
+   and OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE. We should make more of 
+   them available from e.g. a pull-down menu */
+static OsmGpsMapSource_t opt_map_provider = OSM_GPS_MAP_SOURCE_GOOGLE_STREET;
 
 
 static void on_close (GtkWidget *widget, gpointer user_data)
@@ -27,15 +31,11 @@ static void add_gps_point(OsmGpsMap *map, float latitude, float longitude)
 }
 
 
-void show_gps_locations()
+OsmGpsMap *init_map()
 {
-	GtkWidget *window;
-
 	OsmGpsMap *map;
 	OsmGpsMapLayer *osd;
 	char *cachedir, *cachebasedir;
-	int idx;
-	struct dive *dp;
 
 	cachebasedir = osm_gps_map_get_default_cache_directory();
 	cachedir = g_strdup(OSM_GPS_MAP_CACHE_AUTO);
@@ -59,14 +59,12 @@ void show_gps_locations()
 
 	osm_gps_map_layer_add(OSM_GPS_MAP(map), osd);
 	g_object_unref(G_OBJECT(osd));
-	for (idx = 0; idx < dive_table.nr; idx++) {
-		dp = dive_table.dives[idx];
-		if (dp->latitude.udeg != 0 && dp->longitude.udeg != 0){
-			add_gps_point(map, dp->latitude.udeg / 1000000.0,
-				dp->longitude.udeg / 1000000.0);
-		}
-	}
-	osm_gps_map_set_center_and_zoom(map, 0, 0, 0);
+	return map;
+}
+
+void show_map(OsmGpsMap *map)
+{
+	GtkWidget *window;
 
 	/* Enable keyboard navigation */
 	osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_FULLSCREEN, GDK_F11);
@@ -89,3 +87,50 @@ void show_gps_locations()
 
 	gtk_widget_show_all (window);
 }
+
+void show_gps_location(struct dive *dp)
+{
+	OsmGpsMap *map;
+	GError *gerror = NULL;
+	GdkPixbuf *picture;
+
+	double lat = dp->latitude.udeg / 1000000.0;
+	double lng = dp->longitude.udeg / 1000000.0;
+
+	map = init_map();
+
+	if (lat != 0 || lng != 0) {
+		add_gps_point(map, lat, lng);
+		osm_gps_map_set_center_and_zoom(map, lat, lng, 8);
+		picture = gdk_pixbuf_new_from_file("./flag.png", &gerror);
+		if (picture) {
+			osm_gps_map_image_add_with_alignment(map, lat, lng, picture, 0, 1);
+		} else {
+			printf("error message: %s\n", gerror->message);
+		}
+
+	} else {
+		osm_gps_map_set_center_and_zoom(map, 0, 0, 2);
+	}
+	show_map(map);
+}
+
+void show_gps_locations()
+{
+	OsmGpsMap *map;
+	struct dive *dp;
+	int idx;
+
+	map = init_map();
+
+	for (idx = 0; idx < dive_table.nr; idx++) {
+		dp = dive_table.dives[idx];
+		if (dp->latitude.udeg != 0 || dp->longitude.udeg != 0){
+			add_gps_point(map, dp->latitude.udeg / 1000000.0,
+				dp->longitude.udeg / 1000000.0);
+		}
+	}
+	osm_gps_map_set_center_and_zoom(map, 0, 0, 2);
+
+	show_map(map);
+}
-- 
1.8.0.1



More information about the subsurface mailing list