Google maps display

This commit is contained in:
Pascal Brisset
2006-03-02 17:47:44 +00:00
parent 6ebb458a0e
commit 2a29e19ee4
4 changed files with 172 additions and 6 deletions
+64 -5
View File
@@ -106,12 +106,24 @@ let load_map = fun (geomap:G.widget) (vertical_display:MapCanvas.basic_widget) x
geomap#moveto en0
let file_of_url = fun url ->
let set_geo_ref = fun geomap wgs84 ->
let utm_ref = utm_of WGS84 wgs84 in
let wgs84_of_en = fun en ->
of_utm WGS84 {utm_x = utm_ref.utm_x +. en.G.east; utm_y = utm_ref.utm_y +. en.G.north; utm_zone = utm_ref.utm_zone} in
geomap#set_wgs84_of_en wgs84_of_en;
geomap#set_world_unit 1.;
assert (!map_ref = None);
map_ref := Some utm_ref
let file_of_url = fun ?(extension=".xml") 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" ".xml" in
let c = sprintf "wget --cache=off -O %s %s" tmp_file url in
let tmp_file = 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
@@ -467,13 +479,56 @@ let listen_flight_params = fun () ->
in
ignore (Ground_Pprz.message_bind "AP_STATUS" get_ap_status);;
let en_of_wgs84 = fun geomap wgs84 ->
let ref = geomap#wgs84_of_en {G.east=0.; north = 0.} in
let utm_ref = utm_of WGS84 ref in
let utm = utm_of WGS84 wgs84 in
{G.east=utm.utm_x -. utm_ref.utm_x; north=utm.utm_y -. utm_ref.utm_y}
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)
with (** Error, let's try a lower zoom *)
_ -> get_gm_tile wgs84 (zoom+1)
else
failwith "get_gm_tile"
let button_press = fun (geomap:MapCanvas.widget) ev ->
let xc = GdkEvent.Button.x ev
and yc = GdkEvent.Button.y ev in
let (xw, yw) = geomap#window_to_world xc yc in
let en = geomap#en_of_world xw yw in
let wgs84 = geomap#wgs84_of_en en in
let (jpg_file, sw, scale) = get_gm_tile wgs84 1 in
let en_sw = en_of_wgs84 geomap sw in
let en_nw = { en_sw with G.north = en_sw.G.north +. 256. *. scale } in
let scale = scale /. geomap#get_world_unit () in
let map = geomap#display_map ~scale en_nw (GdkPixbuf.from_file jpg_file) in
map#raise 1;
true
let _ =
let ivy_bus = ref "127.255.255.255:2010"
and geo_ref = ref ""
and map_file = ref ""
and mission_file = ref "" in
let options =
[ "-b", Arg.String (fun x -> ivy_bus := x), "Bus\tDefault is 127.255.255.25:2010";
"-ref", Arg.Set_string geo_ref, "Geographic ref (default '')";
"-m", Arg.String (fun x -> map_file := x), "Map description file"] in
Arg.parse (options)
(fun x -> Printf.fprintf stderr "Warning: Don't do anythig with %s\n" x)
@@ -495,6 +550,8 @@ let _ =
let geomap = new MapCanvas.widget ~height:400 () in
let accel_group = geomap#menu_fact#accel_group in
ignore (geomap#canvas#event#connect#button_press (button_press geomap));
(** widget displaying aircraft vertical position *)
let vertical_display = new MapCanvas.basic_widget ~height:400 () in
let ac_vertical_fact = new GMenu.factory vertical_display#file_menu in
@@ -518,8 +575,10 @@ let _ =
vertical_vbox#pack ~expand:true vertical_display#frame#coerce;
(* Loading an initial map *)
if !map_file <> "" then begin
let xml_map_file = Filename.concat default_path_maps !map_file in
if !geo_ref <> "" then
set_geo_ref geomap (Latlong.of_string !geo_ref)
else if !map_file <> "" then begin
let xml_map_file = if !map_file.[0] <> '/' then Filename.concat default_path_maps !map_file else !map_file in
load_map geomap vertical_display xml_map_file
end;
+95 -1
View File
@@ -57,7 +57,7 @@ let (>>) u1 u2 x = (x *. piradian u2) /. piradian u1;;
let deg_string_of_rad = fun r -> Printf.sprintf "%.6f" ((Rad>>Deg)r)
let sprint_degree_of_radian x =
Printf.sprintf "%.4f" ((Rad>>Deg) x)
Printf.sprintf "%.6f" ((Rad>>Deg) x)
let string_degrees_of_geographic sm =
Printf.sprintf "%s\t%s"
@@ -353,3 +353,97 @@ let of_string = fun s ->
| ["LBT2e";x;y] ->
wgs84_of_lambertIIe (ios x) (ios y)
| _ -> invalid_arg (Printf.sprintf "Latlong.of_string: %s" s)
let (/.=) r x = r := !r /. x
let (+.=) r x = r := !r +. x
let (-.=) r x = r := !r -. x
(** 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 ->
let zoom = 18 - zoom in
(* first convert the lat lon to transverse mercator coordintes.*)
let lon = (Rad>>Deg)wgs84.posn_long in
let lon = if lon > 180. then lon -. 180. else lon in
let lon = lon /. 180. in
(* convert latitude to a range -1..+1 *)
let lat = log (tan (pi/.4. +. 0.5*. wgs84.posn_lat)) /. pi in
let tLat = ref (-1.)
and tLon = ref (-1.)
and lonWidth = ref 2.
and latHeight = ref 2. (** Always identical to lonWidth !!! *)
and keyholeString = Buffer.create 3 in
Buffer.add_char keyholeString 't';
for i = 0 to zoom - 1 do
lonWidth /.= 2.;
latHeight /.= 2.;
if !tLat +. !latHeight > lat then
if ((!tLon +. !lonWidth) > lon) then begin
Buffer.add_char keyholeString 't';
end else begin
tLon +.= !lonWidth;
Buffer.add_char keyholeString 's';
end
else begin
tLat +.= !latHeight;
if ((!tLon +. !lonWidth) > lon) then begin
Buffer.add_char keyholeString 'q';
end
else begin
tLon +.= !lonWidth;
Buffer.add_char keyholeString 'r';
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)
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 latHeight = ref 2. in
for i = 1 to String.length keyholeStr - 1 do
lonWidth /.= 2.;
latHeight /.= 2.;
match keyholeStr.[i] with
's' -> lon +.= !lonWidth
| 'r' ->
lat +.= !latHeight;
lon +.= !lonWidth
| 'q' -> lat +.= !latHeight
| 't' -> ()
| _ -> 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 }
+8
View File
@@ -114,3 +114,11 @@ val wgs84_of_lambertIIe : meter -> meter -> geographic
val of_string : string -> geographic
(** [of_string pos] Parses [pos] as "WGS84 45.678 1.2345", "UTM 500123 4500300 31" or "LBT2e 544945 1755355" *)
val gm_tile_string : geographic -> int -> string * geographic * float
(** [gm_tile_string geo zoom] Returns the string code designing the
Google Map tile *)
val gm_lat_long_of_tile : string -> geographic
(** [gm_lat_long_of_tile google_maps_tile_key] Returns the coordinates of the
South West corner of the given tile. *)
+5
View File
@@ -141,6 +141,11 @@ class basic_widget = fun ?(height=800) ?width ?wgs84_of_en () ->
None -> ""
| Some f -> string_degrees_of_geographic (f en)
method wgs84_of_en =
match wgs84_of_en with
None -> raise Not_found
| Some f -> f
method moveto = fun en ->
let (xw, yw) = self#world_of_en en in