X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/5590651454434a0bff2afe3b159e877808083e74..78ac928c4967374d4c7ad5b3024f188074eab36b:/src/dems.c diff --git a/src/dems.c b/src/dems.c index b278e518..08605e0d 100644 --- a/src/dems.c +++ b/src/dems.c @@ -1,6 +1,28 @@ +/* + * viking -- GPS Data and Topo Analyzer, Explorer, and Manager + * + * Copyright (C) 2003-2008, Evan Battaglia + * Copyright (C) 2007, Quy Tonthat + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ #include #include "dems.h" +#include "background.h" typedef struct { VikDEM *dem; @@ -52,8 +74,11 @@ VikDEM *a_dems_load(const gchar *filename) void a_dems_unref(const gchar *filename) { LoadedDEM *ldem = (LoadedDEM *) g_hash_table_lookup ( loaded_dems, filename ); - g_assert ( ldem ); - ldem->ref_count --; + if ( !ldem ) { + /* This is fine - probably means the loaded list was aborted / not completed for some reason */ + return; + } + ldem->ref_count--; if ( ldem->ref_count == 0 ) g_hash_table_remove ( loaded_dems, filename ); } @@ -82,9 +107,11 @@ VikDEM *a_dems_get(const gchar *filename) * we need to know that they weren't referenced though when we * do the a_dems_list_free(). */ -void a_dems_load_list ( GList **dems ) +int a_dems_load_list ( GList **dems, gpointer threaddata ) { GList *iter = *dems; + guint dem_count = 0; + const guint dem_total = g_list_length ( *dems ); while ( iter ) { if ( ! a_dems_load((const gchar *) (iter->data)) ) { GList *iter_temp = iter->next; @@ -94,7 +121,16 @@ void a_dems_load_list ( GList **dems ) } else { iter = iter->next; } + /* When running a thread - inform of progress */ + if ( threaddata ) { + dem_count++; + /* NB Progress also detects abort request via the returned value */ + int result = a_background_thread_progress ( threaddata, ((gdouble)dem_count) / dem_total ); + if ( result != 0 ) + return -1; /* Abort thread */ + } } + return 0; } /* Takes a string list (GList of strings) of dems (filenames). @@ -161,32 +197,46 @@ gint16 a_dems_list_get_elev_by_coord ( GList *dems, const VikCoord *coord ) typedef struct { const VikCoord *coord; + VikDemInterpol method; gint elev; } CoordElev; static gboolean get_elev_by_coord(gpointer key, LoadedDEM *ldem, CoordElev *ce) { VikDEM *dem = ldem->dem; + gdouble lat, lon; if ( dem->horiz_units == VIK_DEM_HORIZ_LL_ARCSECONDS ) { struct LatLon ll_tmp; vik_coord_to_latlon (ce->coord, &ll_tmp ); - ll_tmp.lat *= 3600; - ll_tmp.lon *= 3600; - ce->elev = vik_dem_get_east_north(dem, ll_tmp.lon, ll_tmp.lat); - return (ce->elev != VIK_DEM_INVALID_ELEVATION); + lat = ll_tmp.lat * 3600; + lon = ll_tmp.lon * 3600; } else if (dem->horiz_units == VIK_DEM_HORIZ_UTM_METERS) { static struct UTM utm_tmp; + if (utm_tmp.zone != dem->utm_zone) + return FALSE; vik_coord_to_utm (ce->coord, &utm_tmp); - if ( utm_tmp.zone == dem->utm_zone && - (ce->elev = vik_dem_get_east_north(dem, utm_tmp.easting, utm_tmp.northing)) != VIK_DEM_INVALID_ELEVATION ) - return TRUE; + lat = utm_tmp.northing; + lon = utm_tmp.easting; + } else + return FALSE; + + switch (ce->method) { + case VIK_DEM_INTERPOL_NONE: + ce->elev = vik_dem_get_east_north(dem, lon, lat); + break; + case VIK_DEM_INTERPOL_SIMPLE: + ce->elev = vik_dem_get_simple_interpol(dem, lon, lat); + break; + case VIK_DEM_INTERPOL_BEST: + ce->elev = vik_dem_get_shepard_interpol(dem, lon, lat); + break; } - return FALSE; + return (ce->elev != VIK_DEM_INVALID_ELEVATION); } /* TODO: keep a (sorted) linked list of DEMs and select the best resolution one */ -gint16 a_dems_get_elev_by_coord ( const VikCoord *coord ) +gint16 a_dems_get_elev_by_coord ( const VikCoord *coord, VikDemInterpol method ) { CoordElev ce; @@ -194,9 +244,10 @@ gint16 a_dems_get_elev_by_coord ( const VikCoord *coord ) return VIK_DEM_INVALID_ELEVATION; ce.coord = coord; + ce.method = method; ce.elev = VIK_DEM_INVALID_ELEVATION; - if(!g_hash_table_find(loaded_dems, get_elev_by_coord, &ce)) + if(!g_hash_table_find(loaded_dems, (GHRFunc)get_elev_by_coord, &ce)) return VIK_DEM_INVALID_ELEVATION; return ce.elev; }