@@ -736,6 +736,8 @@ function updateVehicleInfo(vcallsign, newPosition) {
736736 vehicle . marker . setPosition ( latlng ) ;
737737 vehicle . marker . setZIndex ( ( ( vehicle . vehicle_type == "car" ) ? Z_CAR : Z_PAYLOAD ) + zIndex ) ;
738738
739+ if ( ! ! vehicle . marker . setCourse ) vehicle . marker . setCourse ( ( 'gps_heading' in vehicle . curr_position ) ? parseInt ( vehicle . curr_position . gps_heading ) : 90 ) ;
740+
739741 // update horizon circles and icon
740742 if ( vehicle . vehicle_type == "balloon" ) {
741743 updateAltitude ( vcallsign ) ;
@@ -1148,6 +1150,9 @@ var mapInfoBox_handle_horizons = function(event, obj, title) {
11481150var mapInfoBox_handle_truehorizon = function ( event ) { mapInfoBox_handle_horizons ( event , this , "True Horizon" ) ; } ;
11491151var mapInfoBox_handle_horizon = function ( event ) { mapInfoBox_handle_horizons ( event , this , "5° Horizon" ) ; } ;
11501152
1153+ var car_img_cache = { } ;
1154+ var car_canvas = document . createElement ( 'canvas' ) ;
1155+
11511156function addPosition ( position ) {
11521157 var vcallsign = position . vehicle ;
11531158
@@ -1170,19 +1175,65 @@ function addPosition(position) {
11701175 image_src = host_url + markers_url + "car-" + car_colors [ c ] + ".png" ;
11711176
11721177 marker = new google . maps . Marker ( {
1173- icon : {
1174- url : image_src ,
1175- size : new google . maps . Size ( 55 , 25 ) ,
1176- scaledSize : new google . maps . Size ( 55 , 25 ) ,
1177- anchor : new google . maps . Point ( 27 , 22 )
1178- } ,
11791178 zIndex : Z_CAR ,
11801179 position : point ,
11811180 map : map ,
1181+ clickable : false ,
11821182 optimized : false ,
11831183 title : vcallsign
11841184 } ) ;
11851185
1186+ if ( ! ! ! window . HTMLCanvasElement ) {
1187+ marker . setIcon ( {
1188+ url : image_src ,
1189+ size : new google . maps . Size ( 55 , 25 ) ,
1190+ scaledSize : new google . maps . Size ( 55 , 25 ) ,
1191+ anchor : new google . maps . Point ( 27 , 22 )
1192+ } ) ;
1193+ marker . setCourse = function ( deg ) { } ;
1194+ } else {
1195+ marker . setCourse = function ( deg ) {
1196+ deg -= 90 ;
1197+ deg += ( deg < 0 ) ? 360 : 0 ;
1198+
1199+ var radii = deg * DEG_TO_RAD ;
1200+ var img = this . iconImg ;
1201+ var len = Math . max ( img . height , img . width ) * 1.2 ;
1202+ var canvas = document . createElement ( 'canvas' ) ;
1203+ canvas . height = canvas . width = len ;
1204+ var ctx = canvas . getContext ( '2d' ) ;
1205+
1206+ ctx . save ( ) ;
1207+ ctx . translate ( len * 0.5 , len * 0.5 ) ;
1208+ ctx . rotate ( radii ) ;
1209+ if ( deg >= 90 && deg <= 270 ) ctx . scale ( 1 , - 1 ) ;
1210+ ctx . drawImage ( img , - img . width / 2 , - img . height * 0.95 ) ;
1211+ ctx . restore ( ) ;
1212+
1213+ var size = new google . maps . Size ( canvas . width * 0.5 , canvas . height * 0.5 ) ;
1214+ marker . setIcon ( {
1215+ url : canvas . toDataURL ( ) ,
1216+ scaledSize : size ,
1217+ size : size ,
1218+ anchor : new google . maps . Point ( canvas . width * 0.25 , canvas . height * 0.25 )
1219+ } ) ;
1220+ } ;
1221+
1222+ if ( image_src in car_img_cache ) {
1223+ marker . iconImg = car_img_cache [ image_src ] ;
1224+ marker . setCourse ( 90 ) ;
1225+ marker . setPosition ( marker . getPosition ( ) ) ;
1226+ }
1227+ else {
1228+ marker . iconImg = new Image ( ) ;
1229+ car_img_cache [ image_src ] = marker . iconImg ;
1230+ marker . iconImg . onload = function ( ) {
1231+ marker . setCourse ( 90 ) ;
1232+ marker . setPosition ( marker . getPosition ( ) ) ;
1233+ } ;
1234+ marker . iconImg . src = image_src ;
1235+ }
1236+ }
11861237 gmaps_elements . push ( marker ) ;
11871238 }
11881239 else if ( vcallsign == "XX" ) {
@@ -1366,8 +1417,16 @@ function addPosition(position) {
13661417 mlabel . bindTo ( 'text' , marker , 'title' ) ;
13671418 mlabel . bindTo ( 'zIndex' , marker , 'zIndex' ) ;
13681419 google . maps . event . addListener ( marker , 'position_changed' , function ( ) {
1420+ if ( ! ! ! marker . icon ) return ;
1421+
13691422 var pos = mlabel . getProjection ( ) . fromLatLngToDivPixel ( marker . getPosition ( ) ) ;
1370- pos . y -= marker . icon . size . height + 10 ;
1423+
1424+ if ( ! ! marker . iconImg ) {
1425+ pos . y -= marker . icon . size . height * 0.5 + 5 ;
1426+ } else {
1427+ pos . y -= marker . icon . size . height + 10 ;
1428+ }
1429+
13711430 mlabel . set ( 'position' , mlabel . getProjection ( ) . fromDivPixelToLatLng ( pos ) ) ;
13721431 } ) ;
13731432 marker . _label = mlabel ;
@@ -1567,8 +1626,15 @@ function addPosition(position) {
15671626
15681627 vehicle . updated = true ;
15691628 } else { // if car
1570- vehicle . updated = true ;
1629+ // if car doesn't report heading, we calculate it from the last position
1630+ if ( ! ( 'gps_heading' in position ) ) {
1631+ var latlng = new google . maps . LatLng ( position . gps_lat , position . gps_lon ) ;
1632+ var old_latlng = new google . maps . LatLng ( vehicle . curr_position . gps_lat , vehicle . curr_position . gps_lon ) ;
1633+ position . gps_heading = google . maps . geometry . spherical . computeHeading ( old_latlng , latlng ) ;
1634+ }
1635+
15711636 vehicle . curr_position = position ;
1637+ vehicle . updated = true ;
15721638 }
15731639
15741640 // record the start of flight
0 commit comments