#! /usr/bin/env python
"""
gpsdueltokml - Converts NMEA data files to KML tracks

Uses lon/lat data fields from the NMEA sentences as location coordinates
for the KML track data set.  Creates one track for the Hollux GPS module and
a separate track for the EverMore module.

:Copyright: Copyright 2007 Dean Hall.  All rights reserved.
:Author: Dean Hall
:Revision: 0.1
:Date: 2007/08/05

usage: gpsdueltokml.py nmeadatafile1 [nmeadatafileN...]
"""


import os, string, sys
import serial
import nmeagram


DATAFILES = ("gpsduelEverMoreData.dynamic1.nmea",
             "gpsduelHoluxData.dynamic1.nmea",
             "gpsduelEverMoreData.dynamic2.nmea",
             "gpsduelHoluxData.dynamic2.nmea",
            )


KML_FILENAME = "gpsduel.kml"

KML_HEADER = \
"""<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
  <name>GPS Duel to KML</name>
  <Style id="dwhStyle000">
    <LineStyle id="dwhLineStyleRed6">
      <color>7f0000ff</color>
      <width>6</width>
    </LineStyle>
  </Style>
  <Style id="dwhStyle001">
    <LineStyle id="dwhLineStyleGreen6">
      <color>7f00ff00</color>
      <width>6</width>
    </LineStyle>
  </Style>
"""

KML_BODY = \
"""    <Placemark>
    <name>%s</name>
    <styleUrl>#dwhStyle000</styleUrl>
    <MultiGeometry>
      <LineString>
        <coordinates>
        %s
        </coordinates>
      </LineString>
    </MultiGeometry>
  </Placemark>
  <Placemark>
    <name>%s</name>
    <styleUrl>#dwhStyle001</styleUrl>
    <MultiGeometry>
      <LineString>
        <coordinates>
        %s
        </coordinates>
      </LineString>
    </MultiGeometry>
  </Placemark>
"""

KML_FOOTER = \
"""</Document>
</kml>
"""


def nmeaFileToCoords(fn):
    """Read a file full of NMEA sentences and return a string of lat/lon/z
    coordinates.  'z' is often 0.
    """
    data = []
    f = open(fn, 'r')
    for line in f.readlines():
        nmeagram.parseLine(line)
        data.append(str(nmeagram.getField("Longitude")) + ",")
        data.append(str(nmeagram.getField("Latitude")) + ",")
        data.append("0 ")
    f.close()
    return string.join(data,'')


def main():
    # If filenames are given, use them
    if len(sys.argv[1:]) > 0:
        filenames = sys.argv[1:]

    # Else use hardcoded filenames
    else:
        filenames = DATAFILES

    # There should be an even number of files (it's a duel after all)
    assert (len(filenames) & 1) == 0

    # All of the input files should exist
    for fn in filenames:
        assert os.path.exists(fn)

    # Create a specific output file
    cwd = os.path.curdir
    fo = open(os.path.join(cwd, KML_FILENAME), 'w')

    # Write the KML header to the output file
    fo.write(KML_HEADER)

    try:
        # Write a KML body for each pair of files
        for i in range(0, len(filenames), 2):
            fn1 = filenames[i]
            fn2 = filenames[i+1]
            fo.write(KML_BODY % (fn1, nmeaFileToCoords(fn1),
                                 fn2, nmeaFileToCoords(fn2)))

        # Write the KML footer to the output file
        fo.write(KML_FOOTER)

    # Close files in any event
    finally:
        fo.close()


if __name__ == "__main__":
    main()