+/*
+ * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
+ *
+ * Copyright (C) 2003-2008, Evan Battaglia <gtoevan@gmx.net>
+ * Copyright (C) 2007, Quy Tonthat <qtonthat@gmail.com>
+ *
+ * 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 <glib.h>
#include "dems.h"
+#include "background.h"
typedef struct {
VikDEM *dem;
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 );
}
* 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;
} 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).
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;
+ default: 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;
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;
}