This is an automated email from the git hooks/post-receive script. ross-guest pushed a commit to branch master in repository osm-gps-map.
commit 996704e4a82e22fd3452ad524ea1eb17d4c3dfbb Author: David Paleino <da...@debian.org> Date: Fri Jan 8 22:06:45 2010 +0100 Imported Upstream version 0.4 --- .gitignore | 2 + ChangeLog | 18 -- Makefile.am | 24 ++- NEWS | 27 +++ TODO.tasks | 6 - configure.ac | 4 +- openstreetmap-gps-map.anjuta | 44 ----- python/configure.ac | 2 +- python/openstreetmap-gps-map.py | 174 +++++++++++++++++ python/osmgpsmap.defs | 83 +++++++- python/osmgpsmapmodule.c | 24 +-- python/test.sh | 23 --- src/main.c | 147 ++++---------- src/osm-gps-map-types.h | 5 + src/osm-gps-map.c | 424 ++++++++++++++++++++++++++++++++++++---- src/osm-gps-map.h | 42 ++-- 16 files changed, 768 insertions(+), 281 deletions(-) diff --git a/.gitignore b/.gitignore index fb87dc4..6527261 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ python/osmgpsmap.c src/Makefile src/openstreetmap-gps-map stamp-h1 +ChangeLog +COPYING diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index c9b8f0e..0000000 --- a/ChangeLog +++ /dev/null @@ -1,18 +0,0 @@ -2007-12-28 Johannes Schmid,,, <jhs@idefix> - - reviewed by: <delete if not using a buddy> - - * project.anjuta: - -2007-12-23 Johannes Schmid,,, <jhs@idefix> - - reviewed by: <delete if not using a buddy> - - * src/Makefile.am.tpl: - -2007-12-23 Johannes Schmid,,, <jhs@idefix> - - reviewed by: <delete if not using a buddy> - - * src/Makefile.am.tpl: - diff --git a/Makefile.am b/Makefile.am index ebe57ee..f5b08f0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,13 +26,35 @@ EXTRA_DIST = $(openstreetmap_gps_mapdoc_DATA) \ python/aclocal.m4 \ python/configure \ python/osmgpsmapmodule.c \ - python/test.sh \ + python/openstreetmap-gps-map.py \ python/AUTHORS \ python/configure.ac \ python/osmgpsmap.override \ python/NEWS \ python/README +# ChangeLog generation from nautils +distclean-local: + if test "$(srcdir)" = "."; then :; else \ + rm -f ChangeLog; \ + fi + +ChangeLog: + @echo Creating $@ + @if test -d "$(srcdir)/.git"; then \ + (GIT_DIR=$(top_srcdir)/.git ./missing --run git log 0.3.. --stat -M -C --name-status --date=short --no-color) | fmt --split-only > $@.tmp \ + && mv -f $@.tmp $@ \ + || ($(RM) $@.tmp; \ + echo Failed to generate ChangeLog, your ChangeLog may be outdated >&2; \ + (test -f $@ || echo git-log is required to generate this file >> $@)); \ + else \ + test -f $@ || \ + (echo A git checkout and git-log is required to generate ChangeLog >&2 && \ + echo A git checkout and git-log is required to generate this file >> $@); \ + fi + release: scp @PACKAGE@-@vers...@.tar.gz j...@open.grcnz.com:/srv/default/downloads/osm-gps-map/ +.PHONY: ChangeLog + diff --git a/NEWS b/NEWS index e69de29..aac5f58 100644 --- a/NEWS +++ b/NEWS @@ -0,0 +1,27 @@ +Changes in 0.4.0 + * Map can now be constructed by passing a MAP_SOURCE ID instead of + the map repo uri + * Fix iter safety when purging the tile cache + * Fix for segfault when adding images to the map + * Remove map repo uris from public API. They should now be retrieved using + osm_gps_map_source_get_repo_uri(OsmGpsMapSource_t source) + * Add osm_gps_map_get_scale + * Implement a blank map source that just draws grey tiles + * Demo application now stores maps in XDG_CACHE_DIR + * Fix build and crashes on windows + * Add getters for name and zoom + * Add a more complete python example + * Add ability to purge the cache + +Changes in 0.3.0 +====================== + * A new major contributor, Alberto Mardegan, + worked on many of the new features of this release. Thanks a lot Alberto! + * Draw map tracks with Cairo by default. + * Interpolate between zoom levels while waiting for a tile to download. + * Stop using GET_PRIVATE, and cache priv* for performance. + * Keep an extra border of images offscreen for smoother scrolling at + the edges of the map. + * Keep the last N tiles in memory to improve render performance + (previously they were loaded from disk) + * Add some new api; osm_gps_set_center, osm_gps_map_scroll. diff --git a/TODO.tasks b/TODO.tasks deleted file mode 100644 index d1fa282..0000000 --- a/TODO.tasks +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0"?> -<gtodo> - <category title="Personal" place="0"/> - <category title="Business" place="1"/> - <category title="Unfiled" place="2"/> -</gtodo> diff --git a/configure.ac b/configure.ac index 0eb98c2..edb063c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(osm-gps-map, 0.2) +AC_INIT(osm-gps-map, 0.4.0) AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) AC_CONFIG_SRCDIR(osmgpsmap.pc.in) @@ -30,6 +30,8 @@ if test "x$enable_cairo" = "xyes"; then OPENSTREETMAP_GPS_MAP_LIBS="$OPENSTREETMAP_GPS_MAP_LIBS $CAIRO_LIBS" fi +CFLAGS="$CFLAGS -Wall -Wswitch-enum" + AC_OUTPUT([ osmgpsmap.pc Makefile diff --git a/openstreetmap-gps-map.anjuta b/openstreetmap-gps-map.anjuta deleted file mode 100644 index 51ddd65..0000000 --- a/openstreetmap-gps-map.anjuta +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0"?> -<anjuta> - <plugin name="GBF Project Manager" - url="http://anjuta.org/plugins/" - mandatory="yes"> - <require group="Anjuta Plugin" - attribute="Interfaces" - value="IAnjutaProjectManager"/> - <require group="Project" - attribute="Supported-Project-Types" - value="automake"/> - </plugin> - <plugin name="Symbol Browser" - url="http://anjuta.org/plugins/" - mandatory="yes"> - <require group="Anjuta Plugin" - attribute="Interfaces" - value="IAnjutaSymbolManager"/> - </plugin> - <plugin name="Make Build System" - url="http://anjuta.org/plugins/" - mandatory="yes"> - <require group="Anjuta Plugin" - attribute="Interfaces" - value="IAnjutaBuildable"/> - <require group="Build" - attribute="Supported-Build-Types" - value="make"/> - </plugin> - <plugin name="Task Manager" - url="http://anjuta.org/plugins/" - mandatory="no"> - <require group="Anjuta Plugin" - attribute="Interfaces" - value="IAnjutaTodo"/> - </plugin> - <plugin name="Debug Manager" - url="http://anjuta.org/plugins/" - mandatory="no"> - <require group="Anjuta Plugin" - attribute="Interfaces" - value="IAnjutaDebuggerManager"/> - </plugin> -</anjuta> diff --git a/python/configure.ac b/python/configure.ac index 385c2b5..0f74ba6 100644 --- a/python/configure.ac +++ b/python/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.53) -AC_INIT(osmgpsmap-python, 0.1) +AC_INIT(osmgpsmap-python, 0.4.0) AC_CONFIG_SRCDIR(osmgpsmap.defs) AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) diff --git a/python/openstreetmap-gps-map.py b/python/openstreetmap-gps-map.py new file mode 100755 index 0000000..6dfcdc6 --- /dev/null +++ b/python/openstreetmap-gps-map.py @@ -0,0 +1,174 @@ +#!/usr/bin/python + +""" + Copyright (C) Hadley Rich 2008 <h...@nice.net.nz> + based on main.c - with thanks to John Stowers + + osm-gps.py is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + osm-gps.py is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see <http://www.gnu.org/licenses/>. +""" + +import sys +import os.path +import gtk.gdk +import gobject + +#Try static lib first +mydir = os.path.dirname(os.path.abspath(__file__)) +libdir = os.path.join(mydir, ".libs") +sys.path.insert(0, libdir) + +import osmgpsmap + +class UI(gtk.Window): + def __init__(self): + gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) + + self.set_default_size(500, 500) + self.connect('destroy', lambda x: gtk.main_quit()) + self.set_title('OpenStreetMap GPS Mapper') + + self.vbox = gtk.VBox(False, 0) + self.add(self.vbox) + + self.osm = osmgpsmap.GpsMap( + tile_cache=osmgpsmap.get_default_cache_directory(), + ) + self.osm.connect('button_release_event', self.map_clicked) + self.latlon_entry = gtk.Entry() + + zoom_in_button = gtk.Button(stock=gtk.STOCK_ZOOM_IN) + zoom_in_button.connect('clicked', self.zoom_in_clicked) + zoom_out_button = gtk.Button(stock=gtk.STOCK_ZOOM_OUT) + zoom_out_button.connect('clicked', self.zoom_out_clicked) + home_button = gtk.Button(stock=gtk.STOCK_HOME) + home_button.connect('clicked', self.home_clicked) + cache_button = gtk.Button('Cache') + cache_button.connect('clicked', self.cache_clicked) + + self.vbox.pack_start(self.osm) + hbox = gtk.HBox(False, 0) + hbox.pack_start(zoom_in_button) + hbox.pack_start(zoom_out_button) + hbox.pack_start(home_button) + hbox.pack_start(cache_button) + + #add ability to test custom map URIs + ex = gtk.Expander("<b>Map Repository URI</b>") + ex.props.use_markup = True + vb = gtk.VBox() + self.repouri_entry = gtk.Entry() + self.repouri_entry.set_text(self.osm.props.repo_uri) + self.image_format_entry = gtk.Entry() + self.image_format_entry.set_text(self.osm.props.image_format) + gobtn = gtk.Button("Load Map URI") + gobtn.connect("clicked", self.load_map_clicked) + exp = gtk.Label( +""" +Enter an repository URL to fetch map tiles from in the box below. Special metacharacters may be included in this url + +<i>Metacharacters:</i> +\t#X\tMax X location +\t#Y\tMax Y location +\t#Z\tMap zoom (0 = min zoom, fully zoomed out) +\t#S\tInverse zoom (max-zoom - #Z) +\t#Q\tQuadtree encoded tile (qrts) +\t#W\tQuadtree encoded tile (1234) +\t#U\tEncoding not implemeted +\t#R\tRandom integer, 0-4""") + exp.props.xalign = 0 + exp.props.use_markup = True + exp.props.wrap = True + + ex.add(vb) + vb.pack_start(exp, False) + + hb = gtk.HBox() + hb.pack_start(gtk.Label("URI: "), False) + hb.pack_start(self.repouri_entry, True) + vb.pack_start(hb, False) + + hb = gtk.HBox() + hb.pack_start(gtk.Label("Image Format: "), False) + hb.pack_start(self.image_format_entry, True) + vb.pack_start(hb, False) + + vb.pack_start(gobtn, False) + + self.vbox.pack_end(ex, False) + self.vbox.pack_end(self.latlon_entry, False) + self.vbox.pack_end(hbox, False) + + gobject.timeout_add(500, self.print_tiles) + + def load_map_clicked(self, button): + uri = self.repouri_entry.get_text() + format = self.image_format_entry.get_text() + if uri and format: + if self.osm: + #remove old map + self.vbox.remove(self.osm) + + try: + self.osm = osmgpsmap.GpsMap( + tile_cache=osmgpsmap.get_default_cache_directory(), + repo_uri=uri, + image_format=format + ) + self.osm.connect('button_release_event', self.map_clicked) + except Exception, e: + print "ERROR:", e + self.osm = osm.GpsMap() + + self.vbox.pack_start(self.osm, True) + self.osm.connect('button_release_event', self.map_clicked) + self.osm.show() + + def print_tiles(self): + if self.osm.props.tiles_queued != 0: + print self.osm.props.tiles_queued, 'tiles queued' + return True + + def zoom_in_clicked(self, button): + self.osm.set_zoom(self.osm.props.zoom + 1) + + def zoom_out_clicked(self, button): + self.osm.set_zoom(self.osm.props.zoom - 1) + + def home_clicked(self, button): + self.osm.set_mapcenter(-44.39, 171.25, 12) + + def cache_clicked(self, button): + bbox = self.osm.get_bbox() + self.osm.download_maps( + *bbox, + zoom_start=self.osm.props.zoom, + zoom_end=self.osm.props.max_zoom + ) + + def map_clicked(self, osm, event): + self.latlon_entry.set_text( + 'Map Centre: latitude %s longitude %s' % ( + self.osm.props.latitude, + self.osm.props.longitude + ) + ) + + +if __name__ == "__main__": + gtk.gdk.threads_init() + + u = UI() + u.show_all() + gtk.main() + diff --git a/python/osmgpsmap.defs b/python/osmgpsmap.defs index 3ac06d8..6999044 100644 --- a/python/osmgpsmap.defs +++ b/python/osmgpsmap.defs @@ -8,7 +8,26 @@ ) ;; Enumerations and flags ... - +(define-enum MapSource + (in-module "Osm") + (c-name "OsmGpsMapSource_t") + (values + '("None" "OSM_GPS_MAP_SOURCE_NULL") + '("OpenStreetMap" "OSM_GPS_MAP_SOURCE_OPENSTREETMAP") + '("OpenStreetMap Renderer" "OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER") + '("OpenAerialMap" "OSM_GPS_MAP_SOURCE_OPENAERIALMAP") + '("Maps For Free" "OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE") + '("Google Maps" "OSM_GPS_MAP_SOURCE_GOOGLE_STREET") + '("Google Satellite" "OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE") + '("Google Maps Hybrid" "OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID") + '("Virtual Earth" "OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET") + '("Virtual Earth Satellite" "OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE") + '("Virtual Earth Hybrid" "OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID") + '("Yahoo Maps" "OSM_GPS_MAP_SOURCE_YAHOO_STREET") + '("Yahoo Maps Satellite" "OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE") + '("Yahoo Maps Hybrid" "OSM_GPS_MAP_SOURCE_YAHOO_HYBRID") + ) +) ;; From osm-gps-map.h @@ -17,6 +36,11 @@ (return-type "GType") ) +(define-function get_default_cache_directory + (c-name "osm_gps_map_get_default_cache_directory") + (return-type "char*") +) + (define-method download_maps (of-object "OsmGpsMap") (c-name "osm_gps_map_download_maps") @@ -95,6 +119,15 @@ ) ) +(define-method remove_image + (of-object "OsmGpsMap") + (c-name "osm_gps_map_remove_image") + (return-type "gboolean") + (parameters + '("GdkPixbuf*" "image") + ) +) + (define-method clear_images (of-object "OsmGpsMap") (c-name "osm_gps_map_clear_images") @@ -155,6 +188,8 @@ '("min_zoom" (optional)) '("map_x" (optional)) '("map_Y" (optional)) + '("map_source" (optional)) + '("image_format" (optional)) ) ) @@ -192,3 +227,49 @@ ) ) +(define-method get_scale + (of-object "OsmGpsMap") + (c-name "osm_gps_map_get_scale") + (return-type "float") +) + +(define-function source_get_repo_uri + (c-name "osm_gps_map_source_get_repo_uri") + (return-type "const-char*") + (parameters + '("OsmGpsMapSource_t" "source") + ) +) + +(define-function source_get_friendly_name + (c-name "osm_gps_map_source_get_friendly_name") + (return-type "const-char*") + (parameters + '("OsmGpsMapSource_t" "source") + ) +) + +(define-function source_get_max_zoom + (c-name "osm_gps_map_source_get_max_zoom") + (return-type "int") + (parameters + '("OsmGpsMapSource_t" "source") + ) +) + +(define-function source_get_min_zoom + (c-name "osm_gps_map_source_get_min_zoom") + (return-type "int") + (parameters + '("OsmGpsMapSource_t" "source") + ) +) + +(define-function source_get_image_format + (c-name "osm_gps_map_source_get_image_format") + (return-type "const-char*") + (parameters + '("OsmGpsMapSource_t" "source") + ) +) + diff --git a/python/osmgpsmapmodule.c b/python/osmgpsmapmodule.c index c1163a3..e9b22c8 100644 --- a/python/osmgpsmapmodule.c +++ b/python/osmgpsmapmodule.c @@ -34,29 +34,7 @@ initosmgpsmap(void) d = PyModule_GetDict(m); pyosmgpsmap_register_classes(d); - - /* Add this if we ever add an enum or something to osmgpsmap. */ -#if 0 - pyosmgpsmap_add_constants(m, "OSM_GPS_MAP_"); -#endif - - /* Manually add all the Map repository strings */ - PyModule_AddObject(m, "MAP_SOURCE_OPENSTREETMAP", - PyString_FromString(MAP_SOURCE_OPENSTREETMAP)); - PyModule_AddObject(m, "MAP_SOURCE_OPENSTREETMAP_RENDERER", - PyString_FromString(MAP_SOURCE_OPENSTREETMAP_RENDERER)); - PyModule_AddObject(m, "MAP_SOURCE_OPENAERIALMAP", - PyString_FromString(MAP_SOURCE_OPENAERIALMAP)); - PyModule_AddObject(m, "MAP_SOURCE_GOOGLE_HYBRID", - PyString_FromString(MAP_SOURCE_GOOGLE_HYBRID)); - PyModule_AddObject(m, "MAP_SOURCE_GOOGLE_SATTELITE", - PyString_FromString(MAP_SOURCE_GOOGLE_SATTELITE)); - PyModule_AddObject(m, "MAP_SOURCE_GOOGLE_SATTELITE_QUAD", - PyString_FromString(MAP_SOURCE_GOOGLE_SATTELITE_QUAD)); - PyModule_AddObject(m, "MAP_SOURCE_MAPS_FOR_FREE", - PyString_FromString(MAP_SOURCE_MAPS_FOR_FREE)); - PyModule_AddObject(m, "MAP_SOURCE_VIRTUAL_EARTH_SATTELITE", - PyString_FromString(MAP_SOURCE_VIRTUAL_EARTH_SATTELITE)); + pyosmgpsmap_add_constants(m, "OSM_GPS_MAP_"); if (PyErr_Occurred()) { Py_FatalError("can't initialize module osmgpsmap"); diff --git a/python/test.sh b/python/test.sh deleted file mode 100755 index d624efb..0000000 --- a/python/test.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -PYTHONPATH=`pwd`/.libs \ - python -c \ -'import gtk.gdk -import gobject -import osmgpsmap - -gtk.gdk.threads_init() - -def print_tiles(map): - print map.get_property("tiles-queued") - return True - -a = gtk.Window() -a.connect("destroy", lambda x: gtk.main_quit()) -m = osmgpsmap.GpsMap() - -a.add(m) -a.show_all() - -gobject.timeout_add(500, print_tiles, m) - -gtk.main()' diff --git a/src/main.c b/src/main.c index aa90c16..0603822 100644 --- a/src/main.c +++ b/src/main.c @@ -24,24 +24,7 @@ #include <gtk/gtk.h> #include "osm-gps-map.h" -typedef struct { - const char *name; - const char *uri; -} map_source_t; - -static const map_source_t MAP_SOURCES[] = { - {"OpenStreetMap", MAP_SOURCE_OPENSTREETMAP }, - {"OpenStreetMap Renderer", MAP_SOURCE_OPENSTREETMAP_RENDERER }, - {"OpenAerialMap", MAP_SOURCE_OPENAERIALMAP }, - {"Google Maps", MAP_SOURCE_GOOGLE_MAPS }, - {"Google Maps Hybrid", MAP_SOURCE_GOOGLE_HYBRID }, - {"Google Sattelite", MAP_SOURCE_GOOGLE_SATTELITE }, - {"Google Sattelite Quad", MAP_SOURCE_GOOGLE_SATTELITE_QUAD }, - {"Maps For Free", MAP_SOURCE_MAPS_FOR_FREE }, - {"Virtual Earth Sattelite", MAP_SOURCE_VIRTUAL_EARTH_SATTELITE }, -}; - -static int map_provider = 0; +static OsmGpsMapSource_t map_provider = 0; static gboolean maps_in_temp = FALSE; static gboolean debug = FALSE; static GOptionEntry entries[] = @@ -52,7 +35,6 @@ static GOptionEntry entries[] = { NULL } }; - static GdkPixbuf *STAR_IMAGE; typedef struct { @@ -60,17 +42,8 @@ typedef struct { GtkWidget *entry; } timeout_cb_t; -float -deg2rad(float deg) -{ - return (deg * M_PI / 180.0); -} - -float -rad2deg(float rad) -{ - return (rad / M_PI * 180.0); -} +#define DEG2RAD(deg) (deg * M_PI / 180.0) +#define RAD2DEG(rad) (rad / M_PI * 180.0) gboolean on_timeout_check_tiles_in_queue(gpointer user_data) @@ -98,8 +71,8 @@ on_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_d g_debug("Double clicked %f %f", event->x, event->y); coord = osm_gps_map_get_co_ordinates(map, (int)event->x, (int)event->y); osm_gps_map_draw_gps (map, - rad2deg(coord.rlat), - rad2deg(coord.rlon), + RAD2DEG(coord.rlat), + RAD2DEG(coord.rlon), 0); } @@ -107,8 +80,8 @@ on_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_d { coord = osm_gps_map_get_co_ordinates(map, (int)event->x, (int)event->y); osm_gps_map_add_image (map, - rad2deg(coord.rlat), - rad2deg(coord.rlon), + RAD2DEG(coord.rlat), + RAD2DEG(coord.rlon), STAR_IMAGE); } return FALSE; @@ -188,11 +161,13 @@ usage (GOptionContext *context) puts(g_option_context_get_help(context, TRUE, NULL)); printf("Valid map sources:\n"); - for(i=0; i<(sizeof(MAP_SOURCES)/sizeof(MAP_SOURCES[0])); i++) - printf("\t%d:\t%s\n",i,MAP_SOURCES[i].name); + for(i=OSM_GPS_MAP_SOURCE_NULL; i <= OSM_GPS_MAP_SOURCE_YAHOO_HYBRID; i++) + { + const char *name = osm_gps_map_source_get_friendly_name(i); + printf("\t%d:\t%s\n",i,name); + } } - int main (int argc, char **argv) { @@ -205,8 +180,10 @@ main (int argc, char **argv) GtkWidget *homeButton; GtkWidget *cacheButton; GtkWidget *map; + const char *repo_uri; + const char *friendly_name; char *cachedir; - char *homedir; + gboolean fullpath; GError *error = NULL; GOptionContext *context; timeout_cb_t *data; @@ -214,7 +191,7 @@ main (int argc, char **argv) g_thread_init(NULL); gtk_init (&argc, &argv); - context = g_option_context_new ("- test tree model performance"); + context = g_option_context_new ("- Map browser"); g_option_context_set_help_enabled(context, FALSE); g_option_context_add_main_entries (context, entries, NULL); @@ -223,17 +200,25 @@ main (int argc, char **argv) return 1; } - if (map_provider < 0 || map_provider > (sizeof(MAP_SOURCES)/sizeof(MAP_SOURCES[0]))-1) { + /* Only use the repo_uri to check if the user has supplied a + valid map source ID */ + repo_uri = osm_gps_map_source_get_repo_uri(map_provider); + if ( repo_uri == NULL ) { usage(context); return 2; } - if (maps_in_temp) - homedir = g_strdup("/tmp"); - else { - homedir = g_strdup(g_getenv("HOME")); - if (!homedir) - homedir = g_strdup(g_get_home_dir()); + friendly_name = osm_gps_map_source_get_friendly_name(map_provider); + + if (maps_in_temp) { + cachedir = NULL; + fullpath = FALSE; + } else { + char *mapcachedir; + mapcachedir = osm_gps_map_get_default_cache_directory(); + cachedir = g_build_filename(mapcachedir,friendly_name,NULL); + g_free(mapcachedir); + fullpath = TRUE; } if (debug) @@ -243,68 +228,18 @@ main (int argc, char **argv) gtk_window_set_default_size(GTK_WINDOW(window), 400, 400); STAR_IMAGE = gdk_pixbuf_new_from_file_at_size ("poi.png", 24,24,NULL); - cachedir = g_strdup_printf("%s/Maps/%s", homedir, MAP_SOURCES[map_provider].name); g_debug("Map Cache Dir: %s", cachedir); - g_debug("Map Provider: %s (%d)", MAP_SOURCES[map_provider].name, map_provider); - - switch(map_provider) { - //0: OpenStreetMap - //1: OpenStreetMap Renderer - //2: OpenAerialMap - //3: Google Maps - //4: Google Maps Hybrid - //5: Google Sattelite - //6: Google Sattelite Quad - //7: Maps For Free - //8: Virtual Earth Sattelite - case 0: - case 1: - case 2: - case 3: - case 4: - default: - map = g_object_new (OSM_TYPE_GPS_MAP, - "repo-uri",MAP_SOURCES[map_provider].uri, - "tile-cache",cachedir, - "tile-cache-is-full-path",TRUE, - "proxy-uri",g_getenv("http_proxy"), - NULL); - break; - case 7: - //Max Zoom = 11 - map = g_object_new (OSM_TYPE_GPS_MAP, - "repo-uri",MAP_SOURCES[map_provider].uri, - "tile-cache",cachedir, - "tile-cache-is-full-path",TRUE, - "proxy-uri",g_getenv("http_proxy"), - "max-zoom",11, - NULL); - break; - case 5: - case 6: - //Max Zoom = 18 - map = g_object_new (OSM_TYPE_GPS_MAP, - "repo-uri",MAP_SOURCES[map_provider].uri, - "tile-cache",cachedir, - "tile-cache-is-full-path",TRUE, - "proxy-uri",g_getenv("http_proxy"), - "max-zoom",18, - NULL); - break; - case 8: - //Max Zoom = 20 - map = g_object_new (OSM_TYPE_GPS_MAP, - "repo-uri",MAP_SOURCES[map_provider].uri, - "tile-cache",cachedir, - "tile-cache-is-full-path",TRUE, - "proxy-uri",g_getenv("http_proxy"), - "max-zoom",20, - NULL); - break; - } - g_free(cachedir); + g_debug("Map Provider: %s (%d)", friendly_name, map_provider); + + map = g_object_new (OSM_TYPE_GPS_MAP, + "map-source",map_provider, + "tile-cache",cachedir, + "tile-cache-is-full-path",fullpath, + "proxy-uri",g_getenv("http_proxy"), + NULL); + g_free(cachedir); vbox = gtk_vbox_new (FALSE, 2); gtk_container_add (GTK_CONTAINER (window), vbox); @@ -356,6 +291,6 @@ main (int argc, char **argv) g_log_set_handler ("OsmGpsMap", G_LOG_LEVEL_MASK, g_log_default_handler, NULL); gtk_main (); - g_free(homedir); + g_free(cachedir); return 0; } diff --git a/src/osm-gps-map-types.h b/src/osm-gps-map-types.h index bc3c415..47c90df 100644 --- a/src/osm-gps-map-types.h +++ b/src/osm-gps-map-types.h @@ -32,6 +32,11 @@ #define MAX_ZOOM 20 #define MIN_ZOOM 0 +#define OSM_REPO_URI "http://tile.openstreetmap.org/#Z/#X/#Y.png" +#define OSM_MIN_ZOOM 1 +#define OSM_MAX_ZOOM 18 +#define OSM_IMAGE_FORMAT "png" + #define URI_MARKER_X "#X" #define URI_MARKER_Y "#Y" #define URI_MARKER_Z "#Z" diff --git a/src/osm-gps-map.c b/src/osm-gps-map.c index e25a33a..2a0a5f6 100644 --- a/src/osm-gps-map.c +++ b/src/osm-gps-map.c @@ -83,7 +83,9 @@ struct _OsmGpsMapPrivate //contains flags indicating the various special characters //the uri string contains, that will be replaced when calculating //the uri to download. + OsmGpsMapSource_t map_source; char *repo_uri; + char *image_format; int uri_format; //flag indicating if the map source is located on the google gboolean the_google; @@ -104,7 +106,7 @@ struct _OsmGpsMapPrivate GdkGC *gc_map; //The tile painted when one cannot be found - //GdkPixbuf *missing_tile; + GdkPixbuf *null_tile; //For tracking click and drag int drag_counter; @@ -157,7 +159,9 @@ enum PROP_TILES_QUEUED, PROP_GPS_TRACK_WIDTH, PROP_GPS_POINT_R1, - PROP_GPS_POINT_R2 + PROP_GPS_POINT_R2, + PROP_MAP_SOURCE, + PROP_IMAGE_FORMAT }; G_DEFINE_TYPE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA); @@ -421,6 +425,59 @@ my_log_handler (const gchar * log_domain, GLogLevelFlags log_level, const gchar g_log_default_handler (log_domain, log_level, message, user_data); } +static float +osm_gps_map_get_scale_at_point(int zoom, float rlat, float rlon) +{ + /* This is a naieve implementation with values from + http://wiki.openstreetmap.org/index.php/FAQ#What_is_the_map_scale_for_a_particular_zoom_level_of_the_map.3F + http://almien.co.uk/OSM/Tools/Scale/ + + The true scale, becase of the mercator projection of all supported map + sources, depends on the lat and lon of the point */ + switch (zoom) { + case 0: + return 156412.0; + case 1: + return 78206.0; + case 2: + return 39135.758482; + case 3: + return 19567.879241; + case 4: + return 9783.939621; + case 5: + return 4891.969810; + case 6: + return 2445.984905; + case 7: + return 1222.992453; + case 8: + return 611.496226; + case 9: + return 305.748113; + case 10: + return 152.874057; + case 11: + return 76.437028; + case 12: + return 38.218514; + case 13: + return 19.109257; + case 14: + return 9.554629; + case 15: + return 4.777314; + case 16: + return 2.388657; + case 17: + return 1.194329; + case 18: + return 0.597164; + } + + return 0.0; +} + /* clears the trip list and all resources */ static void osm_gps_map_free_trip (OsmGpsMap *map) @@ -637,7 +694,7 @@ osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offse static void osm_gps_map_tile_download_complete (SoupSession *session, SoupMessage *msg, gpointer user_data) { - int fd; + FILE *file; tile_download_t *dl = (tile_download_t *)user_data; OsmGpsMap *map = OSM_GPS_MAP(dl->map); OsmGpsMapPrivate *priv = map->priv; @@ -646,12 +703,12 @@ osm_gps_map_tile_download_complete (SoupSession *session, SoupMessage *msg, gpoi { if (g_mkdir_with_parents(dl->folder,0700) == 0) { - fd = open(dl->filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd != -1) + file = g_fopen(dl->filename, "wb"); + if (file != NULL) { - write (fd, msg->response_body->data, msg->response_body->length); + fwrite (msg->response_body->data, 1, msg->response_body->length, file); g_debug("Wrote %lld bytes to %s", msg->response_body->length, dl->filename); - close (fd); + fclose (file); if (dl->redraw) { @@ -728,8 +785,16 @@ osm_gps_map_download_tile (OsmGpsMap *map, int zoom, int x, int y, gboolean redr g_free(dl->uri); g_free(dl); } else { - dl->folder = g_strdup_printf("%s/%d/%d/",priv->cache_dir, zoom, x); - dl->filename = g_strdup_printf("%s/%d/%d/%d.png",priv->cache_dir, zoom, x, y); + dl->folder = g_strdup_printf("%s%c%d%c%d%c", + priv->cache_dir, G_DIR_SEPARATOR, + zoom, G_DIR_SEPARATOR, + x, G_DIR_SEPARATOR); + dl->filename = g_strdup_printf("%s%c%d%c%d%c%d.%s", + priv->cache_dir, G_DIR_SEPARATOR, + zoom, G_DIR_SEPARATOR, + x, G_DIR_SEPARATOR, + y, + priv->image_format); dl->map = map; dl->redraw = redraw; @@ -771,9 +836,12 @@ osm_gps_map_load_cached_tile (OsmGpsMap *map, int zoom, int x, int y) GdkPixbuf *pixbuf; OsmCachedTile *tile; - filename = g_strdup_printf("%s/%u/%u/%u.png", - priv->cache_dir, - zoom, x, y); + filename = g_strdup_printf("%s%c%d%c%d%c%d.%s", + priv->cache_dir, G_DIR_SEPARATOR, + zoom, G_DIR_SEPARATOR, + x, G_DIR_SEPARATOR, + y, + priv->image_format); tile = g_hash_table_lookup (priv->tile_cache, filename); if (tile) @@ -865,9 +933,17 @@ osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int g_debug("Load tile %d,%d (%d,%d) z:%d", x, y, offset_x, offset_y, zoom); - filename = g_strdup_printf("%s/%u/%u/%u.png", - priv->cache_dir, - zoom, x, y); + if (priv->map_source == OSM_GPS_MAP_SOURCE_NULL) { + osm_gps_map_blit_tile(map, priv->null_tile, offset_x,offset_y); + return; + } + + filename = g_strdup_printf("%s%c%d%c%d%c%d.%s", + priv->cache_dir, G_DIR_SEPARATOR, + zoom, G_DIR_SEPARATOR, + x, G_DIR_SEPARATOR, + y, + priv->image_format); pixbuf = gdk_pixbuf_new_from_file (filename, NULL); if(pixbuf) @@ -1051,9 +1127,9 @@ osm_gps_map_print_tracks (OsmGpsMap *map) if (priv->show_trip_history) osm_gps_map_print_track (map, priv->trip_history); + if (priv->tracks) { - g_debug("TRACK"); GSList* tmp = priv->tracks; while (tmp != NULL) { @@ -1063,24 +1139,23 @@ osm_gps_map_print_tracks (OsmGpsMap *map) } } +static gboolean +osm_gps_map_purge_cache_check(gpointer key, gpointer value, gpointer user) +{ + return (((OsmCachedTile*)value)->redraw_cycle != ((OsmGpsMapPrivate*)user)->redraw_cycle); +} + static void osm_gps_map_purge_cache (OsmGpsMap *map) { - OsmGpsMapPrivate *priv = map->priv; - GHashTableIter iter; - OsmCachedTile *tile; + OsmGpsMapPrivate *priv = map->priv; - if (g_hash_table_size (priv->tile_cache) < priv->max_tile_cache_size) - return; + if (g_hash_table_size (priv->tile_cache) < priv->max_tile_cache_size) + return; - /* run through the cache, and remove the tiles which have not been used - * during the last redraw operation */ - g_hash_table_iter_init (&iter, priv->tile_cache); - while (g_hash_table_iter_next (&iter, NULL, (gpointer)&tile)) - { - if (tile->redraw_cycle != priv->redraw_cycle) - g_hash_table_iter_remove (&iter); - } + /* run through the cache, and remove the tiles which have not been used + * during the last redraw operation */ + g_hash_table_foreach_remove(priv->tile_cache, osm_gps_map_purge_cache_check, priv); } static gboolean @@ -1156,6 +1231,8 @@ osm_gps_map_init (OsmGpsMap *object) priv->uri_format = 0; priv->the_google = FALSE; + priv->map_source = -1; + //Change naumber of concurrent connections option? priv->soup_session = soup_session_async_new_with_options( SOUP_SESSION_USER_AGENT, @@ -1188,18 +1265,45 @@ osm_gps_map_constructor (GType gtype, guint n_properties, GObjectConstructParam { GObject *object; OsmGpsMapPrivate *priv; + OsmGpsMap *map; + const char *uri, *name; //Always chain up to the parent constructor object = G_OBJECT_CLASS(osm_gps_map_parent_class)->constructor(gtype, n_properties, properties); + map = OSM_GPS_MAP(object); priv = OSM_GPS_MAP_PRIVATE(object); + //user can specify a map source ID, or a repo URI as the map source + uri = osm_gps_map_source_get_repo_uri(OSM_GPS_MAP_SOURCE_NULL); + if ( (priv->map_source == 0) || (strcmp(priv->repo_uri, uri) == 0) ) { + g_debug("Using null source"); + priv->map_source = OSM_GPS_MAP_SOURCE_NULL; + + priv->null_tile = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 256, 256); + gdk_pixbuf_fill(priv->null_tile, 0xcccccc00); + } + else if (priv->map_source >= 0) { + //check if the source given is valid + uri = osm_gps_map_source_get_repo_uri(priv->map_source); + if (uri) { + g_debug("Setting map source from ID"); + g_free(priv->repo_uri); + + priv->repo_uri = g_strdup(uri); + priv->image_format = g_strdup( + osm_gps_map_source_get_image_format(priv->map_source)); + priv->max_zoom = osm_gps_map_source_get_max_zoom(priv->map_source); + priv->min_zoom = osm_gps_map_source_get_min_zoom(priv->map_source); + } + } + if (!priv->cache_dir_is_full_path) { char *md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, priv->repo_uri, -1); if (priv->cache_dir) { char *old = priv->cache_dir; //the new cachedir is the given cache dir + the md5 of the repo_uri - priv->cache_dir = g_strdup_printf("%s/%s", old, md5); + priv->cache_dir = g_strdup_printf("%s%c%s", old, G_DIR_SEPARATOR, md5); g_debug("Adjusting cache dir %s -> %s", old, priv->cache_dir); g_free(old); } else { @@ -1210,6 +1314,8 @@ osm_gps_map_constructor (GType gtype, guint n_properties, GObjectConstructParam g_free(md5); } + inspect_map_uri(map); + return object; } @@ -1236,6 +1342,9 @@ osm_gps_map_dispose (GObject *object) if(priv->pixmap) g_object_unref (priv->pixmap); + if (priv->null_tile) + g_object_unref (priv->null_tile); + if(priv->gc_map) g_object_unref(priv->gc_map); @@ -1253,6 +1362,7 @@ osm_gps_map_finalize (GObject *object) g_free(priv->cache_dir); g_free(priv->repo_uri); + g_free(priv->image_format); osm_gps_map_free_trip(map); osm_gps_map_free_tracks(map); @@ -1283,7 +1393,6 @@ osm_gps_map_set_property (GObject *object, guint prop_id, const GValue *value, G break; case PROP_REPO_URI: priv->repo_uri = g_value_dup_string (value); - inspect_map_uri(map); break; case PROP_PROXY_URI: if ( g_value_get_string(value) ) { @@ -1302,7 +1411,14 @@ osm_gps_map_set_property (GObject *object, guint prop_id, const GValue *value, G break; case PROP_TILE_CACHE_DIR: - priv->cache_dir = g_value_dup_string (value); + if ( g_value_get_string(value) ) + priv->cache_dir = g_value_dup_string (value); + else { + priv->cache_dir = g_build_filename( + g_get_tmp_dir(), + "osmgpsmap", + NULL); + } break; case PROP_TILE_CACHE_DIR_IS_FULL_PATH: priv->cache_dir_is_full_path = g_value_get_boolean (value); @@ -1333,6 +1449,12 @@ osm_gps_map_set_property (GObject *object, guint prop_id, const GValue *value, G case PROP_GPS_POINT_R2: priv->ui_gps_point_outer_radius = g_value_get_int (value); break; + case PROP_MAP_SOURCE: + priv->map_source = g_value_get_int (value); + break; + case PROP_IMAGE_FORMAT: + priv->image_format = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1410,6 +1532,12 @@ osm_gps_map_get_property (GObject *object, guint prop_id, GValue *value, GParamS case PROP_GPS_POINT_R2: g_value_set_int(value, priv->ui_gps_point_outer_radius); break; + case PROP_MAP_SOURCE: + g_value_set_int(value, priv->map_source); + break; + case PROP_IMAGE_FORMAT: + g_value_set_string(value, priv->image_format); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1417,7 +1545,7 @@ osm_gps_map_get_property (GObject *object, guint prop_id, GValue *value, GParamS } static gboolean -_osm_gps_map_scroll (GtkWidget *widget, GdkEventScroll *event) +osm_gps_map_scroll_event (GtkWidget *widget, GdkEventScroll *event) { OsmGpsMap *map = OSM_GPS_MAP(widget); OsmGpsMapPrivate *priv = map->priv; @@ -1623,7 +1751,7 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) widget_class->button_press_event = osm_gps_map_button_press; widget_class->button_release_event = osm_gps_map_button_release; widget_class->motion_notify_event = osm_gps_map_motion_notify; - widget_class->scroll_event = _osm_gps_map_scroll; + widget_class->scroll_event = osm_gps_map_scroll_event; g_object_class_install_property (object_class, PROP_AUTO_CENTER, @@ -1661,11 +1789,11 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) PROP_REPO_URI, g_param_spec_string ("repo-uri", "repo uri", - "osm repo uri", - "http://tile.openstreetmap.org/#Z/#X/#Y.png", + "map source tile repository uri", + OSM_REPO_URI, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, + g_object_class_install_property (object_class, PROP_PROXY_URI, g_param_spec_string ("proxy-uri", "proxy uri", @@ -1678,7 +1806,7 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) g_param_spec_string ("tile-cache", "tile cache", "osm local tile cache dir", - "/tmp/Maps", + NULL, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, @@ -1706,7 +1834,7 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) "maximum zoom level", MIN_ZOOM, /* minimum property value */ MAX_ZOOM, /* maximum property value */ - 17, + OSM_MAX_ZOOM, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, @@ -1716,7 +1844,7 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) "minimum zoom level", MIN_ZOOM, /* minimum property value */ MAX_ZOOM, /* maximum property value */ - 1, + OSM_MIN_ZOOM, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, @@ -1799,6 +1927,172 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) 20, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_MAP_SOURCE, + g_param_spec_int ("map-source", + "map source", + "map source ID", + -1, /* minimum property value */ + G_MAXINT, /* maximum property value */ + -1, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_IMAGE_FORMAT, + g_param_spec_string ("image-format", + "image format", + "map source tile repository image format (jpg, png)", + OSM_IMAGE_FORMAT, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); +} + +const char* +osm_gps_map_source_get_friendly_name(OsmGpsMapSource_t source) +{ + switch(source) + { + case OSM_GPS_MAP_SOURCE_NULL: + return "None"; + case OSM_GPS_MAP_SOURCE_OPENSTREETMAP: + return "OpenStreetMap"; + case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: + return "OpenStreetMap Renderer"; + case OSM_GPS_MAP_SOURCE_OPENAERIALMAP: + return "OpenAerialMap"; + case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE: + return "Maps-For-Free"; + case OSM_GPS_MAP_SOURCE_GOOGLE_STREET: + return "Google Maps"; + case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE: + return "Google Satellite"; + case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID: + return "Google Hybrid"; + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET: + return "Virtual Earth"; + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE: + return "Virtual Earth Satellite"; + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID: + return "Virtual Earth Hybrid"; + case OSM_GPS_MAP_SOURCE_YAHOO_STREET: + return "Yahoo Maps"; + case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE: + return "Yahoo Satellite"; + case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID: + return "Yahoo Hybrid"; + default: + return NULL; + } + return NULL; +} + +//http://www.internettablettalk.com/forums/showthread.php?t=5209 +//https://garage.maemo.org/plugins/scmsvn/viewcvs.php/trunk/src/maps.c?root=maemo-mapper&view=markup +//http://www.ponies.me.uk/maps/GoogleTileUtils.java +//http://www.mgmaps.com/cache/MapTileCacher.perl +const char* +osm_gps_map_source_get_repo_uri(OsmGpsMapSource_t source) +{ + switch(source) + { + case OSM_GPS_MAP_SOURCE_NULL: + return "none://"; + case OSM_GPS_MAP_SOURCE_OPENSTREETMAP: + return OSM_REPO_URI; + case OSM_GPS_MAP_SOURCE_OPENAERIALMAP: + /* OpenAerialMap is down, offline till furthur notice + http://openaerialmap.org/pipermail/talk_openaerialmap.org/2008-December/000055.html */ + case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: + return "http://tah.openstreetmap.org/Tiles/tile/#Z/#X/#Y.png"; + case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE: + return "http://maps-for-free.com/layer/relief/z#Z/row#Y/#Z_#X-#Y.jpg"; + case OSM_GPS_MAP_SOURCE_GOOGLE_STREET: + return "http://mt#R.google.com/vt/v=w2.97&x=#X&y=#Y&z=#Z"; + case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID: + /* No longer working "http://mt#R.google.com/mt?n=404&v=w2t.99&x=#X&y=#Y&zoom=#S" */ + case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE: + return "http://khm#R.google.com/kh/v=51&x=#X&y=#Y&z=#Z"; + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET: + return "http://a#R.ortho.tiles.virtualearth.net/tiles/r#W.jpeg?g=50"; + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE: + return "http://a#R.ortho.tiles.virtualearth.net/tiles/a#W.jpeg?g=50"; + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID: + return "http://a#R.ortho.tiles.virtualearth.net/tiles/h#W.jpeg?g=50"; + case OSM_GPS_MAP_SOURCE_YAHOO_STREET: + case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE: + case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID: + /* TODO: Implement signed Y, aka U + * http://us.maps3.yimg.com/aerial.maps.yimg.com/ximg?v=1.7&t=a&s=256&x=%d&y=%-d&z=%d + * x = tilex, + * y = (1 << (MAX_ZOOM - zoom)) - tiley - 1, + * z = zoom - (MAX_ZOOM - 17)); + */ + return NULL; + default: + return NULL; + } + return NULL; +} + +const char * +osm_gps_map_source_get_image_format(OsmGpsMapSource_t source) +{ + switch(source) { + case OSM_GPS_MAP_SOURCE_NULL: + case OSM_GPS_MAP_SOURCE_OPENSTREETMAP: + case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: + return "png"; + case OSM_GPS_MAP_SOURCE_OPENAERIALMAP: + case OSM_GPS_MAP_SOURCE_GOOGLE_STREET: + case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID: + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET: + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE: + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID: + case OSM_GPS_MAP_SOURCE_YAHOO_STREET: + case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE: + case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID: + case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE: + case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE: + return "jpg"; + default: + return "bin"; + } + return "bin"; +} + + +int +osm_gps_map_source_get_min_zoom(OsmGpsMapSource_t source) +{ + return 1; +} + +int +osm_gps_map_source_get_max_zoom(OsmGpsMapSource_t source) +{ + switch(source) { + case OSM_GPS_MAP_SOURCE_NULL: + return 18; + case OSM_GPS_MAP_SOURCE_OPENSTREETMAP: + return OSM_MAX_ZOOM; + case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER: + case OSM_GPS_MAP_SOURCE_OPENAERIALMAP: + case OSM_GPS_MAP_SOURCE_GOOGLE_STREET: + case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID: + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET: + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE: + case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID: + case OSM_GPS_MAP_SOURCE_YAHOO_STREET: + case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE: + case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID: + return 17; + case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE: + return 11; + case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE: + return 18; + default: + return 17; + } + return 17; } void @@ -1831,7 +2125,12 @@ osm_gps_map_download_maps (OsmGpsMap *map, coord_t *pt1, coord_t *pt2, int zoom_ for(j=y1; j<=y2; j++) { // x = i, y = j - filename = g_strdup_printf("%s/%u/%u/%u.png", priv->cache_dir, zoom, i, j); + filename = g_strdup_printf("%s%c%d%c%d%c%d.%s", + priv->cache_dir, G_DIR_SEPARATOR, + zoom, G_DIR_SEPARATOR, + i, G_DIR_SEPARATOR, + j, + priv->image_format); if (!g_file_test(filename, G_FILE_TEST_EXISTS)) { osm_gps_map_download_tile(map, zoom, i, j, FALSE); @@ -1965,7 +2264,7 @@ osm_gps_map_add_image (OsmGpsMap *map, float latitude, float longitude, GdkPixbu //cache w/h for speed, and add image to list im = g_new0(image_t,1); im->w = gdk_pixbuf_get_width(image); - im->h = gdk_pixbuf_get_width(image); + im->h = gdk_pixbuf_get_height(image); im->pt.rlat = deg2rad(latitude); im->pt.rlon = deg2rad(longitude); @@ -1978,6 +2277,28 @@ osm_gps_map_add_image (OsmGpsMap *map, float latitude, float longitude, GdkPixbu } } +gboolean +osm_gps_map_remove_image (OsmGpsMap *map, GdkPixbuf *image) +{ + OsmGpsMapPrivate *priv = map->priv; + if (priv->images) { + GSList *list; + for(list = priv->images; list != NULL; list = list->next) + { + image_t *im = list->data; + if (im->image == image) + { + priv->images = g_slist_remove_link(priv->images, list); + g_object_unref(im->image); + g_free(im); + osm_gps_map_map_redraw_idle(map); + return TRUE; + } + } + } + return FALSE; +} + void osm_gps_map_clear_images (OsmGpsMap *map) { @@ -2169,3 +2490,22 @@ osm_gps_map_scroll (OsmGpsMap *map, gint dx, gint dy) osm_gps_map_map_redraw_idle (map); } +float +osm_gps_map_get_scale(OsmGpsMap *map) +{ + OsmGpsMapPrivate *priv; + + g_return_if_fail (OSM_IS_GPS_MAP (map)); + priv = map->priv; + + return osm_gps_map_get_scale_at_point(priv->map_zoom, priv->center_rlat, priv->center_rlon); +} + +char * osm_gps_map_get_default_cache_directory(void) +{ + return g_build_filename( + g_get_user_cache_dir(), + "osmgpsmap", + NULL); +} + diff --git a/src/osm-gps-map.h b/src/osm-gps-map.h index 1069976..01a4618 100644 --- a/src/osm-gps-map.h +++ b/src/osm-gps-map.h @@ -59,23 +59,33 @@ typedef struct { float rlon; } coord_t; -//http://www.internettablettalk.com/forums/showthread.php?t=5209 -//https://garage.maemo.org/plugins/scmsvn/viewcvs.php/trunk/src/maps.c -//http://www.ponies.me.uk/maps/GoogleTileUtils.java -//http://www.mgmaps.com/cache/MapTileCacher.perl -#define MAP_SOURCE_OPENSTREETMAP "http://tile.openstreetmap.org/#Z/#X/#Y.png" -#define MAP_SOURCE_OPENSTREETMAP_RENDERER "http://tah.openstreetmap.org/Tiles/tile/#Z/#X/#Y.png" -#define MAP_SOURCE_OPENAERIALMAP "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/#Z/#X/#Y.jpg" -#define MAP_SOURCE_GOOGLE_MAPS "http://mt#R.google.com/mt?x=#X&y=#Y&zoom=#S" -//No longer working -//#define MAP_SOURCE_GOOGLE_HYBRID "http://mt#R.google.com/mt?n=404&v=w2t.99&x=#X&y=#Y&zoom=#S" -#define MAP_SOURCE_GOOGLE_HYBRID "http://mt#R.google.com/mt?x=#X&y=#Y&zoom=#S" -#define MAP_SOURCE_GOOGLE_SATTELITE "http://khm#R.google.com/kh?n=404&v=32&x=#X&y=#Y&z=#Z" -#define MAP_SOURCE_GOOGLE_SATTELITE_QUAD "http://khm#R.google.com/kh?n=404&v=3&t=#Q" -#define MAP_SOURCE_MAPS_FOR_FREE "http://maps-for-free.com/layer/relief/z#Z/row#Y/#Z_#X-#Y.jpg" -#define MAP_SOURCE_VIRTUAL_EARTH_SATTELITE "http://a#R.ortho.tiles.virtualearth.net/tiles/a#W.jpeg?g=50" +typedef enum { + OSM_GPS_MAP_SOURCE_NULL, + OSM_GPS_MAP_SOURCE_OPENSTREETMAP, + OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER, + OSM_GPS_MAP_SOURCE_OPENAERIALMAP, + OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE, + OSM_GPS_MAP_SOURCE_GOOGLE_STREET, + OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE, + OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID, + OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET, + OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE, + OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID, + OSM_GPS_MAP_SOURCE_YAHOO_STREET, + OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE, + OSM_GPS_MAP_SOURCE_YAHOO_HYBRID +} OsmGpsMapSource_t; GType osm_gps_map_get_type (void) G_GNUC_CONST; + +const char* osm_gps_map_source_get_friendly_name(OsmGpsMapSource_t source); +const char* osm_gps_map_source_get_repo_uri(OsmGpsMapSource_t source); +const char *osm_gps_map_source_get_image_format(OsmGpsMapSource_t source); +int osm_gps_map_source_get_min_zoom(OsmGpsMapSource_t source); +int osm_gps_map_source_get_max_zoom(OsmGpsMapSource_t source); + +char * osm_gps_map_get_default_cache_directory(void); + void osm_gps_map_download_maps (OsmGpsMap *map, coord_t *pt1, coord_t *pt2, int zoom_start, int zoom_end); void osm_gps_map_get_bbox (OsmGpsMap *map, coord_t *pt1, coord_t *pt2); void osm_gps_map_set_mapcenter (OsmGpsMap *map, float latitude, float longitude, int zoom); @@ -84,6 +94,7 @@ int osm_gps_map_set_zoom (OsmGpsMap *map, int zoom); void osm_gps_map_add_track (OsmGpsMap *map, GSList *track); void osm_gps_map_clear_tracks (OsmGpsMap *map); void osm_gps_map_add_image (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image); +gboolean osm_gps_map_remove_image (OsmGpsMap *map, GdkPixbuf *image); void osm_gps_map_clear_images (OsmGpsMap *map); void osm_gps_map_osd_speed (OsmGpsMap *map, float speed); void osm_gps_map_draw_gps (OsmGpsMap *map, float latitude, float longitude, float heading); @@ -97,6 +108,7 @@ void osm_gps_map_geographic_to_screen (OsmGpsMap *map, gfloat latitude, gfloat longitude, gint *pixel_x, gint *pixel_y); void osm_gps_map_scroll (OsmGpsMap *map, gint dx, gint dy); +float osm_gps_map_get_scale(OsmGpsMap *map); G_END_DECLS -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/osm-gps-map.git _______________________________________________ Pkg-grass-devel mailing list Pkg-grass-devel@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel