Register
Results 1 to 1 of 1
  1. #1
    V.I.P. VIC
    Mjolinor's Avatar
    Join Date
    Jan 2009
    Location
    Burnley Vicshire
    Posts
    1,073
    Thanks Thanks Given 
    49
    Thanks Thanks Received 
    114
    Thanked in
    70 Posts

    Default Google Earth and GPS

    The Linux version of Google Earth doesn't support GPS.

    I have been writing some NMEA parsing software and converting to KML files for import to Google Earth and the KML "commands" support auto refresh.

    This gives a fairly simple way of getting your GPS data into Google Earth
    <?xml version="1.0" encoding="UTF-8"?>
    <kml xmlns="http://earth.google.com/kml/2.1">
    <NetworkLink>
    <name>GPS</name>
    <flyToView>1</flyToView>
    <Url>
    <href>./gps_pos.kml</href>
    <refreshMode>onInterval</refreshMode>
    <refreshInterval>2</refreshInterval>
    </Url>
    </NetworkLink>
    </kml>
    The above file needs to be saved as "something". kml, suggest gps.kml and opened with Google Earth.
    That file auto reloads another file called "gps_pos.kml" every 2 seconds and flies to the waypoint in the file.

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    #include <time.h>
    #include <math.h>

    char *latitude;
    char *longtitude;
    int x=0;
    FILE *dataout_xml;
    float lat, longt;

    int xml_create()
    {
    dataout_xml = fopen("./gps_pos.kml", "w+");

    fprintf (dataout_xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");

    fprintf (dataout_xml, "<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\" xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n");
    fprintf (dataout_xml, "<Document>\n");
    fprintf (dataout_xml, " <name>");
    fprintf (dataout_xml, "Gps position");
    fprintf (dataout_xml, "</name>\n");
    ///////////////////////////////////////////////////////////////
    // definitions for little black circle
    fprintf (dataout_xml, " <Style id=\"sh_placemark_circle_highlight\">\n");
    fprintf (dataout_xml, " <IconStyle>\n");
    fprintf (dataout_xml, " <scale>1.2</scale>\n");
    fprintf (dataout_xml, " <Icon>\n");
    fprintf (dataout_xml, " <href>http://maps.google.com/mapfiles/kml/shapes/placemark_circle_highlight.png</href>\n");
    fprintf (dataout_xml, " </Icon>\n");
    fprintf (dataout_xml, " </IconStyle>\n");
    fprintf (dataout_xml, " <ListStyle>\n");
    fprintf (dataout_xml, " </ListStyle>\n");
    fprintf (dataout_xml, " </Style>\n");
    fprintf (dataout_xml, " <Style id=\"sn_placemark_circle\">\n");
    fprintf (dataout_xml, " <IconStyle>\n");
    fprintf (dataout_xml, " <scale>1.2</scale>\n");
    fprintf (dataout_xml, " <Icon>\n");
    fprintf (dataout_xml, " <href>http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png</href>\n");
    fprintf (dataout_xml, " </Icon>\n");
    fprintf (dataout_xml, " </IconStyle>\n");
    fprintf (dataout_xml, " <ListStyle>\n");
    fprintf (dataout_xml, " </ListStyle>\n");
    fprintf (dataout_xml, " </Style>\n");
    fprintf (dataout_xml, " <StyleMap id=\"msn_placemark_circle\">\n");
    fprintf (dataout_xml, " <Pair>\n");
    fprintf (dataout_xml, " <key>normal</key>\n");
    fprintf (dataout_xml, " <styleUrl>#sn_placemark_circle</styleUrl>\n");
    fprintf (dataout_xml, " </Pair>\n");
    fprintf (dataout_xml, " <Pair>\n");
    fprintf (dataout_xml, " <key>highlight</key>\n");
    fprintf (dataout_xml, " <styleUrl>#sh_placemark_circle_highlight</styleUrl>\n");
    fprintf (dataout_xml, " </Pair>\n");
    fprintf (dataout_xml, " </StyleMap>\n");
    fclose (dataout_xml);
    return(0);
    }

    int place_to_xml()
    {
    dataout_xml = fopen("./gps_pos.kml", "a");
    fprintf (dataout_xml, " <Placemark>\n");
    fprintf (dataout_xml, " <name>");
    fprintf (dataout_xml, "Pos");
    fprintf (dataout_xml, "</name>\n");
    fprintf (dataout_xml, " <styleUrl>#msn_placemark_circle</styleUrl>\n");
    fprintf (dataout_xml, " <Point>\n");
    fprintf (dataout_xml, " <LineString>\n");
    fprintf (dataout_xml, " <tessellate>1</tessellate>\n");
    fprintf (dataout_xml, " </LineString>\n");
    fprintf (dataout_xml, " <coordinates>");
    fprintf (dataout_xml, "%s,%s", longtitude, latitude);
    fprintf (dataout_xml, ",0</coordinates>\n");
    fprintf (dataout_xml, " </Point>\n");
    fprintf (dataout_xml, " </Placemark>\n");
    fprintf (dataout_xml, "</Document>\n");
    fprintf (dataout_xml, "</kml>");
    fclose (dataout_xml);
    return(0);
    }


    //************************************************** ************************************
    static void callback()
    {
    int y, z;
    FILE *input;
    char fromrf[200], nmea_bits[40], minutes[20], latit[15], longti[15];
    float min2deg, deg;
    float latmin, longtmin;

    input = fopen("/dev/rfcomm4", "r");
    if (input == NULL)
    {
    printf ("\nNo GPS\n");
    return;
    }

    while ((strcmp(nmea_bits, "$GPGGA"))!= 0)
    {
    fgets(fromrf, 100, input);
    for (x = 0; x <= 6; x++) nmea_bits[x] = fromrf[x];
    nmea_bits[6] = '\0';
    }
    // At this point I have a valid GPGGA string in fromrf
    // Check the GPS has a fix
    y=0;
    for (x=0;x<=5;x++)
    {
    while (fromrf[y++] != ',');
    }
    // y has the position of the "fix or no fix" digit
    if (fromrf[y] != '1')
    {
    printf ("\n No fix %c\n", fromrf[y]);
    return;
    }
    // Got here, have a fix
    // I need to extract lat and long, here is a valid line
    // $GPGGA,141733.000,3742.434306,N,02403.104390,E,1,4 ,5.25,53.819,M,35.179,M,,*68
    // $GPGGA,064733.327,3742.4148,N,02403.0913,E,1,03,12 .8,0.0,M,35.2,M,0.0,0000*48
    // Time: 141733.000, 14:17:33, 1000ths of seconds, not needed
    // 3742.434306,N, 37 degrees, 42.434306 minutes, North. 11 digits needed and the N (it maybe S sometimes)
    // 02403.104390,E, 24 degrees, 03.104390 minutes East. 12 digits needed and the E (it may be W sometimes)
    // 1 have GPS fix, anything else means no fix
    // The rest are of no interest, maybe checksum at the end if we have problems

    //printf ("%s", fromrf); // print all of the string
    y=0;
    for (x=0;x<=2;x++)
    {
    while (fromrf[y++] != ',');
    }
    y--;
    x=0;
    z=y;
    while (fromrf[--z] != ',');

    // y is the comma at the end of the latitude
    // z is the comma at the beginning of latitude

    if (fromrf[y+1] != 'N') nmea_bits[x++] = '-';

    z++;
    //These two for the whole degrees
    nmea_bits[x++] = fromrf[z++];
    nmea_bits[x++] = fromrf[z++];
    nmea_bits[x++] = '\0';

    // z points at the MS minutes digit
    x=0;
    if (nmea_bits[0] == '-') minutes[x++] = '-'; // if degrees are negative make minutes negative
    while (z++ < y)
    {
    minutes[x++] = fromrf[z-1];
    }
    minutes[x++] = '\0';

    // We have number of whole degrees in "nmea_bits", minutes in "minutes"
    // "minutes[]" and "nmea_bits[]" needs converting to floats
    // divide minutes by 60, add to nmea_bits
    // and converting to a string stored in latit[]
    // that will give us the latitude in degrees and decimal degrees

    // Get previous lat and long for path and distance
    // As floats here
    min2deg = atof(minutes);
    min2deg = min2deg / 60;
    deg = atof(nmea_bits);
    lat = deg + min2deg;
    sprintf (latit, "%f", lat);
    latitude = latit;
    // latitude as degrees now stored in latit[] and displayed in latitude box
    // x is not needed, y and z are the same and are the comma before the N
    // nmea_bits[] is not needed, minutes[] is not needed
    y=y+3;
    // We should now be at the first digit of the longtitude with y
    x=0;
    z=y; // and z
    // need to find sign (East or West)
    while (fromrf[y++] != ',');
    // y is now the sign, East or West
    if (fromrf[y] != 'E') nmea_bits[x++] = '-';
    // sign sorted
    // whole longtitude degrees into nmea_bits
    nmea_bits[x++] = fromrf[z++];
    nmea_bits[x++] = fromrf[z++];
    nmea_bits[x++] = fromrf[z++];
    nmea_bits[x]= '\0';
    // whole degrees sorted
    x=0;
    if (nmea_bits[0] == '-') minutes[x++] = '-'; // if degrees are negative make minutes negative
    while (z++ < y)
    {
    minutes[x++] = fromrf[z-1];
    }
    minutes[x++] = '\0';
    min2deg = atof(minutes);
    min2deg = min2deg / 60;
    longt = atof(nmea_bits);
    longt = longt + min2deg;
    sprintf (longti, "%f", longt);
    longtitude = longti;
    // Latitude, Longitude, N, S E and W now sorted
    place_to_xml();
    }

    int main( int argc,
    char *argv[] )
    {
    latitude = "No data";
    longtitude = "No data";
    printf ("%s, %s\n", latitude, longtitude);
    while (1)
    {
    xml_create();
    callback();
    printf ("%f, %f\n", lat, longt);
    sleep(2);
    }
    return 0;
    }
    The above is the C source to make the "gps_pos.kml" file with 2 second update on the GPS data.

    The serial port is defined as /dev/rfcomm4 in the source so your BT GPS has to be there.

    It should be pretty portable so here is the binary.

    No responsibility accepted for trashed PCs and keep the comments about my C programming abilities on the humourous side, I know I am pretty crap at it. Maybe someone wants to do it properly from here.
    Attached Files Attached Files
    • File Type: zip 7.zip (4.7 KB, 0 views)

 

 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
This website uses cookies
We use cookies to store session information to facilitate remembering your login information, to allow you to save website preferences, to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners.