10 GHashTable
*loaded_dems
= NULL
;
13 static void loaded_dem_free ( LoadedDEM
*ldem
)
15 vik_dem_free ( ldem
->dem
);
22 g_hash_table_destroy ( loaded_dems
);
25 /* To load a dem. if it was already loaded, will simply
26 * reference the one already loaded and return it.
28 VikDEM
*a_dems_load(const gchar
*filename
)
32 /* dems init hash table */
34 loaded_dems
= g_hash_table_new_full ( g_str_hash
, g_str_equal
, g_free
, (GDestroyNotify
) loaded_dem_free
);
36 ldem
= (LoadedDEM
*) g_hash_table_lookup ( loaded_dems
, filename
);
41 VikDEM
*dem
= vik_dem_new_from_file ( filename
);
44 ldem
= g_malloc ( sizeof(LoadedDEM
) );
47 g_hash_table_insert ( loaded_dems
, g_strdup(filename
), ldem
);
52 void a_dems_unref(const gchar
*filename
)
54 LoadedDEM
*ldem
= (LoadedDEM
*) g_hash_table_lookup ( loaded_dems
, filename
);
57 if ( ldem
->ref_count
== 0 )
58 g_hash_table_remove ( loaded_dems
, filename
);
61 /* to get a DEM that was already loaded.
62 * assumes that its in there already,
63 * although it could not be if earlier load failed.
65 VikDEM
*a_dems_get(const gchar
*filename
)
67 LoadedDEM
*ldem
= g_hash_table_lookup ( loaded_dems
, filename
);
74 /* Load a string list (GList of strings) of dems. You have to use get to at them later.
75 * When updating a list as a parameter, this should be bfore freeing the list so
76 * the same DEMs won't be loaded & unloaded.
77 * Modifies the list to remove DEMs which did not load.
80 /* TODO: don't delete them when they don't exist.
81 * we need to warn the user, but we should keep them in the GList.
82 * we need to know that they weren't referenced though when we
83 * do the a_dems_list_free().
85 void a_dems_load_list ( GList
**dems
)
89 if ( ! a_dems_load((const gchar
*) (iter
->data
)) ) {
90 GList
*iter_temp
= iter
->next
;
91 g_free ( iter
->data
);
92 (*dems
) = g_list_remove_link ( (*dems
), iter
);
100 /* Takes a string list (GList of strings) of dems (filenames).
101 * Unrefs all the dems (i.e. "unloads" them), then frees the
102 * strings, the frees the list.
104 void a_dems_list_free ( GList
*dems
)
108 a_dems_unref ((const gchar
*)iter
->data
);
109 g_free ( iter
->data
);
112 g_list_free ( dems
);
115 GList
*a_dems_list_copy ( GList
*dems
)
117 GList
*rv
= g_list_copy ( dems
);
120 if ( ! a_dems_load((const gchar
*) (iter
->data
)) ) {
121 GList
*iter_temp
= iter
->next
; /* delete link, don't bother strdup'ing and free'ing string */
122 rv
= g_list_remove_link ( rv
, iter
);
125 iter
->data
= g_strdup((gchar
*)iter
->data
); /* copy the string too. */
132 gint16
a_dems_list_get_elev_by_coord ( GList
*dems
, const VikCoord
*coord
)
134 static struct UTM utm_tmp
;
135 static struct LatLon ll_tmp
;
141 dem
= a_dems_get ( (gchar
*) iter
->data
);
143 if ( dem
->horiz_units
== VIK_DEM_HORIZ_LL_ARCSECONDS
) {
144 vik_coord_to_latlon ( coord
, &ll_tmp
);
147 elev
= vik_dem_get_east_north(dem
, ll_tmp
.lon
, ll_tmp
.lat
);
148 if ( elev
!= VIK_DEM_INVALID_ELEVATION
)
150 } else if ( dem
->horiz_units
== VIK_DEM_HORIZ_UTM_METERS
) {
151 vik_coord_to_utm ( coord
, &utm_tmp
);
152 if ( utm_tmp
.zone
== dem
->utm_zone
&&
153 (elev
= vik_dem_get_east_north(dem
, utm_tmp
.easting
, utm_tmp
.northing
)) != VIK_DEM_INVALID_ELEVATION
)
159 return VIK_DEM_INVALID_ELEVATION
;
163 const VikCoord
*coord
;
164 VikDemInterpol method
;
168 static gboolean
get_elev_by_coord(gpointer key
, LoadedDEM
*ldem
, CoordElev
*ce
)
170 VikDEM
*dem
= ldem
->dem
;
173 if ( dem
->horiz_units
== VIK_DEM_HORIZ_LL_ARCSECONDS
) {
174 struct LatLon ll_tmp
;
175 vik_coord_to_latlon (ce
->coord
, &ll_tmp
);
176 lat
= ll_tmp
.lat
* 3600;
177 lon
= ll_tmp
.lon
* 3600;
178 } else if (dem
->horiz_units
== VIK_DEM_HORIZ_UTM_METERS
) {
179 static struct UTM utm_tmp
;
180 if (utm_tmp
.zone
!= dem
->utm_zone
)
182 vik_coord_to_utm (ce
->coord
, &utm_tmp
);
183 lat
= utm_tmp
.northing
;
184 lon
= utm_tmp
.easting
;
188 switch (ce
->method
) {
189 case VIK_DEM_INTERPOL_NONE
:
190 ce
->elev
= vik_dem_get_east_north(dem
, lon
, lat
);
192 case VIK_DEM_INTERPOL_SIMPLE
:
193 ce
->elev
= vik_dem_get_simple_interpol(dem
, lon
, lat
);
195 case VIK_DEM_INTERPOL_BEST
:
196 ce
->elev
= vik_dem_get_shepard_interpol(dem
, lon
, lat
);
199 return (ce
->elev
!= VIK_DEM_INVALID_ELEVATION
);
202 /* TODO: keep a (sorted) linked list of DEMs and select the best resolution one */
203 gint16
a_dems_get_elev_by_coord ( const VikCoord
*coord
, VikDemInterpol method
)
208 return VIK_DEM_INVALID_ELEVATION
;
212 ce
.elev
= VIK_DEM_INVALID_ELEVATION
;
214 if(!g_hash_table_find(loaded_dems
, get_elev_by_coord
, &ce
))
215 return VIK_DEM_INVALID_ELEVATION
;