Merge Tethys updates from DG (#146)

* Localization output

* update localiser output

* Start effort management system

* Start of Effort plotting

Strat of effort plotting on map. Framework for using Effort data in other areas (such as Tethys output).

* Logger forms update

Effort and Symbol selectors working with Logger forms. Also functions to add, edit and delete form rows in Viewer mode.

* Update LoggerFormGraphics.java

add in correct symbol managemet to forms graphics.

* Effort lines on map

Sort of working OK in real time mode.

* Working effort system

Currently only for map, but seems to work OK

* Update Tethys to latest nilus schema

* Raven importer

Start of a system for a raven importer. Not quite working yet.

* Raven import

Basic functionality working. Not nice to use though.

* Tethys Localization work

Abstracting out writing of localization objects and document header information so that individual localisers can give fine scale control of this stuff.

* updated Nilus

A few updates around track and target motion measures.
This commit is contained in:
Douglas Gillespie 2024-08-16 10:40:00 +01:00 committed by GitHub
parent bea4a544d0
commit 46bd88c197
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
110 changed files with 4593 additions and 1020 deletions

View File

@ -6,9 +6,8 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-19">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>

4
.gitignore vendored
View File

@ -25,7 +25,9 @@
# eclipse project file
.project
.hprof
# hprof memory analyser files.
*.hprof
java_pid*.*
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

View File

@ -11,9 +11,9 @@ org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=16
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=16
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@ -22,5 +22,5 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=16
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=17

View File

@ -0,0 +1,4 @@
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Tue Jul 16 19:29:56 BST 2024
nilus-3.1.jar>=
nilus-3.1.pom>=

Binary file not shown.

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>tethys.org</groupId>
<artifactId>nilus</artifactId>
<version>3.1</version>
<description>POM was created from install:install-file</description>
</project>

View File

@ -1,4 +1,4 @@
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Tue Jul 16 19:29:56 BST 2024
#Fri Aug 16 08:59:15 BST 2024
nilus-3.1.jar>=
nilus-3.1.pom>=

View File

@ -0,0 +1,8 @@
#Fri Aug 02 15:37:21 BST 2024
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo|sources=1722609441199
github|douggillespie|https\://maven.pkg.github.com/douggillespie/xbee-java|sources=1722609441199
central|https\://repo1.maven.org/maven2|sources=1722609441199
talan|https\://nexus.talanlabs.com/content/repositories/releases/|sources=1722609441199
bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|sources=1722609441199
unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|sources=1722609441199
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo|sources=1721155730840

View File

@ -0,0 +1,16 @@
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Fri Aug 02 15:37:21 BST 2024
@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1721155730838
https\://repo1.maven.org/maven2/.error=
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.error=
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.lastUpdated=1722609441195
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error=
https\://nexus.bedatadriven.com/content/groups/public/.error=
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1721155730561
https\://repo1.maven.org/maven2/.lastUpdated=1721155729103
https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact tethys.org\:nilus\:jar\:sources\:3.1 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: nexus.talanlabs.com
https\://maven.pkg.github.com/douggillespie/xbee-java/.error=
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.lastUpdated=1721155729822
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.error=
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1721155730818
https\://maven.pkg.github.com/douggillespie/xbee-java/.lastUpdated=1721155729785

View File

@ -77,7 +77,7 @@ public class AcquisitionProcess extends PamProcess {
protected PamRawDataBlock rawDataBlock;
private PamDataBlock<DaqStatusDataUnit> daqStatusDataBlock;
private DaqStatusDataBlock daqStatusDataBlock;
AcquisitionProcess acquisitionProcess;
@ -125,12 +125,11 @@ public class AcquisitionProcess extends PamProcess {
// PamUtils.makeChannelMap(acquisitionControl.acquisitionParameters.nChannels),
// acquisitionControl.acquisitionParameters.sampleRate));
addOutputDataBlock(rawDataBlock = new PamRawDataBlock(name, this, //Xiao Yan Deng
addOutputDataBlock(rawDataBlock = new PamRawDataBlock(name, this,
PamUtils.makeChannelMap(acquisitionControl.acquisitionParameters.nChannels,acquisitionControl.acquisitionParameters.getHardwareChannelList()),
acquisitionControl.acquisitionParameters.sampleRate));
daqStatusDataBlock = new PamDataBlock<DaqStatusDataUnit>(DaqStatusDataUnit.class, acquisitionControl.getUnitName(),
daqStatusDataBlock = new DaqStatusDataBlock(acquisitionControl.getUnitName(),
this, 0);
// daqStatusDataBlock.
addOutputDataBlock(daqStatusDataBlock);
@ -1241,6 +1240,9 @@ public class AcquisitionProcess extends PamProcess {
}
public InputStoreInfo getStoreInfo(boolean detail) {
if (runningSystem == null) {
runningSystem = acquisitionControl.findDaqSystem(null);
}
if (runningSystem instanceof DataInputStore) {
return ((DataInputStore) runningSystem).getStoreInfo(detail);
}

View File

@ -0,0 +1,23 @@
package Acquisition;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess;
import dataMap.OfflineDataMap;
import effort.EffortProvider;
import effort.binary.DataMapEffortProvider;
import generalDatabase.DBControlUnit;
public class DaqStatusDataBlock extends PamDataBlock<DaqStatusDataUnit> {
public DaqStatusDataBlock(String dataName, PamProcess parentProcess, int channelMap) {
super(DaqStatusDataUnit.class, dataName, parentProcess, channelMap);
}
@Override
public EffortProvider autoEffortProvider() {
// make a provider which will pick up on the database data.
// db data are written every 60s, so put 62s as max gap.
return new DataMapEffortProvider(this, DBControlUnit.class, 62000L);
}
}

View File

@ -945,8 +945,12 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D
InputStoreInfo storeInfo = new InputStoreInfo(acquisitionControl, allFiles.size(), firstFileStart, lastFileStart, lastFileEnd);
if (detail) {
long[] allFileStarts = new long[allFiles.size()];
long[] allFileEnds = new long[allFiles.size()];
for (int i = 0; i < allFiles.size(); i++) {
allFileStarts[i] = getFileStartTime(allFiles.get(i).getAbsoluteFile());
WavFileType aFile = allFiles.get(i);
allFileStarts[i] = getFileStartTime(aFile.getAbsoluteFile());
aFile.getAudioInfo();
allFileEnds[i] = (allFileStarts[i] + (long) (aFile.getDurationInSeconds()*1000.));
if (allFileStarts[i] < firstFileStart) {
// System.out.printf("Swap first file from %s to %s\n", firstFile.getName(), allFiles.get(i).getName());
firstFile = allFiles.get(i);
@ -961,6 +965,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D
storeInfo.setFirstFileStart(firstFileStart); // just incase changed.
storeInfo.setLastFileEnd(lastFileEnd); // just incase changed
storeInfo.setFileStartTimes(allFileStarts);
storeInfo.setFileEndTimes(allFileEnds);
}
return storeInfo;
}

View File

@ -2,6 +2,7 @@ package GPS;
import java.util.ListIterator;
import GPS.effort.GpsEffortProvider;
import nmeaEmulator.EmulatedData;
import nmeaEmulator.NMEAEmulator;
import pamScrollSystem.ViewLoadObserver;
@ -37,6 +38,7 @@ public class GPSDataBlock extends PamDataBlock<GpsDataUnit> implements NMEAEmula
public GPSDataBlock(PamProcess process) {
super(GpsDataUnit.class, process.getPamControlledUnit().getUnitName(), process, 1);
setSynchLock(NavDataSynchronisation.getSynchobject());
setEffortProvider(new GpsEffortProvider(this));
}
@Override

View File

@ -0,0 +1,96 @@
package GPS.effort;
import java.util.ArrayList;
import java.util.List;
import GPS.GPSDataBlock;
import PamView.symbol.PamSymbolManager;
import PamguardMVC.PamDataUnit;
import PamguardMVC.dataSelector.DataSelector;
import dataMap.OfflineDataMap;
import effort.EffortDataUnit;
import effort.EffortProvider;
public class GpsEffortProvider extends EffortProvider {
private GPSDataBlock gpsDataBlock;
private GpsEffortSymbolManager effortSymbolManager;
private EffortDataUnit realTimeData;
public GpsEffortProvider(GPSDataBlock parentDataBlock) {
super(parentDataBlock);
this.gpsDataBlock = parentDataBlock;
effortSymbolManager = new GpsEffortSymbolManager(gpsDataBlock);
}
@Override
public EffortDataUnit getEffort(long timeMilliseconds) {
return getSingleEffort();
}
@Override
public List<EffortDataUnit> getAllEffortThings() {
EffortDataUnit singleEff = getSingleEffort();
ArrayList<EffortDataUnit> effList = new ArrayList<>(1);
if (singleEff != null) {
effList.add(singleEff);
}
return effList;
}
@Override
public DataSelector getDataSelector(String selectorName) {
return null;
}
@Override
public PamSymbolManager getSymbolManager() {
return effortSymbolManager;
}
private EffortDataUnit getSingleEffort() {
if (!isViewer()) {
return realTimeData;
}
OfflineDataMap dataMap = gpsDataBlock.getPrimaryDataMap();
if (dataMap == null) {
return null;
}
EffortDataUnit effData = new EffortDataUnit(this, null, dataMap.getFirstDataTime(), dataMap.getLastDataTime());
return effData;
}
@Override
public String getName() {
return gpsDataBlock.getDataName();
}
@Override
public void realTimeStart(long timeMilliseconds) {
// Do nothing
}
@Override
public void realTimeStop(long timeMilliseconds) {
// Do nothing
}
@Override
public void newData(PamDataUnit pamDataUnit) {
if (realTimeData == null) {
realTimeData = new EffortDataUnit(this,null,pamDataUnit.getTimeMilliseconds(), pamDataUnit.getTimeMilliseconds());
}
else {
realTimeData.setEffortEnd(pamDataUnit.getTimeMilliseconds());
}
}
@Override
public void viewerLoadData() {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,22 @@
package GPS.effort;
import java.awt.Color;
import PamView.PamColors;
import PamView.PamSymbolType;
import PamView.PamColors.PamColor;
import PamView.symbol.StandardSymbolManager;
import PamView.symbol.SymbolData;
import PamView.symbol.SymbolOnlyManager;
import PamguardMVC.PamDataBlock;
public class GpsEffortSymbolManager extends SymbolOnlyManager {
private static Color defColour = PamColors.getInstance().getColor(PamColor.GPSTRACK);
private static SymbolData defaultSymbol = new SymbolData(PamSymbolType.SYMBOL_LINESEGMENT, 10, 10, false, defColour, defColour);
public GpsEffortSymbolManager(PamDataBlock pamDataBlock) {
super(pamDataBlock, defaultSymbol);
}
}

View File

@ -1,9 +1,6 @@
package Localiser;
import java.io.Serializable;
import PamDetection.LocContents;
import PamDetection.LocalisationInfo;
import tethys.localization.LocalizationCreator;
/**
* Interface to attach to localisation algorithms which can provide basic information
@ -19,4 +16,12 @@ public interface LocalisationAlgorithm {
*/
public LocalisationAlgorithmInfo getAlgorithmInfo();
/**
* Get something that can make LocalisationType objects of a form
* a bit bespoke to the type of localiser. This may be better than having
* the standard functions in LocalizationBuilder guess what's best.
* @return can be null in which case standard functions will do the best they can.
*/
public LocalizationCreator getTethysCreator();
}

View File

@ -5,6 +5,7 @@ import java.io.Serializable;
import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
@Deprecated
public class CombinedBearingLocaliser implements BearingLocaliser {
@ -86,4 +87,10 @@ public class CombinedBearingLocaliser implements BearingLocaliser {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -11,6 +11,7 @@ import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents;
import PamUtils.PamUtils;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
public class LSQBearingLocaliser implements BearingLocaliser {
@ -232,4 +233,10 @@ public class LSQBearingLocaliser implements BearingLocaliser {
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -13,6 +13,7 @@ import PamUtils.ArrayDump;
import PamUtils.PamUtils;
import PamUtils.SystemTiming;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
/**
* Maximum likelihood bearing localiser to get bearings from a closely
@ -652,4 +653,10 @@ public class MLGridBearingLocaliser implements BearingLocaliser {
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -15,6 +15,7 @@ import PamUtils.ArrayDump;
import PamUtils.PamUtils;
import PamUtils.SystemTiming;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
import tethys.pamdata.AutoTethysProvider;
/**
@ -761,6 +762,12 @@ public class MLGridBearingLocaliser2 implements BearingLocaliser {
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
/**
* For passing to Tethys output.

View File

@ -11,6 +11,7 @@ import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents;
import PamUtils.PamUtils;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
/**
* Really simple BearingLocaliser which works with two element closely
@ -309,4 +310,9 @@ public class PairBearingLocaliser implements BearingLocaliser {
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -19,6 +19,7 @@ import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents;
import PamUtils.PamUtils;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
@Deprecated
public class SimplexBearingLocaliser implements BearingLocaliser {
@ -250,6 +251,12 @@ public class SimplexBearingLocaliser implements BearingLocaliser {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
@Override
public Serializable getParameters() {
return null;

View File

@ -38,6 +38,7 @@ import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
@ -83,6 +84,7 @@ import PamView.paneloverlay.overlaymark.MarkOverlayDraw;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.PamSymbolManager;
import PamView.symbol.SymbolData;
import PamView.symbol.modifier.SymbolModifier;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamObservable;
@ -90,6 +92,8 @@ import PamguardMVC.PamObserver;
import PamguardMVC.dataSelector.DataSelectDialog;
import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.debug.Debug;
import effort.EffortDataUnit;
import effort.EffortProvider;
import pamMaths.PamVector;
/**
@ -131,6 +135,8 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
private AffineTransform baseXform;
private boolean repaintBase = false;
private EffortDataUnit latestEffort;
public MapPanel(MapController mapController, SimpleMap simpleMap) {
this.mapController = mapController;
@ -786,6 +792,7 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
private GpsDataUnit lastDrawGpsDataUnit;
private Coordinate3d lastGpsCoodinate;
private PamSymbol latestSymbol;
long getMapStartTime() {
switch (PamController.getInstance().getRunMode()) {
@ -797,22 +804,70 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
}
return PamCalendar.getTimeInMillis();
}
public EffortProvider findEffortProvider() {
if (simpleMapRef.mapParameters.colourByEffort == false) {
return null;
}
if (simpleMapRef.effortDataBlock == null) {
return null;
}
return simpleMapRef.effortDataBlock.getEffortProvider();
}
private void paintTrack(Graphics g, PamDataUnit lastDrawnUnit) {
long mapStartTime = getMapStartTime();
g.setColor(PamColors.getInstance().getColor(PamColor.GPSTRACK));
GPSDataBlock gpsDataBlock = simpleMapRef.getGpsDataBlock();
if (gpsDataBlock == null) {
return;
}
PamSymbolChooser symbolModifier = null;
List<EffortDataUnit> effortThings = null;
EffortDataUnit currentEffortThing = null;
EffortProvider effortProvider = findEffortProvider();
PamSymbol effortSymbol = null;
Iterator<EffortDataUnit> effortIterator = null;
if (effortProvider != null) {
symbolModifier = effortProvider.getSymbolChooser(simpleMapRef.getSelectorName(), rectProj);
effortThings = effortProvider.getAllEffortThings();
if (effortThings == null || effortThings.size() == 0) {
effortThings = null;
}
else {
effortIterator = effortThings.iterator();
}
if (effortIterator != null && effortIterator.hasNext()) {
currentEffortThing = effortIterator.next();
if (symbolModifier != null) {
// effortSymbol = symbolModifier.getPamSymbol(rectProj, currentEffortThing);
effortSymbol = effortProvider.getPamSymbol(symbolModifier, currentEffortThing);
latestEffort = currentEffortThing;
latestSymbol = effortSymbol;
}
}
}
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(1));
long mapStartTime = getMapStartTime();
Color defaultColour = PamColors.getInstance().getColor(PamColor.GPSTRACK);
if (effortSymbol != null) {
g2d.setStroke(new BasicStroke(effortSymbol.getLineThickness()));
}
else {
g2d.setStroke(new BasicStroke(1));
}
if (effortSymbol != null && mapStartTime > currentEffortThing.getEffortStart()) {
g.setColor(effortSymbol.getLineColor());
}
else {
g.setColor(defaultColour);
}
// GPSControl gpsControl = GPSControl.getGpsControl();
// if (gpsControl == null) {
// return;
// }
// PamDataBlock<GpsDataUnit> gpsDataBlock = gpsControl.getGpsDataBlock();
GPSDataBlock gpsDataBlock = simpleMapRef.getGpsDataBlock();
if (gpsDataBlock == null) {
return;
}
long t1 = getMapStartTime(), t2 = Long.MAX_VALUE;
if (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW) {
t1 = simpleMapRef.getViewerScroller().getMinimumMillis();
@ -826,13 +881,48 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
GpsDataUnit dataUnit;
synchronized (gpsDataBlock.getSynchLock()) {
ListIterator<GpsDataUnit> gpsIterator = gpsDataBlock.getListIterator(0);
dataUnit = gpsIterator.next();
if (gpsIterator.hasNext()) {
dataUnit = gpsIterator.next();
gpsData = dataUnit.getGpsData();
lastFixTime = dataUnit.getTimeMilliseconds();
c1 = rectProj.getCoord3d(gpsData.getLatitude(), gpsData.getLongitude(), 0.);
while (gpsIterator.hasNext()) {
dataUnit = gpsIterator.next();
// sort out effort colours.
// if (currentEffortThing != null) {
while (currentEffortThing != null && dataUnit.getTimeMilliseconds() > currentEffortThing.getEffortEnd()) {
// get the next one. then decide if we're in or not.
if (effortIterator.hasNext()) {
currentEffortThing = effortIterator.next();
if (symbolModifier != null) {
effortSymbol = effortProvider.getPamSymbol(symbolModifier, currentEffortThing);
}
}
else {
break;
}
// else {
// currentEffortThing = null;
// effortSymbol = null;
// }
}
// }
if (effortSymbol != null && currentEffortThing.inEffort(dataUnit.getTimeMilliseconds())) {
g.setColor(effortSymbol.getLineColor());
latestEffort = currentEffortThing;
latestSymbol = effortSymbol;
}
else {
g.setColor(defaultColour);
// latestSymbol = null;
}
gpsData = dataUnit.getGpsData();
if (gpsData.isDataOk() == false) {
continue;
@ -909,7 +999,41 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
private void paintNewGPSData(Graphics g, GpsDataUnit newGpsDataUnit) {
Coordinate3d c2;
g.setColor(PamColors.getInstance().getColor(PamColor.GPSTRACK));
// g.setColor(PamColors.getInstance().getColor(PamColor.GPSTRACK));
// if (latestSymbol != null) {
// float t = latestSymbol.getLineThickness();
// if (t != 1) {
// Graphics2D g2d = (Graphics2D) g;
// g2d.setStroke(new BasicStroke(t));
// }
// if (latestEffort != null && latestEffort.inEffort(newGpsDataUnit.getTimeMilliseconds())) {
// g.setColor(latestSymbol.getLineColor());
// }
// }
// else {
EffortProvider effortProvider = findEffortProvider();
boolean effSet = false;
if (effortProvider != null) {
latestEffort = effortProvider.getLastEffort();
if (latestEffort != null) {
PamSymbolChooser symbolModifier = effortProvider.getSymbolChooser(simpleMapRef.getSelectorName(), rectProj);
if (symbolModifier != null) {
PamSymbol symbol = effortProvider.getPamSymbol(symbolModifier, latestEffort);
// PamSymbol symbol = symbolModifier.getPamSymbol(rectProj, latestEffort);
if (symbol != null && latestEffort.inEffort(newGpsDataUnit.getTimeMilliseconds())) {
symbol.getSymbolData().setGraphicsProperties(g);
effSet = true;
}
}
}
}
if (!effSet) {
g.setColor(PamColors.getInstance().getColor(PamColor.GPSTRACK));
}
/**
* This can get quite long, so need to do the same iterating through the effort data as for normal plotting.
*/
GpsData gpsData = newGpsDataUnit.getGpsData();
c2 = rectProj.getCoord3d(gpsData.getLatitude(), gpsData.getLongitude(), 0.);
if (lastGpsCoodinate != null) {
@ -1055,7 +1179,7 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
mapDrawingOptions = null;
rectProj.setProjectorDrawingOptions(null);
}
DataSelector ds = dataBlock.getDataSelector(simpleMapRef.getUnitName(), false, DATASELECTNAME);
DataSelector ds = dataBlock.getDataSelector(simpleMapRef.getSelectorName(), false, DATASELECTNAME);
rectProj.setDataSelector(ds);
// see if the datablock has a symbol manager.
PamSymbolManager symbolManager = dataBlock.getPamSymbolManager();
@ -1252,13 +1376,21 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
@Override
public void addData(PamObservable o, PamDataUnit arg) {
// if (arg instanceof EffortDataUnit) {
// won't work since only the data send notifications.
// System.out.println("Effort add, so repaint base");
// repaintBaseDrawing();
// }
// PamDataBlock block = (PamDataBlock) o;
repaint(250);
}
@Override
public void updateData(PamObservable observable, PamDataUnit pamDataUnit) {
// if (pamDataUnit instanceof EffortDataUnit) {
// System.out.println("Effort update, so repaint base");
// repaintBaseDrawing();
// }
repaint(250);
}
@ -1340,6 +1472,10 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
aBlock.addObserver(this);
}
}
EffortProvider effBlock = findEffortProvider();
if (effBlock != null) {
effBlock.getParentDataBlock().addObserver(this);
}
}
protected void createKey() {
@ -1852,6 +1988,27 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
this.mapController = mapController;
}
@Override
public String getToolTipText(MouseEvent event) {
String tip = super.getToolTipText(event);
if (tip == null) {
return tip;
}
if (tip.startsWith("<html>GPS") == false) {
return tip;
}
return tip;
}
public EffortDataUnit findEffortThing(long timeMilliseconds) {
EffortProvider effortProvider = findEffortProvider();
if (effortProvider == null) {
return null;
}
return effortProvider.getEffort(timeMilliseconds);
}
}

View File

@ -95,6 +95,12 @@ public class MapParameters implements Serializable, Cloneable, ManagedParameters
public int symbolSize = Hydrophone.DefaultSymbolSize;
public boolean colourByEffort = false;
/**
* Name of data block providing effort data.
*/
public String effortDataSource;
private static final int defaultMapRange = 10000;
/**
* Value to store persistently between runs.

View File

@ -31,7 +31,12 @@ import Array.Hydrophone;
import Map.gridbaselayer.GridDialogPanel;
import PamView.dialog.PamDialog;
import PamView.dialog.PamGridBagContraints;
import PamView.dialog.SettingsButton;
import PamView.dialog.SourcePanel;
import PamView.panel.PamNorthPanel;
import PamguardMVC.PamDataBlock;
import effort.EffortProvider;
import effort.swing.EffortSourcePanel;
@ -64,6 +69,8 @@ public class MapParametersDialog extends PamDialog {
private JCheckBox headingUp = new JCheckBox("Ship heading always up");
private JCheckBox showSurface = new JCheckBox("Show sea surface");
private JCheckBox colourByEffort = new JCheckBox("Colour track-line by efort");
private MapFileManager mapFileManager;
@ -78,6 +85,10 @@ public class MapParametersDialog extends PamDialog {
public JCheckBox showGrid;
private SimpleMap simpleMap;
private EffortSourcePanel effortSourcePanel;
private SettingsButton effortSettings;
private MapParametersDialog(java.awt.Window parentFrame, SimpleMap simpleMap) {
@ -110,15 +121,21 @@ public class MapParametersDialog extends PamDialog {
setDialogComponent(tabbedPane);
setHelpPoint("mapping.mapHelp.docs.overview");
// this.enableHelpButton(true);
colourByEffort.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
enableControls();
}
});
//hydroCheckBox.get
}
// MapParameters oldParameters, MapFileManager mapFile
public static MapParameters showDialog(java.awt.Window parentFrame, SimpleMap simpleMap) {
if (singleInstance == null || singleInstance.simpleMap != simpleMap) {
// if (singleInstance == null || singleInstance.simpleMap != simpleMap) {
singleInstance = new MapParametersDialog(parentFrame, simpleMap);
}
// }
singleInstance.mapParameters = simpleMap.mapParameters.clone();
singleInstance.mapFileManager = simpleMap.mapFileManager;
singleInstance.setParams();
@ -141,6 +158,8 @@ public class MapParametersDialog extends PamDialog {
keepShipCentred.setSelected(mapParameters.keepShipCentred);
headingUp.setSelected(mapParameters.headingUp);
showSurface.setSelected(mapParameters.hideSurface == false);
colourByEffort.setSelected(mapParameters.colourByEffort);
effortSourcePanel.setSource(mapParameters.effortDataSource);
filePanel.setMapFile(mapParameters.mapFile);
@ -177,6 +196,8 @@ public class MapParametersDialog extends PamDialog {
return showWarning("Range rings sepration must be > 0");
}
}
mapParameters.colourByEffort = colourByEffort.isSelected();
mapParameters.effortDataSource = effortSourcePanel.getSourceName();
}
catch (Exception Ex) {
return false;
@ -216,6 +237,14 @@ public class MapParametersDialog extends PamDialog {
GridBagLayout layout;
setLayout(layout = new GridBagLayout());
GridBagConstraints constraints = new PamGridBagContraints();
effortSourcePanel = new EffortSourcePanel(singleInstance);
effortSettings = new SettingsButton();
effortSettings.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showEffortSettings();
}
});
// t.setLayout(new GridLayout(4,3));
constraints.anchor = GridBagConstraints.WEST;
constraints.gridx = 0;
@ -224,37 +253,62 @@ public class MapParametersDialog extends PamDialog {
constraints.gridx ++;
addComponent(this,trackShowtime = new JTextField(7), constraints);
constraints.gridx ++;
addComponent(this,new JLabel(" s"), constraints);
addComponent(this,new JLabel(" s "), constraints);
constraints.gridx++;
addComponent(this, colourByEffort, constraints);
constraints.gridx += 2;
constraints.gridwidth = 1;
constraints.fill = constraints.NONE;
constraints.anchor = constraints.LINE_END;
addComponent(this, effortSettings, constraints);
constraints.gridx = 0;
constraints.gridy ++;
constraints.anchor = constraints.LINE_START;
addComponent(this,new JLabel("Data storage time "), constraints);
constraints.gridx ++;
addComponent(this,dataKeepTime = new JTextField(7), constraints);
constraints.gridx ++;
addComponent(this,new JLabel(" s"), constraints);
addComponent(this,new JLabel(" s "), constraints);
constraints.gridx++;
constraints.gridwidth = 3;
constraints.fill = constraints.HORIZONTAL;
addComponent(this, effortSourcePanel.getPanel(), constraints);
constraints.gridx = 0;
constraints.gridy ++;
constraints.gridwidth = 1;
addComponent(this,new JLabel("Data display time "), constraints);
constraints.gridx ++;
addComponent(this,dataShowTime = new JTextField(7), constraints);
constraints.gridx ++;
addComponent(this,new JLabel(" s"), constraints);
addComponent(this,new JLabel(" s "), constraints);
constraints.gridx = 0;
constraints.gridy ++;
constraints.gridwidth = 3;
constraints.gridwidth = 2;
addComponent(this,shipCheckBox, constraints);
constraints.gridy ++;
constraints.gridx += constraints.gridwidth;
addComponent(this,keepShipOnMap, constraints);
constraints.gridy ++;
constraints.gridx = 0;
constraints.gridy ++;
constraints.gridwidth = 3;
addComponent(this,keepShipCentred, constraints);
constraints.gridy ++;
constraints.gridx += constraints.gridwidth;
addComponent(this,headingUp, constraints);
constraints.gridy ++;
constraints.gridx = 0;
addComponent(this, showSurface, constraints);
}
protected void showEffortSettings() {
PamDataBlock effortBlock = effortSourcePanel.getSource();
if (effortBlock == null) {
return;
}
EffortProvider effortProvider = effortBlock.getEffortProvider();
if (effortProvider == null) {
return;
}
effortProvider.showOptionsDialog(singleInstance, simpleMap.getSelectorName());
}
}
class HydrophonePanel extends JPanel {
@ -491,6 +545,9 @@ public class MapParametersDialog extends PamDialog {
colourByChannel.setEnabled(hydroCheckBox.isSelected());
symbolSizeSpinner.setEnabled(hydroCheckBox.isSelected());
ringsRange.setEnabled(ringsType.getSelectedIndex() > 0);
boolean ec = colourByEffort.isSelected();
effortSettings.setSelected(ec);
effortSourcePanel.setEnabled(ec);
}

View File

@ -34,6 +34,7 @@ import PamUtils.LatLong;
import PamUtils.PamCoordinate;
import PamUtils.PamUtils;
import PamguardMVC.debug.Debug;
import effort.EffortDataUnit;
/**
* The Map Rectangle Projector.
@ -427,7 +428,15 @@ public class MapRectProjector extends MapProjector {
if (rPix > 20) {
return null;
}
return closest.getSummaryString();
EffortDataUnit effortData = mapPanelRef.findEffortThing(closest.getTimeMilliseconds());
if (effortData == null) {
return closest.getSummaryString();
}
else {
String effSummary = effortData.toString();
String str = closest.getSummaryString() + "Effort: " + effSummary;
return str;
}
}

View File

@ -101,6 +101,7 @@ import PamguardMVC.PamObservable;
import PamguardMVC.PamObserver;
import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.debug.Debug;
import effort.EffortProvider;
/**
* Mainly a container for map objects, holding the main MapPanel and the right
@ -201,6 +202,8 @@ public class SimpleMap extends JPanel implements PamObserver, PamScrollObserver,
private GridbaseControl gridBaseControl;
protected PamDataBlock effortDataBlock;
// JToolTip mouseToolTip;
public SimpleMap(MapController mapController, boolean isMainTab, MapPanel mapPanel) {
@ -263,6 +266,14 @@ public class SimpleMap extends JPanel implements PamObserver, PamScrollObserver,
public SimpleMap(MapController mapController, boolean isMainTab) {
this(mapController, isMainTab, new MapPanel(mapController, null));
}
/**
* Name for data selectors and data filters.
* @return
*/
public String getSelectorName() {
return getUnitName();
}
public String getUnitName() {
if (thisMapIndex != 0) {
@ -570,6 +581,8 @@ public class SimpleMap extends JPanel implements PamObserver, PamScrollObserver,
}
initViewerControls();
effortDataBlock = PamController.getInstance().getDataBlockByLongName(mapParameters.effortDataSource);
if (mapFileManager != null) {
mapFileManager.readFileData(mapParameters.mapFile);
@ -1146,9 +1159,23 @@ public class SimpleMap extends JPanel implements PamObserver, PamScrollObserver,
}
}
}
subscribeEffortProvider();
return changes;
}
/**
* Subscribe the effort provider to the scroller.
*/
private void subscribeEffortProvider() {
if (viewerScroller == null) {
return;
}
EffortProvider effProv = mapPanel.findEffortProvider();
if (effProv != null) {
viewerScroller.addDataBlock(effProv.getParentDataBlock());
}
}
public PamScrollSlider getViewerScroller() {
return viewerScroller;
@ -1206,6 +1233,7 @@ public class SimpleMap extends JPanel implements PamObserver, PamScrollObserver,
getViewerScroller().reLoad();
}
}
effortDataBlock = PamController.getInstance().getDataBlockByLongName(mapParameters.effortDataSource);
}
@Override

View File

@ -8,6 +8,7 @@ public class InputStoreInfo {
private int nFiles;
private long firstFileStart, lastFileStart, lastFileEnd;
private long[] fileStartTimes;
private long[] allFileEnds;
public InputStoreInfo(DataInputStore dataInputStore, int nFiles, long firstFileStart, long lastFileStart, long lastFileEnd) {
super();
@ -96,6 +97,21 @@ public class InputStoreInfo {
public void setLastFileEnd(long lastFileEnd) {
this.lastFileEnd = lastFileEnd;
}
/**
* Set all file end times.
* @param allFileEnds
*/
public void setFileEndTimes(long[] allFileEnds) {
this.allFileEnds = allFileEnds;
}
/**
* @return the allFileEnds
*/
public long[] getAllFileEnds() {
return allFileEnds;
}

View File

@ -1334,7 +1334,13 @@ public class PamController implements PamControllerInterface, PamSettings {
}
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
for (int iP = 0; iP < pamControlledUnits.get(iU).getNumPamProcesses(); iP++) {
pamControlledUnits.get(iU).getPamProcess(iP).pamStart();
PamProcess pamProcess = pamControlledUnits.get(iU).getPamProcess(iP);
pamProcess.pamStart();
int nOut = pamProcess.getNumOutputDataBlocks();
for (int iB = 0; iB < nOut; iB++) {
PamDataBlock outBlock = pamProcess.getOutputDataBlock(iB);
outBlock.pamStart(startTime);
}
}
// long t2 = System.currentTimeMillis();
// System.out.printf("==================================Time taken to call
@ -1378,11 +1384,19 @@ public class PamController implements PamControllerInterface, PamSettings {
// statusCheckThread = new Thread(new StatusTimer());
// statusCheckThread.start();
ArrayList<PamControlledUnit> pamControlledUnits = pamConfiguration.getPamControlledUnits();
long stopTime = PamCalendar.getTimeInMillis();
// tell all controlled units to stop
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
for (int iP = 0; iP < pamControlledUnits.get(iU).getNumPamProcesses(); iP++) {
pamControlledUnits.get(iU).getPamProcess(iP).pamStop();
PamProcess pamProcess = pamControlledUnits.get(iU).getPamProcess(iP);
pamProcess.pamStop();
int nOut = pamProcess.getNumOutputDataBlocks();
for (int iB = 0; iB < nOut; iB++) {
PamDataBlock outBlock = pamProcess.getOutputDataBlock(iB);
outBlock.pamStop(stopTime);
}
}
}

View File

@ -47,6 +47,7 @@ import fftManager.PamFFTControl;
import group3dlocaliser.Group3DLocaliserControl;
import meygenturbine.MeygenTurbine;
import printscreen.PrintScreenControl;
import ravendata.RavenControl;
import rockBlock.RockBlockControl;
import tethys.TethysControl;
import turbineops.TurbineOperationControl;
@ -473,6 +474,12 @@ final public class PamModel implements PamSettings {
mi.setMaxNumber(1);
//mi.addGUICompatabilityFlag(PamGUIManager.FX); //has FX enabled GUI.
mi.setHidden(SMRUEnable.isEnable() == false);
mi = PamModuleInfo.registerControlledUnit(RavenControl.class.getName(), RavenControl.defaultName);
mi.setToolTipText("Import data from Raven selection tables");
mi.setModulesMenuGroup(utilitiesGroup);
mi.setHidden(SMRUEnable.isEnable() == false);
}
/*

View File

@ -703,7 +703,7 @@ public class PamDetectionOverlayGraphics extends PanelOverlayDraw {
Coordinate3d topLeft = generalProjector.getCoord3d(pamDetection.getTimeMilliseconds(),
frequency[1], 0);
Coordinate3d botRight = generalProjector.getCoord3d(pamDetection.getTimeMilliseconds() +
pamDetection.getSampleDuration() * 1000./parentDataBlock.getSampleRate(),
pamDetection.getDurationInMilliseconds(),
frequency[0], 0);
if (botRight.x < topLeft.x){

View File

@ -372,6 +372,10 @@ public class WarnOnce implements PamSettings {
return -1;
}
if (parent == null) {
parent = PamController.getMainFrame();
}
// show the warning
if (canShowDialog()) {
WarnOnceDialog wo = new WarnOnceDialog(parent, title, message, messageType, helpPoint, error, okButtonText, cancelButtonText);

View File

@ -1,6 +1,9 @@
package PamView.symbol;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.Serializable;
import PamView.PamSymbolType;
@ -165,4 +168,17 @@ public class SymbolData implements Serializable, Cloneable {
this.symbol = symbol;
}
/**
* Set the line properties for the given graphics handle.
* @param g
*/
public void setGraphicsProperties(Graphics g) {
if (lineColor != null) {
g.setColor(lineColor);
}
if (lineThickness != 1) {
((Graphics2D) g).setStroke(new BasicStroke(lineThickness));
}
}
}

View File

@ -0,0 +1,21 @@
package PamView.symbol;
import PamguardMVC.PamDataBlock;
/**
* Version of the standard symbol manager that only has the optoin on the main
* symbol type and no modifiers whatsoever.
* @author dg50
*
*/
public class SymbolOnlyManager extends StandardSymbolManager {
public SymbolOnlyManager(PamDataBlock pamDataBlock, SymbolData defaultSymbol) {
super(pamDataBlock, defaultSymbol);
// TODO Auto-generated constructor stub
}
@Override
public void addSymbolModifiers(PamSymbolChooser psc) {
}
}

View File

@ -58,10 +58,13 @@ import tethys.species.DataBlockSpeciesManager;
import dataGram.DatagramProvider;
import dataMap.BespokeDataMapGraphic;
import dataMap.OfflineDataMap;
import effort.EffortProvider;
import effort.binary.DataMapEffortProvider;
import annotation.DataAnnotationType;
import annotation.handler.AnnotationHandler;
import binaryFileStorage.BinaryDataSource;
import binaryFileStorage.BinaryOfflineDataMap;
import binaryFileStorage.BinaryStore;
import binaryFileStorage.SecondaryBinaryStore;
import PamController.OfflineDataStore;
import PamController.PamControlledUnit;
@ -1081,6 +1084,11 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
System.err.printf("Not loading %s since initialisation not yet complete\n", getDataName());
return false;
}
// long tenDays = 3600L*24L*1000L*10L;
// if (offlineDataLoadInfo.getEndMillis() - offlineDataLoadInfo.getStartMillis() > tenDays) {
// System.out.printf("Big many day data load %s to %s in %s", PamCalendar.formatDateTime(offlineDataLoadInfo.getStartMillis()),
// PamCalendar.formatDateTime(offlineDataLoadInfo.getEndMillis()) ,getLongDataName());
// }
saveViewerData();
@ -1124,6 +1132,11 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
firstViewerUID = Math.min(firstViewerUID, uid);
lastViewerUID = Math.max(lastViewerUID, uid);
}
EffortProvider effProv = getEffortProvider();
if (effProv != null) {
effProv.viewerLoadData();
}
return loadOk;
}
@ -1269,6 +1282,10 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
*/
if (shouldNotify()) {
notifyInstantObservers(pamDataUnit);
EffortProvider effProvider = getEffortProvider();
if (effProvider != null) {
effProvider.newData(pamDataUnit);
}
}
if (offlineDataLoading.isCurrentOfflineLoadKeep()) {
@ -3054,7 +3071,16 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
case PamControllerInterface.HYDROPHONE_ARRAY_CHANGED:
clearDataOrigins();
break;
case PamController.INITIALIZATION_COMPLETE:
effortProvider = autoEffortProvider();
break;
case PamController.ADD_CONTROLLEDUNIT:
if (PamController.getInstance().isInitializationComplete()) {
effortProvider = autoEffortProvider();
}
break;
}
}
/**
@ -3658,6 +3684,8 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
private DataSelectorCreator dataSelectorCreator;
private EffortProvider effortProvider;
public void setRecordingTrigger(RecorderTrigger recorderTrigger) {
this.recorderTrigger = recorderTrigger;
RecorderControl.registerRecorderTrigger(recorderTrigger);
@ -4345,4 +4373,60 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
}
}
}
/**
* @return the effort provider.
*/
public EffortProvider getEffortProvider() {
return effortProvider;
}
/**
* Auto generate an effort provider. This may get called many times
* for blocks without effort, but that doesn't really matter since its
* only going to happen when opening dialogs, etc.
* @return
*/
public EffortProvider autoEffortProvider() {
if (effortProvider != null) {
// don't change if there already is one.
return effortProvider;
}
// see if we can do an auto binary one.
BinaryStore binaryStore = BinaryStore.findBinaryStoreControl();
if (binaryStore != null && getBinaryDataSource() != null) {
return new DataMapEffortProvider(this, BinaryStore.class);
}
// other options may follow ...
return null;
}
/**
* @param effortProvider the effortProvider to set
*/
protected void setEffortProvider(EffortProvider effortProvider) {
this.effortProvider = effortProvider;
}
/**
* Need this notification at startup time to perform a few standard actions.
* @param startTime
*/
public void pamStart(long startTime) {
EffortProvider effP = getEffortProvider();
if (effP != null) {
effP.realTimeStart(startTime);
}
}
/**
* Need this notification at stop time to perform a few standard actions.
* @param startTime
*/
public void pamStop(long stopTime) {
EffortProvider effP = getEffortProvider();
if (effP != null) {
effP.realTimeStop(stopTime);
}
}
}

View File

@ -977,7 +977,15 @@ abstract public class PamDataUnit<T extends PamDataUnit, U extends PamDataUnit>
// add frequency and amplitude information
double[] frequency = this.getFrequency();
if (frequency != null) {
str += "Frequency: " + FrequencyFormat.formatFrequencyRange(this.getFrequency(), true) + "<br>";
boolean allzeros = true;
for (int i = 0; i < frequency.length; i++) {
if (frequency[i] > 0) {
allzeros = false;
}
}
if (!allzeros) {
str += "Frequency: " + FrequencyFormat.formatFrequencyRange(this.getFrequency(), true) + "<br>";
}
}
if (getAmplitudeDB() != 0) {
str += String.format("Amplitude: %3.1fdB<br>", getAmplitudeDB());

View File

@ -34,6 +34,8 @@ import Acquisition.RawDataBinaryDataSource;
import PamController.PamController;
import PamDetection.RawDataUnit;
import PamUtils.PamUtils;
import dataMap.OfflineDataMap;
import effort.EffortProvider;
/**
* Extension of RecyclingDataBlock that is used for Raw audio data.
@ -602,6 +604,13 @@ public class PamRawDataBlock extends AcousticDataBlock<RawDataUnit> {
}
}
@Override
public EffortProvider autoEffortProvider() {
return null;
}
// @Override
// protected void findParentSource() {
// super.findParentSource();

View File

@ -32,6 +32,7 @@ import bearinglocaliser.toad.TOADBearingProvider;
import offlineProcessing.OLProcessDialog;
import offlineProcessing.OfflineTaskGroup;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX2AWT;
import tethys.localization.LocalizationCreator;
import userDisplay.UserDisplayControl;
public class BearingLocaliserControl extends PamControlledUnit implements PamSettings, LocalisationAlgorithm, LocalisationAlgorithmInfo {
@ -238,6 +239,12 @@ public class BearingLocaliserControl extends PamControlledUnit implements PamSet
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
private BearingAlgorithm findAlgorithm() {
BearingAlgorithmGroup[] groups = bearingProcess.getBearingAlgorithmGroups();

View File

@ -39,8 +39,7 @@ import org.w3c.dom.Element;
import rocca.RoccaControl;
import soundPlayback.PlaybackControl;
import targetMotionOld.TargetMotionLocaliser;
import tethys.localization.LocalizationCreator;
import binaryFileStorage.BinaryStore;
import Filters.FilterDialog;
import Filters.FilterParams;
@ -1300,5 +1299,11 @@ public class ClickControl extends PamControlledUnit implements PamSettings, Loca
return clickDetector.getLocaliserInfo();
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -2,6 +2,7 @@ package clickDetector;
import java.util.ListIterator;
import Localiser.LocalisationAlgorithm;
import pamScrollSystem.ViewLoadObserver;
import tethys.TethysControl;
import tethys.pamdata.TethysDataProvider;
@ -336,5 +337,15 @@ public class ClickDataBlock extends AcousticDataBlock<ClickDetection> implement
return new DataAutomationInfo(DataAutomation.AUTOMATIC);
}
@Override
public LocalisationAlgorithm getLocalisationAlgorithm() {
/*
* This is usually the bearing algorithm from click control.
* Howeveer, someone may have added an additional bearing localiser
* in which case, the default function should find that.
*/
return super.getLocalisationAlgorithm();
}
}

View File

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Vector;
import Localiser.LocalisationAlgorithm;
import Localiser.detectionGroupLocaliser.GroupDetection;
import PamController.PamController;
import PamController.PamControllerInterface;
@ -16,9 +17,11 @@ import PamController.PamViewParameters;
import PamUtils.PamCalendar;
import PamView.symbol.StandardSymbolManager;
import pamScrollSystem.ViewLoadObserver;
import targetMotionOld.TargetMotionLocaliser;
import tethys.TethysControl;
import tethys.pamdata.TethysDataProvider;
import tethys.species.DataBlockSpeciesManager;
import clickDetector.ClickControl;
import clickDetector.ClickDetection;
//import staticLocaliser.StaticLocaliserControl;
//import staticLocaliser.StaticLocaliserProvider;
@ -317,6 +320,20 @@ public class OfflineEventDataBlock extends SuperDetDataBlock<OfflineEventDataUni
return new DataAutomationInfo(DataAutomation.MANUALANDAUTOMATIC);
}
@Override
public LocalisationAlgorithm getLocalisationAlgorithm() {
/**
* Need to override the default, which would have been finding the
* main click control. Here, we need to explicitly find the
* Target Motion Localiser
*/
ClickControl clickControl = clickDetector.getClickControl();
ClicksOffline clicksOffline = clickControl.getClicksOffline();
TargetMotionLocaliser<GroupDetection> tml = clickControl.getTargetMotionLocaliser();
return tml;
// return super.getLocalisationAlgorithm();
}
}

View File

@ -0,0 +1,104 @@
package effort;
import PamUtils.PamCalendar;
import PamguardMVC.PamDataUnit;
public class EffortDataUnit extends PamDataUnit {
/**
* Value for effort end to say that effort is ongoing.
*/
public static final long ONGOINGEFFORT = Long.MAX_VALUE/2;
private PamDataUnit referenceDataUnit;
private EffortProvider effortProvider;
public EffortDataUnit(EffortProvider effortProvider, PamDataUnit referenceDataUnit, long effortStart, long effortEnd) {
super(effortStart);
getBasicData().setEndTime(effortEnd);
this.effortProvider = effortProvider;
this.setReferenceDataUnit(referenceDataUnit);
}
/**
*
* @return Start of effort period.
*/
public long getEffortStart() {
return getTimeMilliseconds();
}
/**
*
* @return End of effort period.
*/
public long getEffortEnd() {
return getEndTimeInMilliseconds();
}
/**
* Set the effort end time
* @param endTime
*/
public void setEffortEnd(long endTime) {
getBasicData().setEndTime(endTime);
}
/**
*
* @param timeMilliseconds
* @return time is in effort period
*/
public boolean inEffort(long timeMilliseconds) {
return (timeMilliseconds >= getEffortStart() && timeMilliseconds <= getEffortEnd());
}
/**
* Description of the effort, for tool tips, etc.
* @return
*/
public String getEffortDescription() {
return this.getSummaryString();
}
/**
* @return the referenceDataUnit
*/
public PamDataUnit getReferenceDataUnit() {
return referenceDataUnit;
}
/**
* @param referenceDataUnit the referenceDataUnit to set
*/
public void setReferenceDataUnit(PamDataUnit referenceDataUnit) {
this.referenceDataUnit = referenceDataUnit;
}
@Override
public String toString() {
String str;
if (getEffortEnd() >= ONGOINGEFFORT/2) {
str = String.format("%s ongoing from %s",effortProvider.getName(), PamCalendar.formatDBDateTime(getEffortStart()));
}
else {
str = String.format("%s %s to %s",effortProvider.getName(), PamCalendar.formatDBDateTime(getEffortStart()), PamCalendar.formatDBDateTime(getEffortEnd()));
}
if (referenceDataUnit != null) {
str += "<br>" + referenceDataUnit.getSummaryString();
}
return str;
}
@Override
public int compareTo(PamDataUnit o) {
if (o instanceof EffortDataUnit) {
EffortDataUnit oth = (EffortDataUnit) o;
return (int) (oth.getEffortStart()-getEffortStart());
}
return 0;
}
}

View File

@ -0,0 +1,50 @@
package effort;
import java.util.ArrayList;
import PamController.PamController;
import PamguardMVC.PamDataBlock;
/**
* Singleton class to provide management for all types of Effort in PAMGuard.
* @author dg50
*
*/
public class EffortManager {
private static EffortManager singleInstance;
private EffortManager() {
}
/**
* Get singleton instance of EffortManager
* @return
*/
public static EffortManager getEffortManager() {
if (singleInstance == null) {
singleInstance = new EffortManager();
}
return singleInstance;
}
/**
* Get a list of all data blocks that might provide effort data.
* @return
*/
public ArrayList<PamDataBlock> getEffortDataBlocks() {
ArrayList<PamDataBlock> allBlocks = getPamController().getDataBlocks();
ArrayList<PamDataBlock> effortBlocks = new ArrayList();
for (PamDataBlock aBlock : allBlocks) {
if (aBlock.getEffortProvider() != null) {
effortBlocks.add(aBlock);
}
}
return effortBlocks;
}
private PamController getPamController() {
return PamController.getInstance();
}
}

View File

@ -0,0 +1,192 @@
package effort;
import java.awt.Frame;
import java.awt.Window;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import Map.MapParametersDialog;
import PamController.PamController;
import PamView.GeneralProjector;
import PamView.PamSymbol;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.PamSymbolManager;
import PamView.symbol.SwingSymbolOptionsPanel;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.dataSelector.DataSelectDialog;
import PamguardMVC.dataSelector.DataSelector;
/**
* Set of functions that can be returned from any datablock which can
* give information about effort. For detectors with binary storage, they
* will return a standard binary store effort provider. Others, e.g.
* logger forms, acquisition, etc. can so something much more bespoke. <p>
* For real time, will need quite different behaviour to offline. Datablocks
* with a effortProvider are going to notify this and a local list will be
* kept of starts and ends for the entire operation period. This will be
* overridden for differeing offline scenarios and bespoke cases such as
* logger forms (so need to get a notification in here for every data unit too !)
* @author dg50
*
*/
public abstract class EffortProvider {
private PamDataBlock parentDataBlock;
private boolean isViewer;
public EffortProvider(PamDataBlock parentDataBlock) {
super();
this.parentDataBlock = parentDataBlock;
this.isViewer = PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW;
}
/**
* Notified at real time start.
* @param timeMilliseconds
*/
public abstract void realTimeStart(long timeMilliseconds);
/**
* notified at real time end
* @param timeMilliseconds
*/
public abstract void realTimeStop(long timeMilliseconds); ;
/**
* Notified for real time data.
* @param pamDataUnit
*/
public abstract void newData(PamDataUnit pamDataUnit); ;
/**
* Get the effort for a specific time.
* @param timeMilliseconds
* @return Effort thing. Can be null if off effort.
*/
public EffortDataUnit getEffort(long timeMilliseconds) {
List<EffortDataUnit> allEfforts = getAllEffortThings();
if (allEfforts == null) {
return null;
}
Iterator<EffortDataUnit> it = allEfforts.iterator();
while (it.hasNext()) {
EffortDataUnit next = it.next();
if (timeMilliseconds >= next.getEffortStart() && timeMilliseconds <= next.getEffortEnd()) {
return next;
}
}
return null;
}
/**
* Called when viewer data have been loaded for the parent datablock.
*/
public abstract void viewerLoadData();
/**
* Get all effort things. e.g. for binary data this is more or less a copy of
* the datamap (perhaps new units without the gaps).
* @return
*/
public abstract List<EffortDataUnit> getAllEffortThings();
/**
* @return the parentDataBlock
*/
public PamDataBlock getParentDataBlock() {
return parentDataBlock;
}
/**
* Get a data selector. For specialist effort modules, this will probably call
* through to the datablocks data selection system. Others, such as binaryEffortProvider
* can return null since they are either on or off.
* @param selectorName
* @return
*/
public abstract DataSelector getDataSelector(String selectorName);
/**
* Get the name of this effort provider.
*/
public abstract String getName();
/**
* Get a symbol manager. For specialist effort modules, this will probably call
* through to the datablocks existing symbol management system. Others, such as binaryEffortProvider
* will need a chooser for the simple on/off data types. .
* @return
*/
public abstract PamSymbolManager getSymbolManager();
public PamSymbolChooser getSymbolChooser(String chooserName, GeneralProjector projector) {
PamSymbolManager symbolManager = getSymbolManager();
if (symbolManager == null) {
return null;
}
return symbolManager.getSymbolChooser(chooserName, projector);
}
public PamSymbol getPamSymbol(String symbolChooserName, PamDataUnit dataUnit, GeneralProjector projector) {
PamSymbolChooser chooser = getSymbolChooser(symbolChooserName, projector);
return getPamSymbol(chooser, dataUnit);
}
/**
* Need to use this to get symbols for effort instead of direct calls into
* the symbol chooser, since the symbol chooser will almost definitely want
* it's own type of data unit, NOT the EffortDataUnit which will probably crash
* due to a cast exception.
* @param chooser
* @param dataUnit
* @return
*/
public PamSymbol getPamSymbol(PamSymbolChooser chooser, PamDataUnit dataUnit) {
if (chooser == null) {
return null;
}
// possible that the data is an Effort unit that wraps a real data unit. Need to
// probably pass the original.
if (dataUnit instanceof EffortDataUnit) {
PamDataUnit refData = ((EffortDataUnit) dataUnit).getReferenceDataUnit();
if (refData != null) {
dataUnit = refData;
}
}
return chooser.getPamSymbol(chooser.getProjector(), dataUnit);
}
public boolean showOptionsDialog(Window parent, String observerName) {
PamSymbolChooser symbolChooser = getSymbolChooser(observerName, null);
if (symbolChooser == null) {
return false;
}
SwingSymbolOptionsPanel panel = symbolChooser.getSwingOptionsPanel(null);
if (panel == null) {
return false;
}
DataSelectDialog dataSelectDialog = new DataSelectDialog(parent, parentDataBlock, null, symbolChooser);
boolean ans = dataSelectDialog.showDialog();
return ans;
}
/**
* @return the isViewer
*/
public boolean isViewer() {
return isViewer;
}
public EffortDataUnit getLastEffort() {
List<EffortDataUnit> all = getAllEffortThings();
if (all == null || all.size() == 0) {
return null;
}
return all.get(all.size()-1);
}
}

View File

@ -0,0 +1,158 @@
package effort.binary;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import PamController.OfflineDataStore;
import PamController.PamController;
import PamView.symbol.PamSymbolManager;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.dataSelector.DataSelector;
import binaryFileStorage.BinaryStore;
import dataMap.OfflineDataMap;
import dataMap.OfflineDataMapPoint;
import effort.EffortDataUnit;
import effort.EffortProvider;
/**
* Effort provider for most types of datablock that bases itself off one of the
* datamaps, binary (preferred) or database. Binary better since database doesn't really
* have proper effort data for most blocks.
* However, we want this to work online too, so will need to have quite different functionality
* for real time and viewer operations.
* @author dg50
*
*/
public class DataMapEffortProvider extends EffortProvider {
private DataMapSymbolManager binarySymbolManager;
private Class<?> dataStoreClass;
private long maxGap = 0;
private ArrayList<EffortDataUnit> allEfforts;
/**
*
* @param parentDataBlock
* @param dataStoreClass
* @param maxGapMillis
*/
public DataMapEffortProvider(PamDataBlock parentDataBlock, Class<?> dataStoreClass, long maxGapMillis) {
super(parentDataBlock);
this.dataStoreClass = dataStoreClass;
this.maxGap = maxGapMillis;
binarySymbolManager = new DataMapSymbolManager(parentDataBlock);
}
/**
*
* @param parentDataBlock
* @param dataStoreClass
*/
public DataMapEffortProvider(PamDataBlock parentDataBlock, Class dataStoreClass) {
this(parentDataBlock, dataStoreClass, 0);
}
@Override
public String getName() {
return getParentDataBlock().getDataName();
}
// @Override
// public EffortDataUnit getEffort(long timeMilliseconds) {
// OfflineDataMap dataMap = findDataMap();
// if (dataMap == null) {
// return null;
// }
// OfflineDataMapPoint foundPt = dataMap.findMapPoint(timeMilliseconds);
// if (foundPt != null) {
// return new DataMapEffortThing(this, getParentDataBlock(), foundPt.getStartTime(), foundPt.getEndTime());
// }
// return null;
// }
@Override
public List<EffortDataUnit> getAllEffortThings() {
return allEfforts;
}
private OfflineDataMap findDataMap() {
if (dataStoreClass == null) {
return getParentDataBlock().getPrimaryDataMap();
}
try {
OfflineDataStore dataStore = (OfflineDataStore) PamController.getInstance().findControlledUnit(dataStoreClass, null);
if (dataStore != null) {
return getParentDataBlock().getOfflineDataMap(dataStore);
}
}
catch (Exception e) {
}
return null;
}
@Override
public DataSelector getDataSelector(String selectorName) {
// TODO Auto-generated method stub
return null;
}
@Override
public PamSymbolManager getSymbolManager() {
return binarySymbolManager;
}
@Override
public void realTimeStart(long timeMilliseconds) {
if (allEfforts == null) {
allEfforts = new ArrayList<>();
}
EffortDataUnit newEffort = new EffortDataUnit(this, null, timeMilliseconds, EffortDataUnit.ONGOINGEFFORT);
allEfforts.add(newEffort);
}
@Override
public void realTimeStop(long timeMilliseconds) {
if (allEfforts == null || allEfforts.size() == 0) {
return;
}
EffortDataUnit lastEff = allEfforts.get(allEfforts.size()-1);
lastEff.setEffortEnd(timeMilliseconds);
}
@Override
public void newData(PamDataUnit pamDataUnit) {
// do nothing for individual data units.
}
@Override
public void viewerLoadData() {
// should merge continuous binary data into one big lump or several big lumps if duty cycled.
OfflineDataMap dataMap = findDataMap();
if (dataMap == null) {
return;
}
ArrayList<EffortDataUnit> allPoints = new ArrayList<>();
Iterator<OfflineDataMapPoint> it = dataMap.getListIterator();
DataMapEffortThing currentThing = null;
while (it.hasNext()) {
OfflineDataMapPoint pt = it.next();
if (currentThing == null || pt.getStartTime() - currentThing.getEffortEnd() > maxGap) {
currentThing = new DataMapEffortThing(this, getParentDataBlock(), pt.getStartTime(), pt.getEndTime());
allPoints.add(currentThing);
}
else {
currentThing.setEffortEnd(pt.getEndTime());
}
}
allEfforts = allPoints;
}
}

View File

@ -0,0 +1,22 @@
package effort.binary;
import PamguardMVC.PamDataBlock;
import effort.EffortDataUnit;
import effort.EffortProvider;
public class DataMapEffortThing extends EffortDataUnit {
private PamDataBlock parentDatablock;
public DataMapEffortThing(EffortProvider effortProvider, PamDataBlock parentDatablock, long effortStart, long effortEnd) {
super(effortProvider, null, effortStart, effortEnd);
this.parentDatablock = parentDatablock;
}
@Override
public String getEffortDescription() {
String str = String.format("%s", parentDatablock.getDataName());
return str;
}
}

View File

@ -0,0 +1,18 @@
package effort.binary;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.StandardSymbolManager;
import PamView.symbol.SymbolData;
import PamView.symbol.SymbolOnlyManager;
import PamguardMVC.PamDataBlock;
public class DataMapSymbolManager extends SymbolOnlyManager {
public static SymbolData defaultSymbol = new SymbolData();
public DataMapSymbolManager(PamDataBlock pamDataBlock) {
super(pamDataBlock, defaultSymbol);
}
}

View File

@ -0,0 +1,28 @@
package effort.swing;
import java.awt.Window;
import java.util.ArrayList;
import PamView.dialog.SourcePanel;
import PamguardMVC.PamDataBlock;
import effort.EffortManager;
public class EffortSourcePanel extends SourcePanel {
public EffortSourcePanel(Window ownerWindow) {
super(ownerWindow, PamDataBlock.class, false, false);
}
public EffortSourcePanel(Window ownerWindow, String borderTitle) {
super(ownerWindow, borderTitle, PamDataBlock.class, false, false);
}
@Override
public ArrayList<PamDataBlock> getCompatibleDataBlocks() {
return EffortManager.getEffortManager().getEffortDataBlocks();
}
}

View File

@ -33,6 +33,11 @@ import pamScrollSystem.PamScroller;
import pamScrollSystem.PamScrollerData;
import userDisplay.UserDisplayControl;
/**
* Record scroll effort.
* @author dg50
*
*/
public class EffortControl extends PamControlledUnit implements PamSettings{
public static String unitType = "Scroll Effort";

View File

@ -32,8 +32,8 @@ public class DBMapMakingDialog extends PamDialog {
JPanel p = new JPanel();
p.setBorder(new TitledBorder("Creating data map"));
p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS));
p.add(databaseName = new JLabel(""));
p.add(streamName = new JLabel(""));
p.add(databaseName = new JLabel(" "));
p.add(streamName = new JLabel(" "));
p.add(streamProgress = new JProgressBar());
// p.setPreferredSize(new Dimension(400, 200));
streamName.setPreferredSize(new Dimension(250, 5));

View File

@ -144,11 +144,14 @@ public class LookUpTables {
String topic1 = list.get(i).getTopic().trim();
for (int j = i+1; j < n; j++) {
String code2 = list.get(j).getCode().trim();
String topic2 = list.get(j).getTopic().trim();
String topic2 = list.get(j).getTopic();
if (topic2 != null) {
topic2 = topic2.trim();
if (code.equals(code2) && topic1.equals(topic2)) {
isRepeat[j] = true;
nRepeat++;
}
}
}
}
if (nRepeat == 0) {
@ -183,7 +186,7 @@ public class LookUpTables {
return null;
}
ArrayList<String> topics = new ArrayList<>();
String qStr = "SELECT DISTINCT Topic FROM " + lutTableDef.getTableName();
String qStr = "SELECT DISTINCT Topic FROM " + lutTableDef.getTableName() + " WHERE TOPIC IS NOT NULL";
try {
Statement stmt = con.getConnection().createStatement();
boolean ok = stmt.execute(qStr);

View File

@ -17,8 +17,8 @@ public class Group3DParams implements Serializable, Cloneable, ManagedParameters
public static final long serialVersionUID = 1L;
@Deprecated
private GroupedSourceParameters groupedSourceParams;
// @Deprecated
// private GroupedSourceParameters groupedSourceParams;
private String sourceName;
@ -146,9 +146,9 @@ public class Group3DParams implements Serializable, Cloneable, ManagedParameters
* @return the sourceName
*/
public String getSourceName() {
if (sourceName == null && groupedSourceParams != null) {
sourceName = groupedSourceParams.getDataSource();
}
// if (sourceName == null && groupedSourceParams != null) {
// sourceName = groupedSourceParams.getDataSource();
// }
return sourceName;
}

View File

@ -56,7 +56,6 @@ import pamScrollSystem.AbstractPamScrollerAWT;
import pamScrollSystem.ScrollPaneAddon;
import PamView.PamTabPanel;
import PamView.panel.PamPanel;
import PamView.symbol.StandardSymbolManager;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamController.PamControlledUnitSettings;
@ -67,7 +66,6 @@ import PamUtils.PamCalendar;
import PamUtils.XMLUtils;
import loggerForms.controlDescriptions.ControlTypes;
import loggerForms.controlDescriptions.InputControlDescription;
import loggerForms.PropertyTypes;
import loggerForms.controlDescriptions.ControlDescription;
import loggerForms.formdesign.FormEditDialog;
import loggerForms.formdesign.FormEditor;
@ -75,6 +73,7 @@ import loggerForms.formdesign.FormList;
import loggerForms.propertyInfos.BEARINGinfo;
import loggerForms.propertyInfos.HEADINGinfo;
import loggerForms.propertyInfos.RANGEinfo;
import loggerForms.symbol.LoggerSymbolManager;
/**
*
* @author Graham Weatherup - SMRU
@ -242,7 +241,7 @@ public class FormDescription implements Cloneable, Comparable<FormDescription> {
formsDataBlock = new FormsDataBlock(this, getFormName(), formsControl.getFormsProcess(), 0);
formsDataBlock.SetLogging(new FormsLogging(this,formsDataBlock));
formsDataBlock.setOverlayDraw(new LoggerFormGraphics(formsControl, this));
formsDataBlock.setPamSymbolManager(new StandardSymbolManager(formsDataBlock, LoggerFormGraphics.defaultSymbol, false));
formsDataBlock.setPamSymbolManager(new LoggerSymbolManager(formsDataBlock));
setTimeOfNextSave();
@ -1068,7 +1067,7 @@ public class FormDescription implements Cloneable, Comparable<FormDescription> {
normalForm = createForm();
formComponent = normalForm.getComponent();
}
formsDataDisplayTable = new FormsDataDisplayTable(this);
formsDataDisplayTable = new FormsDataDisplayTable(formsControl, this);
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, formComponent, formsDataDisplayTable.getMainPanel());
if (formSettingsControl.getFormSettings().splitPanelPosition != null) {
@ -1122,7 +1121,8 @@ public class FormDescription implements Cloneable, Comparable<FormDescription> {
}
public LoggerForm createForm() {
return new LoggerForm(this,LoggerForm.NewDataForm);
boolean viewer = PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW;
return new LoggerForm(this, viewer ? LoggerForm.NewDataForm : LoggerForm.NewDataForm);
}
@ -1230,6 +1230,22 @@ public class FormDescription implements Cloneable, Comparable<FormDescription> {
removeForm(parentFrame);
}
}
/**
* Delete a data unit from memory and from database.
* @param dataUnit
* @return
*/
public boolean deleteDataUnit(FormsDataUnit dataUnit) {
if (dataUnit == null) {
return false;
}
boolean ans = getFormsDataBlock().remove(dataUnit, true);
if (formsDataDisplayTable != null) {
formsDataDisplayTable.dataChanged();
}
return ans;
}
/**
* Create a new subtab form on the appropriate sub tab panel.
*/
@ -1646,6 +1662,15 @@ public class FormDescription implements Cloneable, Comparable<FormDescription> {
normalForm.restoreData(formsDataUnit);
}
}
public void optionsChange() {
if (normalForm != null) {
normalForm.optionsChange();
}
if (formsDataDisplayTable != null) {
formsDataDisplayTable.optionsChange();
}
}
/**
* Get a count of open sub tab forms.

View File

@ -16,6 +16,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.logging.LogManager;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
@ -34,6 +35,7 @@ import loggerForms.FormDescription.FormPlotOptionsStore;
import loggerForms.monitor.FormsMonitorMaster;
import PamController.PamControlledUnit;
import PamController.PamControlledUnitSettings;
import PamController.PamController;
import PamController.PamControllerInterface;
import PamController.PamSettingManager;
import PamController.PamSettings;
@ -48,16 +50,14 @@ import PamView.PamTabPanel;
import PamView.PamView;
import PamguardMVC.PamDataBlock;
/**
*
* @author Graham Weatherup
* controls the logger forms module
* @author Graham Weatherup controls the logger forms module
*/
public class FormsControl extends PamControlledUnit {
public class FormsControl extends PamControlledUnit implements PamSettings {
public static ArrayList<String> restrictedTitles = new ArrayList<String>();
private ArrayList<FormDescription> formDescriptions = new ArrayList<FormDescription>();
private ArrayList<UDFErrors> UDFErrors = new ArrayList<UDFErrors>();
@ -66,11 +66,13 @@ public class FormsControl extends PamControlledUnit {
private FormsAlertSidePanel formsAlertSidePanel;
private FormsProcess formsProcess;
public static final String unitType = "Logger Forms";
private FormsMonitorMaster formsMonitor;
private FormsParameters formsParameters = new FormsParameters();
// /** A set of dummy parameters, used solely to pull together different settings for XML export */
// private FormsTempParams dummyParams;
@ -83,8 +85,7 @@ public class FormsControl extends PamControlledUnit {
formsTabPanel = new FormsTabPanel(this);
formsAlertSidePanel = new FormsAlertSidePanel(this);
formsMonitor = new FormsMonitorMaster(this, formsProcess);
// dummyParams = new FormsTempParams();
// PamSettingManager.getInstance().registerSettings(this);
PamSettingManager.getInstance().registerSettings(this);
}
@ -100,7 +101,7 @@ public class FormsControl extends PamControlledUnit {
*
*/
private boolean buildRestrictedTitles() {
DBControlUnit dbControl = DBControlUnit.findDatabaseControl();
if (dbControl == null) {
return false;
@ -108,30 +109,29 @@ public class FormsControl extends PamControlledUnit {
String keywordString = null;
try {
keywordString = DBControlUnit.findDatabaseControl().getDatabaseSystem().getKeywords();
}
catch (NullPointerException e) {
} catch (NullPointerException e) {
return false;
}
String[] keywords;
if (keywordString != null) {
keywords = keywordString.split(",");
for (String k:keywords){
for (String k : keywords) {
restrictedTitles.add(k);
}
}
try {
PamConnection con = DBControlUnit.findConnection();
if (con == null) {
return false;
}
keywordString = con.getConnection().getMetaData().getSQLKeywords();
keywords = keywordString.split(",");
for (String k:keywords){
for (String k : keywords) {
restrictedTitles.add(k);
}
// System.out.println(keywordString);
@ -141,20 +141,21 @@ public class FormsControl extends PamControlledUnit {
} catch (SQLException e) {
e.printStackTrace();
return false;
}
catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see PamController.PamControlledUnit#notifyModelChanged(int)
*/
@Override
public void notifyModelChanged(int changeType) {
switch(changeType) {
switch (changeType) {
case PamControllerInterface.INITIALIZATION_COMPLETE:
generateForms();
break;
@ -173,29 +174,32 @@ public class FormsControl extends PamControlledUnit {
/**
* Get the form description for a specific index.
*
* @param iForm form index
* @return for description
*/
public FormDescription getFormDescription(int iForm) {
return formDescriptions.get(iForm);
}
/**
* Get a form index from a form description
*
* @param formDescription Form Descriptions
* @return form index or -1 if not found
*/
public int getFormIndex(FormDescription formDescription) {
return formDescriptions.indexOf(formDescription);
}
/**
* Find a form which has a particular order value.
* Find a form which has a particular order value.
*
* @param order order (starts from 1 generally)
* @return a form, or null if none have that order.
* @return a form, or null if none have that order.
*/
public FormDescription findFormByOrder(int order) {
for (FormDescription aForm:formDescriptions) {
for (FormDescription aForm : formDescriptions) {
PropertyDescription formProperty = aForm.findProperty(PropertyTypes.ORDER);
if (formProperty == null) {
continue;
@ -210,6 +214,7 @@ public class FormsControl extends PamControlledUnit {
/**
* Find a form description with a given name.
*
* @param formName
* @return form description or null.
*/
@ -217,7 +222,7 @@ public class FormsControl extends PamControlledUnit {
if (formName == null) {
return null;
}
for (FormDescription ad:formDescriptions) {
for (FormDescription ad : formDescriptions) {
if (ad.getFormName().equals(formName)) {
return ad;
}
@ -227,41 +232,40 @@ public class FormsControl extends PamControlledUnit {
}
return null;
}
public Character getOutputTableNameCounterSuffix(FormDescription thisFormDescription){
public Character getOutputTableNameCounterSuffix(FormDescription thisFormDescription) {
String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String thisTableName = thisFormDescription.getDBTABLENAME();
int count=0;
int count = 0;
int position = 0;
for (FormDescription formDescription : formDescriptions){
if ((formDescription.getDBTABLENAME()==thisFormDescription.getDBTABLENAME())){
position=count;
for (FormDescription formDescription : formDescriptions) {
if ((formDescription.getDBTABLENAME() == thisFormDescription.getDBTABLENAME())) {
position = count;
break;
}
count++;
}
// if (count==0){
// return "";
// }else{
// return Character.;
// Integer.toString(arg0, arg1)
// System.out.println("*********");
// System.out.println(position);
// }
// System.out.println(letters.charAt(position));
// System.out.println("*********");
// if (count==0){
// return "";
// }else{
// return Character.;
// Integer.toString(arg0, arg1)
// System.out.println("*********");
// System.out.println(position);
// }
// System.out.println(letters.charAt(position));
// System.out.println("*********");
return letters.charAt(position);
}
/**
* Generates a list of tables beginning with UDF_ and reads
* their contents into a FormDescription
* Generates a list of tables beginning with UDF_ and reads their contents into
* a FormDescription
*/
public void readUDFTables() {
/*
@ -281,7 +285,7 @@ public class FormsControl extends PamControlledUnit {
ArrayList<String> udfTableNameList = new ArrayList<String>();
PamConnection dbCon = dbControl.getConnection();
if (dbCon == null) {
System.out.println("Database not opened: Logger forms cannot be read");
return;
@ -289,42 +293,38 @@ public class FormsControl extends PamControlledUnit {
try {
DatabaseMetaData dbmd = dbCon.getConnection().getMetaData();
String[] types = {"TABLE"};
ResultSet resultSet = dbmd.getTables(null, null, "%", types);//not getting all tables from db in ODB
String[] types = { "TABLE" };
ResultSet resultSet = dbmd.getTables(null, null, "%", types);// not getting all tables from db in ODB
//Loop through database tables
while (resultSet.next()){
// Loop through database tables
while (resultSet.next()) {
String tableName = resultSet.getString(3);
// System.out.println("LogFor: "+tableName);
//If starts with 'UDF_' create form description from it.
if( tableName.toUpperCase().startsWith("UDF_")){
// If starts with 'UDF_' create form description from it.
if (tableName.toUpperCase().startsWith("UDF_")) {
udfTableNameList.add(tableName);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
if (UDFErrors.size()>0){
if (UDFErrors.size() > 0) {
}
for (String tableName:udfTableNameList){
for (String tableName : udfTableNameList) {
FormDescription formDescription = new FormDescription(this, tableName);
formDescriptions.add(formDescription);
}
// at this point, before datablocks are created, sort the forms into order.
// at this point, before datablocks are created, sort the forms into order.
Collections.sort(formDescriptions);
// hotKeyControl.removeAllListeners();
// finally create the datablocks.
// at the same time, can reset the order properties to a simple sequence.
// finally create the datablocks.
// at the same time, can reset the order properties to a simple sequence.
int iForm = 0;
for (FormDescription aFD:formDescriptions) {
for (FormDescription aFD : formDescriptions) {
formsProcess.addOutputDataBlock(aFD.getFormsDataBlock());
aFD.setFormOrderProperty(++iForm);
/*
@ -338,21 +338,24 @@ public class FormsControl extends PamControlledUnit {
}
}
public void addFormDescription(String newFormName){
public void addFormDescription(String newFormName) {
FormDescription formDescription = new FormDescription(this, newFormName);
formsProcess.addOutputDataBlock(formDescription.getFormsDataBlock());
}
/**
* Get the correct type of reference to the forms tab panel.
* @return reference to the forms tab panel.
* Get the correct type of reference to the forms tab panel.
*
* @return reference to the forms tab panel.
*/
public FormsTabPanel getFormsTabPanel() {
return formsTabPanel;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see PamController.PamControlledUnit#getTabPanel()
*/
@Override
@ -372,8 +375,6 @@ public class FormsControl extends PamControlledUnit {
}
/**
* @return the formsProcess
*/
@ -381,7 +382,9 @@ public class FormsControl extends PamControlledUnit {
return formsProcess;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see PamController.PamControlledUnit#createDetectionMenu(java.awt.Frame)
*/
@Override
@ -391,27 +394,38 @@ public class FormsControl extends PamControlledUnit {
detMenu.add(menuItem);
menuItem.addActionListener(new NewLoggerForm(parentFrame));
// if (SMRUEnable.isEnable()) {
JMenu editMenu = new JMenu("Edit form");
for (int i = 0; i < getNumFormDescriptions(); i++) {
FormDescription fd = getFormDescription(i);
JMenuItem fm = new JMenuItem(fd.getFormName() + "...");
fm.addActionListener(new EditForm(parentFrame, fd));
editMenu.add(fm);
}
detMenu.add(editMenu);
JMenu editMenu = new JMenu("Edit form");
for (int i = 0; i < getNumFormDescriptions(); i++) {
FormDescription fd = getFormDescription(i);
JMenuItem fm = new JMenuItem(fd.getFormName() + "...");
fm.addActionListener(new EditForm(parentFrame, fd));
editMenu.add(fm);
}
detMenu.add(editMenu);
// }
detMenu.add(menuItem = new JMenuItem("Regenerate all forms"));
menuItem.addActionListener(new ReGenerateForms(parentFrame));
if (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW) {
JCheckBoxMenuItem changebox = new JCheckBoxMenuItem("Allow Viewer changes");
changebox.setToolTipText("Allow the editing, adding, and deleting of data in Viewer mode");
changebox.setSelected(formsParameters.allowViewerChanges);
changebox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
formsParameters.allowViewerChanges = changebox.isSelected();
notifyOptionsChange();
}
});
detMenu.add(changebox);
}
return detMenu;
}
class NewLoggerForm implements ActionListener {
private Frame parentFrame;
public NewLoggerForm(Frame parentFrame) {
this.parentFrame = parentFrame;
}
@ -419,15 +433,22 @@ public class FormsControl extends PamControlledUnit {
@Override
public void actionPerformed(ActionEvent arg0) {
newLoggerform(parentFrame);
}
}
private void notifyOptionsChange() {
if (formDescriptions == null) {
return;
}
for (FormDescription formDesc: formDescriptions) {
formDesc.optionsChange();
}
}
class ReGenerateForms implements ActionListener {
private Frame parentFrame;
public ReGenerateForms(Frame parentFrame) {
this.parentFrame = parentFrame;
}
@ -435,37 +456,41 @@ public class FormsControl extends PamControlledUnit {
@Override
public void actionPerformed(ActionEvent arg0) {
regenerateForms(parentFrame);
}
}
class EditForm implements ActionListener {
private FormDescription formDescription;
private Frame parentFrame;
public EditForm(Frame parentFrame, FormDescription formDescription) {
super();
this.parentFrame = parentFrame;
this.formDescription = formDescription;
}
@Override
public void actionPerformed(ActionEvent arg0) {
this.formDescription.editForm(parentFrame);
}
}
/**
* Create a new logger form
*
* @param parentFrame parent frame
* @return selected name for new form, or null if nothing created.
* @return selected name for new form, or null if nothing created.
*/
public String newLoggerform(Frame parentFrame) {
String newName = JOptionPane.showInputDialog(parentFrame, "Enter the name for the new user form", "New Logger Form", JOptionPane.OK_CANCEL_OPTION);
String newName = JOptionPane.showInputDialog(parentFrame, "Enter the name for the new user form",
"New Logger Form", JOptionPane.OK_CANCEL_OPTION);
if (newName == null) {
return null;
}
// will make a form table definition with a standard structure and name UDF_ ...
// check the current name starts with UDF and add if necessary.
// check the current name starts with UDF and add if necessary.
if (newName.toUpperCase().startsWith("UDF_") == false) {
newName = "UDF_" + newName;
}
@ -473,11 +498,11 @@ public class FormsControl extends PamControlledUnit {
message += "\nNote that youwill have to exit PAMGUARD and enter form control data by hand into this table.";
message += "\nFuture releases will (hopefully) contain a more friendly programmable interface";
int ans = JOptionPane.showConfirmDialog(parentFrame, message, "Create Form", JOptionPane.OK_CANCEL_OPTION);
if(ans == JOptionPane.CANCEL_OPTION) {
if (ans == JOptionPane.CANCEL_OPTION) {
return null;
}
UDFTableDefinition tableDef = new UDFTableDefinition(newName);
message = String.format("The table %s could not be created in the databse %s", newName,
message = String.format("The table %s could not be created in the databse %s", newName,
DBControlUnit.findDatabaseControl().getDatabaseName());
if (DBControlUnit.findDatabaseControl().getDbProcess().checkTable(tableDef) == false) {
JOptionPane.showMessageDialog(parentFrame, "Error Creating form", message, JOptionPane.ERROR_MESSAGE);
@ -485,33 +510,32 @@ public class FormsControl extends PamControlledUnit {
return newName;
}
/**
* Generate all forms and associated processes, notifying databases, maps, etc
* so that any required actions can be taken.
* so that any required actions can be taken.
*/
private void generateForms() {
buildRestrictedTitles();
readUDFTables();
createProcesses();
formsTabPanel.createForms();
// initialise
// initialise
DBControlUnit dbControl = DBControlUnit.findDatabaseControl();
if (dbControl == null) {
return;
}
DBControlUnit.findDatabaseControl().getDbProcess().updateProcessList();
if (isViewer) {
updateFormDataMaps();
}
formsAlertSidePanel.getFormsAlertPanel().updateFormsShowing();
formsAlertSidePanel.getFormsAlertPanel().updateFormsShowing();
// will also at this point need to tell the main gui frame to update
// it's menu since it needs to incorporate a list of forms for editing
PamView pamView = getPamView();
@ -522,22 +546,23 @@ public class FormsControl extends PamControlledUnit {
formsMonitor.rebuiltForms();
}
/**
* Delete and recreate all forms / form data, etc.
* Delete and recreate all forms / form data, etc.
*
* @param parentFrame
*/
public void regenerateForms(Window parentFrame) {
formsTabPanel.removeAllForms();
for (FormDescription formDescription:formDescriptions) {
for (FormDescription formDescription : formDescriptions) {
formDescription.destroyForms();
}
formDescriptions.clear();
formsProcess.removeAllDataBlocks();
generateForms();
FormsPlotOptionsDialog.deleteDialog();
}
@Override
@ -565,14 +590,16 @@ public class FormsControl extends PamControlledUnit {
boolean ans = FormsPlotOptionsDialog.showDialog(parentFrame, this);
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see PamController.PamControlledUnit#canClose()
*/
@Override
public boolean canClose() {
// return false if any forms have open sub forms.
int subFormCount = 0;
for (FormDescription fd:formDescriptions) {
for (FormDescription fd : formDescriptions) {
subFormCount += fd.getSubformCount();
}
if (subFormCount == 0) {
@ -584,10 +611,10 @@ public class FormsControl extends PamControlledUnit {
}
/**
* Rewrite all UDF tables in forms which have been altered.
* Rewrite all UDF tables in forms which have been altered.
*/
public void rewriteChangedUDFTables() {
for (FormDescription aForm:formDescriptions) {
for (FormDescription aForm : formDescriptions) {
if (aForm.isNeedsUDFSave()) {
aForm.writeUDFTable(null);
aForm.setNeedsUDFSave(false);
@ -614,10 +641,10 @@ public class FormsControl extends PamControlledUnit {
return new ModuleStatus(ModuleStatus.STATUS_OK);
}
/**
* Some things that are meant to be boolean are coming out as int or string so
* need to do some type checking.
* Some things that are meant to be boolean are coming out as int or string so
* need to do some type checking.
*
* @param value
* @return
*/
@ -637,48 +664,31 @@ public class FormsControl extends PamControlledUnit {
int val = (Integer) value;
return val != 0;
}
return null;
}
// @Override
// public Serializable getSettingsReference() {
// return (Serializable) dummyParams;
// }
//
// @Override
// public long getSettingsVersion() {
// return 0;
// }
//
// @Override
// public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
// return false;
// }
//
// /**
// * Private class to pass along various parameter classes that Logger forms use
// *
// * @author mo55
// *
// */
// private class FormsTempParams implements ManagedParameters {
//
// @Override
// public PamParameterSet getParameterSet() {
// PamParameterSet ps = new PamParameterSet(this);
// try {
// Field field = FormsControl.this.getClass().getDeclaredField("formDescriptions");
// ps.put(new PrivatePamParameterData(this, field) {
// @Override
// public Object getData() throws IllegalArgumentException, IllegalAccessException {
// return formDescriptions;
// }
// });
// } catch (NoSuchFieldException | SecurityException e) {
// e.printStackTrace();
// }
// return ps;
// }
// }
@Override
public Serializable getSettingsReference() {
return formsParameters;
}
@Override
public long getSettingsVersion() {
return FormsParameters.serialVersionUID;
}
@Override
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
this.formsParameters = (FormsParameters) pamControlledUnitSettings.getSettings();
return true;
}
/**
* @return the formsParameters
*/
public FormsParameters getFormsParameters() {
return formsParameters;
}
}

View File

@ -7,6 +7,8 @@ import PamguardMVC.PamProcess;
import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.dataSelector.DataSelectorCreator;
import loggerForms.dataselect.FormDataSelCreator;
import loggerForms.effort.FormsEffortUnit;
import loggerForms.effort.LoggerEffortProvider;
import loggerForms.monitor.FormsDataSelectorCreator;
/**
*
@ -16,6 +18,8 @@ import loggerForms.monitor.FormsDataSelectorCreator;
public class FormsDataBlock extends PamDataBlock<FormsDataUnit> {
private FormDescription formDescription;
private LoggerEffortProvider loggerEffortProvider;
public FormsDataBlock(FormDescription formDescription, String dataName,
PamProcess parentProcess, int channelMap) {
@ -25,6 +29,7 @@ public class FormsDataBlock extends PamDataBlock<FormsDataUnit> {
setDataSelectCreator(new FormDataSelCreator(this, formDescription));
// setBinaryDataSource(new FormsBinaryIO(formDescription.getFormsControl(), this));
// setNaturalLifetimeMillis(60000);
setEffortProvider(loggerEffortProvider = new LoggerEffortProvider(this));
}
public FormDescription getFormDescription() {

View File

@ -4,10 +4,15 @@
package loggerForms;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
@ -20,6 +25,7 @@ import PamController.PamController;
import PamUtils.PamCalendar;
import PamView.PamTable;
import PamView.dialog.PamDialog;
import PamView.dialog.warn.WarnOnce;
import PamguardMVC.PamDataBlock;
/**
@ -37,11 +43,13 @@ public class FormsDataDisplayTable {
private JScrollPane scrollPane;
private FormsControl formsControl;
/**
* @param formDescription
*/
public FormsDataDisplayTable(FormDescription formDescription) {
// TODO Auto-generated constructor stub
public FormsDataDisplayTable(FormsControl formsControl, FormDescription formDescription) {
this.formsControl = formsControl;
this.formDescription=formDescription;
// GridLayout(rows,columns)
@ -63,36 +71,16 @@ public class FormsDataDisplayTable {
formsTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
// for now, don't allow edits in viewer mode.
if (PamController.getInstance().getRunMode() != PamController.RUN_PAMVIEW) {
// if (PamController.getInstance().getRunMode() != PamController.RUN_PAMVIEW) {
formsTable.addMouseListener(new EditDataListener());
}
// }
scrollPane = new JScrollPane(formsTable);
mainPanel.add(scrollPane);
// mainPanel.setPreferredSize(new Dimension(800, 200));
}
// class TimerListener implements ActionListener {
// boolean doneLayout;
// public void actionPerformed(ActionEvent ev) {
// // table.
//// nmeaTableData.fireTableRowsUpdated(0, 10);
// formsTableDataModel.fireTableDataChanged();
//
// if (doneLayout == false && formsTableDataModel.getRowCount() > 0) {
// doneLayout = true;
// }
// }
// }
class TableListListener implements ListSelectionListener {
@Override
@ -108,9 +96,15 @@ public class FormsDataDisplayTable {
formDescription.viewDataUnit(formsDataUnit);
}
}
}
private boolean canEdit() {
if (PamController.getInstance().getRunMode() != PamController.RUN_PAMVIEW) {
return true;
}
if (formsControl == null) return false;
return formsControl.getFormsParameters().allowViewerChanges;
}
/**
* Find the data unit for a particular row in the table.
* @param iRow
@ -125,9 +119,11 @@ public class FormsDataDisplayTable {
class EditDataListener extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent e) {
if (canEdit() == false) {
return;
}
if (e.getClickCount() == 2) {
// FormsDataBlock formsDataBlock = formDescription.getFormsDataBlock();
int row = formsTable.getSelectedRow();
FormsDataUnit formsDataUnit = findDataUnitForRow(row);
@ -135,14 +131,32 @@ public class FormsDataDisplayTable {
PamDialog.showWarning(null, "WARNING", "could not find formsDataUnit");
return;
}
FormsDataUnitEditor due = new FormsDataUnitEditor(formDescription,formsDataUnit);
editDataUnit(formsDataUnit);
}
}
@Override
public void mousePressed(MouseEvent e) {
maybePopup(e);
}
@Override
public void mouseReleased(MouseEvent e) {
maybePopup(e);
}
private void maybePopup(MouseEvent e) {
if (e.isPopupTrigger() == false) {
return;
}
if (canEdit() == false) {
return;
}
int row = formsTable.getSelectedRow();
showPopupMenu(e.getPoint());
}
}
@ -259,9 +273,69 @@ public class FormsDataDisplayTable {
return mainPanel;
}
public void showPopupMenu(Point pt) {
FormsDataUnit dataUnit = findDataUnitForRow(formsTable.getSelectedRow());
JPopupMenu menu = new JPopupMenu();
JMenuItem menuItem;
if (dataUnit != null) {
menuItem = new JMenuItem("Edit row ...");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
editDataUnit(dataUnit);
}
});
menu.add(menuItem);
}
menuItem = new JMenuItem("Create row ...");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addDataUnit();
}
});
menu.add(menuItem);
if (dataUnit != null) {
menu.addSeparator();
menuItem = new JMenuItem("Delete row ...");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
deleteDataUnit(dataUnit);
}
});
menu.add(menuItem);
}
menu.show(formsTable, pt.x, pt.y);
}
private boolean editDataUnit(FormsDataUnit dataUnit) {
FormsDataUnitEditor due = new FormsDataUnitEditor(formDescription, dataUnit);
return true;
}
private boolean deleteDataUnit(FormsDataUnit dataUnit) {
if (dataUnit == null) {
return false;
}
int ans = WarnOnce.showWarning("Delete logger form data", "Are you sure you want to delete data Id " + dataUnit.getDatabaseIndex(), WarnOnce.OK_CANCEL_OPTION);
if (ans != WarnOnce.OK_OPTION) {
return false;
}
formDescription.deleteDataUnit(dataUnit);
return true;
}
private boolean addDataUnit() {
formDescription.viewDataUnit(null);
return false;
}
/**
* Called when data have changed in the datablock.
*/
@ -276,4 +350,12 @@ public class FormsDataDisplayTable {
public JScrollPane getScrollPane() {
return scrollPane;
}
/**
* Some optins have changed.
*/
public void optionsChange() {
// TODO Auto-generated method stub
}
}

View File

@ -2,7 +2,10 @@ package loggerForms;
import GPS.GpsData;
import PamUtils.PamCalendar;
import PamView.GeneralProjector;
import PamguardMVC.PamDataUnit;
import generalDatabase.SQLTypes;
import loggerForms.controlDescriptions.ControlDescription;
/**
*
* @author Graham Weatherup
@ -12,9 +15,6 @@ import PamguardMVC.PamDataUnit;
* UTCmillisecond
* PCLocalTime
*
*
*
*
*/
public class FormsDataUnit extends PamDataUnit {
@ -94,6 +94,82 @@ public class FormsDataUnit extends PamDataUnit {
return formOriginLatLong;
}
@Override
public long getTimeMilliseconds() {
Long time = findTimeValue(PropertyTypes.STARTTIME);
if (time != null) {
return time;
}
return super.getTimeMilliseconds();
}
/**
* Find one of the time property controls and get its value.
* @param timeProperty
* @return
*/
public Long findTimeValue(PropertyTypes timeProperty) {
if (formData == null) {
return null;
}
PropertyDescription prop = formDescription.findProperty(timeProperty);
if (prop == null) {
return null;
}
String ctrlTitle = prop.getItemInformation().getStringProperty("Title");
if (ctrlTitle == null) {
return null;
}
int timeControlIndex = formDescription.findInputControlByName(ctrlTitle);
if (timeControlIndex < 0 || timeControlIndex >= formData.length) {
return null;
}
Object timeObj = formData[timeControlIndex];
/*
* this should have found the time contol in the form of a string from the database.
* try to unpack it.
*/
Long timeMillis = SQLTypes.millisFromTimeStamp(timeObj);
return timeMillis;
}
/**
* find a correctly set property value for the end time (if set).
* @return
*/
public Long getSetEndTime() {
return findTimeValue(PropertyTypes.ENDTIME);
}
@Override
public long getEndTimeInMilliseconds() {
Long time = findTimeValue(PropertyTypes.ENDTIME);
if (time != null) {
return time;
}
return super.getEndTimeInMilliseconds();
}
@Override
public String getSummaryString() {
String str = String.format("<html><b>%s</b>", formDescription.getFormNiceName());
Object[] data = getFormData();
int iDat = 0;
for (ControlDescription cd:formDescription.getInputControlDescriptions()) {
if (data[iDat] == null) {
str += String.format("<p>%s: -", cd.getTitle());
}
else {
str += String.format("<p>%s: %s", cd.getTitle(), data[iDat].toString());
}
iDat++;
}
str += "</html>";
return str;
}
}

View File

@ -16,8 +16,6 @@ import PamUtils.PamCalendar;
public class FormsDataUnitEditor{
/**
* @param formDescription
* @param formsDataUnit
@ -29,8 +27,6 @@ public class FormsDataUnitEditor{
JFrame frame=PamController.getInstance().getGuiFrameManager().getFrame(frameNo);
FormsDataUnit updatedData = FormsDataUnitEditDialog.showDialog(frame, formDescription, formsDataUnit);
if (updatedData != null) {

View File

@ -2,16 +2,20 @@ package loggerForms;
import java.util.ArrayList;
import PamController.PamViewParameters;
import loggerForms.controlDescriptions.ControlDescription;
import loggerForms.controlDescriptions.InputControlDescription;
import pamScrollSystem.ViewLoadObserver;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import generalDatabase.PamConnection;
import generalDatabase.PamTableDefinition;
import generalDatabase.SQLLogging;
import generalDatabase.SQLTypes;
public class FormsLogging extends SQLLogging {
FormDescription formDescription;
private FormDescription formDescription;
protected FormsLogging(FormDescription formDescription, PamDataBlock pamDataBlock) {
super(pamDataBlock);
@ -20,53 +24,34 @@ public class FormsLogging extends SQLLogging {
setTableDefinition(formDescription.getOutputTableDef());
}
// @Override
// public void setTableData(PamDataUnit pamDataUnit) {
//
// FormsDataUnit formDataUnit = (FormsDataUnit) pamDataUnit;
// int dataLen = formDataUnit.getFormData().length;
// int tableLen= getTableDefinition().getTableItemCount();
//
//// for (int j=0;j<tableLen;j++){
//// System.out.println(getTableDefinition().getTableItem(j).getName());
//// }
//
// int diff = tableLen-dataLen;
// // put number of standard items as static is pamtable item/table(ie diff ~3-5)
//
//// System.out.printf("Save Forms Data "+PamCalendar.formatDateTime(formDataUnit.getTimeMilliseconds())+"\n");
//
// for (int i=0;i<dataLen;i++){
//// System.out.printf("INTS.. %d dataLen:%d, tableLen:%d, diff:%d \n",i,dataLen,tableLen,diff);
//// if ((formDataUnit.getFormData()[i]==null)){
//// System.out.println("Object "+i+" to save: ~null");
//// getTableDefinition().getTableItem(i+diff).setValue(null); //be null;
//// }else{
//// System.out.println("Object "+i+" to save: "+formDataUnit.getFormData()[i].toString());
//// System.out.println("Name: "+getTableDefinition().getTableItem(i+diff).getName());
//// System.out.println("Data: "+formDataUnit.getFormData()[i]);
// getTableDefinition().getTableItem(i+diff).setValue(formDataUnit.getFormData()[i]);//object
//
//// }
//
// }
//
// }
@Override
public String getViewerLoadClause(SQLTypes sqlTypes, PamViewParameters pvp) {
// modified clause in case the form defines a start time element in which
// case we need an OR of that and UTC.
String standardClause = super.getViewerLoadClause(sqlTypes, pvp);
PropertyDescription startProp = formDescription.findProperty(PropertyTypes.STARTTIME);
if (startProp == null) {
return standardClause;
}
String startName = startProp.getDbTitle();
if (startName == null) {
return standardClause;
}
startName = PamTableDefinition.deblankString(startName); // replace blanks with underscores.
startName = sqlTypes.formatColumnName(startName); // wrap as standard for this database taype.
String t1 = sqlTypes.formatDBDateTimeQueryString(pvp.viewStartTime);
String t2 = sqlTypes.formatDBDateTimeQueryString(pvp.viewEndTime);
String newClause = String.format(" WHERE (UTC BETWEEN %s AND %s) OR (%s BETWEEN %s AND %s) ORDER BY %s, UTC, UTCMilliseconds",
t1, t2, startName, t1, t2, startName);
return newClause;
}
@Override
public void setTableData(SQLTypes sqlTypes, PamDataUnit pamDataUnit) {
FormsDataUnit formDataUnit = (FormsDataUnit) pamDataUnit;
Object[] datas = formDataUnit.getFormData();
// for(LoggerControl lc:formDataUnit.getLoggerForm().getInputControls()){
//
// lc.moveDataToTableItems();
//// for (FormsTableItem fti:lc.getControlDescription().getFormsTableItems()){
////
//// getTableDefinition().getTableItem(fti).setValue(lc.getData());
////
//// }
// }
ArrayList<InputControlDescription> inputCtrls = formDescription.getInputControlDescriptions();
InputControlDescription cd;
@ -76,9 +61,6 @@ public class FormsLogging extends SQLLogging {
}
// for (ControlDescription controlDescription:formDescription.getInputControlDescriptions()){
// controlDescription.moveDataTo
// }
}
/* (non-Javadoc)
@ -98,21 +80,6 @@ public class FormsLogging extends SQLLogging {
}
}
//
// int dataLen = formDescription.getInputControlDescriptions().size();
// int tableLen= getTableDefinition().getTableItemCount();
// int diff = tableLen-dataLen;
// Object[] formData = new Object[dataLen];
// int tableIndex;
// for (int j=0;j<dataLen;j++){
// tableIndex = j+diff;
// formData[j] = getTableDefinition().getTableItem(j+diff).getValue();
// if (formData[j] != null && formData[j].getClass() == String.class) {
// formData[j] = ((String) formData[j]).trim();
// }
// }
// formDescription.getf
FormsDataUnit formsDataUnit = new FormsDataUnit(null, timeMilliseconds, formDescription, formData);
formsDataUnit.setDatabaseIndex(databaseIndex);
@ -120,16 +87,17 @@ public class FormsLogging extends SQLLogging {
return formsDataUnit;
// LoggerForm.
// return new FormsDataUnit(null, timeMilliseconds, formDescription, formData);
}
@Override
public boolean loadViewData(PamConnection con, PamViewParameters pamViewParameters, ViewLoadObserver loadObserver) {
boolean ans = super.loadViewData(con, pamViewParameters, loadObserver);
if (ans) {
getPamDataBlock().sortData();
}
return ans;
}
}

View File

@ -0,0 +1,26 @@
package loggerForms;
import java.io.Serializable;
/**
* Some general parameters for PAMGuard Viewer mode
* @author dg50
*
*/
public class FormsParameters implements Serializable, Cloneable{
public static final long serialVersionUID = 1L;
public boolean allowViewerChanges = false;
@Override
protected FormsParameters clone() {
try {
return (FormsParameters) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -10,6 +10,7 @@ import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -50,6 +51,7 @@ import PamView.PamColors;
import PamView.dialog.PamButton;
import PamView.dialog.PamDialog;
import PamView.dialog.PamLabel;
import PamView.dialog.warn.WarnOnce;
import PamView.panel.PamPanel;
import PamView.panel.VerticalLayout;
import PamguardMVC.PamDataBlock;
@ -136,6 +138,7 @@ public class LoggerForm{
public static final int PreviewDataForm = 2;
private int NewOrEdit;
private LoggerFormPanel lastRow;
private FormsDataUnit restoredDataUnit;
//// /**
//// * used to hold reference to dataUnit being edited in "edit" mode
@ -605,21 +608,35 @@ public class LoggerForm{
* Enable / disable buttons
* <p> for now this is basically just disabling buttons if
* we're in viewer mode. A More sophisticated function
* might consider enabling / diabling depending on whether
* might consider enabling / disabling depending on whether
* or not a form can be saved.
*/
public void enableControls() {
boolean isViewer = PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW;
if (saveButton != null) saveButton.setEnabled(!isViewer);
if (clearButton != null) clearButton.setEnabled(!isViewer);
if (cancelButton != null) cancelButton.setEnabled(!isViewer);
boolean viewerEds = false;
if (formDescription != null) {
FormsControl formsControl = formDescription.getFormsControl();
viewerEds = formsControl.getFormsParameters().allowViewerChanges;
}
if (saveButton != null) {
saveButton.setEnabled(!isViewer || viewerEds);
if (isViewer) {
saveButton.setText(restoredDataUnit == null ? "Save" : "Update...");
}
}
if (clearButton != null) {
clearButton.setEnabled(!isViewer);
}
if (cancelButton != null) {
cancelButton.setEnabled(!isViewer);
}
}
class SaveButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Save")) {
// if (e.getActionCommand().equals("Save")) {
String er = getFormErrors();
getFormWarnings();
@ -628,7 +645,7 @@ public class LoggerForm{
if (er==null){
save();
}
}
// }
}
}
@ -636,17 +653,16 @@ public class LoggerForm{
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Save")) {
// if (e.getActionCommand().equals("Save")) {
String er = getFormErrors();
getFormWarnings();
if (er==null){
save();
formDescription.removeSubtabform(loggerForm);
}
}
// }
}
}
@ -737,9 +753,16 @@ public class LoggerForm{
* @param formsDataUnit
*/
void restoreData(FormsDataUnit formsDataUnit){
// this.formsDataUnit = formsDataUnit;
Object[] formData = formsDataUnit.getFormData();
transferDataArrayToForm(formData);
restoredDataUnit = formsDataUnit;
if (formsDataUnit != null) {
// this.formsDataUnit = formsDataUnit;
Object[] formData = formsDataUnit.getFormData();
transferDataArrayToForm(formData);
}
else {
clear();
}
enableControls();
}
/**
@ -840,14 +863,40 @@ public class LoggerForm{
* Extract and save teh data inot a new PAmDAtaUnit.
*/
private void save() {
//create form data object v
//create form data object
Object[] formData = extractFormData();
boolean isViewer = PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW;
boolean isNew = true;
if (isViewer && restoredDataUnit != null) {
isNew = false;
}
if (NewOrEdit==NewDataForm){
if (isNew){
FormsDataUnit formDataUnit = new FormsDataUnit(loggerForm,PamCalendar.getTimeInMillis(), formDescription, formData);
// dU.setParentDataBlock(formDescription.getFormsDataBlock());
// System.out.println(formDescription.getXMLData(formDataUnit));
formDescription.getFormsDataBlock().addPamData(formDataUnit);
// in viewer mode, will need to do something to get this to save.
if (isViewer) {
formDescription.getFormsDataBlock().getLogging().logData(DBControlUnit.findConnection(), formDataUnit);
formDescription.getFormsDataBlock().sortData();
}
}
else {
// update the data form. Ask first.
Frame win = formDescription.getFormsControl().getGuiFrame();
String msg = "Do you want to update this form with new data ?";
int ans = WarnOnce.showWarning(win, "Logger forms: " + formDescription.getFormName(), msg, WarnOnce.OK_CANCEL_OPTION);
if (ans == WarnOnce.OK_OPTION) {
if (restoredDataUnit == null) {
WarnOnce.showWarning(win, "Logger forms: " + formDescription.getFormName(), "No data to update", WarnOnce.WARNING_MESSAGE);
}
else {
restoredDataUnit.setFormsData(loggerForm, formData);
// should update database on next SaveData, but not before.
formDescription.getFormsDataBlock().updatePamData(restoredDataUnit, PamCalendar.getTimeInMillis());
formDescription.getFormsDataBlock().sortData();
}
}
}
// else if(NewOrEdit==EditDataForm && formsDataUnit != null){
// formsDataUnit.setFormsData(formData);
@ -914,6 +963,9 @@ public class LoggerForm{
public JButton getSaveButton() {
return saveButton;
}
public void optionsChange() {
enableControls();
}
// public GpsData getOriginLatLong(FormsDataUnit formsDataUnit) {
// GpsData gps = getOrigin(GPSOriginSystem.class, formsDataUnit);

View File

@ -32,6 +32,7 @@ import PamView.PamSymbolType;
import PamView.PanelOverlayDraw;
import PamView.GeneralProjector.ParameterType;
import PamView.GeneralProjector.ParameterUnits;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData;
import PamguardMVC.PamDataUnit;
@ -189,7 +190,7 @@ public class LoggerFormGraphics extends PanelOverlayDraw {
double shipCourse = plotOrigin.getCourseOverGround();
double shipHead = plotOrigin.getHeading();
PamSymbol plotSymbol = getPlotSymbol(formDataUnit);
PamSymbol plotSymbol = getPlotSymbol(generalProjector, formDataUnit);
Coordinate3d detOrigin = generalProjector.getCoord3d(plotOrigin.getLatitude(), plotOrigin.getLongitude(), plotOrigin.getHeight());
// see if there is range heading and bearing data.
@ -248,7 +249,7 @@ public class LoggerFormGraphics extends PanelOverlayDraw {
int nControls = data.length;
ControlDescription controlDescription;
ArrayList<InputControlDescription> controlDescriptions = formDescription.getInputControlDescriptions();
PamSymbol plotSymbol = getPlotSymbol(dataUnit);
PamSymbol plotSymbol = getPlotSymbol(generalProjector, dataUnit);
if (plotSymbol == null) {
return null;
}
@ -354,7 +355,22 @@ public class LoggerFormGraphics extends PanelOverlayDraw {
* @param pamDataUnit data unit to plot
* @return symbol.
*/
private PamSymbol getPlotSymbol(FormsDataUnit dataUnit) {
private PamSymbol getPlotSymbol(GeneralProjector projector, FormsDataUnit dataUnit) {
/**
* Try to use the new selector system. If it's not there, then revert to
* the older system.
*/
PamSymbolChooser chooser = null;
if (projector != null) {
chooser = projector.getPamSymbolChooser();
}
if (chooser != null) {
PamSymbol chosenSymbol = chooser.getPamSymbol(projector, dataUnit);
if (chosenSymbol != null) {
return chosenSymbol;
}
}
/**
* first go through all the controls and see which is
* the first one that's initiated plotting. If it's
@ -409,22 +425,7 @@ public class LoggerFormGraphics extends PanelOverlayDraw {
@Override
public String getHoverText(GeneralProjector generalProjector,
PamDataUnit dataUnit, int iSide) {
FormsDataUnit formsDU = (FormsDataUnit) dataUnit;
String str = String.format("<html><b>%s</b>", formDescription.getFormNiceName());
Object[] data = formsDU.getFormData();
int iDat = 0;
for (ControlDescription cd:formDescription.getInputControlDescriptions()) {
if (data[iDat] == null) {
str += String.format("<p>%s: -", cd.getTitle());
}
else {
str += String.format("<p>%s: %s", cd.getTitle(), data[iDat].toString());
}
iDat++;
}
str += "</html>";
return str;
return dataUnit.getSummaryString();
}
private void createSymbols() {

View File

@ -1,7 +1,7 @@
package loggerForms;
public enum PropertyTypes {
ORDER, AUTOALERT,SUBTABS,POPUP,HIDDEN,AUTORECORD,BEARING,
STARTTIME, ENDTIME, ORDER, AUTOALERT,SUBTABS,POPUP,HIDDEN,AUTORECORD,BEARING,
RANGE,HEADING,FONT,DBTABLENAME,
FORMCOLOUR,FORMCOLOR,
HOTKEY,NOCLEAR,NOCANCEL,NOTOFFLINE,NOTONLINE,
@ -16,6 +16,10 @@ public enum PropertyTypes {
public String getDescription() {
switch (this) {
case STARTTIME:
return "Form start time. Will be used as main data UTC. If undefined, form time is save time";
case ENDTIME:
return "Form end time. Will be used data end time in period data";
case AUTOALERT:
return "A warning will be issued if the form has not been completed for a set time";
case AUTORECORD:

View File

@ -3,8 +3,6 @@
*/
package loggerForms.controlDescriptions;
import generalDatabase.EmptyTableDefinition;
import java.sql.Types;
import javax.swing.JPanel;
@ -12,7 +10,6 @@ import javax.swing.JPanel;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import PamUtils.XMLUtils;
import loggerForms.FormDescription;
import loggerForms.FormsDataUnit;
import loggerForms.FormsTableItem;
@ -37,7 +34,6 @@ public abstract class ControlDescription extends ItemDescription {
protected ControlDescription(FormDescription formDescription, ItemInformation itemInformation) {
super(formDescription, itemInformation);
eType = ControlTypes.valueOf(getType());
// System.out.println(getType()+";"+eType.toString());
}
@ -88,11 +84,6 @@ public abstract class ControlDescription extends ItemDescription {
return formsTableItems;
}
private ControlTypes eType;
/**

View File

@ -0,0 +1,15 @@
package loggerForms.effort;
import effort.EffortDataUnit;
import loggerForms.FormsDataUnit;
public class FormsEffortUnit extends EffortDataUnit {
private FormsDataUnit parentFormUnit;
public FormsEffortUnit(LoggerEffortProvider loggerEffortProvider, FormsDataUnit parentFormUnit, long formEndTime) {
super(loggerEffortProvider, parentFormUnit, parentFormUnit.getTimeMilliseconds(), formEndTime);
this.parentFormUnit = parentFormUnit;
}
}

View File

@ -0,0 +1,165 @@
package loggerForms.effort;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import PamController.PamController;
import PamView.symbol.PamSymbolManager;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.dataSelector.DataSelector;
import dataMap.OfflineDataMap;
import effort.EffortDataUnit;
import effort.EffortProvider;
import loggerForms.FormDescription;
import loggerForms.FormsDataBlock;
import loggerForms.FormsDataUnit;
public class LoggerEffortProvider extends EffortProvider {
private FormsDataBlock formsDataBlock;
private ArrayList<EffortDataUnit> onlineEffort;
public LoggerEffortProvider(FormsDataBlock parentDataBlock) {
super(parentDataBlock);
this.formsDataBlock = parentDataBlock;
FormDescription formsDescription = parentDataBlock.getFormDescription();
}
// @Override
// public EffortDataUnit getEffort(long timeMilliseconds) {
// ListIterator<FormsDataUnit> iterator = formsDataBlock.getListIterator(timeMilliseconds, 0, PamDataBlock.MATCH_BEFORE, PamDataBlock.POSITION_BEFORE);
// FormsDataUnit currentUnit = null;
// FormsDataUnit nextUnit = null;
// if (iterator == null) {
// return null;
// }
//
// if (iterator.hasNext()) {
// currentUnit = iterator.next();
// }
// if (iterator.hasNext()) {
// nextUnit = iterator.next();
// }
// if (currentUnit == null) {
// return null;
// }
// long endTime = getEndTime(currentUnit, nextUnit);
//
// return new FormsEffortUnit(this, currentUnit, endTime);
// }
private long getEndTime(FormsDataUnit currentUnit, FormsDataUnit nextUnit) {
Long end = currentUnit.getSetEndTime();
if (end != null) {
return end;
}
if (nextUnit == null) {
return getLastDatasetTime();
}
else {
return nextUnit.getTimeMilliseconds();
}
}
@Override
public List<EffortDataUnit> getAllEffortThings() {
return onlineEffort;
}
@Override
public void viewerLoadData() {
ArrayList<EffortDataUnit> allList = new ArrayList();
ListIterator<FormsDataUnit> iterator = formsDataBlock.getListIterator(0);
FormsDataUnit currentUnit = null;
FormsDataUnit nextUnit = null;
if (iterator.hasNext()) {
currentUnit = iterator.next();
}
while (iterator.hasNext()) {
nextUnit = iterator.next();
long end = getEndTime(currentUnit, nextUnit);
allList.add(new FormsEffortUnit(this, currentUnit, end));
currentUnit = nextUnit;
}
if (currentUnit != null) {
long end = getEndTime(currentUnit, null);
allList.add(new FormsEffortUnit(this, currentUnit, end));
}
onlineEffort = allList;
}
@Override
public DataSelector getDataSelector(String selectorName) {
// TODO Auto-generated method stub
return null;
}
@Override
public PamSymbolManager getSymbolManager() {
return formsDataBlock.getPamSymbolManager();
}
/**
* Get the last time of any data in this dataset from any data map.
* @return
*/
private long getLastDatasetTime() {
long lastTime = Long.MIN_VALUE;
ArrayList<PamDataBlock> allData = PamController.getInstance().getDataBlocks();
for (PamDataBlock aBlock : allData) {
OfflineDataMap dataMap = aBlock.getPrimaryDataMap();
if (dataMap != null) {
lastTime = Math.max(lastTime, dataMap.getLastDataTime());
}
}
return lastTime;
}
@Override
public String getName() {
return formsDataBlock.getDataName();
}
@Override
public void realTimeStart(long timeMilliseconds) {
// Don't do anything with start and end of processing
}
@Override
public void realTimeStop(long timeMilliseconds) {
// Don't do anything with start and end of processing
}
@Override
public void newData(PamDataUnit pamDataUnit) {
// generate effort things from incoming form data.
if (onlineEffort == null) {
onlineEffort = new ArrayList<>();
}
FormsEffortUnit lastEffort = null;
if (onlineEffort.size() > 0) {
lastEffort = (FormsEffortUnit) onlineEffort.get(onlineEffort.size()-1);
}
FormsDataUnit formDataUnit = (FormsDataUnit) pamDataUnit;
long thisStart = formDataUnit.getTimeMilliseconds();
Long thisEnd = formDataUnit.getSetEndTime();
if (lastEffort != null) {
/*
* If the previous effort didn't have a end time, then use this start as that's end.
*/
if (lastEffort.getEffortEnd() >= EffortDataUnit.ONGOINGEFFORT/2) {
lastEffort.setEffortEnd(thisStart);
}
}
if (thisEnd == null) {
thisEnd = EffortDataUnit.ONGOINGEFFORT;
}
FormsEffortUnit newEffort = new FormsEffortUnit(this, formDataUnit, thisEnd);
onlineEffort.add(newEffort);
}
}

View File

@ -11,6 +11,7 @@ import loggerForms.ItemInformation;
import loggerForms.PropertyDescription;
import loggerForms.PropertyTypes;
import loggerForms.UDColName;
import loggerForms.controlDescriptions.ControlTypes;
import loggerForms.formdesign.propertypanels.AutoAlertPanel;
import loggerForms.formdesign.propertypanels.BearingPanel;
import loggerForms.formdesign.propertypanels.BooleanPanel;
@ -26,6 +27,7 @@ import loggerForms.formdesign.propertypanels.PropertyPanel;
import loggerForms.formdesign.propertypanels.RangePanel;
import loggerForms.formdesign.propertypanels.SymbolPanel;
import loggerForms.formdesign.propertypanels.TextPanel;
import loggerForms.formdesign.propertypanels.XReferencePanel;
/**
* Layer that sits between the form description and the actual edit
@ -154,6 +156,10 @@ public class FormEditor {
public PropertyPanel makePropertyPanel(PropertyTypes propertyType) {
switch (propertyType) {
case STARTTIME:
return new XReferencePanel(this, propertyType, ControlTypes.TIMESTAMP);
case ENDTIME:
return new XReferencePanel(this, propertyType, ControlTypes.TIMESTAMP);
case AUTOALERT:
return new IntegerPanel(this, propertyType, UDColName.AutoUpdate, "Alert operator every", "minutes");
case AUTORECORD:

View File

@ -0,0 +1,95 @@
package loggerForms.formdesign.propertypanels;
import java.util.ArrayList;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import loggerForms.ItemInformation;
import loggerForms.PropertyTypes;
import loggerForms.UDColName;
import loggerForms.controlDescriptions.ControlTypes;
import loggerForms.formdesign.ControlTitle;
import loggerForms.formdesign.FormEditor;
import loggerForms.formdesign.FormEditor.EditNotify;
/**
* Property form for a cross reference sontrol.
* @author dg50
*
*/
public class XReferencePanel extends PropertyPanel {
private ControlTypes controlType;
private JComboBox<String> fieldNames;
public XReferencePanel(FormEditor formEditor, PropertyTypes propertyType, ControlTypes controlType) {
super(formEditor, propertyType);
this.controlType = controlType;
addItem(new JLabel(" Use "));
addItem(fieldNames = new JComboBox<String>());
}
/* (non-Javadoc)
* @see loggerForms.formdesign.propertypanels.PropertyPanel#notifyChanges(loggerForms.formdesign.FormEditor.EditNotify)
*/
@Override
public void notifyChanges(EditNotify notifyType) {
fillComboBox();
}
/**
* Fill the combo box with a list of all control names that have
* numeric data which might be used for bearing information.
*/
private void fillComboBox() {
String currentValue = (String) fieldNames.getSelectedItem();
fieldNames.removeAllItems();
ArrayList<ControlTitle> ctrlTitles = formEditor.getControlTitles();
for (ControlTitle title:ctrlTitles) {
if (title.getType() == null) {
continue;
}
if (title.getType() == controlType) {
fieldNames.addItem(title.getItemInformation().getStringProperty(UDColName.Title.toString()));
}
}
if (currentValue != null) {
fieldNames.setSelectedItem(currentValue);
}
else {
// pushProperty();
}
}
@Override
public void propertyEnable(boolean enabled) {
fieldNames.setEnabled(enabled);
}
@Override
public void pushProperty(ItemInformation itemInformation) {
super.pushProperty(itemInformation);
if (itemInformation == null) {
return;
}
try {
fieldNames.setSelectedItem(itemInformation.getStringProperty(UDColName.Title.toString()));
}
catch (Exception e) {};
}
@Override
public ItemInformation fetchProperty(ItemInformation itemInformation) {
itemInformation = super.fetchProperty(itemInformation);
if (itemInformation == null) {
return null;
}
itemInformation.setProperty(UDColName.Title.toString(), fieldNames.getSelectedItem());
return itemInformation;
}
}

View File

@ -0,0 +1,53 @@
package loggerForms.symbol;
import java.awt.Color;
import PamView.GeneralProjector;
import PamView.PamColors;
import PamView.PamSymbolType;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData;
import PamguardMVC.PamDataUnit;
import loggerForms.FormDescription;
import loggerForms.controlDescriptions.ControlDescription;
/**
* Integer symbol modifier. Basically returns the whale colour rotation.
* @author dg50
*
*/
public class IntegerSymbolModifier extends LoggerSymbolModifier {
public IntegerSymbolModifier(FormDescription formDescription, ControlDescription controlDescription,
PamSymbolChooser symbolChooser, int modifyableBits) {
super(formDescription, controlDescription, symbolChooser, modifyableBits);
}
@Override
public SymbolData getSymbolData(GeneralProjector projector, PamDataUnit dataUnit) {
Object data = getControlData(dataUnit);
if (data == null) {
return null;
}
int number = 0;
if (data instanceof String) {
try {
number = Integer.valueOf(data.toString());
}
catch (NumberFormatException e) {
return null;
}
}
if (data instanceof Number) {
try {
number = Integer.valueOf(data.toString());
}
catch (Exception e) {
return null;
}
}
Color col = PamColors.getInstance().getChannelColor(number);
return new SymbolData(PamSymbolType.SYMBOL_CIRCLE, 1, 1, true, col, col);
}
}

View File

@ -0,0 +1,23 @@
package loggerForms.symbol;
import PamView.GeneralProjector;
import PamView.symbol.StandardSymbolChooser;
import PamView.symbol.StandardSymbolManager;
import PamView.symbol.SymbolData;
import PamguardMVC.PamDataBlock;
import dataPlots.data.SimpleSymbolChooser;
import loggerForms.FormsDataBlock;
public class LoggerSymbolChooser extends StandardSymbolChooser {
private FormsDataBlock formsDataBlock;
public LoggerSymbolChooser(StandardSymbolManager standardSymbolManager, FormsDataBlock pamDataBlock,
String displayName, SymbolData defaultSymbol, GeneralProjector projector) {
super(standardSymbolManager, pamDataBlock, displayName, defaultSymbol, projector);
this.formsDataBlock = pamDataBlock;
}
}

View File

@ -0,0 +1,130 @@
package loggerForms.symbol;
import PamView.GeneralProjector;
import PamView.PamSymbol;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.PamSymbolManager;
import PamView.symbol.StandardSymbolChooser;
import PamView.symbol.StandardSymbolManager;
import PamView.symbol.SymbolData;
import PamView.symbol.modifier.SymbolModType;
import PamguardMVC.PamDataBlock;
import loggerForms.FormDescription;
import loggerForms.FormsDataBlock;
import loggerForms.LoggerFormGraphics;
import loggerForms.PropertyDescription;
import loggerForms.PropertyTypes;
import loggerForms.controlDescriptions.ControlDescription;
import loggerForms.formdesign.FormList;
import loggerForms.formdesign.propertypanels.SymbolPanel;
public class LoggerSymbolManager extends StandardSymbolManager {
private FormsDataBlock formsDataBlock;
private SymbolData standardFormSymbol;
public LoggerSymbolManager(FormsDataBlock pamDataBlock) {
super(pamDataBlock, LoggerFormGraphics.defaultSymbol);
this.formsDataBlock = pamDataBlock;
}
@Override
protected LoggerSymbolChooser createSymbolChooser(String displayName, GeneralProjector projector) {
return new LoggerSymbolChooser(this, formsDataBlock, displayName, getDefaultSymbol(), projector);
}
@Override
public SymbolData getDefaultSymbol() {
/**
* the default default is a generic one for logger data. See if it is overridden by a symbol
* specified for the form.
*/
SymbolData formSymbol = getFormSymbol();
if (formSymbol != null) {
return formSymbol;
}
else {
return super.getDefaultSymbol();
}
}
/**
* Get the default symbol for the form. Might be null,
* though might have been set in the form properties.
* @return
*/
public SymbolData getFormSymbol() {
if (standardFormSymbol == null) {
FormDescription formDescription = formsDataBlock.getFormDescription();
PropertyDescription formProperty = formDescription.findProperty(PropertyTypes.SYMBOLTYPE);
if (formProperty == null) {
return null;
}
PamSymbol symbol = SymbolPanel.createSymbol(formProperty.getItemInformation());
if (symbol != null) {
standardFormSymbol = symbol.getSymbolData();
}
}
return standardFormSymbol;
}
@Override
public void addSymbolModifiers(PamSymbolChooser psc) {
// probably don't want the standard ones.
// super.addSymbolModifiers(psc);
/*
* now add symbol modifiers for each control in the form.
* This will primarily be lookups which should have defined colours.
* May be able to do other controls based on their type / null / >0 values.
* Focus on lut's for now.
*/
FormDescription formDescription = formsDataBlock.getFormDescription();
FormList<ControlDescription> ctrls = formDescription.getControlDescriptions();
for (ControlDescription ctrlDescription : ctrls) {
LoggerSymbolModifier modifier = createSymbolModifier(formDescription, ctrlDescription, psc);
if (modifier != null) {
psc.addSymbolModifier(modifier);
}
}
}
private LoggerSymbolModifier createSymbolModifier(FormDescription formDescription,
ControlDescription ctrlDescription, PamSymbolChooser psc) {
switch (ctrlDescription.getEType()) {
case CHAR:
break;
case CHECKBOX:
break;
case COUNTER:
return new IntegerSymbolModifier(formDescription, ctrlDescription, psc, SymbolModType.FILLCOLOUR | SymbolModType.LINECOLOUR);
case DOUBLE:
break;
case INTEGER:
return new IntegerSymbolModifier(formDescription, ctrlDescription, psc, SymbolModType.FILLCOLOUR | SymbolModType.LINECOLOUR);
case LATLONG:
break;
case LOOKUP:
return new LookupSymbolModifier(formDescription, ctrlDescription, psc, SymbolModType.EVERYTHING);
case NMEACHAR:
break;
case NMEAFLOAT:
break;
case NMEAINT:
break;
case SHORT:
return new IntegerSymbolModifier(formDescription, ctrlDescription, psc, SymbolModType.FILLCOLOUR | SymbolModType.LINECOLOUR);
case SINGLE:
break;
case STATIC:
break;
case TIME:
break;
case TIMESTAMP:
break;
default:
break;
}
return null;
}
}

View File

@ -0,0 +1,66 @@
package loggerForms.symbol;
import PamView.GeneralProjector;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData;
import PamView.symbol.modifier.SymbolModifier;
import PamguardMVC.PamDataUnit;
import loggerForms.FormDescription;
import loggerForms.FormsDataUnit;
import loggerForms.controlDescriptions.ControlDescription;
abstract public class LoggerSymbolModifier extends SymbolModifier {
protected FormDescription formDescription;
protected ControlDescription controlDescription;
protected int controlIndex;
public LoggerSymbolModifier(FormDescription formDescription, ControlDescription controlDescription,
PamSymbolChooser symbolChooser, int modifyableBits) {
super(controlDescription.getTitle(), symbolChooser, modifyableBits);
this.formDescription = formDescription;
this.controlDescription = controlDescription;
controlIndex = formDescription.getControlIndex(controlDescription);
}
/**
* Get the data object for this control from the data unit.
* @param dataUnit
* @return
*/
public Object getControlData(PamDataUnit dataUnit) {
if (dataUnit instanceof FormsDataUnit == false) {
return null;
}
FormsDataUnit formDataUnit = (FormsDataUnit) dataUnit;
Object[] data = formDataUnit.getFormData();
if (data == null || data.length <= controlIndex || controlIndex < 0) {
return null;
}
return data[controlIndex];
}
/**
* @return the formDescription
*/
protected FormDescription getFormDescription() {
return formDescription;
}
/**
* @return the controlDescription
*/
protected ControlDescription getControlDescription() {
return controlDescription;
}
/**
* @return the controlIndex
*/
protected int getControlIndex() {
return controlIndex;
}
}

View File

@ -0,0 +1,42 @@
package loggerForms.symbol;
import PamView.GeneralProjector;
import PamView.PamSymbol;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData;
import PamguardMVC.PamDataUnit;
import generalDatabase.lookupTables.LookupItem;
import generalDatabase.lookupTables.LookupList;
import loggerForms.FormDescription;
import loggerForms.FormsDataUnit;
import loggerForms.controlDescriptions.CdLookup;
import loggerForms.controlDescriptions.ControlDescription;
public class LookupSymbolModifier extends LoggerSymbolModifier {
public LookupSymbolModifier(FormDescription formDescription, ControlDescription controlDescription,
PamSymbolChooser symbolChooser, int modifyableBits) {
super(formDescription, controlDescription, symbolChooser, modifyableBits);
}
@Override
public SymbolData getSymbolData(GeneralProjector projector, PamDataUnit dataUnit) {
Object data = getControlData(dataUnit);
if (data == null) {
return null;
}
LookupList lutList = ((CdLookup)controlDescription).getLookupList();
int lutIndex = lutList.indexOfCode(data.toString());
LookupItem lutItem = lutList.getLookupItem(lutIndex);
if (lutItem == null) {
return null;
}
PamSymbol symbol = lutItem.getSymbol();
if (symbol == null) {
return null;
}
return symbol.getSymbolData();
}
}

View File

@ -0,0 +1,103 @@
package ravendata;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import javax.swing.JMenuItem;
import Acquisition.AcquisitionControl;
import PamController.InputStoreInfo;
import PamController.PamConfiguration;
import PamController.PamControlledUnit;
import PamController.PamControlledUnitSettings;
import PamController.PamController;
import PamController.PamSettingManager;
import PamController.PamSettings;
import PamView.dialog.warn.WarnOnce;
import pamViewFX.PamSettingsMenuPane;
import ravendata.swing.RavenImportDialog;
/**
* System for importing and displaying data from Raven selection tables.
* @author dg50
*
*/
public class RavenControl extends PamControlledUnit implements PamSettings {
private RavenProcess ravenProcess;
private static final String unitType = "Raven Import";
public static final String defaultName = unitType;
private RavenParameters ravenParameters = new RavenParameters();
public RavenControl(String unitName) {
super(unitType, unitName);
this.ravenProcess = new RavenProcess(this);
addPamProcess(ravenProcess);
PamSettingManager.getInstance().registerSettings(this);
}
public RavenControl(PamConfiguration pamConfiguration, String unitType, String unitName) {
super(pamConfiguration, unitType, unitName);
}
@Override
public JMenuItem createDetectionMenu(Frame parentFrame) {
JMenuItem menuItem = new JMenuItem("Import Raven data ...");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
importData(parentFrame);
}
});
return menuItem;
}
protected void importData(Frame parentFrame) {
RavenParameters newParams = RavenImportDialog.showDialog(parentFrame, ravenParameters);
if (newParams == null) {
return;
}
ravenParameters = newParams;
// import the data. 1. Check for existing and delete, 2. Import, 3. rebuild datamap, 4. load data
RavenFileReader fileReader = null;
ArrayList<RavenDataRow> ravenData = null;
try {
fileReader = new RavenFileReader(this, ravenParameters.importFile);
ravenData = fileReader.readTable();
fileReader.closeFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
if (ravenData != null) {
ravenProcess.createPAMGuardData(fileReader, ravenData);
}
}
@Override
public Serializable getSettingsReference() {
return ravenParameters;
}
@Override
public long getSettingsVersion() {
return RavenParameters.serialVersionUID;
}
@Override
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
ravenParameters = (RavenParameters) pamControlledUnitSettings.getSettings();
return true;
}
}

View File

@ -0,0 +1,16 @@
package ravendata;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess;
public class RavenDataBlock extends PamDataBlock<RavenDataUnit> {
private RavenProcess ravenProcess;
public RavenDataBlock(RavenProcess parentProcess, int channelMap) {
super(RavenDataUnit.class, "Selection", parentProcess, channelMap);
this.ravenProcess = parentProcess;
}
}

View File

@ -0,0 +1,159 @@
package ravendata;
public class RavenDataRow {
private int iRow;
private String[] data;
private Integer selection;
private String view;
private Integer channel;
private double beginT;
private double endT;
private double f1;
private double f2;
private int[] dataIndexes;
private boolean unpackOK;
// data on a row of raven data from a table.
public RavenDataRow(int iRow, String[] data, int[] dataIndexes) {
this.iRow = iRow;
this.data = data;
this.dataIndexes = dataIndexes;
unpackOK = unpackRow(dataIndexes);
}
/**
* @return the iRow
*/
protected int getiRow() {
return iRow;
}
/**
* @return the data
*/
protected String[] getData() {
return data;
}
/**
* Get a String value from the given column.
* @param iCol
* @return
*/
public String getString(int iCol) {
return data[iCol];
}
/**
* Read an Integer value from the given column.
* @param iCol
* @return
*/
public Integer getInteger(int iCol) {
try {
return Integer.valueOf(data[iCol]);
}
catch (NumberFormatException e) {
return null;
}
}
/**
* Read a double value from the given column.
* @param iCol
* @return
*/
public Double getDouble(int iCol) {
try {
return Double.valueOf(data[iCol]);
}
catch (NumberFormatException e) {
return null;
}
}
/**
* Unpack the row into more useful columns using the column indexes.
* @param mainIndexes
* @return
*/
private boolean unpackRow(int[] mainIndexes) {
try {
selection = getInteger(mainIndexes[0]);
view = getString(mainIndexes[1]);
channel = getInteger(mainIndexes[2]);
beginT = getDouble(mainIndexes[3]);
endT = getDouble(mainIndexes[4]);
f1 = getDouble(mainIndexes[5]);
f2 = getDouble(mainIndexes[6]);
}
catch (Exception e) {
return false;
}
return true;
}
/**
* @return the selection
*/
protected Integer getSelection() {
return selection;
}
/**
* @return the view
*/
protected String getView() {
return view;
}
/**
* @return the channel
*/
protected Integer getChannel() {
return channel;
}
/**
* @return the beginT
*/
protected double getBeginT() {
return beginT;
}
/**
* @return the endT
*/
protected double getEndT() {
return endT;
}
/**
* @return the f1
*/
protected double getF1() {
return f1;
}
/**
* @return the f2
*/
protected double getF2() {
return f2;
}
/**
* @return the dataIndexes
*/
protected int[] getDataIndexes() {
return dataIndexes;
}
/**
* @return the unpackOK
*/
protected boolean isUnpackOK() {
return unpackOK;
}
}

View File

@ -0,0 +1,20 @@
package ravendata;
import PamDetection.PamDetection;
import PamguardMVC.AcousticDataUnit;
import PamguardMVC.DataUnitBaseData;
import PamguardMVC.PamDataUnit;
public class RavenDataUnit extends PamDataUnit implements AcousticDataUnit, PamDetection {
public RavenDataUnit(long timeMilliseconds, int channelMap, long durationMillis, double f1, double f2) {
super(timeMilliseconds);
setChannelBitmap(channelMap);
setDurationInMilliseconds(durationMillis);
double[] freq = {f1, f2};
setFrequency(freq);
}
}

View File

@ -0,0 +1,101 @@
package ravendata;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class RavenFileReader {
private RavenControl ravenControl;
private File ravenFile;
private ArrayList<String> columnNames;
private BufferedReader fileReader;
private static String[] standardColumns = {"Selection", "View", "Channel", "Begin Time (s)", "End Time (s)", "Low Freq (Hz)", "High Freq (Hz)"};
// private static String[] otherColumns = {"Selection", "View", "Channel", "Begin Time (s)", "End Time (s)", "end", "Low Freq (Hz)", "High Freq (Hz)",
// "Begin File", "Delta Time (s)", "File Offset (s)", "Occupancy", "Manual Review", "Notes", "SongNumber"};
/*
* Sometimes some names appear in different places. Bugger.
* so need to find the index of each of the main columns we want.
*/
private int[] mainIndexes;
private int columnErrors;
public RavenFileReader(RavenControl ravenControl, String ravenFile) throws IOException {
this.ravenControl = ravenControl;
this.ravenFile = new File(ravenFile);
openFile();
}
public void closeFile() throws IOException {
if (fileReader != null) {
fileReader.close();
}
}
/**
* open the file, read the file header and get a list of column names.
* @throws IOException
*/
private void openFile() throws IOException {
fileReader = new BufferedReader(new FileReader(ravenFile));
String firstLine = fileReader.readLine();
if (firstLine == null) {
throw new IOException("Empty file");
}
String[] cols = firstLine.split("\t");
columnNames = new ArrayList<>();
for (int i = 0; i < cols.length; i++) {
columnNames.add(cols[i]);
}
checkColumnNames();
}
public ArrayList<RavenDataRow> readTable() throws IOException {
ArrayList<RavenDataRow> allData = new ArrayList();
int iRow = 0;
while(true) {
String aLine = fileReader.readLine();
if (aLine == null) {
break;
}
String[] split = aLine.split("\t");
RavenDataRow aRow = new RavenDataRow(iRow++, split, mainIndexes);
allData.add(aRow);
}
return allData;
}
/**
* Check we have the correct standard columns.
*/
private int checkColumnNames() {
mainIndexes = new int[standardColumns.length];
columnErrors = 0;
for (int i = 0; i < standardColumns.length; i++) {
mainIndexes[i] = columnNames.indexOf(standardColumns[i]);
if (mainIndexes[i] < 0) {
System.out.printf("Raven error: Unable to find column \"%s\" in data table\n", standardColumns[i]);
columnErrors++;
}
}
return columnErrors;
}
public boolean exists() {
return ravenFile.exists();
}
/**
* get a count of column errors.
* @return the columnErrors
*/
protected int getColumnErrors() {
return columnErrors;
}
}

View File

@ -0,0 +1,30 @@
package ravendata;
import PamDetection.AcousticSQLLogging;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import generalDatabase.PamTableItem;
import generalDatabase.SQLLogging;
import generalDatabase.SQLTypes;
public class RavenLogging extends AcousticSQLLogging {
private RavenDataBlock ravenDataBlock;
private RavenControl ravenControl;
private PamTableItem f1;
public RavenLogging(RavenControl ravenControl, RavenDataBlock pamDataBlock) {
super(pamDataBlock, ravenControl.getUnitName());
this.ravenControl = ravenControl;
this.ravenDataBlock = pamDataBlock;
}
@Override
protected PamDataUnit createDataUnit(SQLTypes sqlTypes, long timeMilliseconds, int chanMap, long duration,
double[] f) {
return new RavenDataUnit(timeMilliseconds, chanMap, duration, f[0], f[1]);
}
}

View File

@ -0,0 +1,10 @@
package ravendata;
import java.io.Serializable;
public class RavenParameters implements Serializable, Cloneable {
public static final long serialVersionUID = 1L;
public String importFile;
}

View File

@ -0,0 +1,130 @@
package ravendata;
import java.awt.Color;
import java.util.ArrayList;
import Acquisition.AcquisitionControl;
import PamController.InputStoreInfo;
import PamController.PamController;
import PamView.PamSymbolType;
import PamView.dialog.warn.WarnOnce;
import PamView.symbol.StandardSymbolManager;
import PamView.symbol.SymbolData;
import PamguardMVC.PamProcess;
import dataMap.OfflineDataMap;
import generalDatabase.DBControlUnit;
import ravendata.swing.RavenGraphics;
public class RavenProcess extends PamProcess {
private RavenControl ravenControl;
private RavenDataBlock ravenDataBlock;
private RavenLogging ravenLogging;
private static SymbolData standardSymbol = new SymbolData(PamSymbolType.SYMBOL_SQUARE, 20, 20, false, Color.white, Color.red);
public RavenProcess(RavenControl pamControlledUnit) {
super(pamControlledUnit, null);
this.ravenControl = pamControlledUnit;
ravenDataBlock = new RavenDataBlock(this, 0);
addOutputDataBlock(ravenDataBlock);
ravenLogging = new RavenLogging(pamControlledUnit, ravenDataBlock);
ravenDataBlock.SetLogging(ravenLogging);
ravenDataBlock.setOverlayDraw(new RavenGraphics(ravenDataBlock));
ravenDataBlock.setPamSymbolManager(new StandardSymbolManager(ravenDataBlock, standardSymbol));
}
@Override
public void pamStart() {
// TODO Auto-generated method stub
}
@Override
public void pamStop() {
// TODO Auto-generated method stub
}
protected void createPAMGuardData(RavenFileReader fileReader, ArrayList<RavenDataRow> ravenData) {
/**
* Need to find the acquisition module and then get detailed times of every file, not just
* the datamap, which is currently just a normal databsae map of the db entries, so it not
* necessarily precise on the starts / ends of files for the viewer.
*/
AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
if (daqControl == null) {
WarnOnce.showWarning("No acquisition module", "Can only import ROCCA data if there is a Sound Acquisition Module",
WarnOnce.WARNING_MESSAGE);
return;
}
// need to get the detailed data map.
InputStoreInfo daqInfo = daqControl.getStoreInfo(true);
if (daqInfo == null || daqInfo.getAllFileEnds() == null || daqInfo.getAllFileEnds().length == 0) {
WarnOnce.showWarning("No sound file info module", "Can only import ROCCA data if sound files arre present to extract absolute times",
WarnOnce.WARNING_MESSAGE);
return;
}
// need these to look for gaps to convert ROCCA time to abs time.
long[] fileStarts = daqInfo.getFileStartTimes();
long[] fileEnds = daqInfo.getAllFileEnds();
// make an array of absolute times to match to ROCCA data.
// these are the end times of each file (start of first file is known to be 0).
long[] absTime = new long[fileStarts.length+1]; // one longer to capture end of last file.
for (int i = 0; i < fileStarts.length; i++) {
absTime[i+1] = absTime[i] + fileEnds[i]-fileStarts[i];
}
// delete all existing data from database.
ravenDataBlock.clearAll();
ravenLogging.deleteData(0, System.currentTimeMillis()*2);
for (RavenDataRow ravenRow : ravenData) {
int fileInd = getTimeIndex(ravenRow.getBeginT()*1000, absTime);
if (fileInd == absTime.length) {
String msg = String.format("Data at time %6.4f is beyond the end of available sound file data", ravenRow.getBeginT());
WarnOnce.showWarning("Error importing RAVEN data", msg, WarnOnce.WARNING_MESSAGE);
break;
}
long fileStart = fileStarts[fileInd];
long absStart = fileStart + (long) (ravenRow.getBeginT()*1000.)-absTime[fileInd];
long duration = (long) ((ravenRow.getEndT()-ravenRow.getBeginT())*1000.);
int chanMap = 1<<(ravenRow.getChannel()-1);
RavenDataUnit rdu = new RavenDataUnit(absStart, chanMap, duration, ravenRow.getF1(), ravenRow.getF2());
getRavenDataBlock().addPamData(rdu);
ravenLogging.logData(DBControlUnit.findConnection(), rdu);
}
OfflineDataMap dataMap = ravenDataBlock.getPrimaryDataMap();
// dataMap.c
DBControlUnit dbControl = DBControlUnit.findDatabaseControl();
if (dbControl != null) {
dbControl.createOfflineDataMap(ravenControl.getGuiFrame(), ravenControl);
}
dataMap = ravenDataBlock.getPrimaryDataMap();
}
/**
* Find which file time bin the raven data are in
* @param ravenTime
* @param absTimes
* @return
*/
private int getTimeIndex(double ravenTime, long[] absTimes) {
int i = 0;
while (i < absTimes.length-1 && ravenTime > absTimes[i+1]) {
i++;
}
return i;
}
/**
* @return the ravenDataBlock
*/
public RavenDataBlock getRavenDataBlock() {
return ravenDataBlock;
}
}

View File

@ -0,0 +1,18 @@
package ravendata.swing;
import java.awt.Color;
import PamView.PamDetectionOverlayGraphics;
import PamView.PamSymbol;
import PamView.PamSymbolType;
import PamguardMVC.PamDataBlock;
public class RavenGraphics extends PamDetectionOverlayGraphics {
public static final PamSymbol defaultSymbol = new PamSymbol(PamSymbolType.SYMBOL_SQUARE,12, 12, false, Color.white, Color.red);
public RavenGraphics(PamDataBlock parentDataBlock) {
super(parentDataBlock, defaultSymbol);
}
}

View File

@ -0,0 +1,111 @@
package ravendata.swing;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import PamUtils.PamFileChooser;
import PamUtils.PamFileFilter;
import PamView.dialog.PamDialog;
import PamView.dialog.PamGridBagContraints;
import PamView.panel.PamAlignmentPanel;
import ravendata.RavenParameters;
public class RavenImportDialog extends PamDialog {
private static RavenImportDialog singleInstance;
private RavenParameters ravenParameters;
private JTextField ravenFile;
private JButton chooseButton;
private RavenImportDialog(Window parentFrame) {
super(parentFrame, "Import Raven Data", false);
JPanel mainPanel = new JPanel(new GridBagLayout());
mainPanel.setBorder(new TitledBorder("Choose Raven selection table"));
GridBagConstraints c = new PamGridBagContraints();
ravenFile = new JTextField(80);
ravenFile.setEditable(false);
chooseButton = new JButton("Select ...");
c.gridwidth = 2;
mainPanel.add(ravenFile, c);
c.gridy++;
mainPanel.add(new PamAlignmentPanel(chooseButton, BorderLayout.EAST), c);
chooseButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
chooseFile(e);
}
});
setDialogComponent(mainPanel);
}
protected void chooseFile(ActionEvent e) {
PamFileFilter fileFilter = new PamFileFilter("Raven files", ".txt");
// fileFilter.
PamFileChooser chooser = new PamFileChooser(ravenParameters.importFile);
chooser.setFileFilter(fileFilter);
int ans = chooser.showDialog(this, "Select ...");
if (ans == JFileChooser.APPROVE_OPTION) {
File f = chooser.getSelectedFile();
if (f != null) {
ravenFile.setText(f.getAbsolutePath());
}
}
}
public static RavenParameters showDialog(Window parentFrame, RavenParameters ravenParameters) {
// if (singleInstance == null) {
singleInstance = new RavenImportDialog(parentFrame);
// }
singleInstance.setParams(ravenParameters);
singleInstance.setVisible(true);
return singleInstance.ravenParameters;
}
private void setParams(RavenParameters ravenParameters) {
this.ravenParameters = ravenParameters;
ravenFile.setText(ravenParameters.importFile);
}
@Override
public boolean getParams() {
String fn = ravenFile.getText();
if (fn == null) {
return showWarning("Error - No file selected");
}
File f = new File(fn);
if (f.exists() == false) {
String str = String.format("The file %s does not exist", fn);
return showWarning(str);
}
ravenParameters.importFile = fn;
return true;
}
@Override
public void cancelButtonPressed() {
this.ravenParameters = null;
}
@Override
public void restoreDefaultSettings() {
// TODO Auto-generated method stub
}
}

View File

@ -3,6 +3,7 @@ package targetMotionOld;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
@ -17,12 +18,17 @@ import javax.swing.SwingWorker;
import pamScrollSystem.AbstractScrollManager;
import pamScrollSystem.ViewerScrollerManager;
import targetMotionModule.TargetMotionLocaliserProvider;
import targetMotionOld.algorithms.LeastSquaresNew;
import targetMotionOld.algorithms.Simplex2DNew;
import targetMotionOld.algorithms.Simplex3DNew;
import targetMotionOld.dialog.TargetMotionDialog;
import targetMotionOld.tethys.TMALocalizationCreator;
import tethys.localization.LocalizationCreator;
import GPS.GPSDataBlock;
import GPS.GpsDataUnit;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.algorithms.timeDelayLocalisers.bearingLoc.AbstractLocaliser;
import Localiser.detectionGroupLocaliser.DetectionGroupOptions;
import Localiser.detectionGroupLocaliser.GroupDetection;
@ -32,12 +38,14 @@ import PamController.PamControlledUnit;
import PamController.PamController;
import PamController.PamControllerInterface;
import PamDetection.AbstractLocalisation;
import PamDetection.LocContents;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamObservable;
import PamguardMVC.PamObserver;
import PamguardMVC.PamObserverAdapter;
import PamguardMVC.debug.Debug;
import bearinglocaliser.BearingLocaliserParams;
/**
* Reinstated Target motion add-in as used by the click detector. Hope one day still to replace this
@ -46,7 +54,7 @@ import PamguardMVC.debug.Debug;
*
* @param <T>
*/
public class TargetMotionLocaliser<T extends GroupDetection> extends AbstractLocaliser<T> {
public class TargetMotionLocaliser<T extends GroupDetection> extends AbstractLocaliser<T> implements LocalisationAlgorithm, LocalisationAlgorithmInfo {
public enum Interractive {START, SAVE, BACK, CANCEL, SETNULL, KEEPOLD};
// public enum WorkStatus {IDLE, LOADING, WAITING};
@ -77,6 +85,7 @@ public class TargetMotionLocaliser<T extends GroupDetection> extends AbstractLoc
public int currentEventIndex;
// private T currentEvent;
//private WorkStatus workStatus;
private TMALocalizationCreator tmaLocalizationCreator;
public TargetMotionLocaliser(PamControlledUnit pamControlledUnit, PamDataBlock<T> dataBlock, PamDataBlock subDetectionBlock) {
super(dataBlock);
@ -97,6 +106,11 @@ public class TargetMotionLocaliser<T extends GroupDetection> extends AbstractLoc
return "Target Motion Localiser";
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public boolean localiseDataUnit(T dataUnit) {
// TODO Auto-generated method stub
@ -719,4 +733,30 @@ public class TargetMotionLocaliser<T extends GroupDetection> extends AbstractLoc
return null;
}
}
@Override
public int getLocalisationContents() {
return LocContents.HAS_LATLONG | LocContents.HAS_AMBIGUITY | LocContents.HAS_DEPTH;
}
@Override
public String getAlgorithmName() {
return "Target Motion Localiser";
}
@Override
public LocalizationCreator getTethysCreator() {
if (tmaLocalizationCreator == null) {
tmaLocalizationCreator = new TMALocalizationCreator(this);
}
return tmaLocalizationCreator;
}
@Override
public Serializable getParameters() {
// TODO Auto-generated method stub
// return new BearingLocaliserParams();
return null;
}
}

View File

@ -73,8 +73,7 @@ public class LeastSquaresNew<T extends GroupDetection> extends AbstractTargetMot
@Override
public LocContents getLocContents() {
// TODO Auto-generated method stub
return null;
return new LocContents(LocContents.HAS_LATLONG | LocContents.HAS_PERPENDICULARERRORS);
}
@Override

View File

@ -61,8 +61,7 @@ public class Simplex2DNew<T extends GroupDetection> extends AbstractTargetMotion
@Override
public LocContents getLocContents() {
// TODO Auto-generated method stub
return null;
return new LocContents(LocContents.HAS_LATLONG | LocContents.HAS_PERPENDICULARERRORS);
}
@Override

View File

@ -35,8 +35,7 @@ public class Simplex3DNew<T extends GroupDetection> extends Simplex2DNew<T>{
@Override
public LocContents getLocContents() {
// TODO Auto-generated method stub
return null;
return new LocContents(LocContents.HAS_LATLONG | LocContents.HAS_DEPTH | LocContents.HAS_DEPTHERROR | LocContents.HAS_PERPENDICULARERRORS);
}
}

View File

@ -0,0 +1,181 @@
package targetMotionOld.tethys;
import java.util.List;
import Localiser.LocaliserModel;
import Localiser.algorithms.locErrors.EllipticalError;
import Localiser.algorithms.locErrors.LocaliserError;
import Localiser.detectionGroupLocaliser.GroupLocResult;
import Localiser.detectionGroupLocaliser.GroupLocalisation;
import PamDetection.AbstractLocalisation;
import PamDetection.LocContents;
import PamUtils.LatLong;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import nilus.AngularCoordinateType;
import nilus.LocalizationType;
import nilus.Localize;
import nilus.WGS84CoordinateType;
import nilus.LocalizationType.Angular;
import nilus.LocalizationType.Parameters;
import nilus.LocalizationType.WGS84;
import nilus.LocalizationType.Parameters.TargetMotionAnalysis;
import nilus.Localize.Effort;
import nilus.Localize.Effort.CoordinateReferenceSystem;
import pamMaths.PamVector;
import targetMotionOld.TargetMotionLocaliser;
import tethys.TethysTimeFuncs;
import tethys.localization.CoordinateName;
import tethys.localization.LocalizationBuilder;
import tethys.localization.LocalizationCreator;
import tethys.localization.LocalizationSubTypes;
import tethys.localization.LocalizationTypes;
import tethys.localization.ReferenceFrame;
import tethys.localization.TimeReference;
import tethys.pamdata.AutoTethysProvider;
public class TMALocalizationCreator implements LocalizationCreator {
int maxDimension = 2;
public TMALocalizationCreator(TargetMotionLocaliser targetMotionLocaliser) {
// TODO Auto-generated constructor stub
}
@Override
public boolean sortLocalisationCoordinates(LocalizationBuilder localizationBuilder, PamDataBlock dataBlock) {
Localize doc = localizationBuilder.getCurrentDocument();
Effort locEffort = doc.getEffort();
locEffort.setTimeReference(TimeReference.beam.toString());
List<String> locTypes = locEffort.getLocalizationType();
locTypes.add(LocalizationTypes.Point.toString());
locTypes.add(LocalizationTypes.PerpendicularRange.toString());
CoordinateReferenceSystem coordRefs = locEffort.getCoordinateReferenceSystem();
coordRefs.setName(CoordinateName.WGS84.toString());
coordRefs.setSubtype(LocalizationSubTypes.Geographic.toString());
locEffort.setDimension(2);
return true;
}
@Override
public LocalizationType createLocalization(LocalizationBuilder localizationBuilder, PamDataUnit dataUnit) {
/*
* Add two types of localisation. A WGS84 and a perpendicular range.
*/
AbstractLocalisation pamLoc = dataUnit.getLocalisation();
LatLong latLong = pamLoc.getLatLong(0);
if (pamLoc instanceof GroupLocalisation == false || latLong == null) {
return localizationBuilder.createStandardLocalization(dataUnit);
}
LocalizationType loc = localizationBuilder.makeBaseLoc(dataUnit);
GroupLocalisation groupLoc = (GroupLocalisation) pamLoc;
GroupLocResult groupLocResult = groupLoc.getGroupLocaResult(0);
LocaliserModel tmaModel = groupLocResult.getModel();
boolean hasDepth = false;
LocContents locCont = new LocContents(LocContents.HAS_LATLONG);
if (tmaModel != null) {
locCont = tmaModel.getLocContents();
if (locCont.hasLocContent(LocContents.HAS_DEPTH)) {
hasDepth = true;
}
}
int nDim = hasDepth ? 3 : 2;
maxDimension = Math.max(maxDimension, nDim);
/**
* Export the latlong data.
*/
WGS84 wgs84 = new WGS84();
WGS84CoordinateType coord = new WGS84CoordinateType();
wgs84.setCoordinate(coord);
coord.setLongitude(latLong.getLongitude());
coord.setLatitude(latLong.getLatitude());
if (hasDepth) {
coord.setElevationM(AutoTethysProvider.roundDecimalPlaces(latLong.getHeight(),3));
}
PamVector errors = groupLocResult.getErrorVector();
LocaliserError genError = groupLocResult.getLocError();
WGS84CoordinateType wgsErr = null;
double[] errorVec = null;
if (errors != null) {
errorVec = errors.getVector();
}
else if (genError instanceof EllipticalError) {
EllipticalError elliptical = (EllipticalError) genError;
PamVector dir = genError.getErrorDirection();
// these are errors perpendicular and parallel to the track
// so aren't really lat long errors.
errorVec = elliptical.getEllipseDim();
}
/*
* Needs a bit of work to get errors in correct direction (needs import
* of track data for this value ?) and conversion to latlong units.
*/
// if (errorVec != null && errorVec.length >= 2) {
// wgsErr = new WGS84CoordinateType();
// wgsErr.setLongitude(errorVec[0]);
// wgsErr.setLatitude(errorVec[1]);
// if (hasDepth && errorVec.length >= 3) {
// wgsErr.setElevationM(errorVec[2]);
// }
// wgs84.setCoordinateError(wgsErr);
// }
loc.setWGS84(wgs84);
// set the TMA information
Parameters params = loc.getParameters();
if (params == null) {
params = new Parameters();
loc.setParameters(params);
}
TargetMotionAnalysis tma = new TargetMotionAnalysis();
tma.setStart(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getTimeMilliseconds()));
tma.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getEndTimeInMilliseconds()));
params.setTargetMotionAnalysis(tma);
Long timeAbeam = groupLocResult.getBeamTime();
if (timeAbeam != null) {
loc.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(timeAbeam));
}
// now also output a perpendicular distance.
Double perp = groupLocResult.getPerpendicularDistance();
if (perp != null) {
loc.setPerpendicularRangeM(perp);
}
// con only output one type.
// if (perp != null) {
// AngularCoordinateType acType = new AngularCoordinateType();
// acType.setAngle1(90);
// acType.setDistanceM(AutoTethysProvider.roundDecimalPlaces(perp,1));
// Angular angular = new Angular();
// angular.setCoordinate(acType);
// if (errors != null) {
// AngularCoordinateType angErr = new AngularCoordinateType();
// angErr.setDistanceM(errors.norm());
// angular.setCoordinateError(angErr);
// }
// loc.setAngular(angular);
// }
return loc;
}
@Override
public boolean checkDocument(LocalizationBuilder localizationBuilder) {
boolean ok = localizationBuilder.checkDocument();
Effort locEffort = localizationBuilder.getCurrentDocument().getEffort();
locEffort.setDimension(maxDimension);
return ok;
}
}

View File

@ -1,5 +1,19 @@
package tethys;
import java.util.List;
import PamController.PamControlledUnit;
import PamController.PamguardVersionInfo;
import PamModel.PamPluginInterface;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess;
import nilus.Deployment;
import nilus.DetectionEffort;
import nilus.DetectionEffortKind;
import tethys.niluswraps.PDeployment;
import tethys.output.StreamExportParams;
import tethys.pamdata.TethysDataProvider;
abstract public class CollectionHandler {
private Collection collection;
@ -35,4 +49,93 @@ abstract public class CollectionHandler {
public abstract String getHelpPoint();
/**
* Get the Detection Effort part of a Detections document
* @param pDeployment
* @param dataBlock
* @param exportParams
* @return
*/
public DetectionEffort getDetectorEffort(PDeployment pDeployment, PamDataBlock dataBlock, StreamExportParams exportParams) {
DetectionEffort effort = new DetectionEffort();
Deployment deployment = pDeployment.nilusObject;
Long effortStart = pDeployment.getAudioStart();
Long effortEnd = pDeployment.getAudioEnd();
effort.setStart(TethysTimeFuncs.xmlGregCalFromMillis(effortStart));
effort.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(effortEnd));
// effort.set // no setter for DetectionEffortKind
List<DetectionEffortKind> effortKinds = effort.getKind();
TethysDataProvider dataProvider = dataBlock.getTethysDataProvider(tethysControl);
dataProvider.getEffortKinds(pDeployment, effortKinds, exportParams);
return effort;
}
/**
* Method string for Detections Algorithm documents.
* @param dataBlock
* @return
*/
public String getMethodString(PamDataBlock dataBlock) {
if (dataBlock == null) {
return null;
}
PamProcess process = dataBlock.getParentProcess();
return "PAMGuard " + process.getProcessName();
}
/**
* Software string for Detections Algorithm documents.
* @param dataBlock
* @return
*/
public String getSoftwareString(PamDataBlock dataBlock) {
if (dataBlock == null) {
return null;
}
return dataBlock.getLongDataName();
}
/**
* Software string for Detections Algorithm documents.
* @param dataBlock
* @return
*/
public String getVersionString(PamDataBlock dataBlock) {
if (dataBlock == null) {
return null;
}
PamProcess process = dataBlock.getParentProcess();
PamControlledUnit pcu = process.getPamControlledUnit();
PamPluginInterface plugin = pcu.getPlugin();
if (plugin == null) {
return PamguardVersionInfo.version;
}
else {
return plugin.getVersion();
}
}
/**
*
* @param dataBlock
* @return default value is PAMGuard
*/
public String getSupportSoftware(PamDataBlock dataBlock) {
return "PAMGuard";
}
/**
*
* @param dataBlock
* @return PAMGuard version
*/
public String getSupportSoftwareVersion(PamDataBlock dataBlock) {
// should try to dig into the binary store and get the version from there.
return PamguardVersionInfo.version;
}
}

View File

@ -622,13 +622,15 @@ public class DBXMLQueries {
/**
* Get the names of all detection documents for a given deployment for all data streams.
* @param deploymentId
* Get the names of all the detection or localisation documents for a given deployment id.
* @param collection Localizations or Detetections
* @param deploymentId Deployment document id.
* @return
*/
public ArrayList<String> getDetectionsDocuments(String deploymentId) {
String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}";
public ArrayList<String> getDeploymentDocuments(Collection collection, String deploymentId) {
String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"collectionname/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"collectionname/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}";
String queryStr = queryBase.replace("SomeDeploymentId", deploymentId);
queryStr = queryStr.replace("collectionname", collection.documentName());
DBQueryResult queryResult = null;
try {
queryResult = executeQuery(queryStr);
@ -660,6 +662,86 @@ public class DBXMLQueries {
return detectionDocs;
}
/**
* Get the names of all detection documents for a given deployment for all data streams.
* @param deploymentId
* @return
*/
public ArrayList<String> getDetectionsDocuments(String deploymentId) {
return getDeploymentDocuments(Collection.Detections, deploymentId);
// String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}";
// String queryStr = queryBase.replace("SomeDeploymentId", deploymentId);
// DBQueryResult queryResult = null;
// try {
// queryResult = executeQuery(queryStr);
// } catch (TethysQueryException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// if (queryResult == null || queryResult.queryException != null) {
// return null;
// }
//
// // PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter();
//
// Document doc = convertStringToXMLDocument(queryResult.queryResult);
// if (doc == null) {
// return null;
// }
//
// ArrayList<String> detectionDocs = new ArrayList<>();
//
// NodeList returns = doc.getElementsByTagName("Record");
// if (returns.getLength() == 0) {
// returns = doc.getElementsByTagName("Record");
// }
// for (int i = 0; i < returns.getLength(); i++) {
// Node aNode = returns.item(i);
// detectionDocs.add(aNode.getTextContent());
// }
// return detectionDocs;
}
/**
* Get the names of all localisation documents for a given deployment for all data streams.
* @param deploymentId
* @return
*/
public ArrayList<String> getLocalizationsDocuments(String deploymentId) {
return getDeploymentDocuments(Collection.Localizations, deploymentId);
// String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Localize/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Localize/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}";
// String queryStr = queryBase.replace("SomeDeploymentId", deploymentId);
// DBQueryResult queryResult = null;
// try {
// queryResult = executeQuery(queryStr);
// } catch (TethysQueryException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// if (queryResult == null || queryResult.queryException != null) {
// return null;
// }
//
// // PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter();
//
// Document doc = convertStringToXMLDocument(queryResult.queryResult);
// if (doc == null) {
// return null;
// }
//
// ArrayList<String> detectionDocs = new ArrayList<>();
//
// NodeList returns = doc.getElementsByTagName("Record");
// if (returns.getLength() == 0) {
// returns = doc.getElementsByTagName("Record");
// }
// for (int i = 0; i < returns.getLength(); i++) {
// Node aNode = returns.item(i);
// detectionDocs.add(aNode.getTextContent());
// }
// return detectionDocs;
}
public int countData(PamDataBlock dataBlock, String deploymentId) {
// /**
// * first query for Detections documents associated with this deployment and datablock.

View File

@ -60,7 +60,8 @@ import nilus.Deployment.Data;
import nilus.Deployment.Data.Tracks;
import nilus.Deployment.Data.Tracks.Track;
import nilus.Deployment.Data.Tracks.Track.Point;
import nilus.Deployment.Data.Tracks.Track.Point.BearingDegN;
import nilus.Deployment.Data.Tracks.Track.Point.CourseOverGroundDegN;
import nilus.Deployment.Data.Tracks.Track.Point.HeadingDegN;
import nilus.Deployment.Instrument;
import nilus.Deployment.SamplingDetails;
import nilus.Deployment.Sensors;
@ -890,6 +891,7 @@ public class DeploymentHandler extends CollectionHandler implements TethysStateO
tracks = new Tracks();
deployment.getData().setTracks(tracks);
}
tracks.setSpeedUnit("kn");
List<Track> trackList = tracks.getTrack(); // lists are usually there.
Track aTrack = new Track();
@ -909,13 +911,32 @@ public class DeploymentHandler extends CollectionHandler implements TethysStateO
gpsPoint.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(gpsDataUnit.getTimeMilliseconds()));
gpsPoint.setLatitude(gpsData.getLatitude());
gpsPoint.setLongitude(PamUtils.constrainedAngle(gpsData.getLongitude()));
BearingDegN bdn = gpsPoint.getBearingDegN();
if (bdn == null) {
bdn = new BearingDegN();
gpsPoint.setBearingDegN(bdn);
CourseOverGroundDegN cog = gpsPoint.getCourseOverGroundDegN();
if (cog == null) {
cog = new CourseOverGroundDegN();
gpsPoint.setCourseOverGroundDegN(cog);
}
bdn.setValue(AutoTethysProvider.roundDecimalPlaces(PamUtils.constrainedAngle(gpsData.getHeading()),1));
gpsPoint.setSpeedKn(AutoTethysProvider.roundDecimalPlaces(gpsData.getSpeed(),2));
cog.setValue(PamUtils.constrainedAngle(gpsData.getCourseOverGround()));
cog.setNorth(HeadingTypes.TRUE.toString());
Double trueHead = gpsData.getTrueHeading();
if (trueHead != null && trueHead.isInfinite()) {
HeadingDegN th = new HeadingDegN();
th.setValue(PamUtils.constrainedAngle(trueHead));
th.setNorth(HeadingTypes.TRUE.toString());
gpsPoint.setHeadingDegN(th);
}
else {
// else try magnetic
Double magHead = gpsData.getMagneticHeading();
if (magHead != null && magHead.isInfinite()) {
HeadingDegN mh = new HeadingDegN();
mh.setValue(PamUtils.constrainedAngle(magHead));
mh.setNorth(HeadingTypes.MAGNETIC.toString());
gpsPoint.setHeadingDegN(mh);
}
}
gpsPoint.setSpeedOverGround(AutoTethysProvider.roundDecimalPlaces(gpsData.getSpeed(),2));
points.add(gpsPoint);
lastPointTime = gpsDataUnit.getTimeMilliseconds();

View File

@ -0,0 +1,24 @@
package tethys.deployment;
/**
* Enum of heading types (mostly for track output in Deployment documents)
* @author dg50
*
*/
public enum HeadingTypes {
TRUE, MAGNETIC;
@Override
public String toString() {
switch (this) {
case MAGNETIC:
return "magnetic";
case TRUE:
return "true";
default:
break;
}
return null;
}
}

View File

@ -1,6 +1,5 @@
package tethys.detection;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -14,16 +13,11 @@ import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import PamController.PamControlledUnit;
import PamController.PamController;
import PamController.PamguardVersionInfo;
import PamDetection.LocContents;
import PamDetection.LocalisationInfo;
import PamModel.PamPluginInterface;
import PamUtils.PamCalendar;
import PamView.dialog.PamDialog;
import PamView.dialog.warn.WarnOnce;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamProcess;
import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.superdet.SuperDetDataBlock;
import PamguardMVC.superdet.SuperDetDataBlock.ViewerLoadPolicy;
@ -32,20 +26,12 @@ import dataMap.OfflineDataMapPoint;
import nilus.AlgorithmType;
import nilus.AlgorithmType.SupportSoftware;
import nilus.Localize.Effort;
import nilus.Localize.Effort.CoordinateReferenceSystem;
import nilus.Localize.Effort.ReferencedDocuments;
import nilus.Localize.Effort.ReferencedDocuments.Document;
import nilus.Localize.Localizations;
import nilus.DataSourceType;
import nilus.Deployment;
import nilus.Detection;
import nilus.DetectionEffort;
import nilus.DetectionEffortKind;
import nilus.DetectionGroup;
import nilus.Detections;
import nilus.GranularityEnumType;
import nilus.Helper;
import nilus.Localize;
import tethys.Collection;
import tethys.CollectionHandler;
import tethys.TethysControl;
@ -53,11 +39,8 @@ import tethys.TethysTimeFuncs;
import tethys.dbxml.DBXMLConnect;
import tethys.dbxml.TethysException;
import tethys.deployment.DeploymentHandler;
import tethys.localization.CoordinateName;
import tethys.localization.LocalizationBuilder;
import tethys.localization.LocalizationHandler;
import tethys.localization.LocalizationSubType;
import tethys.localization.LocalizationType;
import tethys.localization.PLocalization;
import tethys.niluswraps.NilusDataWrapper;
import tethys.niluswraps.PDeployment;
import tethys.niluswraps.PDetections;
@ -78,7 +61,6 @@ import tethys.swing.export.DetectionsExportWizard;
public class DetectionsHandler extends CollectionHandler {
public int uniqueDetectionsId=1;
public int uniqueDetectionId;
private volatile boolean activeExport;
@ -134,94 +116,94 @@ public class DetectionsHandler extends CollectionHandler {
}
/**
* Get the Detection Effort part of a Detections document
* @param pDeployment
* @param dataBlock
* @param exportParams
* @return
*/
private DetectionEffort getDetectorEffort(PDeployment pDeployment, PamDataBlock dataBlock, StreamExportParams exportParams) {
DetectionEffort effort = new DetectionEffort();
Deployment deployment = pDeployment.nilusObject;
Long effortStart = pDeployment.getAudioStart();
Long effortEnd = pDeployment.getAudioEnd();
effort.setStart(TethysTimeFuncs.xmlGregCalFromMillis(effortStart));
effort.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(effortEnd));
// effort.set // no setter for DetectionEffortKind
List<DetectionEffortKind> effortKinds = effort.getKind();
TethysDataProvider dataProvider = dataBlock.getTethysDataProvider(tethysControl);
dataProvider.getEffortKinds(pDeployment, effortKinds, exportParams);
return effort;
}
/**
* Method string for Detections Algorithm documents.
* @param dataBlock
* @return
*/
public String getMethodString(PamDataBlock dataBlock) {
if (dataBlock == null) {
return null;
}
PamProcess process = dataBlock.getParentProcess();
return "PAMGuard " + process.getProcessName();
}
/**
* Software string for Detections Algorithm documents.
* @param dataBlock
* @return
*/
public String getSoftwareString(PamDataBlock dataBlock) {
if (dataBlock == null) {
return null;
}
return dataBlock.getLongDataName();
}
/**
* Software string for Detections Algorithm documents.
* @param dataBlock
* @return
*/
public String getVersionString(PamDataBlock dataBlock) {
if (dataBlock == null) {
return null;
}
PamProcess process = dataBlock.getParentProcess();
PamControlledUnit pcu = process.getPamControlledUnit();
PamPluginInterface plugin = pcu.getPlugin();
if (plugin == null) {
return PamguardVersionInfo.version;
}
else {
return plugin.getVersion();
}
}
/**
*
* @param dataBlock
* @return default value is PAMGuard
*/
public String getSupportSoftware(PamDataBlock dataBlock) {
return "PAMGuard";
}
/**
*
* @param dataBlock
* @return PAMGuard version
*/
public String getSupportSoftwareVersion(PamDataBlock dataBlock) {
// should try to dig into the binary store and get the version from there.
return PamguardVersionInfo.version;
}
// /**
// * Get the Detection Effort part of a Detections document
// * @param pDeployment
// * @param dataBlock
// * @param exportParams
// * @return
// */
// private DetectionEffort getDetectorEffort(PDeployment pDeployment, PamDataBlock dataBlock, StreamExportParams exportParams) {
// DetectionEffort effort = new DetectionEffort();
// Deployment deployment = pDeployment.nilusObject;
// Long effortStart = pDeployment.getAudioStart();
// Long effortEnd = pDeployment.getAudioEnd();
// effort.setStart(TethysTimeFuncs.xmlGregCalFromMillis(effortStart));
// effort.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(effortEnd));
// // effort.set // no setter for DetectionEffortKind
// List<DetectionEffortKind> effortKinds = effort.getKind();
//
// TethysDataProvider dataProvider = dataBlock.getTethysDataProvider(tethysControl);
// dataProvider.getEffortKinds(pDeployment, effortKinds, exportParams);
//
//
// return effort;
// }
//
// /**
// * Method string for Detections Algorithm documents.
// * @param dataBlock
// * @return
// */
// public String getMethodString(PamDataBlock dataBlock) {
// if (dataBlock == null) {
// return null;
// }
// PamProcess process = dataBlock.getParentProcess();
// return "PAMGuard " + process.getProcessName();
//
// }
//
// /**
// * Software string for Detections Algorithm documents.
// * @param dataBlock
// * @return
// */
// public String getSoftwareString(PamDataBlock dataBlock) {
// if (dataBlock == null) {
// return null;
// }
// return dataBlock.getLongDataName();
// }
//
// /**
// * Software string for Detections Algorithm documents.
// * @param dataBlock
// * @return
// */
// public String getVersionString(PamDataBlock dataBlock) {
// if (dataBlock == null) {
// return null;
// }
// PamProcess process = dataBlock.getParentProcess();
// PamControlledUnit pcu = process.getPamControlledUnit();
// PamPluginInterface plugin = pcu.getPlugin();
// if (plugin == null) {
// return PamguardVersionInfo.version;
// }
// else {
// return plugin.getVersion();
// }
// }
//
// /**
// *
// * @param dataBlock
// * @return default value is PAMGuard
// */
// public String getSupportSoftware(PamDataBlock dataBlock) {
// return "PAMGuard";
// }
//
// /**
// *
// * @param dataBlock
// * @return PAMGuard version
// */
// public String getSupportSoftwareVersion(PamDataBlock dataBlock) {
// // should try to dig into the binary store and get the version from there.
// return PamguardVersionInfo.version;
// }
/**
* Detections will be exported in a separate worker thread since export may take some time and
@ -418,14 +400,13 @@ public class DetectionsHandler extends CollectionHandler {
ArrayList<PDeployment> deployments = depHandler.getMatchedDeployments();
LocalizationHandler localizationHandler = tethysControl.getLocalizationHandler();
LocalizationBuilder localizationBuilder = null;
/*
* The main documents for both dets and locs.
*/
Detections detectionsDocument = null;
Localize localiseDocument = null;
DetectionGroup onEffortDetections = null;
Localizations localisations = null;
OfflineDataMap dataMap = dataBlock.getPrimaryDataMap();
DataSelector dataSelector = dataBlock.getDataSelector(tethysControl.getDataSelectName(), false);
@ -479,11 +460,10 @@ public class DetectionsHandler extends CollectionHandler {
// onEffortDetections = null;
// detectionList = null;
// }
if (localiseDocument == null && streamExportParams.exportLocalisations) {
localiseDocument = startLocalisationDocument(deployment, detectionsDocument, dataBlock, streamExportParams);
Effort eff = localiseDocument.getEffort();
localiseDocument.getEffort().setStart(TethysTimeFuncs.xmlGregCalFromMillis(deployment.getAudioStart()));
localisations = localiseDocument.getLocalizations();
if (localizationBuilder == null && streamExportParams.exportLocalisations) {
localizationBuilder = new LocalizationBuilder(tethysControl, deployment, detectionsDocument, dataBlock, streamExportParams);
Effort eff = localizationBuilder.getCurrentDocument().getEffort();
eff.setStart(TethysTimeFuncs.xmlGregCalFromMillis(deployment.getAudioStart()));
}
// else {
// localisations = null;
@ -517,11 +497,7 @@ public class DetectionsHandler extends CollectionHandler {
* Localisations don't do granularity, so do all.
*/
if (streamExportParams.exportLocalisations) {
// convert the dets into localisations and add them.
nilus.LocalizationType localization = localizationHandler.createLocalization(localiseDocument, dataBlock, dataUnit, streamExportParams);
if (localization != null) {
localisations.getLocalization().add(localization);
}
localizationBuilder.addLocalization(dataUnit);
}
if (exportCount % 100 == 0) {
@ -552,16 +528,16 @@ public class DetectionsHandler extends CollectionHandler {
}
detectionsDocument = null;
}
if (localiseDocument != null) {
closeLocaliseDocument(localiseDocument, mapPoint.getEndTime());
if (localizationBuilder != null) {
localizationBuilder.closeDocument(mapPoint.getEndTime());
try {
if (checkLocaliseDocument(localiseDocument, granularityHandler)) {
dbxmlConnect.postAndLog(localiseDocument);
if (localizationBuilder.checkDocument()) {
dbxmlConnect.postAndLog(localizationBuilder.getCurrentDocument());
}
} catch (TethysException e) {
tethysControl.showException(e);
}
localiseDocument = null;
localizationBuilder = null;
}
}
@ -598,27 +574,19 @@ public class DetectionsHandler extends CollectionHandler {
}
detectionsDocument = null;
}
if (localiseDocument != null) {
Detection dets[] = granularityHandler.cleanup(deployment.getAudioEnd());
if (dets != null) {
for (int dd = 0; dd < dets.length; dd++) {
exportCount++;
documentCount++;
// localiseDocument.getOnEffort().getDetection().add(dets[dd]);
}
}
prog = new DetectionExportProgress(deployment, detectionsDocument,totalMapPoints, doneMapPoints,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_WRITING);
closeLocaliseDocument(localiseDocument, deployment.getAudioEnd());
prog = new DetectionExportProgress(deployment, detectionsDocument,totalMapPoints, doneMapPoints,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_WRITING);
if (localizationBuilder != null) {
localizationBuilder.closeDocument(deployment.getAudioEnd());
try {
if (checkLocaliseDocument(localiseDocument, granularityHandler)) {
dbxmlConnect.postAndLog(localiseDocument);
if (localizationBuilder.checkDocument()) {
dbxmlConnect.postAndLog(localizationBuilder.getCurrentDocument());
}
} catch (TethysException e) {
tethysControl.showException(e);
tethysControl.showException(e);
}
localizationBuilder = null;
}
localiseDocument = null;
}
}
// prog = new DetectionExportProgress(null, null,totalMapPoints, totalMapPoints,
@ -686,175 +654,6 @@ public class DetectionsHandler extends CollectionHandler {
return detections;
}
private Localize startLocalisationDocument(PDeployment deployment, Detections detectionsDocument, PamDataBlock dataBlock,
StreamExportParams exportParams) {
Localize localisations = new Localize();
try {
Helper.createRequiredElements(localisations);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
return null;
}
Effort eff = localisations.getEffort();
if (eff == null) {
eff = new Effort();
try {
Helper.createRequiredElements(eff);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
return null;
}
localisations.setEffort(eff);
}
if (detectionsDocument != null) {
/*
* add the reference document information.
* Within PAMGuard, this will always be 1:1 with a Detections doc.
*/
ReferencedDocuments refDocs = eff.getReferencedDocuments();
if (refDocs == null) {
refDocs = new ReferencedDocuments();
try {
Helper.createRequiredElements(refDocs);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
eff.setReferencedDocuments(refDocs);
}
Document detectsDoc = new Document();
detectsDoc.setId(detectionsDocument.getId());
detectsDoc.setType(Collection.Detections.collectionName());
detectsDoc.setIndex(BigInteger.ZERO);
eff.getReferencedDocuments().getDocument().add(detectsDoc);
}
TethysDataProvider dataProvider = dataBlock.getTethysDataProvider(tethysControl);
String prefix = deployment.nilusObject.getId() + "_" + dataProvider.getDetectionsName();
String fullId = "";
/*
* Check the document name isn't already used and increment id as necessary.
*/
while (true) {
fullId = String.format("%s_%d", prefix, uniqueDetectionsId++);
if (!tethysControl.getDbxmlQueries().documentExists(Collection.Localizations.toString(), fullId)) {
break;
}
}
localisations.setId(fullId);
// detections.setDescription(dataProvider.getDescription(deployment, tethysExportParams));
localisations.setDescription(exportParams.getNilusDetectionDescription());
DataSourceType dataSource = new DataSourceType();
dataSource.setDeploymentId(deployment.nilusObject.getId());
// dataSource.setEnsembleId(""); ToDo
localisations.setDataSource(dataSource);
AlgorithmType algorithm = localisations.getAlgorithm();
if (dataProvider != null) {
algorithm = dataProvider.getAlgorithm(Collection.Localizations);
// detections.setAlgorithm(algorithm);
}
LocalisationAlgorithm locAlgorithm = dataBlock.getLocalisationAlgorithm();
LocalisationAlgorithmInfo locAlgoinfo = null;
if (locAlgorithm != null) {
locAlgoinfo = locAlgorithm.getAlgorithmInfo();
}
if (locAlgoinfo != null) {
algorithm.setMethod(locAlgoinfo.getAlgorithmName());
}
else {
algorithm.setMethod(getMethodString(dataBlock));
}
algorithm.setSoftware(getSoftwareString(dataBlock));
algorithm.setVersion(getVersionString(dataBlock));
List<SupportSoftware> supSoft = algorithm.getSupportSoftware();
SupportSoftware supportSoft = new SupportSoftware();
supportSoft.setSoftware(getSupportSoftware(dataBlock));
supportSoft.setVersion(getSupportSoftwareVersion(dataBlock));
supSoft.add(supportSoft);
localisations.setAlgorithm(algorithm);
localisations.setUserId("PAMGuard user");
// localisations.setEffort(getLocaliserEffort(deployment, dataBlock, exportParams));
sortLocaliseCoordinates(dataBlock, localisations);
// sort out coordinate system.
return localisations;
}
private boolean sortLocaliseCoordinates(PamDataBlock dataBlock, Localize localisations) {
LocalisationInfo locInfo = dataBlock.getLocalisationContents();
Effort locEffort = localisations.getEffort();
if (locEffort == null) {
locEffort = new Effort();
localisations.setEffort(locEffort);
}
try {
Helper.createRequiredElements(locEffort);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
return false;
}
locEffort.setTimeReference("relative");
// List<String> locTypes = locEffort.getLocalizationType();
boolean ambiguity = locInfo.hasLocContent(LocContents.HAS_AMBIGUITY);
CoordinateReferenceSystem coordRefs = locEffort.getCoordinateReferenceSystem();
if (locInfo.getLocContent() == 0) {
return false;
}
else if (locInfo.hasLocContent(LocContents.HAS_LATLONG)) {
coordRefs.setName(CoordinateName.WGS84.toString());
coordRefs.setSubtype(LocalizationSubType.Geographic.toString());
locEffort.setLocalizationType(LocalizationType.Point.toString());
// locEffort.set
if (locInfo.hasLocContent(LocContents.HAS_DEPTH)) {
locEffort.setDimension(3);
}
else {
locEffort.setDimension(2);
}
// locEffort.set
}
else if (locInfo.hasLocContent(LocContents.HAS_XYZ)) {
coordRefs.setName(CoordinateName.Cartesian.toString());
coordRefs.setSubtype(LocalizationSubType.Engineering.toString());
locEffort.setLocalizationType(LocalizationType.Point.toString());
locEffort.setDimension(3);
}
else if (locInfo.hasLocContent(LocContents.HAS_XY)) {
coordRefs.setName(CoordinateName.Cartesian.toString());
coordRefs.setSubtype(LocalizationSubType.Engineering.toString());
locEffort.setLocalizationType(LocalizationType.Point.toString());
locEffort.setDimension(2);
}
else if (locInfo.hasLocContent(LocContents.HAS_BEARING)) {
coordRefs.setName(CoordinateName.Polar.toString());
coordRefs.setSubtype(LocalizationSubType.Engineering.toString());
locEffort.setLocalizationType(LocalizationType.Bearing.toString());
if (ambiguity) {
locEffort.setDimension(1);
}
else {
locEffort.setDimension(2);
}
}
else {
return false;
}
return true;
}
private nilus.Localize.Effort getLocaliserEffort(PDeployment deployment, PamDataBlock dataBlock, StreamExportParams exportParams) {
// TODO Auto-generated method stub
return null;
}
/**
* Close a detections document. This basically just means rewriting the end time and it's only
* important in the event that a document got too big and has to be restarted.
@ -865,9 +664,6 @@ public class DetectionsHandler extends CollectionHandler {
detections.getEffort().setEnd(TethysTimeFuncs.xmlGregCalFromMillis(audioEnd));
}
private void closeLocaliseDocument(Localize localiseDocument, long endTime) {
localiseDocument.getEffort().setEnd(TethysTimeFuncs.xmlGregCalFromMillis(endTime));
}
/**
@ -914,10 +710,6 @@ public class DetectionsHandler extends CollectionHandler {
return true;
}
private boolean checkLocaliseDocument(Localize localiseDocument, GranularityHandler granularityHandler) {
// TODO Auto-generated method stub
return true;
}
/**
* Worker thread for exporting detections.

View File

@ -7,5 +7,38 @@ package tethys.localization;
*
*/
public enum CoordinateName {
WGS84, UTM, Cartesian, Polar, Spherical, Cylindrical, Range, PerpindicularRange;
WGS84, UTM, Cartesian, Polar, Spherical, Cylindrical, Range, PerpendicularRange;
/*
* I beleive there is only one LocalizationSubType for each of these.
* Cartesian onwards is always engineering subtype
* WGS84 must be geographic
* UTM must be derived.
*/
/*
* Localizationtype is more confusing
* e.g. for WGS84, LocalizationType might be point or track.
* UTM can be point or track.
* The most of the others
*
*/
public LocalizationSubTypes getSubType() {
switch (this) {
case Cartesian:
case Cylindrical:
case PerpendicularRange:
case Polar:
case Range:
case Spherical:
return LocalizationSubTypes.Engineering;
case UTM:
return LocalizationSubTypes.Derived;
case WGS84:
return LocalizationSubTypes.Geographic;
default:
break;
}
return null;
}
}

View File

@ -0,0 +1,619 @@
package tethys.localization;
import java.math.BigInteger;
import java.util.List;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.detectionGroupLocaliser.GroupLocResult;
import Localiser.detectionGroupLocaliser.GroupLocalisation;
import PamDetection.AbstractLocalisation;
import PamDetection.LocContents;
import PamDetection.LocalisationInfo;
import PamUtils.LatLong;
import PamUtils.PamUtils;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import nilus.AlgorithmType;
import nilus.AngularCoordinateType;
import nilus.BearingType;
import nilus.DataSourceType;
import nilus.Detections;
import nilus.Helper;
import nilus.LocalizationType;
import nilus.Localize;
import nilus.SpeciesIDType;
import nilus.WGS84CoordinateType;
import nilus.AlgorithmType.SupportSoftware;
import nilus.LocalizationType.Angular;
import nilus.LocalizationType.Bearing;
import nilus.LocalizationType.Parameters;
import nilus.LocalizationType.References;
import nilus.LocalizationType.WGS84;
import nilus.LocalizationType.Parameters.TargetMotionAnalysis;
import nilus.LocalizationType.References.Reference;
import nilus.Localize.Effort;
import nilus.Localize.Effort.CoordinateReferenceSystem;
import nilus.Localize.Effort.ReferencedDocuments;
import nilus.Localize.Effort.ReferencedDocuments.Document;
import pamMaths.PamVector;
import tethys.Collection;
import tethys.TethysControl;
import tethys.TethysTimeFuncs;
import tethys.niluswraps.PDeployment;
import tethys.output.StreamExportParams;
import tethys.pamdata.AutoTethysProvider;
import tethys.pamdata.TethysDataProvider;
import tethys.species.DataBlockSpeciesManager;
import tethys.species.SpeciesMapItem;
/**
* Class to build a single localisation document during export.
* Works hand in had with the global LocalisationHandler and also
* with other functions it's going to find in the datablock and whatever localisation
* algorithm was used.
* @author dg50
*
*/
public class LocalizationBuilder {
private PDeployment deployment;
private Detections detectionsDocument;
private PamDataBlock dataBlock;
private StreamExportParams streamExportParams;
private TethysControl tethysControl;
private LocalizationHandler localisationHandler;
private LocalisationAlgorithm localisationAlgorithm;
private Localize currentDocument;
private LocalizationCreator localisationCreator;
private TethysDataProvider dataProvider;
public LocalizationBuilder(TethysControl tethysControl, PDeployment deployment, Detections detectionsDocument, PamDataBlock dataBlock,
StreamExportParams exportParams) {
this.deployment = deployment;
this.detectionsDocument = detectionsDocument;
this.dataBlock = dataBlock;
this.streamExportParams = exportParams;
this.tethysControl = tethysControl;
dataProvider = dataBlock.getTethysDataProvider(tethysControl);
localisationHandler = tethysControl.getLocalizationHandler();
localisationAlgorithm = dataBlock.getLocalisationAlgorithm();
if (localisationAlgorithm != null) {
localisationCreator = localisationAlgorithm.getTethysCreator();
}
currentDocument = startLocalisationDocument(deployment, detectionsDocument, dataBlock, exportParams);
}
public Localize startLocalisationDocument(PDeployment deployment, Detections detectionsDocument, PamDataBlock dataBlock,
StreamExportParams exportParams) {
currentDocument = new Localize();
try {
Helper.createRequiredElements(currentDocument);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
return null;
}
Effort eff = currentDocument.getEffort();
if (eff == null) {
eff = new Effort();
try {
Helper.createRequiredElements(eff);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
return null;
}
currentDocument.setEffort(eff);
}
if (detectionsDocument != null) {
/*
* add the reference document information.
* Within PAMGuard, this will always be 1:1 with a Detections doc.
*/
ReferencedDocuments refDocs = eff.getReferencedDocuments();
if (refDocs == null) {
refDocs = new ReferencedDocuments();
try {
Helper.createRequiredElements(refDocs);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
eff.setReferencedDocuments(refDocs);
}
Document detectsDoc = new Document();
detectsDoc.setId(detectionsDocument.getId());
detectsDoc.setType(Collection.Localizations.collectionName());
detectsDoc.setIndex(BigInteger.ZERO);
eff.getReferencedDocuments().getDocument().add(detectsDoc);
}
String prefix = deployment.nilusObject.getId() + "_" + dataProvider.getDetectionsName();
String fullId = localisationHandler.getLocalisationdocId(prefix);
currentDocument.setId(fullId);
// detections.setDescription(dataProvider.getDescription(deployment, tethysExportParams));
currentDocument.setDescription(exportParams.getNilusDetectionDescription());
DataSourceType dataSource = new DataSourceType();
dataSource.setDeploymentId(deployment.nilusObject.getId());
// dataSource.setEnsembleId(""); ToDo
currentDocument.setDataSource(dataSource);
AlgorithmType algorithm = currentDocument.getAlgorithm();
if (dataProvider != null) {
algorithm = dataProvider.getAlgorithm(Collection.Localizations);
// detections.setAlgorithm(algorithm);
}
LocalisationAlgorithm locAlgorithm = dataBlock.getLocalisationAlgorithm();
LocalisationAlgorithmInfo locAlgoinfo = null;
if (locAlgorithm != null) {
locAlgoinfo = locAlgorithm.getAlgorithmInfo();
}
if (locAlgoinfo != null) {
algorithm.setMethod(locAlgoinfo.getAlgorithmName());
}
else {
algorithm.setMethod(localisationHandler.getMethodString(dataBlock));
}
algorithm.setSoftware(localisationHandler.getSoftwareString(dataBlock));
algorithm.setVersion(localisationHandler.getVersionString(dataBlock));
List<SupportSoftware> supSoft = algorithm.getSupportSoftware();
SupportSoftware supportSoft = new SupportSoftware();
supportSoft.setSoftware(localisationHandler.getSupportSoftware(dataBlock));
supportSoft.setVersion(localisationHandler.getSupportSoftwareVersion(dataBlock));
supSoft.add(supportSoft);
currentDocument.setAlgorithm(algorithm);
currentDocument.setUserId("PAMGuard user");
// localisations.setEffort(getLocaliserEffort(deployment, dataBlock, exportParams));
sortLocaliseCoordinates(dataBlock);
// sort out coordinate system.
return currentDocument;
}
private boolean sortLocaliseCoordinates(PamDataBlock dataBlock) {
boolean done = false;
if (localisationCreator != null) {
done = localisationCreator.sortLocalisationCoordinates(this, dataBlock);
}
if (!done) {
sortStandardCoordinates(dataBlock);
}
return done;
}
public boolean sortStandardCoordinates(PamDataBlock dataBlock) {
LocalisationInfo locInfo = dataBlock.getLocalisationContents();
Effort locEffort = currentDocument.getEffort();
if (locEffort == null) {
locEffort = new Effort();
currentDocument.setEffort(locEffort);
}
try {
Helper.createRequiredElements(locEffort);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
return false;
}
locEffort.setTimeReference("relative");
// List<String> locTypes = locEffort.getLocalizationType();
boolean ambiguity = locInfo.hasLocContent(LocContents.HAS_AMBIGUITY);
CoordinateReferenceSystem coordRefs = locEffort.getCoordinateReferenceSystem();
List<String> locTypes = locEffort.getLocalizationType();
if (locInfo.getLocContent() == 0) {
return false;
}
else if (locInfo.hasLocContent(LocContents.HAS_LATLONG)) {
coordRefs.setName(CoordinateName.WGS84.toString());
coordRefs.setSubtype(LocalizationSubTypes.Geographic.toString());
locTypes.add(LocalizationTypes.Point.toString());
// locEffort.set
if (locInfo.hasLocContent(LocContents.HAS_DEPTH)) {
locEffort.setDimension(3);
}
else {
locEffort.setDimension(2);
}
// locEffort.set
}
else if (locInfo.hasLocContent(LocContents.HAS_XYZ)) {
coordRefs.setName(CoordinateName.Cartesian.toString());
coordRefs.setSubtype(LocalizationSubTypes.Engineering.toString());
locTypes.add(LocalizationTypes.Point.toString());
locEffort.setDimension(3);
}
else if (locInfo.hasLocContent(LocContents.HAS_XY)) {
coordRefs.setName(CoordinateName.Cartesian.toString());
coordRefs.setSubtype(LocalizationSubTypes.Engineering.toString());
locTypes.add(LocalizationTypes.Point.toString());
locEffort.setDimension(2);
}
else if (locInfo.hasLocContent(LocContents.HAS_BEARING)) {
coordRefs.setName(CoordinateName.Polar.toString());
coordRefs.setSubtype(LocalizationSubTypes.Engineering.toString());
locTypes.add(LocalizationTypes.Bearing.toString());
if (ambiguity) {
locEffort.setDimension(1);
}
else {
locEffort.setDimension(2);
}
}
else {
return false;
}
return true;
}
public LocalizationType addLocalization(PamDataUnit dataUnit) {
LocalizationType newLoc = createLocalization(dataUnit);
if (newLoc != null) {
currentDocument.getLocalizations().getLocalization().add(newLoc);
}
return newLoc;
}
private LocalizationType createLocalization(PamDataUnit dataUnit) {
if (localisationCreator != null) {
return localisationCreator.createLocalization(this, dataUnit);
}
else {
return createStandardLocalization(dataUnit);
}
}
public LocalizationType createStandardLocalization(PamDataUnit dataUnit) {
/*
* Get the current type from the document. This should always exist, so
* just go for it, then switch on the value to make the localisation.
*/
CoordinateReferenceSystem coordSystem = currentDocument.getEffort().getCoordinateReferenceSystem();
String name = coordSystem.getName();
CoordinateName coordName = CoordinateName.valueOf(name);
if (coordName == null) {
return null;
}
LocalizationType locEl = null;
switch (coordName) {
case Cartesian:
locEl = createCartesianLoc(dataUnit);
break;
case Cylindrical:
locEl = createCylindricalLoc(dataUnit);
break;
case PerpendicularRange:
locEl = createPerpRange(dataUnit);
break;
case Polar:
locEl = createPolarLoc(dataUnit);
break;
case Range:
locEl = createRangeLoc(dataUnit);
break;
case Spherical:
locEl = createSphericalLoc(dataUnit);
break;
case UTM:
break;
case WGS84:
locEl = createWGS84Loc(dataUnit);
break;
default:
break;
}
return locEl;
}
public LocalizationType makeBaseLoc(PamDataUnit dataUnit) {
LocalizationType locType = new LocalizationType();
try {
Helper.createRequiredElements(locType);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
locType.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getTimeMilliseconds()));
locType.setEvent(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getTimeMilliseconds()).toString());
DataBlockSpeciesManager spManager = dataBlock.getDatablockSpeciesManager();
if (spManager != null) {
SpeciesMapItem speciesStuff = spManager.getSpeciesItem(dataUnit);
SpeciesIDType species = new SpeciesIDType();
if (speciesStuff != null) {
species.setValue(BigInteger.valueOf(speciesStuff.getItisCode()));
locType.setSpeciesId(species);
}
}
References references = locType.getReferences();
if (references == null) {
references = new References();
try {
Helper.createRequiredElements(references);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
locType.setReferences(references);
}
Reference reference = new Reference();
reference.setIndex(BigInteger.valueOf(dataUnit.getUID()));
reference.setEventRef("UID");
locType.getReferences().getReference().add(reference);
return locType;
}
/**
* Get angle in degrees constrained to 0-360
* @param radians
* @return
*/
public double constrainRadianAngle(double radians) {
double deg = Math.toDegrees(radians);
if (Math.abs(deg) > 3600) {
return 359.9;
}
deg = PamUtils.constrainedAngle(deg);
deg = AutoTethysProvider.roundDecimalPlaces(deg, 2);
return deg;
}
/**
* Convert a vertical angle from radians to degrees and round.
* @param radians
* @return
*/
public double toSlantAngle(double radians) {
/*
* these really need to be constrained to -90 to 90, but I don't see what to do if
* they are outside that range.
*/
double deg = Math.toDegrees(radians);
deg= PamUtils.constrainedAngle(deg, 180);
deg = AutoTethysProvider.roundDecimalPlaces(deg, 2);
return deg;
}
public LocalizationType createWGS84Loc(PamDataUnit dataUnit) {
AbstractLocalisation loc = dataUnit.getLocalisation();
if (loc == null) {
return null;
}
LatLong latlong = loc.getLatLong(0);
if (latlong == null) {
return null;
}
LocalizationType locType = makeBaseLoc(dataUnit);
/**
* Export the latlong data.
*/
WGS84 wgs84 = new WGS84();
WGS84CoordinateType coord = new WGS84CoordinateType();
wgs84.setCoordinate(coord);
coord.setLongitude(latlong.getLongitude());
coord.setLatitude(latlong.getLatitude());
coord.setElevationM(AutoTethysProvider.roundDecimalPlaces(latlong.getHeight(),3));
PamVector planarVec = loc.getPlanarVector();
locType.setWGS84(wgs84);
// locType.setParameters(null);
Parameters params = locType.getParameters();
if (params == null) {
params = new Parameters();
locType.setParameters(params);
}
TargetMotionAnalysis tma = new TargetMotionAnalysis();
tma.setStart(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getTimeMilliseconds()));
tma.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getEndTimeInMilliseconds()));
params.setTargetMotionAnalysis(tma);
// see if it's possible to get a beam measurement.
if (loc instanceof GroupLocalisation) {
GroupLocalisation groupLoc = (GroupLocalisation) loc;
GroupLocResult groupLocResult = groupLoc.getGroupLocaResult(0);
Double perpDist = groupLocResult.getPerpendicularDistance();
Long beamTime = groupLocResult.getBeamTime();
if (perpDist != null && beamTime != null) {
AngularCoordinateType acType = new AngularCoordinateType();
acType.setAngle1(90);
acType.setDistanceM(AutoTethysProvider.roundDecimalPlaces(perpDist,1));
Angular angular = new Angular();
angular.setCoordinate(acType);
locType.setAngular(angular);
locType.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(beamTime));
currentDocument.getEffort().setTimeReference(TimeReference.beam.toString());
}
// groupLoc.getp
}
/*
* Try to also add a range loc.
*/
// loc.
return locType;
}
public LocalizationType createSphericalLoc(PamDataUnit dataUnit) {
// TODO Auto-generated method stub
return null;
}
public LocalizationType createRangeLoc(PamDataUnit dataUnit) {
// TODO Auto-generated method stub
return null;
}
public LocalizationType createBearingLoc(PamDataUnit dataUnit) {
AbstractLocalisation loc = dataUnit.getLocalisation();
if (loc == null) {
return null;
}
LocalizationType locType = makeBaseLoc(dataUnit);
double[] angles = loc.getAngles();
if (angles == null || angles.length == 0) {
return null;
}
BearingType angType = new BearingType();
angType.setAngle1(constrainRadianAngle(angles[0]));
if (angles.length >= 2) {
angType.setAngle2(toSlantAngle(angles[1]));
// if (angType.getAngle2() > 360) {
// angType.setAngle2(Math.toDegrees(angles[1]));
// }
}
Bearing bearing = new Bearing();
bearing.setCoordinate(angType);
locType.setBearing(bearing);
double[] angErr = loc.getAngleErrors();
if (angErr != null && angErr.length >= 1) {
BearingType angErrType = new BearingType();
angErrType.setAngle1(constrainRadianAngle(angErr[0]));
if (angErr.length >= 2) {
angErrType.setAngle2(constrainRadianAngle(angErr[1]));
}
bearing.setCoordinateError(angErrType);
}
return locType;
}
public LocalizationType createPolarLoc(PamDataUnit dataUnit) {
AbstractLocalisation loc = dataUnit.getLocalisation();
if (loc == null) {
return null;
}
if (loc.hasLocContent(LocContents.HAS_RANGE) == false) {
// do the more basic bearing type instead.
return createBearingLoc(dataUnit);
}
LocalizationType locType = makeBaseLoc(dataUnit);
double[] angles = loc.getAngles();
if (angles == null || angles.length == 0) {
return null;
}
AngularCoordinateType angType = new AngularCoordinateType();
angType.setAngle1(constrainRadianAngle(angles[0]));
if (angles.length >= 2) {
angType.setAngle2(constrainRadianAngle(angles[1]));
if (angType.getAngle2() > 360) {
angType.setAngle2(toSlantAngle(angles[1]));
}
}
if (loc.hasLocContent(LocContents.HAS_RANGE)) {
angType.setDistanceM(loc.getRange(0));
}
Angular angular = new Angular();
angular.setCoordinate(angType);
locType.setAngular(angular);
double[] angErr = loc.getAngleErrors();
if (angErr != null && angErr.length >= 1) {
AngularCoordinateType angErrType = new AngularCoordinateType();
angErrType.setAngle1(constrainRadianAngle(angErr[0]));
if (angErr.length >= 2) {
angErrType.setAngle2(constrainRadianAngle(angErr[1]));
}
if (loc.hasLocContent(LocContents.HAS_RANGEERROR)) {
angErrType.setDistanceM(loc.getRangeError(0));
}
angular.setCoordinateError(angErrType);
}
return locType;
}
public LocalizationType createPerpRange(PamDataUnit dataUnit) {
// TODO Auto-generated method stub
return null;
}
public LocalizationType createCylindricalLoc(PamDataUnit dataUnit) {
// TODO Auto-generated method stub
return null;
}
public LocalizationType createCartesianLoc(PamDataUnit dataUnit) {
// TODO Auto-generated method stub
return null;
}
/**
* @return the deployment
*/
public PDeployment getDeployment() {
return deployment;
}
/**
* @return the detectionsDocument
*/
public Detections getDetectionsDocument() {
return detectionsDocument;
}
/**
* @return the dataBlock
*/
public PamDataBlock getDataBlock() {
return dataBlock;
}
/**
* @return the exportParams
*/
public StreamExportParams getExportParams() {
return streamExportParams;
}
/**
* @return the tethysControl
*/
public TethysControl getTethysControl() {
return tethysControl;
}
/**
* @return the localisationHandler
*/
public LocalizationHandler getLocalisationHandler() {
return localisationHandler;
}
/**
* @return the localisationAlgorithm
*/
public LocalisationAlgorithm getLocalisationAlgorithm() {
return localisationAlgorithm;
}
/**
* @return the currentDocument
*/
public Localize getCurrentDocument() {
return currentDocument;
}
public void closeDocument(long endTime) {
currentDocument.getEffort().setEnd(TethysTimeFuncs.xmlGregCalFromMillis(endTime));
}
public boolean checkDocument() {
// TODO Auto-generated method stub
return true;
}
}

View File

@ -0,0 +1,21 @@
package tethys.localization;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import nilus.LocalizationType;
/**
* Creator thingy that Localisation algorithms can use to overwrite any standard
* behaviour in LocalizatinBuilder.
* @author dg50
*
*/
public interface LocalizationCreator {
public boolean sortLocalisationCoordinates(LocalizationBuilder localizationBuilder, PamDataBlock dataBlock) ;
public LocalizationType createLocalization(LocalizationBuilder localizationBuilder, PamDataUnit dataUnit);
public boolean checkDocument(LocalizationBuilder localizationBuilder);
}

View File

@ -1,6 +1,5 @@
package tethys.localization;
import java.math.BigInteger;
import java.util.ArrayList;
import Localiser.detectionGroupLocaliser.GroupLocResult;
@ -10,14 +9,6 @@ import PamDetection.LocContents;
import PamUtils.LatLong;
import PamUtils.PamUtils;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import nilus.AngularCoordinateType;
import nilus.BearingType;
import nilus.CoordinateType;
import nilus.Helper;
import nilus.LocalizationType;
import nilus.LocalizationType.References;
import nilus.LocalizationType.References.Reference;
import nilus.Localize;
import nilus.SpeciesIDType;
import pamMaths.PamVector;
@ -25,17 +16,14 @@ import nilus.Localize.Effort.CoordinateReferenceSystem;
import tethys.Collection;
import tethys.CollectionHandler;
import tethys.TethysControl;
import tethys.TethysTimeFuncs;
import tethys.detection.StreamDetectionsSummary;
import tethys.niluswraps.NilusDataWrapper;
import tethys.niluswraps.PDeployment;
import tethys.output.StreamExportParams;
import tethys.pamdata.AutoTethysProvider;
import tethys.species.DataBlockSpeciesManager;
import tethys.species.SpeciesMapItem;
public class LocalizationHandler extends CollectionHandler {
private int uniqueLocalisationsId = 1;
public LocalizationHandler(TethysControl tethysControl) {
super(tethysControl, Collection.Localizations);
}
@ -63,7 +51,7 @@ public class LocalizationHandler extends CollectionHandler {
* Get a list of Localization documents associated with a particular data block for the list of deployments
* documents. Group them by abstract or something
* @param dataBlock
* @param deployments can be null for all deployments.
* @param deployments can be null for all deployments.
* @return
*/
public StreamDetectionsSummary<NilusDataWrapper<PLocalization>> getStreamLocalizations(PamDataBlock dataBlock, ArrayList<PDeployment> deployments) {
@ -93,276 +81,18 @@ public class LocalizationHandler extends CollectionHandler {
return null;
}
/**
* Create a Localization element object to add to a Localizations document.
* @param localiseDocument
* @param dataBlock
* @param dataUnit
* @param streamExportParams
* @return
*/
public LocalizationType createLocalization(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
StreamExportParams streamExportParams) {
public String getLocalisationdocId(String prefix) {
/*
* Get the current type from the document. This should always exist, so
* just go for it, then switch on the value to make the localisation.
* Check the document name isn't already used and increment id as necessary.
*/
CoordinateReferenceSystem coordSystem = localiseDocument.getEffort().getCoordinateReferenceSystem();
String name = coordSystem.getName();
CoordinateName coordName = CoordinateName.valueOf(name);
if (coordName == null) {
return null;
}
LocalizationType locEl = null;
switch (coordName) {
case Cartesian:
locEl = createCartesianLoc(localiseDocument, dataBlock, dataUnit, streamExportParams);
break;
case Cylindrical:
locEl = createCylindricalLoc(localiseDocument, dataBlock, dataUnit, streamExportParams);
break;
case PerpindicularRange:
locEl = createPerpRange(localiseDocument, dataBlock, dataUnit, streamExportParams);
break;
case Polar:
locEl = createPolarLoc(localiseDocument, dataBlock, dataUnit, streamExportParams);
break;
case Range:
locEl = createRangeLoc(localiseDocument, dataBlock, dataUnit, streamExportParams);
break;
case Spherical:
locEl = createSphericalLoc(localiseDocument, dataBlock, dataUnit, streamExportParams);
break;
case UTM:
break;
case WGS84:
locEl = createWGS84Loc(localiseDocument, dataBlock, dataUnit, streamExportParams);
break;
default:
break;
}
return locEl;
}
private LocalizationType makeBaseLoc(PamDataBlock dataBlock, PamDataUnit dataUnit) {
LocalizationType locType = new LocalizationType();
try {
Helper.createRequiredElements(locType);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
locType.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getTimeMilliseconds()));
DataBlockSpeciesManager spManager = dataBlock.getDatablockSpeciesManager();
if (spManager != null) {
SpeciesMapItem speciesStuff = spManager.getSpeciesItem(dataUnit);
SpeciesIDType species = new SpeciesIDType();
if (speciesStuff != null) {
species.setValue(BigInteger.valueOf(speciesStuff.getItisCode()));
locType.setSpeciesId(species);
String fullId;
while (true) {
fullId = String.format("%s_%d", prefix, uniqueLocalisationsId++);
if (!tethysControl.getDbxmlQueries().documentExists(Collection.Localizations.toString(), fullId)) {
break;
}
}
References references = locType.getReferences();
if (references == null) {
references = new References();
try {
Helper.createRequiredElements(references);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
locType.setReferences(references);
}
Reference reference = new Reference();
reference.setIndex(BigInteger.valueOf(dataUnit.getUID()));
reference.setEventRef("UID");
locType.getReferences().getReference().add(reference);
return locType;
}
/**
* Get angle in degrees constrained to 0-360
* @param radians
* @return
*/
private double constrainRadianAngle(double radians) {
double deg = Math.toDegrees(radians);
if (Math.abs(deg) > 3600) {
return 359.9;
}
deg = PamUtils.constrainedAngle(deg);
deg = AutoTethysProvider.roundDecimalPlaces(deg, 2);
return deg;
}
/**
* Convert a vertical angle from radians to degrees and round.
* @param radians
* @return
*/
private double toSlantAngle(double radians) {
/*
* these really need to be constrained to -90 to 90, but I don't see what to do if
* they are outside that range.
*/
double deg = Math.toDegrees(radians);
deg= PamUtils.constrainedAngle(deg, 180);
deg = AutoTethysProvider.roundDecimalPlaces(deg, 2);
return deg;
}
private LocalizationType createWGS84Loc(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
StreamExportParams streamExportParams) {
AbstractLocalisation loc = dataUnit.getLocalisation();
if (loc == null) {
return null;
}
LatLong latlong = loc.getLatLong(0);
if (latlong == null) {
return null;
}
LocalizationType locType = makeBaseLoc(dataBlock, dataUnit);
CoordinateType coord = new CoordinateType();
coord.setX(latlong.getLongitude());
coord.setY(latlong.getLatitude());
coord.setZ(latlong.getHeight());
PamVector planarVec = loc.getPlanarVector();
locType.setCoordinate(coord);
// see if it's possible to get a beam measurement.
if (loc instanceof GroupLocalisation) {
GroupLocalisation groupLoc = (GroupLocalisation) loc;
GroupLocResult groupLocResult = groupLoc.getGroupLocaResult(0);
Double perpDist = groupLocResult.getPerpendicularDistance();
Long beamTime = groupLocResult.getBeamTime();
if (perpDist != null && beamTime != null) {
AngularCoordinateType acType = new AngularCoordinateType();
acType.setAngle1(90);
acType.setDistanceM(AutoTethysProvider.roundDecimalPlaces(perpDist,1));
locType.setAngularCoordinate(acType);
locType.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(beamTime));
locType.setCoordinate(null);
}
// groupLoc.getp
}
/*
* Try to also add a range loc.
*/
// loc.
return locType;
}
private LocalizationType createSphericalLoc(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
StreamExportParams streamExportParams) {
// TODO Auto-generated method stub
return null;
}
private LocalizationType createRangeLoc(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
StreamExportParams streamExportParams) {
// TODO Auto-generated method stub
return null;
}
private LocalizationType createBearingLoc(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
StreamExportParams streamExportParams) {
AbstractLocalisation loc = dataUnit.getLocalisation();
if (loc == null) {
return null;
}
LocalizationType locType = makeBaseLoc(dataBlock, dataUnit);
double[] angles = loc.getAngles();
if (angles == null || angles.length == 0) {
return null;
}
BearingType angType = new BearingType();
angType.setAngle1(constrainRadianAngle(angles[0]));
if (angles.length >= 2) {
angType.setAngle2(toSlantAngle(angles[1]));
// if (angType.getAngle2() > 360) {
// angType.setAngle2(Math.toDegrees(angles[1]));
// }
}
locType.setBearing(angType);
double[] angErr = loc.getAngleErrors();
if (angErr != null && angErr.length >= 1) {
BearingType angErrType = new BearingType();
angErrType.setAngle1(constrainRadianAngle(angErr[0]));
if (angErr.length >= 2) {
angErrType.setAngle2(constrainRadianAngle(angErr[1]));
}
locType.setBearingError(angErrType);
}
return locType;
}
private LocalizationType createPolarLoc(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
StreamExportParams streamExportParams) {
AbstractLocalisation loc = dataUnit.getLocalisation();
if (loc == null) {
return null;
}
if (loc.hasLocContent(LocContents.HAS_RANGE) == false) {
// do the more basic bearing type instead.
return createBearingLoc(localiseDocument, dataBlock, dataUnit, streamExportParams);
}
LocalizationType locType = makeBaseLoc(dataBlock, dataUnit);
double[] angles = loc.getAngles();
if (angles == null || angles.length == 0) {
return null;
}
AngularCoordinateType angType = new AngularCoordinateType();
angType.setAngle1(constrainRadianAngle(angles[0]));
if (angles.length >= 2) {
angType.setAngle2(constrainRadianAngle(angles[1]));
if (angType.getAngle2() > 360) {
angType.setAngle2(toSlantAngle(angles[1]));
}
}
if (loc.hasLocContent(LocContents.HAS_RANGE)) {
angType.setDistanceM(loc.getRange(0));
}
locType.setAngularCoordinate(angType);
double[] angErr = loc.getAngleErrors();
if (angErr != null && angErr.length >= 1) {
AngularCoordinateType angErrType = new AngularCoordinateType();
angErrType.setAngle1(constrainRadianAngle(angErr[0]));
if (angErr.length >= 2) {
angErrType.setAngle2(constrainRadianAngle(angErr[1]));
}
if (loc.hasLocContent(LocContents.HAS_RANGEERROR)) {
angErrType.setDistanceM(loc.getRangeError(0));
}
locType.setAngularCoordinateError(angErrType);
}
return locType;
}
private LocalizationType createPerpRange(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
StreamExportParams streamExportParams) {
// TODO Auto-generated method stub
return null;
}
private LocalizationType createCylindricalLoc(Localize localiseDocument, PamDataBlock dataBlock,
PamDataUnit dataUnit, StreamExportParams streamExportParams) {
// TODO Auto-generated method stub
return null;
}
private LocalizationType createCartesianLoc(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
StreamExportParams streamExportParams) {
// TODO Auto-generated method stub
return null;
return fullId;
}
}

Some files were not shown because too many files have changed in this diff Show More