diff --git a/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT sdm.launch b/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT sdm.launch index c6adf7bec2d..f29b76fe2ce 100644 --- a/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT sdm.launch +++ b/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT sdm.launch @@ -41,5 +41,5 @@ - + diff --git a/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch b/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch index 1107e49c502..b0f7c71b37e 100644 --- a/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch +++ b/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch @@ -38,7 +38,7 @@ - + - + diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoExtendedSensorDataMetadata.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoExtendedSensorDataMetadata.java index f92f94ccf56..e4182e242db 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoExtendedSensorDataMetadata.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoExtendedSensorDataMetadata.java @@ -13,7 +13,7 @@ import java.util.Objects; * * The first columns need to be consistent with {@link BravoSensorDataMetadata}. */ -public enum BravoExtendedSensorDataMetadata { +public enum BravoExtendedSensorDataMetadata implements ColumnMetadata { RIDE_HEIGHT_PORT_HULL("RideHeightPort"), // RIDE_HEIGHT_STBD_HULL("RideHeightStbd"), // HEEL("Heel"), // diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoSensorDataMetadata.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoSensorDataMetadata.java index 9f9e112d48d..ff0bf3ab939 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoSensorDataMetadata.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoSensorDataMetadata.java @@ -11,7 +11,7 @@ import java.util.Objects; * * The current implementation only stores a subset of the information available during the import. */ -public enum BravoSensorDataMetadata { +public enum BravoSensorDataMetadata implements ColumnMetadata { RIDE_HEIGHT_PORT_HULL("RideHeightPortHull"), // RIDE_HEIGHT_STBD_HULL("RideHeightStbdHull"), // diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/ColumnMetadata.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/ColumnMetadata.java new file mode 100644 index 00000000000..3c995a69384 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/ColumnMetadata.java @@ -0,0 +1,12 @@ +package com.sap.sailing.domain.common.sensordata; + +import com.sap.sailing.domain.common.tracking.DoubleVectorFix; +import com.sap.sailing.domain.common.tracking.SensorFix; + +/** + * Definition of column metadata used by {@link SensorFix} implementations to resolve columns in underlying + * {@link DoubleVectorFix DoubleVectorFixes}. + */ +public interface ColumnMetadata { + int getColumnIndex(); +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/ExpeditionExtendedSensorDataMetadata.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/ExpeditionExtendedSensorDataMetadata.java new file mode 100755 index 00000000000..21ea278366f --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/ExpeditionExtendedSensorDataMetadata.java @@ -0,0 +1,75 @@ +package com.sap.sailing.domain.common.sensordata; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import com.sap.sailing.domain.common.tracking.DoubleVectorFix; + +/** + * Metadata that defines the column structure of BravoExtended fixes when imported as {@link com.sap.sailing.domain.common.tracking.DoubleVectorFix}. + * + * The current implementation only stores a subset of the information available during the import. + * + * The first columns need to be consistent with {@link BravoSensorDataMetadata}. + */ +public enum ExpeditionExtendedSensorDataMetadata { + HEEL("Heel", BravoExtendedSensorDataMetadata.HEEL); + + private String columnName; + + /** + * Expedition extended fixes are mapped to Bravo extended fixes whose metadata is described + * in {@link BravoExtendedSensorDataMetadata}. When parsing an Expedition file, the columns + * in the resulting {@link DoubleVectorFix} must be chosen such that they match up with the + * corresponding fields as described by {@link BravoExtendedSensorDataMetadata}. This turns + * the ordinals of this enum's literals insignificant; the position is taken solely from + * the Bravo metadata. + */ + private BravoExtendedSensorDataMetadata mappedToBravoField; + + private ExpeditionExtendedSensorDataMetadata(String columnName, BravoExtendedSensorDataMetadata mappedToBravoField) { + this.columnName = columnName; + this.mappedToBravoField = mappedToBravoField; + } + + public String getColumnName() { + return columnName; + } + + public int getColumnIndex() { + return mappedToBravoField.getColumnIndex(); + } + + public static ExpeditionExtendedSensorDataMetadata byColumnName(String valueName) { + ExpeditionExtendedSensorDataMetadata[] values = ExpeditionExtendedSensorDataMetadata.values(); + for (ExpeditionExtendedSensorDataMetadata item : values) { + if (Objects.equals(item.getColumnName(), valueName)) { + return item; + } + } + return null; + } + + public static int getTrackColumnCount() { + return ExpeditionExtendedSensorDataMetadata.values().length; + } + + public static List getTrackColumnNames() { + ArrayList colNames = new ArrayList<>(getTrackColumnCount()); + for (ExpeditionExtendedSensorDataMetadata item : ExpeditionExtendedSensorDataMetadata.values()) { + colNames.add(item.getColumnName()); + } + return colNames; + } + + public static Map getColumnNamesToIndexInDoubleFix() { + final Map columnNamesToIndexInDoubleFix = new HashMap<>(); + for (final ExpeditionExtendedSensorDataMetadata column : ExpeditionExtendedSensorDataMetadata.values()) { + columnNamesToIndexInDoubleFix.put(column.getColumnName(), column.getColumnIndex()); + } + return columnNamesToIndexInDoubleFix; + } +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/BravoExtendedFixImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/BravoExtendedFixImpl.java index 1c32c3ae0f5..7b9c6bae80c 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/BravoExtendedFixImpl.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/BravoExtendedFixImpl.java @@ -3,9 +3,14 @@ package com.sap.sailing.domain.common.tracking.impl; import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.sensordata.BravoExtendedSensorDataMetadata; +import com.sap.sailing.domain.common.sensordata.ColumnMetadata; import com.sap.sailing.domain.common.tracking.BravoExtendedFix; +import com.sap.sailing.domain.common.tracking.BravoFix; import com.sap.sailing.domain.common.tracking.DoubleVectorFix; +/** + * Implementation of {@link BravoExtendedFix}. {@link BravoExtendedFix} adds more measures compared to {@link BravoFix}. + */ public class BravoExtendedFixImpl extends BravoFixImpl implements BravoExtendedFix { private static final long serialVersionUID = 5622321493028301922L; @@ -13,6 +18,11 @@ public class BravoExtendedFixImpl extends BravoFixImpl implements BravoExtendedF super(fix); } + @Override + protected ColumnMetadata resolveMetadataFromValueName(String valueName) { + return BravoExtendedSensorDataMetadata.byColumnName(valueName); + } + @Override public double getPortDaggerboardRake() { return fix.get(BravoExtendedSensorDataMetadata.DB_RAKE_PORT.getColumnIndex()); diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/BravoFixImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/BravoFixImpl.java index ca8bcec9f48..605ee7b5ca3 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/BravoFixImpl.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/BravoFixImpl.java @@ -5,35 +5,24 @@ import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.impl.MeterDistance; import com.sap.sailing.domain.common.sensordata.BravoSensorDataMetadata; +import com.sap.sailing.domain.common.sensordata.ColumnMetadata; import com.sap.sailing.domain.common.tracking.BravoFix; import com.sap.sailing.domain.common.tracking.DoubleVectorFix; -import com.sap.sse.common.TimePoint; /** * Implementation of {@link BravoFix} that wraps a {@link DoubleVectorFix} which holds the actual sensor data. The * mapping metadata is stored in the {@link BravoSensorDataMetadata} enum. */ -public class BravoFixImpl implements BravoFix { +public class BravoFixImpl extends SensorFixImpl implements BravoFix { private static final long serialVersionUID = 2033254212013221160L; - protected final DoubleVectorFix fix; public BravoFixImpl(DoubleVectorFix fix) { - this.fix = fix; + super(fix); } - + @Override - public double get(String valueName) { - BravoSensorDataMetadata colDefEnum = BravoSensorDataMetadata.byColumnName(valueName); - if (colDefEnum == null) { - throw new IllegalArgumentException("Unknown value \"" + valueName + "\" for " + getClass().getSimpleName()); - } - int index = colDefEnum.getColumnIndex(); - return fix.get(index); - } - - @Override - public TimePoint getTimePoint() { - return fix.getTimePoint(); + protected ColumnMetadata resolveMetadataFromValueName(String valueName) { + return BravoSensorDataMetadata.byColumnName(valueName); } @Override diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/SensorFixImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/SensorFixImpl.java new file mode 100644 index 00000000000..b25d68eda28 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/SensorFixImpl.java @@ -0,0 +1,44 @@ +package com.sap.sailing.domain.common.tracking.impl; + +import com.sap.sailing.domain.common.sensordata.ColumnMetadata; +import com.sap.sailing.domain.common.tracking.DoubleVectorFix; +import com.sap.sailing.domain.common.tracking.SensorFix; +import com.sap.sse.common.TimePoint; + +/** + * Abstract implementation of {@link SensorFix} that implements the generic value access through + * {@link SensorFixImpl#get(String)} by resolving a {@link ColumnMetadata} instance for a given valueName. The data is + * taken from the underlying {@link DoubleVectorFix} by using the column index taken from the resolved + * {@link ColumnMetadata} instance. + */ +public abstract class SensorFixImpl implements SensorFix { + private static final long serialVersionUID = -5815764620564953478L; + protected final DoubleVectorFix fix; + + public SensorFixImpl(DoubleVectorFix fix) { + super(); + assert fix != null; + this.fix = fix; + } + + @Override + public TimePoint getTimePoint() { + return fix.getTimePoint(); + } + + @Override + public double get(String valueName) { + final ColumnMetadata columnMetadata = resolveMetadataFromValueName(valueName); + if (columnMetadata == null) { + throw new IllegalArgumentException("Unknown value \"" + valueName + "\" for " + getClass().getSimpleName()); + } + int index = columnMetadata.getColumnIndex(); + return fix.get(index); + } + + /** + * To be implemented by subclasses to resolve the associated {@link ColumnMetadata} for a given valueName. The + * result may be null if the given valueName is unknown for the fix implementation. + */ + protected abstract ColumnMetadata resolveMetadataFromValueName(String valueName); +} diff --git a/java/com.sap.sailing.domain.deckmanadapter/src/com/sap/sailing/domain/deckmanadapter/impl/Activator.java b/java/com.sap.sailing.domain.deckmanadapter/src/com/sap/sailing/domain/deckmanadapter/impl/Activator.java index b32cb3c4670..5dde7b339ea 100755 --- a/java/com.sap.sailing.domain.deckmanadapter/src/com/sap/sailing/domain/deckmanadapter/impl/Activator.java +++ b/java/com.sap.sailing.domain.deckmanadapter/src/com/sap/sailing/domain/deckmanadapter/impl/Activator.java @@ -6,7 +6,6 @@ import org.osgi.framework.BundleContext; import com.sap.sailing.server.trackfiles.common.GPSFixImporterRegistration; public class Activator implements BundleActivator { - @Override public void start(BundleContext context) throws Exception { GPSFixImporterRegistration.register(new DeckmanGPSFixImporter(), context); @@ -15,5 +14,4 @@ public class Activator implements BundleActivator { @Override public void stop(BundleContext context) throws Exception { } - } diff --git a/java/com.sap.sailing.domain.deckmanadapter/src/com/sap/sailing/domain/deckmanadapter/impl/DeckmanAdapterImpl.java b/java/com.sap.sailing.domain.deckmanadapter/src/com/sap/sailing/domain/deckmanadapter/impl/DeckmanAdapterImpl.java index 6db2e1b6a55..d1c1b37be66 100755 --- a/java/com.sap.sailing.domain.deckmanadapter/src/com/sap/sailing/domain/deckmanadapter/impl/DeckmanAdapterImpl.java +++ b/java/com.sap.sailing.domain.deckmanadapter/src/com/sap/sailing/domain/deckmanadapter/impl/DeckmanAdapterImpl.java @@ -11,5 +11,4 @@ public class DeckmanAdapterImpl implements DeckmanAdapter { public LogFile parseLogFile(Reader r) throws IOException { return new LogFileImpl(r); } - } diff --git a/java/com.sap.sailing.domain.expeditionadapter/.classpath b/java/com.sap.sailing.domain.expeditionadapter/.classpath new file mode 100755 index 00000000000..eca7bdba8f0 --- /dev/null +++ b/java/com.sap.sailing.domain.expeditionadapter/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/java/com.sap.sailing.domain.expeditionadapter/.project b/java/com.sap.sailing.domain.expeditionadapter/.project new file mode 100755 index 00000000000..a413084a0cd --- /dev/null +++ b/java/com.sap.sailing.domain.expeditionadapter/.project @@ -0,0 +1,28 @@ + + + com.sap.sailing.domain.expeditionadapter + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/java/com.sap.sailing.domain.expeditionadapter/.settings/org.eclipse.jdt.core.prefs b/java/com.sap.sailing.domain.expeditionadapter/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 00000000000..0c68a61dca8 --- /dev/null +++ b/java/com.sap.sailing.domain.expeditionadapter/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/java/com.sap.sailing.domain.expeditionadapter/.settings/org.eclipse.pde.core.prefs b/java/com.sap.sailing.domain.expeditionadapter/.settings/org.eclipse.pde.core.prefs new file mode 100755 index 00000000000..f29e940a005 --- /dev/null +++ b/java/com.sap.sailing.domain.expeditionadapter/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/java/com.sap.sailing.domain.expeditionadapter/META-INF/MANIFEST.MF b/java/com.sap.sailing.domain.expeditionadapter/META-INF/MANIFEST.MF new file mode 100755 index 00000000000..43e36b46448 --- /dev/null +++ b/java/com.sap.sailing.domain.expeditionadapter/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Expeditionadapter +Bundle-SymbolicName: com.sap.sailing.domain.expeditionadapter +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: SAP +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Import-Package: org.osgi.framework +Require-Bundle: com.sap.sailing.server.trackfiles, + com.sap.sailing.domain, + com.sap.sse.common, + com.sap.sailing.domain.common +Bundle-Activator: com.sap.sailing.domain.expeditionadapter.impl.Activator diff --git a/java/com.sap.sailing.domain.expeditionadapter/build.properties b/java/com.sap.sailing.domain.expeditionadapter/build.properties new file mode 100755 index 00000000000..34d2e4d2dad --- /dev/null +++ b/java/com.sap.sailing.domain.expeditionadapter/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/java/com.sap.sailing.domain.expeditionadapter/pom.xml b/java/com.sap.sailing.domain.expeditionadapter/pom.xml new file mode 100755 index 00000000000..420cb8c34f6 --- /dev/null +++ b/java/com.sap.sailing.domain.expeditionadapter/pom.xml @@ -0,0 +1,12 @@ + + + 4.0.0 + + root + com.sap.sailing + 1.0.0-SNAPSHOT + + com.sap.sailing.domain.expeditionadapter + eclipse-plugin + diff --git a/java/com.sap.sailing.domain.expeditionadapter/src/com/sap/sailing/domain/expeditionadapter/impl/Activator.java b/java/com.sap.sailing.domain.expeditionadapter/src/com/sap/sailing/domain/expeditionadapter/impl/Activator.java new file mode 100755 index 00000000000..a73939a8ac8 --- /dev/null +++ b/java/com.sap.sailing.domain.expeditionadapter/src/com/sap/sailing/domain/expeditionadapter/impl/Activator.java @@ -0,0 +1,17 @@ +package com.sap.sailing.domain.expeditionadapter.impl; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +import com.sap.sailing.server.trackfiles.common.GPSFixImporterRegistration; + +public class Activator implements BundleActivator { + @Override + public void start(BundleContext context) throws Exception { + GPSFixImporterRegistration.register(new ExpeditionGPSFixImporter(), context); + } + + @Override + public void stop(BundleContext context) throws Exception { + } +} diff --git a/java/com.sap.sailing.domain.expeditionadapter/src/com/sap/sailing/domain/expeditionadapter/impl/ExpeditionGPSFixImporter.java b/java/com.sap.sailing.domain.expeditionadapter/src/com/sap/sailing/domain/expeditionadapter/impl/ExpeditionGPSFixImporter.java new file mode 100755 index 00000000000..edae24e5e61 --- /dev/null +++ b/java/com.sap.sailing.domain.expeditionadapter/src/com/sap/sailing/domain/expeditionadapter/impl/ExpeditionGPSFixImporter.java @@ -0,0 +1,61 @@ +package com.sap.sailing.domain.expeditionadapter.impl; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.Date; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import com.sap.sailing.domain.common.impl.DegreeBearingImpl; +import com.sap.sailing.domain.common.impl.DegreePosition; +import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl; +import com.sap.sailing.domain.common.tracking.GPSFixMoving; +import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl; +import com.sap.sailing.domain.trackfiles.TrackFileImportDeviceIdentifier; +import com.sap.sailing.domain.trackfiles.TrackFileImportDeviceIdentifierImpl; +import com.sap.sailing.domain.trackimport.FormatNotSupportedException; +import com.sap.sailing.domain.trackimport.GPSFixImporter; +import com.sap.sailing.server.trackfiles.impl.ExpeditionExtendedDataImporterImpl; + +public class ExpeditionGPSFixImporter implements GPSFixImporter { + private static final String LAT_COLUMN_HEADING = ExpeditionExtendedDataImporterImpl.COL_NAME_LAT; + private static final String LON_COLUMN_HEADING = ExpeditionExtendedDataImporterImpl.COL_NAME_LON; + private static final String COG_COLUMN_HEADING = "Ext_COG"; + private static final String SOG_COLUMN_HEADING = "Ext_SOG"; + @Override + public void importFixes(InputStream inputStream, Callback callback, boolean inferSpeedAndBearing, final String sourceName) + throws FormatNotSupportedException, IOException { + TrackFileImportDeviceIdentifier device = new TrackFileImportDeviceIdentifierImpl(sourceName, getType() + "@" + new Date()); + final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); + final String headerLine = br.readLine(); + final Map columnDefinitions = ExpeditionExtendedDataImporterImpl.parseHeader(headerLine); + final AtomicInteger lineNr = new AtomicInteger(0); + br.lines().forEach(line->{ + if (!line.trim().isEmpty()) { + ExpeditionExtendedDataImporterImpl.parseLine(lineNr.incrementAndGet(), sourceName, line, columnDefinitions, + (timePoint, columnValues, columns)->{ + final double latDeg = Double.parseDouble(columnValues[columns.get(LAT_COLUMN_HEADING)]); + final double lonDeg = Double.parseDouble(columnValues[columns.get(LON_COLUMN_HEADING)]); + final double cogDeg = Double.parseDouble(columnValues[columns.get(COG_COLUMN_HEADING)]); + final double sogKnots = Double.parseDouble(columnValues[columns.get(SOG_COLUMN_HEADING)]); + final GPSFixMoving fix = new GPSFixMovingImpl(new DegreePosition(latDeg, lonDeg), timePoint, + new KnotSpeedWithBearingImpl(sogKnots, new DegreeBearingImpl(cogDeg))); + callback.addFix(fix, device); + }); + } + }); + } + + @Override + public Iterable getSupportedFileExtensions() { + return Arrays.asList(new String[] { "csv", "log", "txt" }); + } + + @Override + public String getType() { + return "Expedition"; + } +} diff --git a/java/com.sap.sailing.domain.expeditionadapter/src/com/sap/sailing/domain/expeditionadapter/impl/FieldType.java b/java/com.sap.sailing.domain.expeditionadapter/src/com/sap/sailing/domain/expeditionadapter/impl/FieldType.java new file mode 100755 index 00000000000..4eb2a0b87ef --- /dev/null +++ b/java/com.sap.sailing.domain.expeditionadapter/src/com/sap/sailing/domain/expeditionadapter/impl/FieldType.java @@ -0,0 +1,7 @@ +package com.sap.sailing.domain.expeditionadapter.impl; + +public enum FieldType { + date, race_name, leg_name, leg_score, boat_speed, heel, leeway, rudder, heading, course, depth, + tws, twa, twd, aws, awa, latitude, longitude, sog, cog, abstwa, absawa, absheel, absleeway, absrudder, + foresail, staysail, mainsail, forestay, rake, vmg, status, starboard_port, rudder2, keelang, absrudder2, abskeelang; +} diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java index 15879dfdb15..a2c738b79e6 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java @@ -112,6 +112,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogCloseOpe import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMarkEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorBravoExtendedMappingEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorBravoMappingEventImpl; +import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorEventImpl; @@ -1713,6 +1714,9 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { } else if (eventClass.equals(RegattaLogDeviceCompetitorBravoExtendedMappingEventImpl.class.getSimpleName())) { return loadRegattaLogDeviceCompetitorBravoExtendedMappingEvent(createdAt, author, logicalTimePoint, id, dbObject, regattaLogIdentifier, o); + } else if (eventClass.equals(RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl.class.getSimpleName())) { + return loadRegattaLogDeviceCompetitorExpeditionExtendedMappingEvent(createdAt, author, logicalTimePoint, id, dbObject, + regattaLogIdentifier, o); } else if (eventClass.equals(RegattaLogDeviceMarkMappingEvent.class.getSimpleName())) { return loadRegattaLogDeviceMarkMappingEvent(createdAt, author, logicalTimePoint, id, dbObject, regattaLogIdentifier, o); } else if (eventClass.equals(RegattaLogCloseOpenEndedDeviceMappingEvent.class.getSimpleName())) { @@ -1911,6 +1915,13 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { regattaLogIdentifier, outerDBObject, RegattaLogDeviceCompetitorBravoExtendedMappingEventImpl::new); } + private RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl loadRegattaLogDeviceCompetitorExpeditionExtendedMappingEvent( + TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable id, + final DBObject dbObject, RegattaLikeIdentifier regattaLogIdentifier, DBObject outerDBObject) { + return loadRegattaLogDeviceCompetitorSensorDataMappingEvent(createdAt, author, logicalTimePoint, id, dbObject, + regattaLogIdentifier, outerDBObject, RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl::new); + } + private MappingT loadRegattaLogDeviceCompetitorSensorDataMappingEvent( TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable id, final DBObject dbObject, RegattaLikeIdentifier regattaLogIdentifier, DBObject outerDBObject, diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/Activator.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/Activator.java index fa8980c1f5f..8be4cc22076 100644 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/Activator.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/Activator.java @@ -89,6 +89,7 @@ public class Activator implements BundleActivator { new MasterDataImportClassLoaderServiceImpl(), null)); registrations.add(context.registerService(SensorFixMapper.class, new BravoDataFixMapper(), null)); registrations.add(context.registerService(SensorFixMapper.class, new BravoExtendedDataFixMapper(), null)); + registrations.add(context.registerService(SensorFixMapper.class, new ExpeditionExtendedDataFixMapper(), null)); sensorFixMapperTracker = createSensorFixMapperServiceTracker(context); racingEventServiceTracker = ServiceTrackerFactory.createAndOpen(context, RacingEventService.class); diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BravoDataFixMapper.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BravoDataFixMapper.java index 7f822f11560..f8165a00079 100644 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BravoDataFixMapper.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BravoDataFixMapper.java @@ -20,7 +20,7 @@ public class BravoDataFixMapper implements SensorFixMapper getTrack(DynamicTrackedRace race, Competitor key) { return race.getOrCreateSensorTrack(key, BravoFixTrack.TRACK_NAME, - () -> new BravoFixTrackImpl(key, BravoFixTrack.TRACK_NAME, false)); + () -> new BravoFixTrackImpl(key, BravoFixTrack.TRACK_NAME, /* hasExtendedFixes */ false)); } @Override diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BravoExtendedDataFixMapper.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BravoExtendedDataFixMapper.java index 9aab573d347..cdb1c97f32d 100644 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BravoExtendedDataFixMapper.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/BravoExtendedDataFixMapper.java @@ -21,7 +21,7 @@ public class BravoExtendedDataFixMapper implements SensorFixMapper getTrack(DynamicTrackedRace race, Competitor key) { return race.getOrCreateSensorTrack(key, BravoFixTrack.TRACK_NAME, - () -> new BravoFixTrackImpl(key, BravoFixTrack.TRACK_NAME, true)); + () -> new BravoFixTrackImpl(key, BravoFixTrack.TRACK_NAME, /* hasExtendedFixes */ true)); } @Override diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/ExpeditionExtendedDataFixMapper.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/ExpeditionExtendedDataFixMapper.java new file mode 100755 index 00000000000..a0ba6a432c3 --- /dev/null +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/ExpeditionExtendedDataFixMapper.java @@ -0,0 +1,40 @@ +package com.sap.sailing.domain.racelogtracking.impl; + +import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent; +import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.common.tracking.BravoExtendedFix; +import com.sap.sailing.domain.common.tracking.BravoFix; +import com.sap.sailing.domain.common.tracking.DoubleVectorFix; +import com.sap.sailing.domain.common.tracking.impl.BravoExtendedFixImpl; +import com.sap.sailing.domain.racelog.tracking.SensorFixMapper; +import com.sap.sailing.domain.tracking.BravoFixTrack; +import com.sap.sailing.domain.tracking.DynamicSensorFixTrack; +import com.sap.sailing.domain.tracking.DynamicTrackedRace; +import com.sap.sailing.domain.tracking.impl.BravoFixTrackImpl; + +/** + * {@link SensorFixMapper} implementation to product {@link BravoExtendedFix}es from {@link DoubleVectorFix}es + * interpreted as "Expedition" data. The data has significant overlap with what we typically receive from the + * "Bravo" devices. Ultimately, the naming may need to be adjusted, better reflecting that the "Bravo" extended + * tracks now assume general responsibility for a broader set of sensor values that may be assigned to a + * competitor, beyond just GPS tracking data. + */ +public class ExpeditionExtendedDataFixMapper implements SensorFixMapper, Competitor> { + + @Override + public DynamicSensorFixTrack getTrack(DynamicTrackedRace race, Competitor key) { + return race.getOrCreateSensorTrack(key, BravoFixTrack.TRACK_NAME, + () -> new BravoFixTrackImpl(key, BravoFixTrack.TRACK_NAME, /* hasExtendedFixes */ true)); + } + + @Override + public BravoExtendedFix map(DoubleVectorFix fix) { + return new BravoExtendedFixImpl(fix); + } + + @Override + public boolean isResponsibleFor(Class> eventType) { + return RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl.class.isAssignableFrom(eventType); + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/events/impl/RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/events/impl/RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl.java new file mode 100755 index 00000000000..b0049dbb1e3 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/events/impl/RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl.java @@ -0,0 +1,28 @@ +package com.sap.sailing.domain.abstractlog.regatta.events.impl; + +import java.io.Serializable; + +import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; +import com.sap.sse.common.TimePoint; + +/** + * Mapping event for devices mapped for "Expedition" extended type fixes, coming from the + * "Expedition" software that was originally used in the context of this solution only for + * handling wind data but now is also used to forward sensor data into competitor tracks. + */ +public class RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl extends AbstractRegattaLogDeviceCompetitorSensorDataMappingEventImpl { + private static final long serialVersionUID = -7865925670153838864L; + + public RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint, + AbstractLogEventAuthor author, Serializable pId, Competitor mappedTo, DeviceIdentifier device, + TimePoint from, TimePoint to) { + super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, to); + } + + public RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author, + Competitor mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to) { + super(logicalTimePoint, author, mappedTo, device, from, to); + } +} diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java index baa80fa589a..70c5e21cd04 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java @@ -1150,4 +1150,9 @@ public class MockedTrackedRace implements DynamicTrackedRace { String trackName) { return Collections.emptySet(); } + + @Override + public Speed getAverageSpeedOverGround(Competitor competitor, TimePoint timePoint) { + return null; + } } diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java index 2a0d856e3d1..05132e8622e 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java @@ -702,4 +702,9 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { String trackName) { return Collections.emptySet(); } + + @Override + public Speed getAverageSpeedOverGround(Competitor competitor, TimePoint timePoint) { + return null; + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index 1ff7b0f376b..b9141f4552d 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -25,9 +25,11 @@ import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.base.RaceColumnListener; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.MaxPointsReason; +import com.sap.sailing.domain.common.Mile; import com.sap.sailing.domain.common.NoWindError; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.Speed; +import com.sap.sailing.domain.common.impl.KnotSpeedImpl; import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.NumberOfCompetitorsInLeaderboardFetcher; @@ -40,6 +42,7 @@ import com.sap.sailing.domain.racelog.RaceLogIdentifier; import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.util.impl.RaceColumnListeners; +import com.sap.sse.common.Duration; import com.sap.sse.common.ObscuringIterable; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; @@ -789,31 +792,12 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW @Override public Speed getAverageSpeedOverGround(Competitor competitor, TimePoint timePoint) { - Speed result = null; - for (TrackedRace trackedRace : getTrackedRaces()) { - if (Util.contains(trackedRace.getRace().getCompetitors(), competitor)) { - NavigableSet markPassings = trackedRace.getMarkPassings(competitor); - if (!markPassings.isEmpty()) { - TimePoint from = markPassings.first().getTimePoint(); - TimePoint to; - if (timePoint.after(markPassings.last().getTimePoint()) && - markPassings.last().getWaypoint() == trackedRace.getRace().getCourse().getLastWaypoint()) { - // stop counting when competitor finished the race - to = markPassings.last().getTimePoint(); - } else { - if (markPassings.last().getWaypoint() != trackedRace.getRace().getCourse().getLastWaypoint() && - timePoint.after(markPassings.last().getTimePoint())) { - result = null; - break; - } - to = timePoint; - } - Distance distanceTraveled = trackedRace.getDistanceTraveled(competitor, timePoint); - if (distanceTraveled != null) { - result = distanceTraveled.inTime(to.asMillis()-from.asMillis()); - } - } - } + Speed result = null; + final Duration totalTimeSailed = this.getTotalTimeSailed(competitor, timePoint); + final Distance totalDistanceSailed = this.getTotalDistanceTraveled(competitor, timePoint); + if (totalDistanceSailed != null && totalTimeSailed != null) { + result = new KnotSpeedImpl(totalDistanceSailed.getMeters() / + totalTimeSailed.asSeconds() / Mile.METERS_PER_NAUTICAL_MILE * 3600.0); } return result; } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/trackimport/BaseDoubleVectorFixImporter.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/trackimport/BaseDoubleVectorFixImporter.java new file mode 100644 index 00000000000..d7f46670a47 --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/trackimport/BaseDoubleVectorFixImporter.java @@ -0,0 +1,46 @@ +package com.sap.sailing.domain.trackimport; + +import java.io.IOException; +import java.io.InputStream; + +import com.sap.sailing.domain.common.tracking.DoubleVectorFix; +import com.sap.sailing.domain.trackfiles.TrackFileImportDeviceIdentifier; + +/** + * Definition of importers used by SensorDataImportServlet to do the import of a specific file type. + */ +public interface BaseDoubleVectorFixImporter { + public interface Callback { + void addFixes(Iterable fixes, TrackFileImportDeviceIdentifier device); + } + + /** + * Parses the uploaded file and calls the callback for every fix that's contained in the input. + * + * @param inputStream + * the uploaded file as {@link InputStream} + * @param callback + * the callback to call for every new fix + * @param sourceName + * the uploaded file's name. This can be used to identify the file type if the importer can import + * different formats. + * @param downsample + * whether or not the importer shall reduce the sampling frequency during import; if {@code false}, all + * fixes read from the {@code inputStream} will be forwarded to the {@code callback}; otherwise, multiple + * fixes may be averaged, smoothened and then forwarded as only one combined fix to the {@code callback}. + * @throws FormatNotSupportedException + * if the uploaded file can't be parsed by the importer + * @throws IOException + * if there is a problem while reading the file + */ + void importFixes(InputStream inputStream, Callback callback, String filename, String sourceName, boolean downsample) + throws FormatNotSupportedException, IOException; + + /** + * The type is a String that's presented to the user for selection of the type when doing an import. + * The type is used on import to identify the importer to use depending on the user's selection. + * + * @return name of the file type to be imported by the importer + */ + String getType(); +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/trackimport/DoubleVectorFixImporter.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/trackimport/DoubleVectorFixImporter.java old mode 100644 new mode 100755 index 0bf8ba1fa45..6d58d2a02fd --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/trackimport/DoubleVectorFixImporter.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/trackimport/DoubleVectorFixImporter.java @@ -1,59 +1,22 @@ package com.sap.sailing.domain.trackimport; -import java.io.IOException; -import java.io.InputStream; import java.io.Serializable; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent; import com.sap.sailing.domain.base.Competitor; -import com.sap.sailing.domain.common.tracking.DoubleVectorFix; import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; -import com.sap.sailing.domain.trackfiles.TrackFileImportDeviceIdentifier; import com.sap.sse.common.TimePoint; /** * Definition of importers used by SensorDataImportServlet to do the import of a specific file type. */ -public interface DoubleVectorFixImporter { - - public interface Callback { - void addFixes(Iterable fixes, TrackFileImportDeviceIdentifier device); - } - - /** - * Parses the uploaded file and calls the callback for every fix that's contained in the input. - * - * @param inputStream - * the uploaded file as {@link InputStream} - * @param callback - * the callback to call for every new fix - * @param sourceName - * the uploaded file's name. This can be used to identify the file type if the importer can import - * different formats. - * @param downsample TODO - * @throws FormatNotSupportedException - * if the uploaded file can't be parsed by the importer - * @throws IOException - * if there is a problem while reading the file - */ - void importFixes(InputStream inputStream, Callback callback, String filename, String sourceName, boolean downsample) - throws FormatNotSupportedException, IOException; - - /** - * The type is a String that's presented to the user for selection of the type when doing an import. - * The type is used on import to identify the importer to use depending on the user's selection. - * - * @return name of the file type to be imported by the importer - */ - String getType(); - +public interface DoubleVectorFixImporter extends BaseDoubleVectorFixImporter { /** * Creates the {@link RegattaLogEvent} for the DeviceMapping. */ RegattaLogDeviceCompetitorSensorDataMappingEvent createEvent(TimePoint createdAt, TimePoint logicalTimePoint, AbstractLogEventAuthor author, Serializable id, Competitor mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to); - } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java index 19cf1f6dc63..d6d114e47ba 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java @@ -1012,4 +1012,12 @@ public interface TrackedRace extends Serializable, IsManagedByCache getAttachedRaceLogs(); + /** + * Computes the average speed over ground for a {@link Competitor} based on times and distances + * for all finished {@link TrackedLegOfCompetitor}s. + * + * @param timePoint time point up and until to compute the speed + */ + Speed getAverageSpeedOverGround(Competitor competitor, TimePoint timePoint); + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index dcf53b30598..a93c22b0f4c 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -74,6 +74,7 @@ import com.sap.sailing.domain.common.CourseChange; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.LegType; import com.sap.sailing.domain.common.ManeuverType; +import com.sap.sailing.domain.common.Mile; import com.sap.sailing.domain.common.NauticalSide; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.Position; @@ -4189,4 +4190,23 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl public Iterable getAttachedRaceLogs() { return new HashSet<>(attachedRaceLogs.values()); } + + @Override + public Speed getAverageSpeedOverGround(Competitor competitor, TimePoint timePoint) { + Speed result = null; + Duration totalTimeSailedInRace = Duration.NULL; + Distance totalDistanceSailedInRace = Distance.NULL; + for (TrackedLeg legGeneral : getTrackedLegs()) { + TrackedLegOfCompetitor leg = legGeneral.getTrackedLeg(competitor); + if (leg != null && leg.getTime(timePoint) != null) { + totalDistanceSailedInRace.add(leg.getDistanceTraveled(timePoint)); + totalTimeSailedInRace.plus(leg.getTime(timePoint)); + } + } + if (!totalTimeSailedInRace.equals(Duration.NULL) && !totalDistanceSailedInRace.equals(Distance.NULL)) { + result = new KnotSpeedImpl(totalDistanceSailedInRace.getMeters() / + totalTimeSailedInRace.asSeconds() / Mile.METERS_PER_NAUTICAL_MILE * 3600.0); + } + return result; + } } diff --git a/java/com.sap.sailing.feature.p2build/raceanalysis.product b/java/com.sap.sailing.feature.p2build/raceanalysis.product index 323a04edf26..3a90dec43c3 100755 --- a/java/com.sap.sailing.feature.p2build/raceanalysis.product +++ b/java/com.sap.sailing.feature.p2build/raceanalysis.product @@ -38,6 +38,7 @@ + @@ -90,4 +91,11 @@ + + + + + + + diff --git a/java/com.sap.sailing.feature/feature.xml b/java/com.sap.sailing.feature/feature.xml index 728e3f5ab9a..b5be4ddd98f 100755 --- a/java/com.sap.sailing.feature/feature.xml +++ b/java/com.sap.sailing.feature/feature.xml @@ -395,4 +395,11 @@ Computes leaderboard information for sailing races and offers RESTful APIs to al version="0.0.0" unpack="false"/> + + diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java index 58af534d869..7337703c9d7 100644 --- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java @@ -720,7 +720,6 @@ public class MockedTrackedRace implements DynamicTrackedRace { @Override public boolean isUsingMarkPassingCalculator() { - // TODO Auto-generated method stub return false; } @@ -881,4 +880,9 @@ public class MockedTrackedRace implements DynamicTrackedRace { String trackName) { return Collections.emptySet(); } + + @Override + public Speed getAverageSpeedOverGround(Competitor competitor, TimePoint timePoint) { + return null; + } } diff --git a/java/com.sap.sailing.gwt.ui/DataMining.css b/java/com.sap.sailing.gwt.ui/DataMining.css index 54a9607fc06..5f52d30e4ad 100644 --- a/java/com.sap.sailing.gwt.ui/DataMining.css +++ b/java/com.sap.sailing.gwt.ui/DataMining.css @@ -257,4 +257,4 @@ input.magnifier { .queryDefinitionViewerContent { background-color: white; padding: 5px; -} \ No newline at end of file +} diff --git a/java/com.sap.sailing.gwt.ui/SailingGWT sdm.launch b/java/com.sap.sailing.gwt.ui/SailingGWT sdm.launch index 54e1704423a..0e9d9decea6 100755 --- a/java/com.sap.sailing.gwt.ui/SailingGWT sdm.launch +++ b/java/com.sap.sailing.gwt.ui/SailingGWT sdm.launch @@ -62,5 +62,5 @@ - + diff --git a/java/com.sap.sailing.gwt.ui/SailingGWT.launch b/java/com.sap.sailing.gwt.ui/SailingGWT.launch index 3ec300f1256..3dd4667c212 100644 --- a/java/com.sap.sailing.gwt.ui/SailingGWT.launch +++ b/java/com.sap.sailing.gwt.ui/SailingGWT.launch @@ -58,7 +58,7 @@ - + - + diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/app/DesktopActivityMapper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/app/DesktopActivityMapper.java index cd607d79b82..34ecac07a44 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/app/DesktopActivityMapper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/app/DesktopActivityMapper.java @@ -3,7 +3,6 @@ package com.sap.sailing.gwt.home.desktop.app; import com.google.gwt.activity.shared.Activity; import com.google.gwt.activity.shared.ActivityMapper; import com.google.gwt.place.shared.Place; -import com.sap.sailing.gwt.common.client.formfactor.DeviceDetector; import com.sap.sailing.gwt.home.desktop.places.aboutus.AboutUsActivityProxy; import com.sap.sailing.gwt.home.desktop.places.aboutus.AboutUsPlace; import com.sap.sailing.gwt.home.desktop.places.contact.ContactActivityProxy; @@ -37,6 +36,7 @@ import com.sap.sailing.gwt.home.shared.places.user.confirmation.ConfirmationPlac import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetActivityProxy; import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetPlace; import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace; +import com.sap.sse.gwt.client.formfactor.DeviceDetector; public class DesktopActivityMapper implements ActivityMapper { private final DesktopClientFactory clientFactory; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.gss index bbb5545e440..88081595726 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.gss +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.gss @@ -48,9 +48,3 @@ text-align: right; } } -.sitefooter_language_link { - color: #efaa00; - display: inline-block; - cursor: pointer; - margin-left: 0.666666666666667em; -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.java index 02fc522ec7e..d56dd87fbc3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.java @@ -1,28 +1,13 @@ package com.sap.sailing.gwt.home.desktop.partials.footer; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; - import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.AnchorElement; -import com.google.gwt.dom.client.DivElement; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.logical.shared.ValueChangeEvent; -import com.google.gwt.http.client.UrlBuilder; -import com.google.gwt.i18n.client.LocaleInfo; -import com.google.gwt.text.shared.Renderer; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.EventListener; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.Window.Location; -import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.ValueListBox; import com.google.gwt.user.client.ui.Widget; import com.google.web.bindery.event.shared.EventBus; import com.sap.sailing.gwt.home.desktop.app.DesktopPlacesNavigator; @@ -30,9 +15,6 @@ import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewPlace; import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs; import com.sap.sailing.gwt.home.shared.SwitchingEntryPoint; import com.sap.sailing.gwt.home.shared.app.PlaceNavigation; -import com.sap.sse.common.Util; -import com.sap.sse.common.Util.Pair; -import com.sap.sse.gwt.client.GWTLocaleUtil; public class Footer extends Composite { private static FooterPanelUiBinder uiBinder = GWT.create(FooterPanelUiBinder.class); @@ -40,32 +22,8 @@ public class Footer extends Composite { interface FooterPanelUiBinder extends UiBinder { } - @UiField Anchor changeLanguageLink; @UiField AnchorElement imprintAnchorLink; - @UiField DivElement languageSelectionDiv; - @UiField(provided = true) ValueListBox> changeLanguageList = new ValueListBox>(new Renderer>() { - @Override - public String render(Pair object) { - if(object == null) { - return ""; - } - if(object.getB() != null) { - return object.getB(); - } - return object.getA(); - } - - @Override - public void render(Pair object, Appendable appendable) throws IOException { - appendable.append(render(object)); - } - }); - @UiField AnchorElement mobileUi; - private String otherLanguage; - private final LocaleInfo currentLocale = LocaleInfo.getCurrentLocale(); - - @UiField(provided = true) final PlaceNavigation releaseNotesNavigation; @@ -76,7 +34,6 @@ public class Footer extends Composite { initWidget(uiBinder.createAndBindUi(this)); navigator.getImprintNavigation().configureAnchorElement(imprintAnchorLink); - updateUI(); DOM.sinkEvents(mobileUi, Event.ONCLICK); DOM.setEventListener(mobileUi, new EventListener() { @Override @@ -89,58 +46,4 @@ public class Footer extends Composite { }); } - - @UiHandler("changeLanguageLink") - public void changeLanguage(ClickEvent e) { - if(otherLanguage != null) { - UrlBuilder builder = Location.createUrlBuilder().setParameter("locale", otherLanguage); - Window.Location.replace(builder.buildString()); - } - } - - @UiHandler("changeLanguageList") - void onListSelection(ValueChangeEvent> event) { - String selectedLocaleName = event.getValue().getA(); - if(!currentLocale.getLocaleName().equals(selectedLocaleName)) { - UrlBuilder builder = Location.createUrlBuilder().setParameter("locale", selectedLocaleName); - Window.Location.replace(builder.buildString()); - } - } - - private void updateUI() { - final Iterable availableLocales = GWTLocaleUtil.getAvailableLocales(); - final int localeCount = Util.size(availableLocales); - - if (localeCount <= 1) { - // only current language (or removed default) available - changeLanguageLink.removeFromParent(); - changeLanguageList.removeFromParent(); - languageSelectionDiv.removeFromParent(); - return; - } - if (Util.size(availableLocales) == 2) { - changeLanguageList.removeFromParent(); - // current language + one we can switch to - for (String localeName : availableLocales) { - if (!currentLocale.getLocaleName().equals(localeName)) { - otherLanguage = localeName; - changeLanguageLink.setText(LocaleInfo.getLocaleNativeDisplayName(otherLanguage)); - return; - } - } - return; - } - changeLanguageLink.removeFromParent(); - Collection> values = new ArrayList<>(); - Pair selectedValue = null; - for (String localeName : availableLocales) { - Pair value = new Pair(localeName, LocaleInfo.getLocaleNativeDisplayName(localeName)); - values.add(value); - if (currentLocale.getLocaleName().equals(localeName)) { - selectedValue = value; - } - } - changeLanguageList.setValue(selectedValue); - changeLanguageList.setAcceptableValues(values); - } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.ui.xml index a0bfd39be8e..e67cc4cc916 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/Footer.ui.xml @@ -1,37 +1,11 @@ - - .languageSelect::-ms-expand { - display: none; - } - .languageSelect { - -webkit-appearance: none; - -moz-appearance: none; - -ms-appearance: none; - appearance: none; - - margin-top: 25px; - color: #efaa00; - line-height: 1.5em; - height: 1.5em; - display: inline-block; - border: transparent; - cursor: pointer; - padding-right: 1.2em; - background: #333; - cursor: pointer; - - background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZlcnNpb249JzEuMScgaGVpZ2h0PScxOHB4JyB3aWR0aD0nMTZweCc+PHRleHQgeD0nMCcgeT0nMTUnIGZpbGw9JyNlZmFhMDAnIGZvbnQtc2l6ZT0nMTYnPiYjOTY2MDs8L3RleHQ+PC9zdmc+"); - background-position: right center; - background-repeat: no-repeat; - - } -
@@ -61,11 +35,8 @@
-
- : - - -
+
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/FooterResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/FooterResources.java index ce5aad9d4f1..7c73496fd50 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/FooterResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/footer/FooterResources.java @@ -16,6 +16,5 @@ public interface FooterResources extends ClientBundle { String sitefooter_links(); String sitefooter_links_link(); String sitefooter_language(); - String sitefooter_language_link(); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/old/EventRegattaLeaderboard.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/old/EventRegattaLeaderboard.gss index 1c2c0a867a0..c19abc8c77e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/old/EventRegattaLeaderboard.gss +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/old/EventRegattaLeaderboard.gss @@ -238,7 +238,7 @@ } .letItScroll { overflow-x: auto; - margin: 10px 0px; + padding: 10px 30px 10px 10px; } .regattaleaderboard_meta_fullscreen_button { background-color: #9f9f9f; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/event/AbstractEventActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/event/AbstractEventActivity.java old mode 100755 new mode 100644 index 90a2371b370..aa8ca601d0f --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/event/AbstractEventActivity.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/event/AbstractEventActivity.java @@ -232,7 +232,8 @@ public abstract class AbstractEventActivity ex regattaRaceStatesSettings.getVisibleRegattaSettings().addValue(getRegattaId()); } } - return EntryPointWithSettingsLinkFactory.createRegattaOverviewLink(new RegattaOverviewContextDefinition(getCtx().getEventId()), regattaRaceStatesSettings); + return EntryPointWithSettingsLinkFactory.createRegattaOverviewLink( + new RegattaOverviewContextDefinition(getCtx().getEventId()), regattaRaceStatesSettings, false); } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.gss index 70cd072f687..32b7a0e8c59 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.gss +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.gss @@ -14,11 +14,8 @@ .sitefooter_language { display: block; } -a.sitefooter_language_link { - color: #fff; -} -a.sitefooter_language_linkactive { - color: #efaa00; +.sitefooter_language select { + font-size: 110%; } .sitefooter_links { font-weight: 600; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.java index a07f9cbce7d..a7f75d1530c 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.java @@ -1,34 +1,19 @@ package com.sap.sailing.gwt.home.mobile.partials.footer; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.AnchorElement; -import com.google.gwt.dom.client.DivElement; import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.logical.shared.ValueChangeEvent; -import com.google.gwt.http.client.UrlBuilder; -import com.google.gwt.i18n.client.LocaleInfo; -import com.google.gwt.text.shared.Renderer; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.EventListener; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.Window.Location; -import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.ValueListBox; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewPlace; import com.sap.sailing.gwt.home.mobile.app.MobilePlacesNavigator; import com.sap.sailing.gwt.home.shared.SwitchingEntryPoint; -import com.sap.sse.common.Util.Pair; /** * Mobile page footer with several links and the ability to switch the language. @@ -39,32 +24,10 @@ public class Footer extends Composite { interface FooterPanelUiBinder extends UiBinder { } - private String otherLanguage; - private final LocaleInfo currentLocale = LocaleInfo.getCurrentLocale(); - private MobilePlacesNavigator placeNavigator; - - @UiField Anchor changeLanguageLink; @UiField AnchorElement imprintAnchorLink; - @UiField DivElement languageSelectionDiv; @UiField AnchorElement desktopUi; - @UiField(provided = true) ValueListBox> changeLanguageList = new ValueListBox>(new Renderer>() { - @Override - public String render(Pair object) { - if(object == null) { - return ""; - } - if(object.getB() != null) { - return object.getB(); - } - return object.getA(); - } - - @Override - public void render(Pair object, Appendable appendable) throws IOException { - appendable.append(render(object)); - } - }); + private final MobilePlacesNavigator placeNavigator; public Footer(MobilePlacesNavigator placeNavigator) { this.placeNavigator = placeNavigator; @@ -73,7 +36,6 @@ public class Footer extends Composite { initWidget(uiBinder.createAndBindUi(this)); placeNavigator.getImprintNavigation().configureAnchorElement(imprintAnchorLink); - updateUI(); DOM.sinkEvents(desktopUi, Event.ONCLICK); DOM.setEventListener(desktopUi, new EventListener() { @Override @@ -86,62 +48,9 @@ public class Footer extends Composite { }); } - @UiHandler("changeLanguageLink") - public void changeLanguage(ClickEvent e) { - if(otherLanguage != null) { - UrlBuilder builder = Location.createUrlBuilder().setParameter("locale", otherLanguage); - Window.Location.replace(builder.buildString()); - } - } - - @UiHandler("changeLanguageList") - void onListSelection(ValueChangeEvent> event) { - String selectedLocaleName = event.getValue().getA(); - if(!currentLocale.getLocaleName().equals(selectedLocaleName)) { - UrlBuilder builder = Location.createUrlBuilder().setParameter("locale", selectedLocaleName); - Window.Location.replace(builder.buildString()); - } - } - @UiHandler("whatsNewLinkUi") void onWhatsNew(ClickEvent e) { placeNavigator.getWhatsNewNavigation(WhatsNewPlace.WhatsNewNavigationTabs.SailingAnalytics).goToPlace(); } - private void updateUI() { - Set availableLocales = new HashSet(Arrays.asList(LocaleInfo.getAvailableLocaleNames())); - availableLocales.remove("default"); - - if(availableLocales.size() <= 1) { - // only current language (or removed default) available - changeLanguageLink.removeFromParent(); - changeLanguageList.removeFromParent(); - languageSelectionDiv.removeFromParent(); - return; - } - if(availableLocales.size() == 2) { - changeLanguageList.removeFromParent(); - // current language + one we can switch to - for(String localeName : availableLocales) { - if(!currentLocale.getLocaleName().equals(localeName)) { - otherLanguage = localeName; - changeLanguageLink.setText(LocaleInfo.getLocaleNativeDisplayName(otherLanguage)); - return; - } - } - return; - } - changeLanguageLink.removeFromParent(); - Set> values = new HashSet<>(); - Pair selectedValue = null; - for(String localeName : availableLocales) { - Pair value = new Pair(localeName, LocaleInfo.getLocaleNativeDisplayName(localeName)); - values.add(value); - if(currentLocale.getLocaleName().equals(localeName)) { - selectedValue = value; - } - } - changeLanguageList.setValue(selectedValue); - changeLanguageList.setAcceptableValues(values); - } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.ui.xml index 14bf6904283..c48a3dd984e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.ui.xml @@ -1,60 +1,17 @@ - - - - - - - .languageSelect::-ms-expand { - display: none; - } - - .languageSelect { - -webkit-appearance: none; - -moz-appearance: none; - -ms-appearance: none; - appearance: none; - margin-top: 25px; - color: #efaa00; - line-height: 1.5em; - height: 1.5em; - display: inline-block; - border: transparent; - cursor: pointer; - padding-right: 1.2em; - background: #333; - cursor: pointer; - background-image: - url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZlcnNpb249JzEuMScgaGVpZ2h0PScxOHB4JyB3aWR0aD0nMTZweCc+PHRleHQgeD0nMCcgeT0nMTUnIGZpbGw9JyNlZmFhMDAnIGZvbnQtc2l6ZT0nMTYnPiYjOTY2MDs8L3RleHQ+PC9zdmc+"); - background-position: right center; - background-repeat: no-repeat; - font-size: 110%; - } - + + + +