Flights, airplanes and Google Maps

Not long ago I was working on an interesting project for a jet charter services company. Part of this project was creating a flight tracker.

Flight tracker is a term for a feature where you can enter a code for some flight and see all sorts of info about that flight, such as current velocity, height, position etc.

The interesting part was building a map using Google Maps 3.0 API. That map should show current plane position and route the plane has passed, something like the plane trail. It looks like this:

Map before

If you look at that, it seems that the plane is not turning in right direction at all. I think this is much better:

Let me show you how I did this small but interesting task.

Creating polyline and markers

First of all, the service I used for this was Flightaware API (FlightXML 2.0). It’s a SOAP web service that you can query for all kinds of information relevant to flight. The idea was to generate javascript for the map server side.

I obviously needed some coordinates in order to draw a polyline on google map, so I used GetLastTrack API call http://flightaware.com/commercial/flightxml/explorer/#op_GetLastTrack, which returns an array of aircraft’s current longitude and latitude:

public function getCoordinates()
{		
    $lastTrack = $this->_service->callGetLastTrack();
    $coordinatesArray = get_object_vars($flightPosition);
    $lat = $coordinatesArray['latitude'];
    $lon = $coordinatesArray['longitude'];
    $coordinates = $lat . ', ' . $lon ;
    return $coordinates;
}
var polyline = new google.maps.Polyline({
    map: map, //reference to map object
    geodesic: true,
    path: ['.$this->getCoordinates().'],
    strokeColor: "#66ff00",
    strokeOpacity: 2,
    strokeWeight: 1
});

I needed 3 points, origin airport, destination airport and current aircraft position. Gathering those information was not a problem using Flightaware API calls, so I created three Google Maps markers:

var icon = new google.maps.MarkerImage(
    "http://www.charterjetscompany.com/planeicon.png",
);
var marker1 = new google.maps.Marker({
    position: point1,
    map: map,
    icon: icon
});        
var point2 = new google.maps.LatLng('.$this->airportOrigin->AirportInfoResult->latitude.',
					'.$this->airportOrigin->AirportInfoResult->longitude.');
var marker2 = new google.maps.Marker({
    position: point2,
    map: map,
    icon: "http://www.charterjetscompany.com/img.php?text='.$this->airportOrigin->code.'"
});
var point3 = new google.maps.LatLng('.$this->airportDestination->AirportInfoResult->latitude.',
					'.$this->airportDestination->AirportInfoResult->longitude.');    
var marker3 = new google.maps.Marker({
    position: point3,
    map: map,
    icon: "http://www.charterjetscompany.com/img.php?text='.$this->airportDestination->code.'"
});     

The img.php script is simply creating an image from text.

Rotating image

Now we come to the problem I mentioned on the start, basically rotating the plane in the direction it’s heading. To be honest, I am aware that there might have been better solutions for this, I did it server side, but I guess it could have also been done client side with some of the jQuery rotation plugins.

If you remember I made an API call that returned list of aircraft positions (that we used for creating a polyline). We need last 2 positions in order to determine the angle for aicraft. So we will send those 2 positions to a php script that will rotate the image for us based on some calculations. This is what was sent to that script:

end($allPositions);
$key = key($allPositions);
$this->last2Positions = array(
    'x2' => $allPositions[$key]['latitude'],
    'y2' => $allPositions[$key]['longitude'],
    'x1' => $allPositions[$key-1]['latitude'],
    'y1' => $allPositions[$key-1]['longitude']
);

So that eventually we could replace our original request for image with this:

http://www.charterjetscompany.com/rotate.php?'.http_build_query($this->last2Positions)

Mathematical part

Now we come to mathematical part of the problem. Can’t really say that I am a brilliant mathematician, but somehow after a while I thought I could use this formula:

arctan((y2 – y1) / (x2 – x1))

And in PHP:

$coordinates = $_GET;
$degrees = rad2deg(atan(($coordinates['y2']-$coordinates['y1'])/($coordinates['x2']-$coordinates['x1'])));
$degrees = -1 * $degrees;

Setting background

This was all fine, until I found out that the picture I got this way had black background. After playing with different php image options, this was the result:

$icon = "http://www.charterjetscompany.com/plane.png";
$im = imagecreatefrompng($icon);
imagesavealpha($im , true);
$pngTransparency = imagecolorallocatealpha($im , 0, 0, 0, 127);
imagefill($im , 0, 0, $pngTransparency);

$rotate = imagerotate($im, $degrees, $pngTransparency);

imagealphablending($rotate,true);
imagesavealpha($rotate,true);
header('Content-Type: image/png');
imagepng($rotate);

However this was not the end. There was still one thing to do.

Anchor point change

The plane icon is not centered on the end position. Since we changed image size when we were rotating it, the anchor point for image is now not the same.

Luckily Google Maps 3.0 provides us with a nice anchor option for Icon object so we can we can choose where we want our picture to display relative to coordinates:

In order to achieve this we must pass offset in pixels as 4th argument to our Icon constructor.

img.onload = function() {
    planeIconOffsetWidth = this.width / 2;
    planeIconOffsetHeight = this.height / 2;
}
var icon = new google.maps.MarkerImage(
    "http://www.charterjetscompany.com/rotate.php?'.http_build_query($this->last2Positions).'",
    null,
    null,
    new google.maps.Point(planeIconOffsetWidth, planeIconOffsetHeight)
);

 

That was it! It certainly was enjoyable to work on a task that was different from the usual ones. Did you have similar experience?

Airplane

Would you like to recommend this article to your friends or colleagues?
Feel free to share.

facebooktwittergoogle_plusredditlinkedin
This article was posted in category General, PHP.

Article "Flights, airplanes and Google Maps" has 1 response

Colin Bernard says: August 27, 2017 at 8:36 pm

Thank you this helped me a ton!! This would be super helpful for anyone looking to rotate custom markers with google maps API. Couldn’t find another solution that worked.

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

*

*

*