summaryrefslogtreecommitdiff
path: root/vendor/github.com/tkrajina/gpxgo/gpx/xml.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tkrajina/gpxgo/gpx/xml.go')
-rw-r--r--vendor/github.com/tkrajina/gpxgo/gpx/xml.go178
1 files changed, 178 insertions, 0 deletions
diff --git a/vendor/github.com/tkrajina/gpxgo/gpx/xml.go b/vendor/github.com/tkrajina/gpxgo/gpx/xml.go
new file mode 100644
index 0000000..e24217a
--- /dev/null
+++ b/vendor/github.com/tkrajina/gpxgo/gpx/xml.go
@@ -0,0 +1,178 @@
+// Copyright 2013, 2014 Peter Vasil, Tomo Krajina. All
+// rights reserved. Use of this source code is governed
+// by a BSD-style license that can be found in the
+// LICENSE file.
+
+package gpx
+
+import (
+ "bytes"
+ "encoding/xml"
+ "errors"
+ "io/ioutil"
+ "os"
+ "strings"
+ "time"
+)
+
+// An array cannot be constant :( The first one if the default layout:
+var TIMELAYOUTS = []string{
+ "2006-01-02T15:04:05Z",
+ "2006-01-02T15:04:05",
+ "2006-01-02 15:04:05Z",
+ "2006-01-02 15:04:05",
+}
+
+func init() {
+ /*
+ fmt.Println("----------------------------------------------------------------------------------------------------")
+ fmt.Println("This API is experimental, it *will* change")
+ fmt.Println("----------------------------------------------------------------------------------------------------")
+ */
+}
+
+type ToXmlParams struct {
+ Version string
+ Indent bool
+}
+
+/*
+ * Params are optional, you can set null to use GPXs Version and no indentation.
+ */
+func ToXml(g *GPX, params ToXmlParams) ([]byte, error) {
+ version := g.Version
+ if len(params.Version) > 0 {
+ version = params.Version
+ }
+ indentation := params.Indent
+
+ var gpxDoc interface{}
+ if version == "1.0" {
+ gpxDoc = convertToGpx10Models(g)
+ } else if version == "1.1" {
+ gpxDoc = convertToGpx11Models(g)
+ } else {
+ g.Version = "1.1"
+ gpxDoc = convertToGpx11Models(g)
+ }
+
+ var buffer bytes.Buffer
+ buffer.WriteString(xml.Header)
+ if indentation {
+ bytes, err := xml.MarshalIndent(gpxDoc, "", " ")
+ if err != nil {
+ return nil, err
+ }
+ buffer.Write(bytes)
+ } else {
+ bytes, err := xml.Marshal(gpxDoc)
+ if err != nil {
+ return nil, err
+ }
+ buffer.Write(bytes)
+ }
+ return buffer.Bytes(), nil
+}
+
+func guessGPXVersion(bytes []byte) (string, error) {
+ bytesCount := 1000
+ if len(bytes) < 1000 {
+ bytesCount = len(bytes)
+ }
+
+ startOfDocument := string(bytes[:bytesCount])
+
+ parts := strings.Split(startOfDocument, "<gpx")
+ if len(parts) <= 1 {
+ return "", errors.New("Invalid GPX file, cannot find version")
+ }
+ parts = strings.Split(parts[1], "version=")
+
+ if len(parts) <= 1 {
+ return "", errors.New("Invalid GPX file, cannot find version")
+ }
+
+ if len(parts[1]) < 10 {
+ return "", errors.New("Invalid GPX file, cannot find version")
+ }
+
+ result := parts[1][1:4]
+
+ return result, nil
+}
+
+func parseGPXTime(timestr string) (*time.Time, error) {
+ if strings.Contains(timestr, ".") {
+ // Probably seconds with milliseconds
+ timestr = strings.Split(timestr, ".")[0]
+ }
+ timestr = strings.Trim(timestr, " \t\n\r")
+ for _, timeLayout := range TIMELAYOUTS {
+ t, err := time.Parse(timeLayout, timestr)
+
+ if err == nil {
+ return &t, nil
+ }
+ }
+
+ return nil, errors.New("Cannot parse " + timestr)
+}
+
+func formatGPXTime(time *time.Time) string {
+ if time == nil {
+ return ""
+ }
+ if time.Year() <= 1 {
+ // Invalid date:
+ return ""
+ }
+ return time.Format(TIMELAYOUTS[0])
+}
+
+func ParseFile(fileName string) (*GPX, error) {
+ f, err := os.Open(fileName)
+ if err != nil {
+ return nil, err
+ }
+
+ defer f.Close()
+
+ bytes, err := ioutil.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+
+ return ParseBytes(bytes)
+}
+
+func ParseBytes(bytes []byte) (*GPX, error) {
+ version, err := guessGPXVersion(bytes)
+ if err != nil {
+ // Unknown version, try with 1.1
+ version = "1.1"
+ }
+
+ if version == "1.0" {
+ g := &gpx10Gpx{}
+ err := xml.Unmarshal(bytes, &g)
+ if err != nil {
+ return nil, err
+ }
+
+ return convertFromGpx10Models(g), nil
+ } else if version == "1.1" {
+ g := &gpx11Gpx{}
+ err := xml.Unmarshal(bytes, &g)
+ if err != nil {
+ return nil, err
+ }
+
+ return convertFromGpx11Models(g), nil
+ } else {
+ return nil, errors.New("Invalid version:" + version)
+ }
+}
+
+func ParseString(str string) (*GPX, error) {
+ return ParseBytes([]byte(str))
+}