]> git.street.me.uk Git - andy/viking.git/blobdiff - src/dems.c
Add Refresh to consider reloading a Mapnik Rendering configuration.
[andy/viking.git] / src / dems.c
index b278e5183b2a09ab72489829d0dbeddd5a8275c6..5845db1ddfc364384f6bbedc589733887a620a83 100644 (file)
@@ -1,6 +1,28 @@
+/*
+ * 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 <glib.h>
 
 #include "dems.h"
+#include "background.h"
 
 typedef struct {
   VikDEM *dem;
 
 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 );
 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 );
 }
   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().
  */
  * 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;
 {
   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;
   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;
     }
     } 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).
 }
 
 /* Takes a string list (GList of strings) of dems (filenames).
@@ -161,32 +197,47 @@ gint16 a_dems_list_get_elev_by_coord ( GList *dems, const VikCoord *coord )
 
 typedef struct {
   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;
   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 );
 
   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;
   } 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);
     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 */
 }
 
 /* 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;
 
 {
   CoordElev ce;
 
@@ -194,9 +245,10 @@ gint16 a_dems_get_elev_by_coord ( const VikCoord *coord )
     return VIK_DEM_INVALID_ELEVATION;
 
   ce.coord = coord;
     return VIK_DEM_INVALID_ELEVATION;
 
   ce.coord = coord;
+  ce.method = method;
   ce.elev = VIK_DEM_INVALID_ELEVATION;
 
   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;
 }
     return VIK_DEM_INVALID_ELEVATION;
   return ce.elev;
 }