1 package au.gov.amsa.geo.distance;
2
3 import static au.gov.amsa.geo.distance.Renderer.saveAsPng;
4
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.InputStreamReader;
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.concurrent.TimeUnit;
14 import java.util.zip.GZIPInputStream;
15
16 import org.apache.log4j.Logger;
17
18 import com.google.common.base.Charsets;
19
20 import au.gov.amsa.geo.BinaryCellValuesObservable;
21 import au.gov.amsa.geo.OperatorCellValuesToBytes;
22 import au.gov.amsa.geo.Util;
23 import au.gov.amsa.geo.distance.DistanceTravelledCalculator.CalculationResult;
24 import au.gov.amsa.geo.model.Bounds;
25 import au.gov.amsa.geo.model.CellValue;
26 import au.gov.amsa.geo.model.Options;
27 import au.gov.amsa.geo.model.SegmentOptions;
28 import au.gov.amsa.navigation.ShipStaticData;
29 import au.gov.amsa.navigation.ShipStaticData.Info;
30 import au.gov.amsa.risky.format.AisClass;
31 import au.gov.amsa.util.identity.MmsiValidator2;
32 import au.gov.amsa.util.rx.OperatorWriteBytes;
33 import rx.Observable;
34 import rx.functions.Func1;
35
36 public class DistanceTravelledMain {
37 private static Logger log = Logger.getLogger(DistanceTravelledMain.class);
38
39 private static void run(String directory, Options options, boolean gui, String dataSetName) {
40 InputStream is;
41 try {
42 is = new GZIPInputStream(
43 new FileInputStream("/media/an/ship-data/ais/ship-data-2014-v2.txt.gz"));
44 } catch (IOException e) {
45 throw new RuntimeException(e);
46 }
47 Map<Integer, Info> shipInfo = ShipStaticData
48 .getMapFromReader(new InputStreamReader(is, Charsets.UTF_8));
49
50 List<Setting> settings = new ArrayList<>();
51 settings.add(Setting.create(30, 30, "fishing"));
52 settings.add(Setting.create(52, 52, "tug"));
53 settings.add(Setting.create(60, 69, "passenger"));
54 settings.add(Setting.create(70, 79, "cargo"));
55 settings.add(Setting.create(80, 89, "tanker"));
56 settings.add(Setting.create(90, 99, "other"));
57 settings.add(Setting.create(-1, -1, "class_b"));
58 settings.add(Setting.create(0, 100, "all"));
59
60 for (Setting setting : settings) {
61
62 Func1<Info, Boolean> shipSelector = info -> info != null
63 && ((info.cls == AisClass.B && setting.lowerBound == -1)
64 || (info.cls == AisClass.A && (info.shipType.isPresent()
65 && info.shipType.get() >= setting.lowerBound
66 && info.shipType.get() <= setting.upperBound)))
67 && MmsiValidator2.INSTANCE.isValid(info.mmsi);
68 calculateTrafficDensity(directory, options, gui, shipInfo, shipSelector,
69 setting.name + "-" + dataSetName);
70 }
71 }
72
73 private static class Setting {
74 final int lowerBound;
75 final int upperBound;
76 final String name;
77
78 Setting(int lowerBound, int upperBound, String name) {
79 this.lowerBound = lowerBound;
80 this.upperBound = upperBound;
81 this.name = name;
82 }
83
84 public static Setting create(int lowerBound, int upperBound, String name) {
85 return new Setting(lowerBound, upperBound, name);
86 }
87 }
88
89 private static void calculateTrafficDensity(String directory, Options options, boolean gui,
90 Map<Integer, Info> shipInfo, Func1<Info, Boolean> shipSelector, String name) {
91 System.out.println("-----------------------------------------------------");
92 System.out.println("------ " + name);
93 System.out.println("-----------------------------------------------------");
94
95 final Observable<File> files = Util.getFiles(directory, ".*\\.track")
96
97 .filter(file -> {
98 String s = file.getName();
99 String mmsiString = s.substring(0, s.indexOf(".track"));
100 long mmsi = Long.parseLong(mmsiString);
101 Info info = shipInfo.get(mmsi);
102 return shipSelector.call(info);
103 });
104
105 CalculationResult result = DistanceTravelledCalculator.calculateTrafficDensity(options,
106 files, 1, 1);
107
108 if (gui) {
109 DisplayPanel.displayGui(files, options, result);
110 }
111 String filename = result.getCells()
112
113 .lift(new OperatorCellValuesToBytes(options))
114
115 .lift(new OperatorWriteBytes())
116
117 .toBlocking().single();
118 log.info("result saved to file " + filename);
119
120 CalculationResult resultFromFile = new CalculationResult(BinaryCellValuesObservable
121 .readValues(new File(filename)).skip(1).cast(CellValue.class), result.getMetrics());
122
123 boolean produceImage = false;
124 boolean produceDensitiesText = false;
125 boolean produceDensitiesNetcdf = true;
126
127 File outputDirectory = new File("/media/an/traffic-density/netcdf");
128
129 if (produceImage) {
130
131 saveAsPng(Renderer.createImage(options, 2, 12800, resultFromFile),
132 new File(outputDirectory, name + "-map.png"));
133 }
134
135 if (produceDensitiesText) {
136 DistanceTravelledCalculator.saveCalculationResultAsText(options, result,
137 new File(outputDirectory, name + "-densities.txt").getAbsolutePath());
138 }
139
140 if (produceDensitiesNetcdf) {
141 DistanceTravelledCalculator.saveCalculationResultAsNetcdf(options, result,
142 new File(outputDirectory, name + "-densities.nc").getAbsolutePath());
143 }
144 }
145
146 private static Options createOptions(double cellSizeDegrees) {
147 return Options.builder()
148
149 .originLat(0)
150
151 .originLon(0)
152
153 .cellSizeDegrees(cellSizeDegrees)
154
155 .bounds(new Bounds(15, 67, -60, 179))
156
157
158
159
160
161
162
163
164 .segmentOptions(SegmentOptions.builder()
165
166 .maxSpeedKnots(100)
167
168 .speedCheckDistanceThresholdNm(30)
169
170 .speedCheckMinTimeDiff(3, TimeUnit.MINUTES)
171
172 .maxTimePerSegment(1, TimeUnit.DAYS)
173
174 .maxDistancePerSegmentNm(500.0)
175
176 .build())
177
178 .build();
179 }
180
181 public static void main(String[] args) throws InterruptedException {
182
183 log.info("starting");
184
185 final double cellSizeDegrees;
186 if (args.length > 1)
187 cellSizeDegrees = Double.parseDouble(args[1]);
188 else
189 cellSizeDegrees = 0.02;
190
191 final Options options = createOptions(cellSizeDegrees);
192 for (int i = 0; i <= 10; i++)
193 System.out.println(options.getGrid().centreLon(i));
194
195 for (int i = 2014; i <= 2016; i++) {
196 String directory = "/media/an/binary-fixes-5-minute/" + i;
197 run(directory, options, false, i + "");
198 }
199 }
200 }