[maps] add support for multiple resolution tiles

If available in cache, the highest resolution is displayed.
Lower resolution are displayed behind higher resolution.
TODO: change the max resolution for download at runtime in gcs (startup
parameter for now)

This should fix #277 and close #364
This commit is contained in:
Gautier Hattenberger
2013-03-21 18:01:26 +01:00
parent 14751f8d86
commit d9f86b8051
5 changed files with 27 additions and 6 deletions
+3
View File
@@ -29,6 +29,7 @@ open Printf
let tile_size = 256, 256
let zoom_max = 22
let zoom_min = 18
let cache_path = ref "/var/tmp"
@@ -150,6 +151,8 @@ let is_prefix = fun a b ->
(** Get the tile or one which contains it from the cache *)
let get_from_cache = fun dir f ->
let files = Sys.readdir dir in
(* sort files to have the longest names first *)
Array.sort (fun a b -> String.length b - String.length a) files;
let rec loop = fun i ->
if i < Array.length files then
let fi = files.(i) in
+2
View File
@@ -23,6 +23,8 @@
*)
val tile_size : int * int
val zoom_max : int
val zoom_min : int
val tile_coverage : float -> int -> float * float
(** [tile_coverage wgs84_lat zoom] Returns (width,height) *)
+14 -2
View File
@@ -152,6 +152,8 @@ class basic_widget = fun ?(height=800) ?width ?(projection = Mercator) ?georef (
let canvas = GnoCanvas.canvas ~packing:(frame#pack ~expand:true) () in
let background = GnoCanvas.group canvas#root
and still = GnoCanvas.group canvas#root in
(* create several layers of canvas group to display the map in correct order *)
let maps = Array.init (Gm.zoom_max - Gm.zoom_min + 1) (fun _ -> GnoCanvas.group background) in
let view_cbs = Hashtbl.create 3 in (* Store for view event callback *)
let region_rectangle = GnoCanvas.rect canvas#root ~props:[`WIDTH_PIXELS 2; `OUTLINE_COLOR "red"] in
@@ -184,6 +186,7 @@ class basic_widget = fun ?(height=800) ?width ?(projection = Mercator) ?georef (
method toolbar = toolbar
method background = background
method still = still
method maps = maps
method top_still = 3.5*.s
method utc_time = utc_time
method set_utc_time = fun h m s ->
@@ -373,14 +376,23 @@ class basic_widget = fun ?(height=800) ?width ?(projection = Mercator) ?georef (
self#of_world (xw, yw)
method display_pixbuf = fun ?opacity ((x1,y1), geo1) ((x2,y2), geo2) image ->
method display_pixbuf = fun ?opacity ?level ((x1,y1), geo1) ((x2,y2), geo2) image ->
let x1 = float x1 and x2 = float x2
and y1 = float y1 and y2 = float y2 in
let image =
match opacity with
None -> image
| Some o -> set_opacity image o in
let pix = GnoCanvas.pixbuf ~x:(-.x1) ~y:(-.y1)~pixbuf:image ~props:[`ANCHOR `NW] background in
let map_layer = match level with
| None -> 0
| Some l ->
if l > Gm.zoom_max then
Array.length maps - 1
else if l < Gm.zoom_min then
0
else l - Gm.zoom_min
in
let pix = GnoCanvas.pixbuf ~x:(-.x1) ~y:(-.y1) ~pixbuf:image ~props:[`ANCHOR `NW] maps.(map_layer) in
let xw1, yw1 = self#world_of geo1
and xw2, yw2 = self#world_of geo2 in
+2
View File
@@ -43,6 +43,7 @@ class widget :
float * float -> float -> float -> float -> GnoCanvas.line
method background : GnoCanvas.group
method background_event : GnoCanvas.item_event -> bool
method maps : GnoCanvas.group array
method canvas : GnoCanvas.canvas
method center : Latlong.geographic -> unit
method circle :
@@ -57,6 +58,7 @@ class widget :
method display_group : string -> unit
method display_pixbuf :
?opacity:int ->
?level:int ->
(int * int) * Latlong.geographic ->
(int * int) * Latlong.geographic -> GdkPixbuf.pixbuf -> GnoCanvas.pixbuf
method display_xy : string -> unit
+6 -4
View File
@@ -72,7 +72,7 @@ let add_tile = fun tile_key ->
loop 0 [|gm_tiles|] 0
let display_the_tile = fun (geomap:MapCanvas.widget) tile jpg_file ->
let display_the_tile = fun (geomap:MapCanvas.widget) tile jpg_file level ->
let south_lat = tile.Gm.sw_corner.LL.posn_lat
and west_long = tile.Gm.sw_corner.LL.posn_long in
let north_lat = south_lat +. tile.Gm.height
@@ -83,7 +83,7 @@ let display_the_tile = fun (geomap:MapCanvas.widget) tile jpg_file ->
try
let pixbuf = GdkPixbuf.from_file jpg_file in
ignore (GMain.Idle.add (fun () ->
let map = geomap#display_pixbuf ((0,tx), tile.Gm.sw_corner) ((ty,0),ne) pixbuf in
let map = geomap#display_pixbuf ((0,tx), tile.Gm.sw_corner) ((ty,0),ne) pixbuf ~level in
map#raise 1;
false));
add_tile tile.Gm.key
@@ -103,7 +103,8 @@ let display_tile = fun (geomap:MapCanvas.widget) wgs84 ->
let key = desired_tile.Gm.key in
if not (mem_tile key) then
let (tile, jpg_file) = Gm.get_tile wgs84 1 in
display_the_tile geomap tile jpg_file
let level = String.length tile.Gm.key in
display_the_tile geomap tile jpg_file level
exception New_displayed of int
@@ -135,7 +136,8 @@ let fill_window = fun (geomap:MapCanvas.widget) zoomlevel ->
| Empty ->
if zoom = 1 then
let tile, image = Gm.get_image key in
display_the_tile geomap tile image;
let level = String.length tile.Gm.key in
display_the_tile geomap tile image level;
raise (New_displayed (zoomlevel+1-String.length tile.Gm.key))
else begin
trees.(i) <- Node (Array.create 4 Empty);