Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new plugin for showing AIS positions of vessels #21556

Merged
merged 103 commits into from
Feb 3, 2025
Merged
Changes from 1 commit
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
ddb8fab
new plugin: AIS vessel tracker, initial version
f-n Jun 16, 2024
f31f333
new plugin: AIS vessel tracker, initial version
f-n Jun 16, 2024
2a4eb97
insert some AIS objects for test purposes
f-n Jun 16, 2024
36ea38a
Merge branch 'osmandapp:master' into master
f-n Jun 16, 2024
984114f
Merge branch 'master' of https://github.com/f-n/OsmAnd
f-n Jun 16, 2024
b881cae
added syntax check for IP address and port number in settings dialog
f-n Jun 17, 2024
4fc4199
display distance and bearing in context menu
f-n Jun 18, 2024
57b9064
add 2 settings: AIS_OBJ_LOST_TIMEOUT and AIS_SHIP_LOST_TIMEOUT
f-n Jun 21, 2024
705bbd4
ship destination consisting of "@" is considered as invalid
f-n Jun 21, 2024
4afa720
improved preference setup dialog for network setting: show current va…
f-n Jun 22, 2024
32ebd90
new class to calculate CPA nd TCPA (not included into GUI yet)
f-n Jun 25, 2024
9b95c9d
update of CPA class after some testing (not included into GUI yet)
f-n Jun 30, 2024
c61a34e
use CPA data request in AIS object context menu to display CPA, TCPA
f-n Jul 1, 2024
c9eb718
some code refactoring
f-n Jul 2, 2024
406a2c8
additional preferences regarding CPA (not used in the application yet)
f-n Jul 2, 2024
93e4a5f
code refactoring regarding maxObjectAgeInMinutes, vesselLostTimeoutIn…
f-n Jul 2, 2024
a2fe7b4
add CPA check into vessel visualisation
f-n Jul 4, 2024
e70e8a2
adjust layout of context menu entries
f-n Jul 6, 2024
6006050
add disclaimer in the plugin description
f-n Jul 7, 2024
ad66408
address some concurrency issue in AIS object list
f-n Jul 21, 2024
2a435cb
use getCurrentLocation() instead of getLocation() for CPA calculations
f-n Jul 21, 2024
62131ba
add TCP connection reset after mapActivityResume in special situations
f-n Jul 23, 2024
a00ce91
added icon in the top area of the context menu
f-n Jul 23, 2024
460b7cb
do not show negative CPA times in context menu
f-n Jul 29, 2024
41804f5
change bitmap+color handling
f-n Jul 31, 2024
c3081a2
adjust logic for bitmap/color selection
f-n Aug 4, 2024
e662ce4
merge
f-n Aug 11, 2024
a8a4d77
adjustments after merge
f-n Aug 11, 2024
bd97816
Merge branch 'osmandapp:master' into master
f-n Aug 11, 2024
41cb344
merge
f-n Aug 11, 2024
82c727c
restart network listeners in cast of protocol change (UDP/TCP)
f-n Aug 13, 2024
932e4c2
increase max number of AIS objects to 200
f-n Aug 13, 2024
57f1d43
Merge branch 'osmandapp:master' into master
f-n Aug 14, 2024
831d16e
merge
f-n Aug 14, 2024
d2d355f
Merge branch 'osmandapp:master' into master
f-n Aug 15, 2024
821b7e8
Merge branch 'osmandapp:master' into master
f-n Aug 21, 2024
354e98a
Merge branch 'osmandapp:master' into master
f-n Aug 22, 2024
351f5fe
Merge branch 'osmandapp:master' into master
f-n Aug 23, 2024
a517a93
Merge branch 'osmandapp:master' into master
f-n Aug 23, 2024
0ad07ed
Merge branch 'osmandapp:master' into master
f-n Aug 24, 2024
6d869a8
Merge branch 'osmandapp:master' into master
f-n Aug 24, 2024
2217579
Merge branch 'osmandapp:master' into master
f-n Aug 25, 2024
acb5931
Merge branch 'osmandapp:master' into master
f-n Aug 25, 2024
862e7fe
Merge branch 'osmandapp:master' into master
f-n Aug 26, 2024
2a14544
adjusted CPA warning indication: add new condition: examine time when…
f-n Sep 24, 2024
bfb7b7b
change the available set for configurable CPA warning distances (now …
f-n Sep 24, 2024
8ba1e6e
Merge remote-tracking branch 'origin/master'
f-n Sep 26, 2024
5528bc8
fixed wrong visualisation for AIS message type 18
f-n Sep 26, 2024
ef3b284
adjusted/extended object description in the context menu
f-n Sep 26, 2024
5751e5a
adjust visualisation of moored vessels (vessels at rest): draw a circ…
f-n Sep 27, 2024
c8d7277
added two new AIS object types: AIS_VESSEL_AUTHORITIES and AIS_VESSE…
f-n Sep 28, 2024
0fa48ed
correct wrong color definition in AisObject.selectColor()
f-n Oct 18, 2024
b91c88d
allow status change from VALID to INVALID for some AIS attributes
f-n Oct 19, 2024
3440de8
created new AisObjectType: AIS_VESSEL_OTHER with individual color
f-n Oct 19, 2024
26a8e7c
special handling for objectClass = AIS_INVALID: might be moveable
f-n Oct 20, 2024
6a75d68
new plugin: AIS vessel tracker, initial version
f-n Jun 16, 2024
9bbd7fa
new plugin: AIS vessel tracker, initial version
f-n Jun 16, 2024
75f91e1
insert some AIS objects for test purposes
f-n Jun 16, 2024
84aa2eb
added syntax check for IP address and port number in settings dialog
f-n Jun 17, 2024
cfa015f
display distance and bearing in context menu
f-n Jun 18, 2024
a439e0b
add 2 settings: AIS_OBJ_LOST_TIMEOUT and AIS_SHIP_LOST_TIMEOUT
f-n Jun 21, 2024
8955967
ship destination consisting of "@" is considered as invalid
f-n Jun 21, 2024
78ceb14
improved preference setup dialog for network setting: show current va…
f-n Jun 22, 2024
7549fbe
new class to calculate CPA nd TCPA (not included into GUI yet)
f-n Jun 25, 2024
d12c0c5
update of CPA class after some testing (not included into GUI yet)
f-n Jun 30, 2024
3362c2a
use CPA data request in AIS object context menu to display CPA, TCPA
f-n Jul 1, 2024
7660bbb
some code refactoring
f-n Jul 2, 2024
fa21385
additional preferences regarding CPA (not used in the application yet)
f-n Jul 2, 2024
92eb0dc
code refactoring regarding maxObjectAgeInMinutes, vesselLostTimeoutIn…
f-n Jul 2, 2024
5ac23cf
add CPA check into vessel visualisation
f-n Jul 4, 2024
68f8d80
adjust layout of context menu entries
f-n Jul 6, 2024
1ab832e
add disclaimer in the plugin description
f-n Jul 7, 2024
8a65f7e
address some concurrency issue in AIS object list
f-n Jul 21, 2024
823aafc
use getCurrentLocation() instead of getLocation() for CPA calculations
f-n Jul 21, 2024
173df3e
add TCP connection reset after mapActivityResume in special situations
f-n Jul 23, 2024
562da86
added icon in the top area of the context menu
f-n Jul 23, 2024
8467b79
do not show negative CPA times in context menu
f-n Jul 29, 2024
abde360
change bitmap+color handling
f-n Jul 31, 2024
30ca7cc
adjust logic for bitmap/color selection
f-n Aug 4, 2024
0e72e91
adjustments after merge
f-n Aug 11, 2024
a9da155
restart network listeners in cast of protocol change (UDP/TCP)
f-n Aug 13, 2024
0cf6b9f
increase max number of AIS objects to 200
f-n Aug 13, 2024
06586cb
adjusted CPA warning indication: add new condition: examine time when…
f-n Sep 24, 2024
457d61b
change the available set for configurable CPA warning distances (now …
f-n Sep 24, 2024
0f6716d
fixed wrong visualisation for AIS message type 18
f-n Sep 26, 2024
f1b03c5
adjusted/extended object description in the context menu
f-n Sep 26, 2024
39978be
adjust visualisation of moored vessels (vessels at rest): draw a circ…
f-n Sep 27, 2024
46fb122
added two new AIS object types: AIS_VESSEL_AUTHORITIES and AIS_VESSE…
f-n Sep 28, 2024
1c3cd32
correct wrong color definition in AisObject.selectColor()
f-n Oct 18, 2024
dcd9967
allow status change from VALID to INVALID for some AIS attributes
f-n Oct 19, 2024
e5dcee3
created new AisObjectType: AIS_VESSEL_OTHER with individual color
f-n Oct 19, 2024
e310ec1
special handling for objectClass = AIS_INVALID: might be moveable
f-n Oct 20, 2024
acc6095
after git rebase
f-n Nov 23, 2024
ea02688
Merge branch 'osmandapp:master' into master
f-n Dec 3, 2024
9187499
Merge branch 'osmandapp:master' into master
f-n Dec 4, 2024
39a8127
Merge branch 'osmandapp:master' into master
f-n Dec 5, 2024
284249d
Merge branch 'osmandapp:master' into master
f-n Dec 8, 2024
a323d98
Merge branch 'osmandapp:master' into master
f-n Dec 10, 2024
3461633
Merge branch 'master' into ais
Chumva Dec 20, 2024
af0aba7
Remove unnecessary changes
Chumva Dec 20, 2024
1987620
Merge remote-tracking branch 'origin/master'
Chumva Jan 31, 2025
2bdf5e0
Add ability to show ais info from plugin
Chumva Jan 31, 2025
e83dfbf
Show plugin only in dev build, also add min zoom level for drawing
Chumva Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
use CPA data request in AIS object context menu to display CPA, TCPA
  • Loading branch information
f-n committed Nov 23, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 3362c2a16242876cdac85bd9f0d55db584ded7dc
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package net.osmand.plus.plugins.aistracker;

import static net.osmand.plus.plugins.aistracker.AisTrackerHelper.getCpa;
import static net.osmand.plus.utils.OsmAndFormatter.FORMAT_MINUTES;

import static java.lang.Math.ceil;

import android.annotation.SuppressLint;

import androidx.annotation.NonNull;
@@ -67,6 +70,38 @@ private String getOwnLocationAsString(@Nullable OsmAndLocationProvider locationP
return null;
}
*/
@SuppressLint("DefaultLocale")
private void addCpaInfo(@NonNull SortedSet<Integer> msgTypes,
@Nullable OsmAndLocationProvider locationProvider) {
if (msgTypes.contains(21) || msgTypes.contains(9)) {
return;
}
if ((aisObject.getCog() != AisObjectConstants.INVALID_COG) &&
(aisObject.getSog() != AisObjectConstants.INVALID_SOG)) {
AisTrackerHelper.Cpa cpa = new AisTrackerHelper.Cpa();
Location aisLocation = aisObject.getLocation();
if (aisLocation != null) {
getCpa(aisLocation, locationProvider, cpa);
if (cpa.isValid()) {
double cpaTime = cpa.getTcpa();
double hours = ceil(cpaTime);
double minutes = (cpaTime - hours) * 60.0;
addMenuItem("CPA", String.format("%.1f nm", cpa.getCpaDist()));
if (cpaTime > 0.0) {
if (hours >= 2.0) {
addMenuItem("TCPA", String.format("%.0f hours %.0f min", hours, minutes));
} else if (hours >= 1.0) {
addMenuItem("TCPA", String.format("%.0f hour %.0f min", hours, minutes));
} else {
addMenuItem("TCPA", String.format("%.0f min", minutes));
}
} else {
addMenuItem("TCPA", String.format("%.1f hours", cpaTime));
}
}
}
}
}

private void addMenuItem(@NonNull String type, @Nullable String value) {
if (value != null) {
@@ -127,6 +162,7 @@ public void addPlainMenuItems(String typeStr, PointDescription pointDescription,
addMenuItem("Bearing", String.format("%.1f", bearing));
} catch (Exception ignore) { }
}
addCpaInfo(msgTypes, locationProvider);
/*
// test:
addMenuItem("# loc", getOwnLocationAsString(locationProvider));
44 changes: 30 additions & 14 deletions OsmAnd/src/net/osmand/plus/plugins/aistracker/AisTrackerHelper.java
Original file line number Diff line number Diff line change
@@ -39,6 +39,7 @@ public static class Cpa {
private float cpaDist; // in miles
private Location newPos1; // position of first object at time tcpa
private Location newPos2; // position of first object at time tcpa
private boolean valid;
public Cpa() {
reset();
}
@@ -47,6 +48,7 @@ public void reset() {
tcpa = INVALID_TCPA;
newPos1 = null;
newPos2 = null;
valid = false;
}
public void setTcpa(double x) { this.tcpa = x; }
public void setCpaDist(float x) { this.cpaDist = x; }
@@ -56,6 +58,8 @@ public void reset() {
public float getCpaDist() { return cpaDist; }
public Location getCpaPos1() { return newPos1; }
public Location getCpaPos2() { return newPos2; }
public void validate() { valid = true; }
public boolean isValid() { return valid; }
}

/* calculate the Time to Closest Point of Approach (TCPA) of two moving objects:
@@ -67,8 +71,12 @@ private static double getTcpa(@NonNull Vector x, @NonNull Vector y,
@NonNull Vector vx, @NonNull Vector vy, double lonCorrection) {
Vector dx = new Vector( y.sub(x));
Vector dv = new Vector(vy.sub(vx));
double divisor = dv.dot(dv); // TODO: check for Div/0
return -(((dx.x * dv.x) + (dx.y * dv.y / lonCorrection)) / divisor); // TODO: check for Div/0
double divisor = dv.dot(dv);
if ((Math.abs(divisor) < 1.0E-10f) || (lonCorrection < 1.0E-10f)) {
// avoid div by 0 or invalid lonCorrection
return INVALID_TCPA;
}
return -(((dx.x * dv.x) + (dx.y * dv.y / lonCorrection)) / divisor);
}

/* to calculate the Time to Closest Point of Approach (TCPA) between the objects x and y,
@@ -77,7 +85,7 @@ private static double getTcpa(@NonNull Location x, @NonNull Location y, double l
if (checkSpeedAndBearing(x, y)) {
return INVALID_TCPA;
}
if (lonCorrection < 0.001) {
if (lonCorrection < 1.0E-10f) {
// in this case the lonCorrection is considered invalid -> new calculation
lonCorrection = getLonCorrection(x);
}
@@ -113,8 +121,12 @@ private static Location getCpa(@NonNull Location x, @NonNull Location y, boolean
return null;
}
double tcpa = getTcpa(x,y);
Location base = useFirstAsReference ? x : y;
return getNewPosition(base, tcpa);
if (tcpa == INVALID_TCPA) {
return null;
} else {
Location base = useFirstAsReference ? x : y;
return getNewPosition(base, tcpa);
}
}

/* to calculate the Closest Point of Approach (CPA) between the objects x and y,
@@ -159,13 +171,16 @@ public static void getCpa(@NonNull Location loc1, @NonNull Location loc2,
@NonNull Cpa result) {
if (!checkSpeedAndBearing(loc1, loc2)) {
double tcpa = getTcpa(loc1, loc2);
Location cpaX = getNewPosition(loc1, tcpa);
Location cpaY = getNewPosition(loc2, tcpa);
result.setTcpa(tcpa);
result.setCpaPos1(cpaX);
result.setCpaPos2(cpaY);
if ((cpaX != null) && (cpaY != null)) {
result.setCpaDist(meterToMiles(cpaX.distanceTo(cpaY)));
if (tcpa != INVALID_TCPA) {
Location cpaX = getNewPosition(loc1, tcpa);
Location cpaY = getNewPosition(loc2, tcpa);
result.setTcpa(tcpa);
result.setCpaPos1(cpaX);
result.setCpaPos2(cpaY);
if ((cpaX != null) && (cpaY != null)) {
result.setCpaDist(meterToMiles(cpaX.distanceTo(cpaY)));
result.validate();
}
}
}
}
@@ -191,7 +206,8 @@ public static Location getNewPosition(@Nullable Location x, double time) {
if (x != null) {
if (x.hasBearing() && x.hasSpeed()) {
LatLonPoint a = new LatLonPoint(x.getLatitude(), x.getLongitude());
LatLonPoint b = a.getPoint(x.getSpeed() * time * Math.PI / 5556.0, bearingInRad(x.getBearing()));
LatLonPoint b = a.getPoint(x.getSpeed() * time * Math.PI / 5556.0,
bearingInRad(x.getBearing()));
Location newX = new Location(x);
newX.setLongitude(b.getLongitude());
newX.setLatitude(b.getLatitude());
@@ -209,7 +225,7 @@ public static Location getNewPosition(@Nullable Location x, double time) {
private static double getLonCorrection(@Nullable Location loc) {
if (loc != null) {
Location x = new Location(loc);
// simulate a "measurement" trio towards East...
// simulate a "measurement" trip towards East...
x.setSpeed(knotsToMeterPerSecond(1.0f)); // speed -> 1 kn
x.setBearing(90.0f); // course -> east
Location yEast = getNewPosition(x, 1.0); // new position after 1 hour
114 changes: 80 additions & 34 deletions OsmAnd/src/net/osmand/plus/plugins/aistracker/AisTrackerLayer.java
Original file line number Diff line number Diff line change
@@ -62,43 +62,22 @@ public AisTrackerLayer(@NonNull Context context, @NonNull AisTrackerPlugin plugi
initTimer();
startNetworkListener();

initTestObjects(); // for test purposes:
// for test purposes: remove later...
initTestObjects();
testCpa();
}

private void initTestObjects() {
// passenger ship
AisObject ais = new AisObject(34568, 1, 20, 0, 1, 320,
320.0, 8.4, 50.738d, 7.099d, 0.0);
updateAisObjectList(ais);
ais = new AisObject(34568, 5, 0, "TEST-CALLSIGN1", "TEST-Ship", 60 /* passenger */, 56,
65, 8, 12, 2,
"Potsdam", 8, 15, 22, 5);
updateAisObjectList(ais);
// sailing boat
ais = new AisObject(454011, 1, 20, 8, 0, 120,
125.0, 4.4, 50.737d, 7.098d, 0.0);
updateAisObjectList(ais);
ais = new AisObject(454011, 5, 0, "TEST-CALLSIGN2", "TEST-Sailor", 36 /* sailing */, 0,
0, 0, 0, 0,
"@@@", 0, 0, 0, 0);
updateAisObjectList(ais);
// land station
ais = new AisObject(878121, 4, 50.736d, 7.100d);
updateAisObjectList(ais);
// AIDS
ais = new AisObject( 521077, 21, 50.735d, 7.101d, 2,
0, 0, 0, 0);
updateAisObjectList(ais);
// aircraft
ais = new AisObject(910323, 9, 15, 65, 180.5, 55.0, 50.734d, 7.102d);
updateAisObjectList(ais);

private void testCpa() {
// here some tests for the geo (CPA) calculation
// define 3 (vessel) objects
// for coordinate transformation see https://www.koordinaten-umrechner.de
Location x1 = new Location("test", 49.5d, -1.0d); // 49°30'N, 1°00'W
Location x2 = new Location("test", 49.916667d, 0.416667d); // 49°55'N, 0°25'E
Location x3 = new Location("test", 49.666667d, -0.75d); // 49°40'N, 0°45'W
Location y1, y2, y3;
Location x4 = new Location("test", 49.5d, -4.0d); // 49°30'N, 4°00'W
Location x5 = new Location("test", 50.0d, -3.75d); // 50°00'N, 3°45'W
// taken from marine chart: distances: x1 - x3: 13.8 nm, x2 - x3: 47,2 nm, x4 - x5: 31.4 nm
Location y1, y2, y3, y4, y5;
Log.d("AisTrackerLayer", "# test0: position 1 after 0 hours: "
+ LocationConvert.convertLatitude(x1.getLatitude(), FORMAT_MINUTES, true)
+ ", " + LocationConvert.convertLongitude(x1.getLongitude(), FORMAT_MINUTES, true));
@@ -108,8 +87,17 @@ private void initTestObjects() {
Log.d("AisTrackerLayer", "# test0: position 3 after 0 hours: "
+ LocationConvert.convertLatitude(x3.getLatitude(), FORMAT_MINUTES, true)
+ ", " + LocationConvert.convertLongitude(x3.getLongitude(), FORMAT_MINUTES, true));
Log.d("AisTrackerLayer", "# test0: position 4 after 0 hours: "
+ LocationConvert.convertLatitude(x4.getLatitude(), FORMAT_MINUTES, true)
+ ", " + LocationConvert.convertLongitude(x4.getLongitude(), FORMAT_MINUTES, true));
Log.d("AisTrackerLayer", "# test0: position 5 after 0 hours: "
+ LocationConvert.convertLatitude(x5.getLatitude(), FORMAT_MINUTES, true)
+ ", " + LocationConvert.convertLongitude(x5.getLongitude(), FORMAT_MINUTES, true));

// use case: x1: course 0°, speed 5kn, x3: course 270°, speed 10kn, time: 1h, 1.5h
// test case: x1: course 0°, speed 5kn, x3: course 270°, speed 10kn, time: 1h, 1.5h
// taken from marine chart:
// position after 1h: x1: 49°35'N, 1°00'W, x3: 49°40'N, 1°0.5'W, distance: 5.0nm
// position after 1.5h: x1: 49°37.5'N, 1°00'W, x3: 49°40'N, 1°8.5'W, distance: 6.0nm
x1.setSpeed(knotsToMeterPerSecond(5.0f));
x1.setBearing(0.0f);
x3.setSpeed(knotsToMeterPerSecond(10.0f));
@@ -124,7 +112,7 @@ private void initTestObjects() {
if ((y1 != null) && (y3 != null)) {
Log.d("AisTrackerLayer", "# test1: position 1 after 1 hour: "
+ LocationConvert.convertLatitude(y1.getLatitude(), FORMAT_MINUTES, true)
+ ", " + LocationConvert.convertLongitude(y1.getLongitude(), FORMAT_MINUTES, true));
+ ", " + LocationConvert.convertLongitude(y1.getLongitude(), FORMAT_MINUTES, true));
Log.d("AisTrackerLayer", "# test1: position 3 after 1 hour: "
+ LocationConvert.convertLatitude(y3.getLatitude(), FORMAT_MINUTES, true)
+ ", " + LocationConvert.convertLongitude(y3.getLongitude(), FORMAT_MINUTES, true));
@@ -153,7 +141,11 @@ private void initTestObjects() {
Log.d("AisTrackerLayer", "# test1: dist1: " + meterToMiles(y1.distanceTo(y3)));
}

// use case: x1: course 0°, speed 5kn, x3: course 270°, speed 5kn, time 1h, 1.5h, 2h
// test case: x1: course 0°, speed 5kn, x3: course 270°, speed 5kn, time 1h, 1.5h, 2h
// taken from marine chart:
// position after 1h: x1: 49°35'N, 1°00'W, x3: 49°40'N, 0°52.7'W, distance: 6.8nm
// position after 1.5h: x1: 49°37.5'N, 1°00'W, x3: 49°40'N, 0°56.7'W, distance: 3.1nm
// position after 2h: x1: 49°40'N, 1°00'W, x3: 49°40'N, 1°0.5'W, distance: 0.3nm
x1.setSpeed(knotsToMeterPerSecond(5.0f));
x1.setBearing(0.0f);
x3.setSpeed(knotsToMeterPerSecond(5.0f));
@@ -197,7 +189,9 @@ private void initTestObjects() {
Log.d("AisTrackerLayer", "# test2: dist1: " + meterToMiles(y1.distanceTo(y3)));
}

// use case: x2: course 270°, speed 5kn, x3: course 45°, speed 5kn, time 5h
// test case: x2: course 270°, speed 5kn, x3: course 45°, speed 5kn, time 5h
// taken from marine chart:
// position after 5h: x2: 49°55'N, 0°14.1'W, x3: 49°57.8'N, 0°17.5'W, distance: 3.5nm
x2.setSpeed(knotsToMeterPerSecond(5.0f));
x2.setBearing(270.0f);
x3.setSpeed(knotsToMeterPerSecond(5.0f));
@@ -219,6 +213,58 @@ private void initTestObjects() {
Log.d("AisTrackerLayer", "# test3: dist1: " + meterToMiles(y2.distanceTo(y3)));
}

// test case: x4: course 45°, speed 10kn, x5: course 70°, speed 5kn, time 6h
// taken from marine chart:
// position after 6h: x4: 50°12.1'N, 2°54.4'W, x5: 50°10.1'N, 3°1.5'W, distance: 5nm
x4.setSpeed(knotsToMeterPerSecond(10.0f));
x4.setBearing(45.0f);
x5.setSpeed(knotsToMeterPerSecond(5.0f));
x5.setBearing(70.0f);
cpa1.reset();
getCpa(x4, x5, cpa1);
Log.d("AisTrackerLayer", "# test4: tcpa(x4, x5): " + cpa1.getTcpa());
Log.d("AisTrackerLayer", "# test4: dist at tcpa: " + cpa1.getCpaDist());
Log.d("AisTrackerLayer", "# test4: dist0: " + meterToMiles(x4.distanceTo(x5)));
y4 = AisTrackerHelper.getNewPosition(x4, 6.0);
y5 = AisTrackerHelper.getNewPosition(x5, 6.0);
if ((y4 != null) && (y5 != null)) {
Log.d("AisTrackerLayer", "# test4: position 4 after 6 hours: "
+ LocationConvert.convertLatitude(y4.getLatitude(), FORMAT_MINUTES, true)
+ ", " + LocationConvert.convertLongitude(y4.getLongitude(), FORMAT_MINUTES, true));
Log.d("AisTrackerLayer", "# test4: position 5 after 6 hours: "
+ LocationConvert.convertLatitude(y5.getLatitude(), FORMAT_MINUTES, true)
+ ", " + LocationConvert.convertLongitude(y5.getLongitude(), FORMAT_MINUTES, true));
Log.d("AisTrackerLayer", "# test4: dist1: " + meterToMiles(y4.distanceTo(y5)));
}
}
private void initTestObjects() {
// passenger ship
AisObject ais = new AisObject(34568, 1, 20, 0, 1, 320,
320.0, 8.4, 50.738d, 7.099d, 0.0);
updateAisObjectList(ais);
ais = new AisObject(34568, 5, 0, "TEST-CALLSIGN1", "TEST-Ship", 60 /* passenger */, 56,
65, 8, 12, 2,
"Potsdam", 8, 15, 22, 5);
updateAisObjectList(ais);
// sailing boat
ais = new AisObject(454011, 1, 20, 8, 0, 120,
125.0, 4.4, 50.737d, 7.098d, 0.0);
updateAisObjectList(ais);
ais = new AisObject(454011, 5, 0, "TEST-CALLSIGN2", "TEST-Sailor", 36 /* sailing */, 0,
0, 0, 0, 0,
"@@@", 0, 0, 0, 0);
updateAisObjectList(ais);
// land station
ais = new AisObject(878121, 4, 50.736d, 7.100d);
updateAisObjectList(ais);
// AIDS
ais = new AisObject( 521077, 21, 50.735d, 7.101d, 2,
0, 0, 0, 0);
updateAisObjectList(ais);
// aircraft
ais = new AisObject(910323, 9, 15, 65, 180.5, 55.0, 50.734d, 7.102d);
updateAisObjectList(ais);

//removeOldestAisObjectListEntry();
//removeLostAisObjects();
}