mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-06 07:53:43 +08:00
Cache for Google Maps tiles
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Multi aircrafts map display
|
||||
*
|
||||
* Copyright (C) 2004 CENA/ENAC, Pascal Brisset, Antoine Drouin
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
@@ -52,6 +52,12 @@ let (//) = Filename.concat
|
||||
let default_path_srtm = home // "data" // "srtm"
|
||||
let default_path_maps = home // "data" // "maps" // ""
|
||||
let default_path_missions = home // "conf"
|
||||
let gm_tiles_path = home // "var" // "maps"
|
||||
let _ =
|
||||
ignore (Sys.command (sprintf "mkdir -p %s" gm_tiles_path))
|
||||
|
||||
let google_maps_url = fun s -> sprintf "http://kh1.google.com/kh?n=404&v=3&t=%s" s
|
||||
|
||||
|
||||
|
||||
type aircraft = {
|
||||
@@ -117,17 +123,23 @@ let set_geo_ref = fun geomap wgs84 ->
|
||||
map_ref := Some utm_ref
|
||||
|
||||
|
||||
exception Wget_failure of string
|
||||
|
||||
let file_of_url = fun ?(extension=".xml") url ->
|
||||
let file_of_url = fun ?(extension=".xml") ?dest url ->
|
||||
if String.sub url 0 7 = "file://" then
|
||||
String.sub url 7 (String.length url - 7)
|
||||
else
|
||||
let tmp_file = Filename.temp_file "fp" extension in
|
||||
let tmp_file =
|
||||
match dest with
|
||||
Some s -> s
|
||||
| None -> Filename.temp_file "fp" extension in
|
||||
let c = sprintf "wget --cache=off -O %s '%s'" tmp_file url in
|
||||
if Sys.command c = 0 then
|
||||
tmp_file
|
||||
else
|
||||
failwith c
|
||||
else begin
|
||||
Sys.remove tmp_file;
|
||||
raise (Wget_failure url)
|
||||
end
|
||||
|
||||
let load_mission = fun color geomap xml ->
|
||||
let lat0 = float_attr xml "lat0"
|
||||
@@ -487,19 +499,40 @@ let en_of_wgs84 = fun geomap wgs84 ->
|
||||
{G.east=utm.utm_x -. utm_ref.utm_x; north=utm.utm_y -. utm_ref.utm_y}
|
||||
|
||||
|
||||
let is_prefix = fun a b ->
|
||||
String.length b >= String.length a &&
|
||||
a = String.sub b 0 (String.length a)
|
||||
|
||||
let get_gm_from_cache = fun f ->
|
||||
let files = Sys.readdir gm_tiles_path in
|
||||
let rec loop = fun i ->
|
||||
if i < Array.length files then
|
||||
let fi = files.(i) in
|
||||
if is_prefix (Filename.chop_extension fi) f then
|
||||
let (sw, s) = Latlong.gm_lat_long_of_tile f in
|
||||
(gm_tiles_path // fi, sw, s)
|
||||
else
|
||||
loop (i+1)
|
||||
else
|
||||
raise Not_found in
|
||||
loop 0
|
||||
|
||||
|
||||
let rec get_gm_tile = fun wgs84 zoom ->
|
||||
if zoom < 10 then
|
||||
try
|
||||
let (gm_string, sw, scale) = Latlong.gm_tile_string wgs84 zoom in
|
||||
let url = sprintf "http://kh1.google.com/kh?n=404&v=3&t=%s" gm_string in
|
||||
let jpg_file = file_of_url ~extension:".jpg" url in
|
||||
|
||||
(jpg_file, sw, scale)
|
||||
try get_gm_from_cache gm_string with
|
||||
Not_found ->
|
||||
let url = google_maps_url gm_string in
|
||||
let jpg_file = gm_tiles_path // (gm_string ^ ".jpg") in
|
||||
ignore (file_of_url ~extension:".jpg" ~dest:jpg_file url);
|
||||
(jpg_file, sw, scale)
|
||||
with (** Error, let's try a lower zoom *)
|
||||
_ -> get_gm_tile wgs84 (zoom+1)
|
||||
Wget_failure __ -> get_gm_tile wgs84 (zoom+1)
|
||||
else
|
||||
failwith "get_gm_tile"
|
||||
failwith "download_gm_tile"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+21
-23
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Geographic conversion utilities
|
||||
*
|
||||
* Copyright (C) 2004 CENA/ENAC, Pascal Brisset, Antoine Drouin
|
||||
* Copyright (C) 2004-2006 ENAC, Pascal Brisset, Antoine Drouin
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
@@ -360,6 +360,22 @@ let (/.=) r x = r := !r /. x
|
||||
let (+.=) r x = r := !r +. x
|
||||
let (-.=) r x = r := !r -. x
|
||||
|
||||
|
||||
let gm_pos_and_scale = fun keyholeString tLat latHeight tLon lonWidth ->
|
||||
let tmp_lat = fun l -> 2. *. atan (exp (l *. pi)) -. pi/.2. in
|
||||
let bl_lat = tmp_lat tLat in
|
||||
let tr_lat = tmp_lat (tLat +. latHeight) in
|
||||
let bottom_left = {posn_lat = bl_lat ; posn_long = tLon *. pi} in
|
||||
let top_right = {posn_lat = tr_lat;
|
||||
posn_long = bottom_left.posn_long +. lonWidth *. pi } in
|
||||
|
||||
let utm_bottom_left = utm_of WGS84 bottom_left
|
||||
and utm_top_right = utm_of WGS84 top_right in
|
||||
(*** Printf.fprintf stderr "%fx%f\n" (utm_bottom_left.utm_x -. utm_top_right.utm_x) (utm_bottom_left.utm_y -. utm_top_right.utm_y); ***)
|
||||
let scale = utm_distance utm_bottom_left utm_top_right /. sqrt (2. *. 256.*.256.) in
|
||||
(keyholeString, bottom_left, scale)
|
||||
|
||||
|
||||
(** Returns a keyhole string for a longitude (x), latitude (y), and zoom
|
||||
for Google Maps (http://www.ponies.me.uk/maps/GoogleTileUtils.java) *)
|
||||
let gm_tile_string = fun wgs84 zoom ->
|
||||
@@ -403,26 +419,14 @@ let gm_tile_string = fun wgs84 zoom ->
|
||||
end
|
||||
end
|
||||
done;
|
||||
let tmp_lat = fun l -> 2. *. atan (exp (l *. pi)) -. pi/.2. in
|
||||
let bl_lat = tmp_lat !tLat in
|
||||
let tr_lat = tmp_lat (!tLat +. !latHeight) in
|
||||
let bottom_left = {posn_lat = bl_lat ; posn_long = !tLon *. pi} in
|
||||
let top_right = {posn_lat = tr_lat;
|
||||
posn_long = bottom_left.posn_long +. !lonWidth *. pi } in
|
||||
|
||||
let utm_bottom_left = utm_of WGS84 bottom_left
|
||||
and utm_top_right = utm_of WGS84 top_right in
|
||||
Printf.fprintf stderr "%fx%f\n" (utm_bottom_left.utm_x -. utm_top_right.utm_x) (utm_bottom_left.utm_y -. utm_top_right.utm_y);
|
||||
let scale = utm_distance utm_bottom_left utm_top_right /. sqrt (2. *. 256.*.256.) in
|
||||
(Buffer.contents keyholeString, bottom_left, scale)
|
||||
|
||||
gm_pos_and_scale (Buffer.contents keyholeString) !tLat !latHeight !tLon !lonWidth
|
||||
|
||||
let gm_lat_long_of_tile = fun keyholeStr ->
|
||||
assert(keyholeStr.[0] = 't');
|
||||
|
||||
let lon = ref (-180.)
|
||||
and lonWidth = ref 360.
|
||||
and lat = ref (-1.)
|
||||
and lat = ref (-1.)
|
||||
and latHeight = ref 2. in
|
||||
|
||||
for i = 1 to String.length keyholeStr - 1 do
|
||||
@@ -439,11 +443,5 @@ let gm_lat_long_of_tile = fun keyholeStr ->
|
||||
| _ -> invalid_arg ("gm_get_lat_long " ^ keyholeStr)
|
||||
done;
|
||||
|
||||
latHeight +.= !lat;
|
||||
latHeight := (2. *. atan (exp (pi *. !latHeight))) -. (pi /. 2.);
|
||||
|
||||
lat := (2. *. atan (exp (pi *. !lat))) -. (pi /. 2.);
|
||||
|
||||
latHeight -.= !lat;
|
||||
lon := (Deg>>Rad)!lon;
|
||||
{ posn_lat = !lat; posn_long = !lon }
|
||||
let (_, sw, s) = gm_pos_and_scale keyholeStr !lat !latHeight (!lon/.180.) (!lonWidth/.180.) in
|
||||
(sw, s)
|
||||
|
||||
@@ -117,8 +117,8 @@ val of_string : string -> geographic
|
||||
|
||||
val gm_tile_string : geographic -> int -> string * geographic * float
|
||||
(** [gm_tile_string geo zoom] Returns the string code designing the
|
||||
Google Map tile *)
|
||||
Google Map tile, coordinates of SW corner and scale *)
|
||||
|
||||
val gm_lat_long_of_tile : string -> geographic
|
||||
val gm_lat_long_of_tile : string -> geographic * float
|
||||
(** [gm_lat_long_of_tile google_maps_tile_key] Returns the coordinates of the
|
||||
South West corner of the given tile. *)
|
||||
South West corner and the scale of the given tile. *)
|
||||
|
||||
Reference in New Issue
Block a user