in reply to Re^4: Calculate aircraft headings from GPS data for google kml display
in thread Calculate aircraft headings from GPS data for google kml display

can you give a bit hint, especially the # at the end, :-)!
  1. my @headers = split ' ', do{ my $raw = <DATA>; $raw =~ tr[",][ ]; $raw }; #"
    • Read the header line into $raw;
    • Get rid of the quotes and commas and replace with spaces;
    • return the modified line to split and split on whitespace;
    • The #" at the end is just a comment; it balances up the earlier ", and prevents it from screwing up the syntax highlighting in my editor.
  2. $line =~ tr[",][ ]; #"

    Same as above. (Though it was wrong for the rest of the lines, a C&P error correct below.)

  3. push @{ $planes{ $aid } }, \%row;

    push a reference to the hash constructed from teh most recent line into the array indexed by the aircraft id.

  4. next unless @{ $planes{ $aid } } > 1;

    If we don't have 2 or more lines (in the array) for this aircraft, we cannot calculate a bearing yet, so skip to the next line.

A couple of corrections and a couple of tweaks:

With the extended dataset (still no course changes!), produces:

C:\test>junk53 Aircraft: 685 heading: -90.000 Aircraft: 721 heading: 0.000 Aircraft: 704 heading: 0.000 Aircraft: 685 heading: -90.000 Aircraft: 709 heading: 0.000 Aircraft: 721 heading: 0.000 Aircraft: 685 heading: -90.000 Aircraft: 709 heading: 90.000 Aircraft: 704 heading: 0.000 Aircraft: 721 heading: 0.000 Aircraft: 685 heading: -90.000 Aircraft: 704 heading: 0.000 Aircraft: 709 heading: 90.000 Aircraft: 721 heading: 0.000 Aircraft: 709 heading: 0.000 Aircraft: 704 heading: 0.000 Aircraft: 685 heading: -90.000 Aircraft: 721 heading: 0.000 Aircraft: 709 heading: 90.000 Aircraft: 704 heading: 0.000 Aircraft: 685 heading: -90.000 Aircraft: 721 heading: 0.000 Aircraft: 709 heading: 90.000 Aircraft: 685 heading: -90.000 Aircraft: 704 heading: 0.000 Aircraft: 721 heading: 0.000 Aircraft: 685 heading: -90.000 Aircraft: 704 heading: 0.000 Aircraft: 709 heading: 90.000 Aircraft: 721 heading: 0.000 Aircraft: 709 heading: 0.000 Aircraft: 685 heading: -90.000 Aircraft: 704 heading: 0.000 Aircraft: 721 heading: 0.000 Aircraft: 685 heading: -90.000 Aircraft: 704 heading: 0.000 Aircraft: 709 heading: 90.000 Aircraft: 721 heading: 0.000 Aircraft: 704 heading: 0.000 Aircraft: 685 heading: -90.000 Aircraft: 709 heading: 90.000 Aircraft: 721 heading: 0.000 Aircraft: 704 heading: 0.000 Aircraft: 685 heading: -90.000 Aircraft: 709 heading: 0.000 Aircraft: 721 heading: 0.000 Aircraft: 709 heading: 90.000 Aircraft: 685 heading: -90.000

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^6: Calculate aircraft headings from GPS data for google kml display
by hujunsimon (Sexton) on Jun 11, 2014 at 00:23 UTC

    Thank you for the excellent explanation, it all becomes quite clear !

    I have made few tweak on your code and try to integrate my original code, which is to generate kml file for google display, here is my attempt, but unfortunately the code doesn't run as expected. I think the problem is at reading the file. i switch from using 'while' to 'foreach' to loop through the file, but it doesn't work. I must have done something silly. Any suggestions ?!

    Also i have also replaced your 'next unless' statement to 'if', it should works the same.

    #!/usr/bin/perl use strict; use POSIX qw(ceil floor); open(INPUT, $infile); my @lines = <INPUT>; close(INPUT); open(OUTPUT, ">$outfile"); my $timeCounter = 0; my $seconds = 0; my $minutes = 0; my $hours = 0; my $comma = ","; my $space = " "; print OUTPUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"."\n"; print OUTPUT "<kml xmlns=\"http://earth.google.com/kml/2.1\">"."\n"; print OUTPUT "<Folder>"."\n"; print OUTPUT "<LookAt><longitude>-0.45</longitude><latitude>51.4666667 +</latitude><altitude>1500</altitude><range>7000</range><tilt>65</tilt +><heading>0</heading></LookAt>"."\n"; my @headers = split ' ', do{ my $raw = <INPUT>; $raw =~ tr[",][ ]; $ra +w }; #" printf @headers; my %planes; foreach my $currentLine(@lines) { my @fields = split',', $currentLine; #--- At this point, we have the data from the current line. We nee +d to convert this to appropriate kml elements my %row; @row{ @headers } = @fields; #--- Get all the elements my $rowid = $row{rowid}; my $aid = $row{aircraft_id}; my $actual_date_time = $row{actual_date_time}; my $latitude = $row{latitude}; my $longitude = $row{longitude}; my $radio_altitude = $row{radio_altitude}; my $ground_speed = $row{ground_speed}; my $thrust_engine_1 = $row{thrust_engine_1}; my $thrust_engine_2 = $row{thrust_engine_2}; my $nox_total = $row{nox_total}; my $co_total = $row{co_total}; #--- Now, convert start and end times into UTC my @timeString = split(my $space,$actual_date_time); $actual_date_time = @timeString[0]."T".@timeString[1]; #--- Determine the heading push @{ $planes{ $aid } }, \%row; if ( @{ $planes{ $aid} } > 1) { my $lat1 = $planes{ $aid }[ -2 ]{latitude}; my $lat2 = $planes{ $aid }[ -1 ]{latitude}; my $dlat = $lat2 - $lat1; my $lon1 = $planes{ $aid }[ -2 ]{longitude}; my $lon2 = $planes{ $aid }[ -1 ]{longitude}; my $dlon = $lon2 - $lon1; my $y = sin( $dlon / 180 ) * cos( $lat2 /180 ); my $x = cos( $lat1 /180 ) * sin( $lat2/180 ) - sin( $lat1/180 ) * +cos( $lat2/180 ) * cos( $dlon/180 ); my $heading = atan2( $y, $x ) * 57.2957795; } else { my $heading= 0; } #--- (1) Determine the geometry my $icon = "./blue_plane.png"; print OUTPUT "<Placemark><Style><IconStyle><scale>1.0</scale><head +ing>"; print OUTPUT my $heading; print OUTPUT "</heading><Icon><href>$icon</href></Icon></IconStyle +></Style><Point><coordinates>"; print OUTPUT $longitude.$comma.$latitude.$comma.$radio_altitude; print OUTPUT "</coordinates><altitudeMode>relativeToGround</altitu +deMode></Point>"; print OUTPUT "<TimeStamp><when>$actual_date_time</when></TimeStamp +>"; print OUTPUT "<description>"."ID:".$rowid."<hr/>"."time:".$actual_ +date_time."<hr/>"."Ground_speed:".$ground_speed."<hr/>"."Thrust_engin +e_1:".$thrust_engine_1."<hr/>"."thrust_engine_2:".$thrust_engine_2."< +hr/>"."nox_total:".$nox_total."<hr/>"."co_total:".$co_total."<hr/>"." +longitude:".$longitude."<hr/>"."latitude:".$latitude."<hr/>"."radio_a +ltitude:".$radio_altitude."<hr/></description>"; print OUTPUT "</Placemark>"."\n"; } print OUTPUT "</Folder></kml>";

    Thanks in Millions !

    Si

      You're slurping the entire file into an array:

      open(INPUT, $infile); my @lines = <INPUT>; close(INPUT);

      Which means by the time you reach where I loaded the header line:

      my @headers = split ' ', do{ my $raw = <INPUT>; $raw =~ tr[",][ ]; $ra +w }; #"

      There is nothing left to read.

      Either shift the first line off of the array:

      my @headers = split ' ', do{ my $raw = shift @lines; $raw =~ tr[",][ ] +; $raw }; #"

      Or don't slurp the file and revert to using while.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Hi BrowserUk, sorry, went away for holiday last week. thanks a lot for your advice, it works like a charm now !

        Simon