diff --git a/cmd/flightlog2kml/main.go b/cmd/flightlog2kml/main.go
index 2d245b5..2efe4d0 100644
--- a/cmd/flightlog2kml/main.go
+++ b/cmd/flightlog2kml/main.go
@@ -28,7 +28,13 @@ func main() {
dump_log := os.Getenv("DUMP_LOG") != ""
files, _ := options.ParseCLI(getVersion)
if len(files) == 0 {
- options.Usage()
+ if len(options.Config.Mission) > 0 {
+ outms := kmlgen.GenKmlName(options.Config.Mission, options.Config.MissionIndex)
+ kmlgen.GenerateMissionOnly(outms)
+ show_output(outms)
+ } else {
+ options.Usage()
+ }
os.Exit(1)
}
@@ -92,14 +98,7 @@ func main() {
if !res {
fmt.Fprintf(os.Stderr, "*** skipping KML/Z for log with no valid geospatial data\n")
} else {
- if outfn != "" {
- rp, err := realpath.Realpath(outfn)
- if err != nil || rp == "" {
- fmt.Printf("%-8.8s : <%s> <%s>\n", "RealPath", rp, err)
- rp = outfn
- }
- fmt.Printf("%-8.8s : %s\n", "Output", rp)
- }
+ show_output(outfn)
}
fmt.Println()
}
@@ -109,3 +108,14 @@ func main() {
}
}
}
+
+func show_output(outfn string) {
+ if outfn != "" {
+ rp, err := realpath.Realpath(outfn)
+ if err != nil || rp == "" {
+ fmt.Printf("%-8.8s : <%s> <%s>\n", "RealPath", rp, err)
+ rp = outfn
+ }
+ fmt.Printf("%-8.8s : %s\n", "Output", rp)
+ }
+}
diff --git a/cmd/mission2kml/main.go b/cmd/mission2kml/main.go
index 8cde87e..d25b94b 100644
--- a/cmd/mission2kml/main.go
+++ b/cmd/mission2kml/main.go
@@ -3,7 +3,9 @@ package main
import (
"flag"
"fmt"
+ types "github.com/stronnag/bbl2kml/pkg/api/types"
mission "github.com/stronnag/bbl2kml/pkg/mission"
+ kml "github.com/twpayne/go-kml"
"log"
"os"
"path/filepath"
@@ -68,7 +70,7 @@ Examples:
flag.BoolVar(&dms, "dms", dms, "Show positions as DMS (vice decimal degrees)")
flag.StringVar(&homepos, "home", homepos, "Use home location")
- flag.IntVar(&idx, "mission-index", 1, "Mission Index")
+ flag.IntVar(&idx, "mission-index", 0, "Mission Index")
flag.Parse()
files := flag.Args()
if len(files) == 0 {
@@ -99,18 +101,44 @@ Examples:
}
}
}
+ err := generateKML(files[0], idx, dms, home)
+ if err != nil {
+ log.Fatalf("mission2kmk: %+v\n", err)
+ }
+}
- _, m, err := mission.Read_Mission_File_Index(files[0], idx)
- if m != nil && err == nil {
- if len(home) == 0 {
- if m.Metadata.Homey != 0 && m.Metadata.Homex != 0 {
- home = append(home, m.Metadata.Homey, m.Metadata.Homex)
+func generateKML(mfile string, idx int, dms bool, homep []float64) error {
+ kname := filepath.Base(mfile)
+ d := kml.Folder(kml.Name(kname)).Add(kml.Open(true))
+ _, mm, err := mission.Read_Mission_File(mfile)
+ if err == nil {
+ isviz := true
+ for nm, _ := range mm.Segment {
+ nmx := nm + 1
+ if idx == 0 || nmx == idx {
+ ms := mm.To_mission(nmx)
+ if len(homep) == 0 {
+ if ms.Metadata.Homey != 0 && ms.Metadata.Homex != 0 {
+ homep = append(homep, ms.Metadata.Homey, ms.Metadata.Homex)
+ }
+ }
+ var hpos types.HomeRec
+ if len(homep) == 2 {
+ hpos.HomeLat = homep[0]
+ hpos.HomeLon = homep[1]
+ hpos.Flags = types.HOME_ARM
+ }
+ if len(homep) > 2 {
+ hpos.HomeAlt = homep[2]
+ hpos.Flags |= types.HOME_ALT
+ }
+ mf := ms.To_kml(hpos, dms, false, nmx, isviz)
+ d.Add(mf)
+ isviz = false
}
}
-
- m.Dump(dms, home...)
- }
- if err != nil {
- log.Fatalf("mission2kmk: %+v\n", err)
+ k := kml.KML(d)
+ k.WriteIndent(os.Stdout, "", " ")
}
+ return err
}
diff --git a/meson.build b/meson.build
index 556945b..f55bdde 100644
--- a/meson.build
+++ b/meson.build
@@ -1,4 +1,4 @@
-project('flightlog2kml', version : '1.0.3-rc1')
+project('flightlog2kml', version : '1.0.4-rc1')
meson.add_install_script('meson/post_install.py')
version = get_option('version')
commit = get_option('commit')
diff --git a/pkg/kmlgen/kmlbuilder.go b/pkg/kmlgen/kmlbuilder.go
index a46d458..1a777fe 100644
--- a/pkg/kmlgen/kmlbuilder.go
+++ b/pkg/kmlgen/kmlbuilder.go
@@ -13,6 +13,7 @@ import (
"image/color"
"log"
"os"
+ "path/filepath"
"strings"
)
@@ -470,6 +471,39 @@ func add_ground_track(rec types.LogRec) kml.Element {
return f
}
+func GenerateMissionOnly(outfn string) {
+ kname := filepath.Base(options.Config.Mission)
+ d := kml.Folder(kml.Name(kname)).Add(kml.Open(true))
+ _, mm, err := mission.Read_Mission_File(options.Config.Mission)
+ if err == nil {
+ isviz := true
+ for nm, _ := range mm.Segment {
+ nmx := nm + 1
+ if options.Config.MissionIndex == 0 || nmx == options.Config.MissionIndex {
+ ms := mm.To_mission(nmx)
+ if geo.Getfrobnication() {
+ for k, mi := range ms.MissionItems {
+ if mi.Is_GeoPoint() {
+ ms.MissionItems[k].Lat, ms.MissionItems[k].Lon, _ = geo.Frobnicate_move(ms.MissionItems[k].Lat, ms.MissionItems[k].Lon, 0)
+ }
+ }
+ }
+ var hpos types.HomeRec
+
+ if ms.Metadata.Homey != 0 && ms.Metadata.Homex != 0 {
+ hpos.HomeLat = ms.Metadata.Homey
+ hpos.HomeLon = ms.Metadata.Homex
+ hpos.Flags = types.HOME_ARM
+ }
+ mf := ms.To_kml(hpos, options.Config.Dms, false, nmx, isviz)
+ d.Add(mf)
+ isviz = false
+ }
+ }
+ write_kml(outfn, d)
+ }
+}
+
func GenerateKML(hpos types.HomeRec, rec types.LogRec, outfn string,
meta types.FlightMeta, smap types.MapRec) {
@@ -485,20 +519,42 @@ func GenerateKML(hpos types.HomeRec, rec types.LogRec, outfn string,
d.Add(add_ground_track(rec))
if len(options.Config.Mission) > 0 {
- _, ms, err := mission.Read_Mission_File_Index(options.Config.Mission, options.Config.MissionIndex)
+ _, mm, err := mission.Read_Mission_File(options.Config.Mission)
if err == nil {
- if geo.Getfrobnication() {
- for k, mi := range ms.MissionItems {
- if mi.Is_GeoPoint() {
- ms.MissionItems[k].Lat, ms.MissionItems[k].Lon, _ = geo.Frobnicate_move(ms.MissionItems[k].Lat, ms.MissionItems[k].Lon, 0)
+ isviz := true
+ for nm, _ := range mm.Segment {
+ nmx := nm + 1
+ if options.Config.MissionIndex == 0 || nmx == options.Config.MissionIndex {
+ ms := mm.To_mission(nmx)
+ if geo.Getfrobnication() {
+ for k, mi := range ms.MissionItems {
+ if mi.Is_GeoPoint() {
+ ms.MissionItems[k].Lat, ms.MissionItems[k].Lon, _ = geo.Frobnicate_move(ms.MissionItems[k].Lat, ms.MissionItems[k].Lon, 0)
+ }
+ }
}
+ mf := ms.To_kml(hpos, options.Config.Dms, false, nmx, isviz)
+ d.Add(mf)
+ isviz = false
}
}
- mf := ms.To_kml(hpos, options.Config.Dms, false)
- d.Add(mf)
- } else {
- fmt.Fprintf(os.Stderr, "* Failed to read mission file %s\n", options.Config.Mission)
}
+ /**
+ _, ms, err := mission.Read_Mission_File_Index(options.Config.Mission, options.Config.MissionIndex)
+ if err == nil {
+ if geo.Getfrobnication() {
+ for k, mi := range ms.MissionItems {
+ if mi.Is_GeoPoint() {
+ ms.MissionItems[k].Lat, ms.MissionItems[k].Lon, _ = geo.Frobnicate_move(ms.MissionItems[k].Lat, ms.MissionItems[k].Lon, 0)
+ }
+ }
+ }
+ mf := ms.To_kml(hpos, options.Config.Dms, false)
+ d.Add(mf)
+ } else {
+ fmt.Fprintf(os.Stderr, "* Failed to read mission file %s\n", options.Config.Mission)
+ }
+ **/
}
e := kml.ExtendedData(kml.Data(kml.Name("Log"), kml.Value(meta.LogName())))
@@ -558,7 +614,10 @@ func GenerateKML(hpos types.HomeRec, rec types.LogRec, outfn string,
d.Add(f1)
}
}
+ write_kml(outfn, d)
+}
+func write_kml(outfn string, d *kml.CompoundElement) {
var err error
if strings.HasSuffix(outfn, ".kmz") {
z := kmz.NewKMZ(d)
diff --git a/pkg/mission/mission-read.go b/pkg/mission/mission-read.go
index 89e96cc..fb2c425 100644
--- a/pkg/mission/mission-read.go
+++ b/pkg/mission/mission-read.go
@@ -6,7 +6,7 @@ import (
"os"
)
-func (mm *MultiMission) to_mission(mi int) *Mission {
+func (mm *MultiMission) To_mission(mi int) *Mission {
m := &Mission{}
if mi > len(mm.Segment) {
mi = len(mm.Segment)
@@ -20,7 +20,7 @@ func (mm *MultiMission) to_mission(mi int) *Mission {
return m
}
-func Read_Mission_File_Index(path string, idx int) (string, *Mission, error) {
+func Read_Mission_File(path string) (string, *MultiMission, error) {
var dat []byte
r, err := os.Open(path)
if err == nil {
@@ -33,9 +33,17 @@ func Read_Mission_File_Index(path string, idx int) (string, *Mission, error) {
mtype, mm := handle_mission_data(dat, path)
if mm == nil {
fmt.Fprintf(os.Stderr, "Note: Mission fails verification %s\n", mtype)
- return mtype, nil, nil
}
- m := mm.to_mission(idx)
+ return mtype, mm, nil
+ }
+}
+
+func Read_Mission_File_Index(path string, idx int) (string, *Mission, error) {
+ mtype, mm, err := Read_Mission_File(path)
+ if err == nil {
+ m := mm.To_mission(idx)
return mtype, m, nil
+ } else {
+ return mtype, nil, err
}
}
diff --git a/pkg/mission/mission.go b/pkg/mission/mission.go
index 3a11caa..578467d 100644
--- a/pkg/mission/mission.go
+++ b/pkg/mission/mission.go
@@ -220,7 +220,7 @@ func (m *Mission) Dump(dms bool, homep ...float64) {
hpos.HomeAlt = homep[2]
hpos.Flags |= types.HOME_ALT
}
- k := kml.KML(m.To_kml(hpos, dms, true))
+ k := kml.KML(m.To_kml(hpos, dms, true, 1, true))
k.WriteIndent(os.Stdout, "", " ")
}
diff --git a/pkg/mission/to_kml.go b/pkg/mission/to_kml.go
index a319be3..e475457 100644
--- a/pkg/mission/to_kml.go
+++ b/pkg/mission/to_kml.go
@@ -2,16 +2,16 @@ package mission
import (
"fmt"
+ types "github.com/stronnag/bbl2kml/pkg/api/types"
+ geo "github.com/stronnag/bbl2kml/pkg/geo"
kml "github.com/twpayne/go-kml"
"github.com/twpayne/go-kml/icon"
"image/color"
- geo "github.com/stronnag/bbl2kml/pkg/geo"
- types "github.com/stronnag/bbl2kml/pkg/api/types"
)
-func (m *Mission) get_fly_points (addAlt int32) ([]kml.Coordinate, bool) {
+func (m *Mission) get_fly_points(addAlt int32) ([]kml.Coordinate, bool) {
var points []kml.Coordinate
- nsize := len(m.MissionItems)
+ nsize := len(m.MissionItems)
ret := false
jumpC := make([]int16, nsize)
@@ -64,9 +64,9 @@ func (m *Mission) get_fly_points (addAlt int32) ([]kml.Coordinate, bool) {
return points, ret
}
-func (m *Mission) To_kml(hpos types.HomeRec, dms bool, fake bool) kml.Element {
+func (m *Mission) To_kml(hpos types.HomeRec, dms bool, fake bool, mmidx int, isvis bool) kml.Element {
var points []kml.Coordinate
- var wps []kml.Element
+ var wps []kml.Element
llat := 0.0
llon := 0.0
lalt := int32(0)
@@ -78,7 +78,7 @@ func (m *Mission) To_kml(hpos types.HomeRec, dms bool, fake bool) kml.Element {
if (hpos.Flags & types.HOME_ALT) == types.HOME_ALT {
addAlt = int32(hpos.HomeAlt)
} else {
- bingelev, err := geo.GetElevation(hpos.HomeLat, hpos.HomeLon)
+ bingelev, err := geo.GetElevation(hpos.HomeLat, hpos.HomeLon)
if err == nil {
addAlt = int32(bingelev)
hpos.Flags |= types.HOME_ALT
@@ -97,7 +97,7 @@ func (m *Mission) To_kml(hpos types.HomeRec, dms bool, fake bool) kml.Element {
var alt int32
for _, mi := range m.MissionItems {
- if mi.Action == "JUMP" || mi.Action == "SET_HEAD" || mi.Action == "RTH" {
+ if mi.Action == "JUMP" || mi.Action == "SET_HEAD" || mi.Action == "RTH" {
lat = llat
lon = llon
alt = lalt
@@ -127,7 +127,7 @@ func (m *Mission) To_kml(hpos types.HomeRec, dms bool, fake bool) kml.Element {
default:
bname = mi.Action
}
- name:= fmt.Sprintf("%s %d", bname, mi.No)
+ name := fmt.Sprintf("%s %d", bname, mi.No)
p := kml.Placemark(
kml.Name(name),
kml.Description(fmt.Sprintf("Action: %s
Position: %s
Elevation: %dm
GPS Altitude: %dm
",
@@ -138,6 +138,7 @@ func (m *Mission) To_kml(hpos types.HomeRec, dms bool, fake bool) kml.Element {
kml.Coordinates(kml.Coordinate{Lon: lon, Lat: lat, Alt: float64(alt)}),
),
)
+ p.Add(kml.Visibility(isvis))
wps = append(wps, p)
}
@@ -164,7 +165,7 @@ func (m *Mission) To_kml(hpos types.HomeRec, dms bool, fake bool) kml.Element {
pts, rth := m.get_fly_points(addAlt)
points = append(points, pts...)
- if rth && (hpos.Flags & types.HOME_ALT) == types.HOME_ALT {
+ if rth && (hpos.Flags&types.HOME_ALT) == types.HOME_ALT {
points = append(points, kml.Coordinate{Lon: hpos.HomeLon, Lat: hpos.HomeLat, Alt: float64(addAlt)})
}
@@ -179,8 +180,10 @@ func (m *Mission) To_kml(hpos types.HomeRec, dms bool, fake bool) kml.Element {
),
)
- return kml.Folder(kml.Name("Mission File")).Add(kml.Description(desc)).
- Add(kml.Visibility(true)).Add(mission_styles()...).Add(track).Add(wps...)
+ track.Add(kml.Visibility(isvis))
+ fldnam := fmt.Sprintf("Mission #%d", mmidx)
+ return kml.Folder(kml.Name(fldnam)).Add(kml.Description(desc)).
+ Add(kml.Visibility(isvis)).Add(mission_styles()...).Add(track).Add(wps...)
}
func mission_styles() []kml.Element {
@@ -190,8 +193,7 @@ func mission_styles() []kml.Element {
kml.IconStyle(
kml.Scale(0.8),
kml.Icon(
- kml.Href(icon.PaddleHref("ylw-diamond"),
- ),
+ kml.Href(icon.PaddleHref("ylw-diamond")),
),
),
kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
@@ -202,45 +204,40 @@ func mission_styles() []kml.Element {
kml.IconStyle(
kml.Scale(0.8),
kml.Icon(
- kml.Href(icon.PaddleHref("red-diamond"),
- ),
+ kml.Href(icon.PaddleHref("red-diamond")),
),
),
- kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
- kml.Text(`$[name]
$[description]
`)),
+ kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
+ kml.Text(`$[name]
$[description]
`)),
),
kml.SharedStyle(
"styleSET_HEAD",
kml.IconStyle(
kml.Scale(0.8),
kml.Icon(
- kml.Href(icon.PaddleHref("ylw-diamond"),
- ),
+ kml.Href(icon.PaddleHref("ylw-diamond")),
),
),
- kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
- kml.Text(`$[name]
$[description]
`)),
+ kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
+ kml.Text(`$[name]
$[description]
`)),
),
kml.SharedStyle(
"styleWAYPOINT",
kml.IconStyle(
kml.Scale(0.8),
kml.Icon(
- kml.Href(icon.PaddleHref("ltblu-circle"),
- ),
+ kml.Href(icon.PaddleHref("ltblu-circle")),
),
),
kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
kml.Text(`$[name]
$[description]
`)),
-
),
kml.SharedStyle(
"stylePOSHOLD_UNLIM",
kml.IconStyle(
kml.Scale(0.8),
kml.Icon(
- kml.Href(icon.PaddleHref("grn-diamond"),
- ),
+ kml.Href(icon.PaddleHref("grn-diamond")),
),
),
kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
@@ -251,20 +248,18 @@ func mission_styles() []kml.Element {
kml.IconStyle(
kml.Scale(0.8),
kml.Icon(
- kml.Href(icon.PaddleHref("grn-circle"),
- ),
+ kml.Href(icon.PaddleHref("grn-circle")),
),
),
- kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
- kml.Text(`$[name]
$[description]
`)),
+ kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
+ kml.Text(`$[name]
$[description]
`)),
),
kml.SharedStyle(
"styleJUMP",
kml.IconStyle(
kml.Scale(0.8),
kml.Icon(
- kml.Href(icon.PaddleHref("purple-circle"),
- ),
+ kml.Href(icon.PaddleHref("purple-circle")),
),
),
kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
@@ -275,24 +270,22 @@ func mission_styles() []kml.Element {
kml.IconStyle(
kml.Scale(0.8),
kml.Icon(
- kml.Href(icon.PaddleHref("pink-stars"),
- ),
+ kml.Href(icon.PaddleHref("pink-stars")),
),
),
- kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
- kml.Text(`$[name]
$[description]
`)),
+ kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
+ kml.Text(`$[name]
$[description]
`)),
),
kml.SharedStyle(
"styleFakeHome",
kml.IconStyle(
kml.Scale(0.8),
kml.Icon(
- kml.Href(icon.PaddleHref("orange-stars"),
- ),
+ kml.Href(icon.PaddleHref("orange-stars")),
),
),
- kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
- kml.Text(`$[name]
$[description]
`)),
+ kml.BalloonStyle(kml.BgColor(color.RGBA{R: 0xde, G: 0xde, B: 0xde, A: 0x40}),
+ kml.Text(`$[name]
$[description]
`)),
),
kml.SharedStyle(
"styleWPTrack",
diff --git a/pkg/options/options.go b/pkg/options/options.go
index 79677b5..a15e2d3 100644
--- a/pkg/options/options.go
+++ b/pkg/options/options.go
@@ -166,7 +166,7 @@ func ParseCLI(gv func() string) ([]string, string) {
flag.IntVar(&Config.HomeAlt, "home-alt", Config.HomeAlt, "[OTX] home altitude")
flag.BoolVar(&Config.Dump, "dump", false, "Dump log headers and exit")
flag.StringVar(&Config.Mission, "mission", "", "Optional mission file name")
- flag.IntVar(&Config.MissionIndex, "mission-index", 1, "Optional mission file index")
+ flag.IntVar(&Config.MissionIndex, "mission-index", 0, "Optional mission file index")
}
if strings.HasPrefix(app, "fl2mqtt") {
flag.StringVar(&Config.Mqttopts, "broker", "", "Mqtt URI (mqtt://[user[:pass]@]broker[:port]/topic[?cafile=file]")
@@ -217,15 +217,13 @@ func ParseCLI(gv func() string) ([]string, string) {
Config.HomeAlt = -999999 // sentinel
}
/*
- if Config.Idx == 0 {
- Config.Idx = 1
+ if Config.Idx == 0 {
+ Config.Idx = 1
+ }
+ if Config.MissionIndex == 0 {
+ Config.MissionIndex = 1
}
*/
-
- if Config.MissionIndex == 0 {
- Config.MissionIndex = 1
- }
-
if err != nil {
fmt.Fprintf(os.Stderr, "Warning: config file ignored due to error: %v\n", err)
}