view MakeWaypoints.kt @ 12:698b3335a63d default tip

Fix leading comment.
author David Barts <n5jrn@me.com>
date Thu, 26 Aug 2021 23:06:33 -0700
parents a56d3d3b5efd
children
line wrap: on
line source

/*
 * Make waypoints. In Kotlin, because the JVM has a uniquely non-sucky
 * way to write XML.
 */

import javax.xml.stream.*
import java.io.FileOutputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.TimeZone
import kotlin.math.abs

private const val MYNAME = "MakeWaypoints"
private const val CHARSET = "UTF-8"
private val WP_TIME_FORMAT = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").apply {
   timeZone = TimeZone.getTimeZone("GMT")
}

fun main(args: Array<String>): Unit {
    /* parse arguments */
    val syntaxError = "${MYNAME}: syntax: [-latfirst] file"
    if (args.size < 1 || args.size > 2) {
        System.err.println(syntaxError)
        System.exit(2)
    }
    var latFirst = false
    var fileArg = 0
    if (args[0].startsWith('-')) {
        latFirst = args[0].equals("-latfirst", ignoreCase = true)
        if (!latFirst || args.size != 2) {
            System.err.println(syntaxError)
            System.exit(2)
        }
        fileArg = 1
    }
    if (args.size != fileArg + 1) {
        System.err.println(syntaxError)
        System.exit(2)
    }
    val outName = args[fileArg]

    /* explain purpose */
    println("Enter waypoints below, end with empty line.")
    println()

    /* process input from user */
    val invalid = "${MYNAME}: invalid entry, please try again"
    FileOutputStream(outName).use stream@{
        XMLOutputFactory.newInstance().createXMLStreamWriter(it, CHARSET).run {
            writeStartDocument(CHARSET, "1.0")
            writeStartElement("gpx")
            writeAttribute("creator", "MakeWaypoints")
            writeAttribute("version", "1.1")
            writeDefaultNamespace("http://www.topografix.com/GPX/1/1")

            while (true) {
                if (latFirst)
                    print("Latitude, longitude: ")
                else
                    print("Longitude, latitude: ")
                val longLat = readLine()
                if (longLat.isNullOrEmpty()) {
                    writeEndDocument()
                    close()
                    return@stream
                }
                val parts = longLat.split(',')
                if (parts.size != 2) {
                    System.err.println(invalid)
                    continue
                }
                val (lat, long) = if (latFirst)
                    Pair(parts[0].trim(), parts[1].trim())
                else
                    Pair(parts[1].trim(), parts[0].trim())
                val dLat = lat.toDoubleOrNull()
                val dLong = long.toDoubleOrNull()
                if (dLat == null || abs(dLat) > 90.0 || dLong == null || abs(dLong) > 180.0) {
                    System.err.println(invalid)
                    continue
                }
                print("Name: ")
                val name = readLine()
                if (name.isNullOrEmpty()) {
                    System.err.println(invalid)
                    continue
                }
                writeStartElement("wpt")
                writeAttribute("lat", lat)
                writeAttribute("lon", long)
                writeStartElement("time")
                writeCharacters(WP_TIME_FORMAT.format(Date()))
                writeEndElement()
                writeStartElement("name")
                writeCharacters(name)
                writeEndElement()
                writeEndElement()
            }
        }
    }
}