diff --git a/sw/lib/ocaml/gm.ml b/sw/lib/ocaml/gm.ml index 3a92869d0c..789b2db1bd 100644 --- a/sw/lib/ocaml/gm.ml +++ b/sw/lib/ocaml/gm.ml @@ -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 diff --git a/sw/lib/ocaml/gm.mli b/sw/lib/ocaml/gm.mli index 7be6cbddaf..008c02243e 100644 --- a/sw/lib/ocaml/gm.mli +++ b/sw/lib/ocaml/gm.mli @@ -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) *) diff --git a/sw/lib/ocaml/mapCanvas.ml b/sw/lib/ocaml/mapCanvas.ml index 82dc10e217..06ba68f4e2 100644 --- a/sw/lib/ocaml/mapCanvas.ml +++ b/sw/lib/ocaml/mapCanvas.ml @@ -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 diff --git a/sw/lib/ocaml/mapCanvas.mli b/sw/lib/ocaml/mapCanvas.mli index 5259c7700d..dc95020615 100644 --- a/sw/lib/ocaml/mapCanvas.mli +++ b/sw/lib/ocaml/mapCanvas.mli @@ -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 diff --git a/sw/lib/ocaml/mapGoogle.ml b/sw/lib/ocaml/mapGoogle.ml index 874b2c15e5..28a6e591e8 100644 --- a/sw/lib/ocaml/mapGoogle.ml +++ b/sw/lib/ocaml/mapGoogle.ml @@ -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);