mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-05 23:49:00 +08:00
[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:
@@ -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
|
||||
|
||||
@@ -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) *)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user