/
location.go
88 lines (73 loc) · 2.08 KB
/
location.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package dji
import (
"bufio"
"io"
"io/ioutil"
"os"
"regexp"
"strconv"
"strings"
mErrors "github.com/konradit/mmt/pkg/errors"
"github.com/konradit/mmt/pkg/utils"
)
type LatLongPair struct {
Latitude, Longitude *regexp.Regexp
Indicator string
}
type ACType int
const (
NewAircraft ACType = iota
OldAircraft
)
var allDrones = map[ACType]LatLongPair{
NewAircraft: {
Latitude: regexp.MustCompile(`\[latitude[ ]?: ([+-]?(\d+\.?\d*)|(\.\d+))\]`),
Longitude: regexp.MustCompile(`\[long[t]?itude[ ]?: ([+-]?(\d+\.?\d*)|(\.\d+))\]`), // DJI and their typos...
},
OldAircraft: {
Latitude: regexp.MustCompile(`GPS[ ]?\(([+-]?(\d+\.?\d*)|(\.\d+))`),
Longitude: regexp.MustCompile(`,[ ]?([+-]?(\d+\.?\d*)|(\.\d+)),[ ]?\d+\)`),
},
}
type LocationService struct{}
func (LocationService) GetLocation(path string) (*utils.Location, error) {
switch true {
case strings.Contains(path, ".MP4") || strings.Contains(path, ".SRT"):
return fromSRT(path)
case strings.Contains(path, ".JPG") || strings.Contains(path, ".DNG"):
return utils.LocationFromEXIF(path)
default:
return nil, mErrors.ErrInvalidFile
}
}
func fromSRT(srtPath string) (*utils.Location, error) {
fs, err := os.Open(strings.Replace(srtPath, ".MP4", ".SRT", -1))
if err != nil {
return nil, err
}
defer fs.Close()
reader := bufio.NewReader(fs)
limitedSizeReader := io.LimitReader(reader, 2048)
content, err := ioutil.ReadAll(limitedSizeReader)
if err != nil {
return nil, err
}
latAsFloat, lonAsFloat := float64(0), float64(0)
for _, drone := range allDrones {
latMatches := drone.Latitude.FindAllStringSubmatch(string(content), -1)
lonMatches := drone.Longitude.FindAllStringSubmatch(string(content), -1)
if len(lonMatches) == 0 || len(latMatches) == 0 {
continue
}
latAsFloat, err = strconv.ParseFloat(latMatches[0][1], 64)
if err != nil {
return nil, err
}
lonAsFloat, err = strconv.ParseFloat(lonMatches[0][1], 64)
if err != nil {
return nil, err
}
return &utils.Location{Latitude: latAsFloat, Longitude: lonAsFloat}, nil
}
return nil, mErrors.ErrNoRecognizedSRTFormat
}