mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-15 10:18:45 +00:00
bug6069: Sailor Profile Name is available as a new dimension in data mining
This commit is contained in:
+2
-1
@@ -285,4 +285,5 @@ RatioDurationLongVsShortTack=Ratio duration long tack / short tack
|
||||
Discarded=Discarded
|
||||
DurationFromRaceStartToFirstTack=Duration from race start to first tack
|
||||
TypeOfFirstLeg=Type of first leg
|
||||
TenthInLeg=Which tenth of the leg (1-10)
|
||||
TenthInLeg=Which tenth of the leg (1-10)
|
||||
SailorProfile=Sailor Profile
|
||||
+2
-1
@@ -283,4 +283,5 @@ RatioDurationLongVsShortTack=Verhältnis gesegelte Dauer auf Streck- zu Holebug
|
||||
Discarded=Gestrichen
|
||||
DurationFromRaceStartToFirstTack=Dauer vom Start der Wettfahrt bis zur ersten Wende
|
||||
TypeOfFirstLeg=Art des ersten Bahnschenkels
|
||||
TenthInLeg=Zehntel des Bahnschenkels (1-10)
|
||||
TenthInLeg=Zehntel des Bahnschenkels (1-10)
|
||||
SailorProfile=Seglerprofil
|
||||
+5
@@ -34,6 +34,11 @@ public interface AbstractHasTrackedLegSliceOfCompetitorContext extends HasWindOn
|
||||
@Connector(messageKey="Competitor")
|
||||
public Competitor getCompetitor();
|
||||
|
||||
@Connector(messageKey="SailorProfile")
|
||||
default public SailorProfile getSailorProfile() {
|
||||
return getTrackedLegContext().getTrackedRaceContext().getLeaderboardContext().getLeaderboardGroupContext().getSailorProfiles().getProfileForCompetitor(getCompetitor());
|
||||
}
|
||||
|
||||
@Statistic(messageKey="DistanceTraveled", resultDecimals=2, ordinal=0)
|
||||
public Distance getDistanceTraveled();
|
||||
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.server.preferences.SailorProfilePreference;
|
||||
import com.sap.sailing.server.preferences.SailorProfilePreferences;
|
||||
import com.sap.sse.common.NamedWithUUID;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* A sailor profile currently mainly consists of a set of competitors that it consolidates into a single profile. It can
|
||||
* be used particularly in a data mining context when there are multiple distinct records that from a user's point of
|
||||
* view represent the same sailor/competitor. With this, a user can define a {@link SailorProfile} like an "equivalence
|
||||
* class" that allows the user to, e.g., filter or group data mining results based on a competitor's "equivalence
|
||||
* class."
|
||||
* <p>
|
||||
*
|
||||
* A typical example would be a single-handed class, say "ILCA 6," where the same person has been participating in
|
||||
* several events, but each time captured with a different technical competitor ID, maybe even competing under different
|
||||
* sail numbers. Yet, during analysis, it may make sense to group the results for all of these entities under one sailor
|
||||
* profile.
|
||||
* <p>
|
||||
*
|
||||
* Technically, the sailor profiles are managed as user preferences in the user store. A preference converter can turn
|
||||
* the underlying JSON string into an {@link SailorProfilePreferences} object which contains
|
||||
* {@link SailorProfilePreference}. These, in turn, can be converted to instances of a type implementing this interface.
|
||||
* <p>
|
||||
*
|
||||
* Comparability is defined such that no two profiles with different {@link #getId() IDs} will ever compare equal.
|
||||
* Beyond this, {@link SailorProfile}s with a greater number of {@link #getCompetitors() competitors} than another will
|
||||
* be considered "greater." In case of an equal number of competitors, the sailor profile {@link #getName() name} will
|
||||
* be used for lexicographic ordering. In case of equal names, sorting will work by the stringified version of the
|
||||
* {@link #getId() UUID}.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface SailorProfile extends NamedWithUUID, Comparable<SailorProfile> {
|
||||
Iterable<Competitor> getCompetitors();
|
||||
|
||||
@Override
|
||||
default int compareTo(SailorProfile o) {
|
||||
int result = Integer.compare(Util.size(getCompetitors()), Util.size(o.getCompetitors()));
|
||||
if (result == 0) {
|
||||
result = getName().compareTo(o.getName());
|
||||
if (result == 0) {
|
||||
result = getId().compareTo(o.getId());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+12
-4
@@ -1,13 +1,21 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
|
||||
/**
|
||||
* A "data mining" view on the current user's sailor profiles as define in the user preferences.
|
||||
* When constructed, it collects all of the user's sailor profiles and builds a map from the
|
||||
* {@link Competitor} objects to the {@link SailorProfile} objects that refer to that competitor.
|
||||
* A "data mining" view on the current user's sailor profiles as defined in the user preferences. When an instance is
|
||||
* constructed, it collects all of the user's sailor profiles and builds a map from the {@link Competitor} objects to
|
||||
* the {@link SailorProfile} objects that refer to that {@link Competitor}.
|
||||
* <p>
|
||||
*
|
||||
* When more than one of the user's {@link SailorProfile}s comprise the same {@link Competitor}, a stable algorithm
|
||||
* for determining a single preferred {@link SailorProfile} for the {@link Competitor} will be used in the
|
||||
* {@link #getProfileForCompetitor(Competitor)}, finding the "greatest" (as defined by the {@link Comparable} property
|
||||
* of the {@link SailorProfile} interface) profile for the {@link Competitor}.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface SailorProfiles {
|
||||
|
||||
SailorProfile getProfileForCompetitor(Competitor competitor);
|
||||
}
|
||||
|
||||
+11
-2
@@ -1,6 +1,10 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardGroupContext;
|
||||
import com.sap.sailing.datamining.data.SailorProfile;
|
||||
import com.sap.sailing.datamining.data.SailorProfiles;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
@@ -51,8 +55,13 @@ public class LeaderboardGroupWithContext implements HasLeaderboardGroupContext {
|
||||
public synchronized SailorProfiles getSailorProfiles() {
|
||||
if (sailorProfiles == null) {
|
||||
final SailorProfilePreferences sailorProfilePreferences = getSecurityService().getPreferenceObject(getSecurityService().getCurrentUser().getName(), SailorProfilePreferences.PREF_NAME);
|
||||
for (final SailorProfilePreference sailorProfilePreference : sailorProfilePreferences.getSailorProfiles()) {
|
||||
|
||||
if (sailorProfilePreferences != null) {
|
||||
final List<SailorProfile> theSailorProfiles = new ArrayList<>();
|
||||
for (final SailorProfilePreference sailorProfilePreference : sailorProfilePreferences.getSailorProfiles()) {
|
||||
final SailorProfile sailorProfile = new SailorProfileImpl(sailorProfilePreference.getUuid(), sailorProfilePreference.getName(), sailorProfilePreference.getCompetitors());
|
||||
theSailorProfiles.add(sailorProfile);
|
||||
}
|
||||
sailorProfiles = new SailorProfilesImpl(theSailorProfiles);
|
||||
}
|
||||
}
|
||||
return sailorProfiles;
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sailing.datamining.data.SailorProfile;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.NamedWithUUIDImpl;
|
||||
|
||||
public class SailorProfileImpl extends NamedWithUUIDImpl implements SailorProfile {
|
||||
private static final long serialVersionUID = 5851705759679719738L;
|
||||
|
||||
private final List<Competitor> competitors;
|
||||
|
||||
public SailorProfileImpl(UUID id, String name, Iterable<Competitor> competitors) {
|
||||
super(name, id);
|
||||
final List<Competitor> myCompetitors = new ArrayList<>();
|
||||
Util.addAll(competitors, myCompetitors);
|
||||
this.competitors = myCompetitors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getCompetitors() {
|
||||
return Collections.unmodifiableList(competitors);
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.datamining.data.SailorProfile;
|
||||
import com.sap.sailing.datamining.data.SailorProfiles;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
|
||||
public class SailorProfilesImpl implements SailorProfiles {
|
||||
final Map<Competitor, SailorProfile> profilesForCompetitor;
|
||||
|
||||
/**
|
||||
* Constructs the mapping from {@link Competitor} to {@link SailorProfile} based on the
|
||||
* {@link SailorProfile#compareTo(SailorProfile) ordering} of the {@link SailorProfile}s. For each competitor,
|
||||
* {@link #getProfileForCompetitor(Competitor)} will return the "greatest" profile found that
|
||||
* {@link SailorProfile#getCompetitors() contains} that competitor.
|
||||
*/
|
||||
public SailorProfilesImpl(final Iterable<SailorProfile> sailorProfiles) {
|
||||
this.profilesForCompetitor = new HashMap<>();
|
||||
for (final SailorProfile sailorProfile : sailorProfiles) {
|
||||
for (final Competitor competitor : sailorProfile.getCompetitors()) {
|
||||
final SailorProfile existingSailorProfileForCompetitor = profilesForCompetitor.get(competitor);
|
||||
if (existingSailorProfileForCompetitor == null || existingSailorProfileForCompetitor.compareTo(sailorProfile) < 0) {
|
||||
profilesForCompetitor.put(competitor, sailorProfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SailorProfile getProfileForCompetitor(Competitor competitor) {
|
||||
return profilesForCompetitor.get(competitor);
|
||||
}
|
||||
}
|
||||
+3
@@ -25,6 +25,9 @@
|
||||
leg's end waypoint (e.g., the windward mark for an upwind leg). The metrics are again
|
||||
available in signed/unsigned as well as in absolute and relative (to half the leg distance)
|
||||
variants.</li>
|
||||
<li>Introduced a new Data Mining dimension "Sailor Profile Name." With this, if a user in their "User Details"
|
||||
creates one or more "Sailor Profiles" to group multiple occurrences of what is to be considered "the same sailor"
|
||||
into one profile, these profiles can be used for filtering and grouping in data mining.</li>
|
||||
</ul>
|
||||
<h5 class="articleSubheadline">October 2024</h5>
|
||||
<ul class="bulletList">
|
||||
|
||||
Reference in New Issue
Block a user