2020-04-15 09:46:58 +01:00
package main
import (
2020-04-15 20:56:10 +01:00
"encoding/json"
2020-04-21 08:45:05 +01:00
"flag"
2020-04-15 09:46:58 +01:00
"fmt"
2020-04-15 20:56:10 +01:00
"io"
"io/ioutil"
2020-04-15 09:46:58 +01:00
"log"
"os"
2020-04-15 20:56:10 +01:00
"path"
2020-04-15 09:46:58 +01:00
2020-04-20 23:08:57 +01:00
"github.com/dhconnelly/rtreego"
"github.com/ray1729/gpx-utils/pkg/cafes"
2020-04-18 12:58:53 +01:00
"github.com/ray1729/gpx-utils/pkg/placenames"
2020-04-15 09:46:58 +01:00
)
func main ( ) {
2020-04-18 14:26:48 +01:00
log . SetFlags ( 0 )
2020-04-21 08:45:05 +01:00
stopNames := flag . String ( "stops" , "" , "Source for refreshment stops" )
2020-07-14 09:15:08 +01:00
minDist := flag . Float64 ( "min-dist" , 0.2 , "Minimum distance (km) between points of interest" )
minSettlement := flag . String ( "min-settlement" , "Other Settlement" , "Exclude populated places smaller than this (City, Town, Village, Hamlet, Other Settlement)" )
2020-04-21 08:45:05 +01:00
flag . Parse ( )
if flag . NArg ( ) != 1 {
2020-07-14 09:15:08 +01:00
log . Fatal ( "Usage: %s [--stops=ctccambridge|cyclingmaps] [--min-dist X] [--min-settlement S] GPX_FILE_OR_DIRECTORY" )
2020-04-18 14:26:48 +01:00
}
2020-04-21 08:45:05 +01:00
inFile := flag . Arg ( 0 )
2020-04-18 14:26:48 +01:00
info , err := os . Stat ( inFile )
if err != nil {
log . Fatal ( err )
2020-04-15 09:46:58 +01:00
}
2020-04-21 08:45:05 +01:00
var stops * rtreego . Rtree
if * stopNames != "" {
var err error
stops , err = cafes . New ( ) . Get ( * stopNames )
if err != nil {
log . Fatal ( err )
}
2020-04-20 23:08:57 +01:00
}
2020-04-18 12:58:53 +01:00
gs , err := placenames . NewGPXSummarizer ( )
2020-04-15 09:46:58 +01:00
if err != nil {
log . Fatal ( err )
}
2020-07-14 09:15:08 +01:00
gs . SetMinDistance ( * minDist )
gs . SetMinSettlement ( * minSettlement )
2020-04-18 14:26:48 +01:00
if info . IsDir ( ) {
2020-04-21 08:45:05 +01:00
err = summarizeDirectory ( gs , stops , inFile )
2020-04-15 20:56:10 +01:00
} else {
2020-04-21 08:45:05 +01:00
err = summarizeSingleFile ( gs , stops , inFile )
2020-04-15 20:56:10 +01:00
}
if err != nil {
log . Fatal ( err )
}
}
2020-04-20 23:08:57 +01:00
func summarizeDirectory ( gs * placenames . GPXSummarizer , stops * rtreego . Rtree , dirName string ) error {
2020-04-15 20:56:10 +01:00
files , err := ioutil . ReadDir ( dirName )
if err != nil {
return err
}
for _ , f := range files {
if f . IsDir ( ) || path . Ext ( f . Name ( ) ) != ".gpx" {
2020-04-15 09:46:58 +01:00
continue
}
2020-04-15 20:56:10 +01:00
filename := path . Join ( dirName , f . Name ( ) )
2020-04-17 13:01:05 +01:00
r , err := os . Open ( filename )
if err != nil {
return fmt . Errorf ( "error opening %s for reading: %v" , filename , err )
}
2020-04-15 20:56:10 +01:00
log . Printf ( "Analyzing %s" , filename )
2020-04-20 23:08:57 +01:00
summary , err := gs . SummarizeTrack ( r , stops )
2020-04-15 20:56:10 +01:00
if err != nil {
return fmt . Errorf ( "error creating summary of GPX track %s: %v" , filename , err )
}
outfile := filename [ : len ( filename ) - 4 ] + ".json"
wc , err := os . OpenFile ( outfile , os . O_CREATE | os . O_TRUNC | os . O_RDWR , 0644 )
if err != nil {
return fmt . Errorf ( "error creating output file %s: %v" , outfile , err )
}
err = writeSummary ( summary , wc )
if err != nil {
wc . Close ( )
return fmt . Errorf ( "error marshalling JSON to %s: %v" , outfile , err )
}
if err = wc . Close ( ) ; err != nil {
return fmt . Errorf ( "error closing file %s: %v" , outfile , err )
2020-04-15 09:46:58 +01:00
}
}
2020-04-15 20:56:10 +01:00
return nil
}
2020-04-20 23:08:57 +01:00
func summarizeSingleFile ( gs * placenames . GPXSummarizer , stops * rtreego . Rtree , filename string ) error {
2020-04-17 13:01:05 +01:00
r , err := os . Open ( filename )
if err != nil {
return fmt . Errorf ( "error opening %s for reading: %v" , filename , err )
}
2020-04-20 23:08:57 +01:00
summary , err := gs . SummarizeTrack ( r , stops )
2020-04-15 20:56:10 +01:00
if err != nil {
return fmt . Errorf ( "error creating summary of GPX track %s: %v" , filename , err )
}
if err = writeSummary ( summary , os . Stdout ) ; err != nil {
return fmt . Errorf ( "error marshalling summary for %s: %v" , filename , err )
}
return nil
}
2020-04-18 12:58:53 +01:00
func writeSummary ( s * placenames . TrackSummary , w io . Writer ) error {
2020-04-15 20:56:10 +01:00
enc := json . NewEncoder ( w )
enc . SetIndent ( "" , " " )
if err := enc . Encode ( s ) ; err != nil {
return err
}
return nil
2020-04-15 09:46:58 +01:00
}