• No results found

As already mentioned, for the trend analysis, a number of ports were selected based on their size and traffic. There were also a couple of known ports included in this dataset to easier interpret the results. The ports used in the analysis were:

NLRTM— Rotterdam, Netherlands

NOOSL— Oslo, Norway

CNSHG— Shanghai, China

NLMSV— Maasvlakte, Netherlands

SGSIN— Singapore, Singapore

USHPY— Baytown, USA

BEANR— Antwerpen, Belgium

TWKHH— Kaohsiung, Taiwan

JPYOK— Yokohama, Japan

The same process as for the single-case analysis was conducted, but on a higher level as the main purpose of this study was to establish a trend in terms of a impact factor of vessel segmentation on port frequencies. Figure A.6 shows a similar version of the table used for the single port analysis (Figure A.2) but also shows the number of transitions that differed from the most frequent next port when considering segments (i.e. the estimated improvement factor).

It is apparent that there are variances in improvement factors for

dif-Chapter A: Feasibility study - Summary 108

Figure A.6:Port frequencies and transition distribution as they relate to the most frequent next port for the selected ports

Figure A.7:Distribution of improvement factors for each origin port considering segments

Chapter A: Feasibility study - Summary 109

ferent ports ranging from as low as1.25% to as high as91.40%. In the case of NLRTM, which is mostly a dry bulk port, there were no considerable improvements as almost all vessels are of the same segment. For the port NLMSV, the opposite was the case as there were a plethora of different types of vessels that frequented the port. Figure A.7 shows the distribution of the improvement factor considering segments for each origin port as well as the overall average impact factor for these 9 ports which was36.88%.

Furthermore, when looking at the impact of sub-segments, as Figure A.8 shows, it seems that the improvement factor has increased overall. For example, in the case ofNLRTM, the improvement factor has increased from1.25%to19.66%, and although this varied for the different ports, the overall average improvement factor increased from36.88%to50.28%.

Figure A.8:Distribution of improvement factors for each origin port considering sub-segments

A prediction method considering the frequencies of ports for vessel des-tination predictions would choose the most frequent next port for the predicted next destination. In this scenario, ignoring the vessel’s type (segmentation) would give the wrong prediction for a lot of vessels from different segments in a lot of ports. The results from the feasibility study clearly indicates that applying the as-pect of vessel segmentation to such models would definitively have an impact on prediction accuracy and, therefore, is worth investigating further.

Appendix B

Trajectory sampler Golang package

Code listing B.1:Trajectory sampler package

1 // Package sampler can be used to sample 2D trajectories based on distance as well as 3D trajectories based on time

2 package sampler 3

4 import (

5 "errors"

6 "sort"

7 "time"

8

9 "github.com/paulmach/orb"

10 "github.com/paulmach/orb/encoding/wkt"

11 "github.com/paulmach/orb/geo"

12 "github.com/paulmach/orb/resample"

13 "github.com/twpayne/go-geom"

14 "github.com/twpayne/go-geom/encoding/ewkbhex"

15 geomwkt "github.com/twpayne/go-geom/encoding/wkt"

16 ) 17

18 // Metric either time or distance used for sampling 19 type Metric string

20

21 const (

22 // Time sampling uses hours as SamplRate unit 23 Time Metric = "time"

24 // Distance sampling uses meters as SamplRate unit 25 Distance Metric = "distance"

26 ) 27

28 // Instance of sampler 29 type Instance struct {

30 // Trajectory in (E)WKT format, e.g. (LINESTRING Z (x, y, timestamp)) 31 WKTTrajectory string

32 // Trajectory in (E)WBT format, e.g. (01020000800801058A1A4CC312424025B5548F949B5454240000) 33 WKBHexTrajectory string

34 Metric Metric

35 // SampleRate unit is hours for time and meters for distance 36 SampleRate int

110

Chapter B: Trajectory sampler Golang package 111

37 } 38

39 // Parsers 40

41 // parse2DTrajectory parses a trajectory not containing Z coordinates

42 // we want orb.Geometry for the resampling method which doesn’t support 3D geometry, 43 // so we use parse3DTrajectory and flatten the coords

44 func (s *Instance) parse2DTrajectory() (orb.LineString, error) { 45 geoLine, err := s.parse3DTrajectory()

46 if err != nil {

53 lineString = append(lineString, orb.Point{c[0], c[1]})

54 }

55

56 return lineString, nil 57 }

58

59 // parse3DTrajectory parses a 3D trajectory where the Z coordinate contains time 60 func (s *Instance) parse3DTrajectory() (*geom.LineString, error) {

61 var (

62 geometry geom.T

63 err error

64 )

65

66 if s.WKBHexTrajectory == "" && s.WKTTrajectory == "" {

67 return nil, errors.New("specify either WKTTrajectory, or WKBHexTrajectory")

68 }

69

70 if s.WKBHexTrajectory != "" {

71 geometry, err = ewkbhex.Decode(s.WKBHexTrajectory)

72 if err != nil {

73 return nil, err

74 }

75 }

76

77 if s.WKTTrajectory != "" {

78 geometry, err = geomwkt.Unmarshal(s.WKTTrajectory)

79 if err != nil {

80 return nil, err

81 }

82 }

83

84 line, ok := geometry.(*geom.LineString)

85 if !ok {

86 return nil, errors.New("geometry was not a valid linestring")

87 }

88

89 return line, nil 90 }

91

92 // Resample runs resampling based on given config 93 func (s *Instance) Resample() (string, error) { 94 switch s.Metric {

95 case Distance:

96 return s.resampleDistance()

Chapter B: Trajectory sampler Golang package 112

97 case Time:

98 return s.resampleTime()

99 default:

100 return "", errors.New("metric was not specified to a valid metric")

101 }

102 } 103

104 func (s *Instance) resampleDistance() (string, error) { 105 parsed, err := s.parse2DTrajectory()

106 if err != nil { 107 return "", err

108 }

109

110 sampled := resample.ToInterval(parsed, geo.DistanceHaversine, float64(s.SampleRate)) 111 return wkt.MarshalString(sampled), nil

112 } 113

114 // resampleTime resamples trajectory based on s.SampleRate given in hours.

115 // Extracts the first position within intervals based on sample rate 116 func (s *Instance) resampleTime() (string, error) {

117 var err error 118

119 trajectory, err := s.parse3DTrajectory() 120 if err != nil {

129 // within each interval add the first coord to reducedCoords 130 for _, interval := range intervals {

131 var first *geom.Coord

132

133 // find coord first within interval

134 for i := range coords {

135 coordInterval := s.roundTime(int64(coords[i][2]))

136 if coordInterval == interval {

137 first = &coords[i]

143 reducedCoords = append(reducedCoords, *first)

144 }

145 }

146

147 // if the last coord wasn’t in the reduced coords, add it 148 lastReduced := reducedCoords[len(reducedCoords)-1]

149 if !lastReduced.Equal(geom.XYZ, coords[len(coords)-1]) {

150 reducedCoords = append(reducedCoords, coords[len(coords)-1])

151 }

152

153 if len(reducedCoords) <= 1 {

154 return "", errors.New("too few points in sampled trajectory")

155 }

156

Chapter B: Trajectory sampler Golang package 113

157 reduced, err := geom.NewLineString(geom.XYZ).SetCoords(reducedCoords) 158 if err != nil {

159 return "", err

160 }

161

162 return geomwkt.Marshal(reduced) 163 }

164

165 // time sampling helpers 166

167 func (s *Instance) roundTime(ts int64) time.Time {

168 return time.Unix(ts, 0).UTC().Round(time.Duration(s.SampleRate) * time.Hour) 169 }

170

171 func (s *Instance) getTimeIntervals(trajectory *geom.LineString) []time.Time { 172 times := make(map[string]time.Time)

173 for _, coord := range trajectory.Coords() { 174 rounded := s.roundTime(int64(coord[2]))

175 times[rounded.Format("2006.01.02:15:04")] = rounded

176 }

177

178 ret := make([]time.Time, 0, len(times)) 179 for _, value := range times {

180 ret = append(ret, value)

181 }

182

183 sort.Slice(ret, func(i, j int) bool { 184 return ret[i].Before(ret[j])

185 })

186

187 return ret

NTNU Norwegian University of Science and Technology Faculty of Information Technology and Electrical Engineering Department of Computer Science

Morten Omholt-JensenVessel destination forecasting based on historical AIS data

Morten Omholt-Jensen

Vessel destination forecasting based on historical AIS data

Master’s thesis in Applied Computer Science Supervisor: Christopher Frantz

June 2021

Master ’s thesis