mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-07 11:32:16 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
2ed0ead422
80 files changed
+2908
-1460
No files matched your search
+1
-1
@@ -2,5 +2,5 @@ package com.sap.sailing.domain.common;
|
||||
|
||||
public enum ScoringSchemeType {
|
||||
LOW_POINT, HIGH_POINT, HIGH_POINT_ESS_OVERALL, HIGH_POINT_LAST_BREAKS_TIE, HIGH_POINT_FIRST_GETS_TEN,
|
||||
HIGH_POINT_FIRST_GETS_ONE, LOW_POINT_WINNER_GETS_ZERO, HIGH_POINT_WINNER_GETS_SIX
|
||||
HIGH_POINT_FIRST_GETS_ONE, LOW_POINT_WINNER_GETS_ZERO, HIGH_POINT_WINNER_GETS_SIX, HIGH_POINT_WINNER_GETS_FIVE
|
||||
}
|
||||
+2
-2
@@ -13,7 +13,7 @@ import java.util.Comparator;
|
||||
public class NaturalComparator implements Comparator<String> {
|
||||
boolean caseSensitive;
|
||||
|
||||
public NaturalComparator(boolean caseSensitive){
|
||||
public NaturalComparator(boolean caseSensitive) {
|
||||
this.caseSensitive = caseSensitive;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class NaturalComparator implements Comparator<String> {
|
||||
*/
|
||||
@Override
|
||||
public int compare(String a, String b) {
|
||||
if(!caseSensitive){
|
||||
if (!caseSensitive){
|
||||
a = a.toLowerCase();
|
||||
b = a.toLowerCase();
|
||||
}
|
||||
|
||||
+4
-1
@@ -89,7 +89,7 @@ public class TeamImpl extends NamedImpl implements DynamicTeam {
|
||||
|
||||
@Override
|
||||
public Nationality getNationality() {
|
||||
return getNationalityDonor().getNationality();
|
||||
return getNationalityDonor() == null ? null : getNationalityDonor().getNationality();
|
||||
}
|
||||
|
||||
private WithNationality getNationalityDonor() {
|
||||
@@ -111,6 +111,9 @@ public class TeamImpl extends NamedImpl implements DynamicTeam {
|
||||
for (Person sailor : getSailors()) {
|
||||
((DynamicPerson) sailor).setNationality(newNationality);
|
||||
}
|
||||
if (getCoach() != null) {
|
||||
getCoach().setNationality(newNationality);
|
||||
}
|
||||
for (NationalityChangeListener listener : getNationalityChangeListeners()) {
|
||||
listener.nationalityChanged(this, oldNationality, newNationality);
|
||||
}
|
||||
|
||||
+36
-3
@@ -1,11 +1,15 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sailing.util.impl.LockUtil;
|
||||
import com.sap.sailing.util.impl.NamedReentrantReadWriteLock;
|
||||
|
||||
public class VenueImpl implements Venue {
|
||||
private static final long serialVersionUID = 6854152040737643290L;
|
||||
@@ -16,25 +20,54 @@ public class VenueImpl implements Venue {
|
||||
* "NATO alphabet" (Alpha, Bravo, Charlie, ...).
|
||||
*/
|
||||
private final List<CourseArea> courseAreas;
|
||||
|
||||
private NamedReentrantReadWriteLock courseAreasLock;
|
||||
|
||||
public VenueImpl(String name) {
|
||||
this.name = name;
|
||||
courseAreas = new ArrayList<CourseArea>();
|
||||
courseAreasLock = createCourseAreasLock(name);
|
||||
}
|
||||
|
||||
private NamedReentrantReadWriteLock createCourseAreasLock(String name) {
|
||||
return new NamedReentrantReadWriteLock("Course Areas for venue "+name, /* fair */ false);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
ois.defaultReadObject();
|
||||
if (courseAreasLock == null) {
|
||||
courseAreasLock = createCourseAreasLock(getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<CourseArea> getCourseAreas() {
|
||||
return Collections.unmodifiableList(courseAreas);
|
||||
LockUtil.lockForRead(courseAreasLock);
|
||||
try {
|
||||
return Collections.unmodifiableList(courseAreas);
|
||||
} finally {
|
||||
LockUtil.unlockAfterRead(courseAreasLock);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCourseArea(CourseArea courseArea) {
|
||||
courseAreas.add(courseArea);
|
||||
LockUtil.lockForWrite(courseAreasLock);
|
||||
try {
|
||||
courseAreas.add(courseArea);
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(courseAreasLock);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCourseArea(CourseArea courseArea) {
|
||||
courseAreas.remove(courseArea);
|
||||
LockUtil.lockForWrite(courseAreasLock);
|
||||
try {
|
||||
courseAreas.remove(courseArea);
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(courseAreasLock);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-4
@@ -122,7 +122,7 @@ public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
|
||||
eventsById.put(event.getId(), event);
|
||||
notifyListenersAboutReceive(event);
|
||||
} else {
|
||||
logger.warning(String.format("%s (%s) was not added to race log %s. Ignoring", event, event.getClass().getName(), getId()));
|
||||
logger.fine(String.format("%s (%s) was not added to race log %s because it already existed there.", event, event.getClass().getName(), getId()));
|
||||
}
|
||||
return isAdded;
|
||||
}
|
||||
@@ -142,8 +142,8 @@ public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
|
||||
revokeIfNecessary(event);
|
||||
eventsById.put(event.getId(), event);
|
||||
} else {
|
||||
logger.warning(String
|
||||
.format("%s (%s) was not loaded into log. Ignoring", event, event.getClass().getName()));
|
||||
logger.fine(String
|
||||
.format("%s (%s) was not loaded into log because it already existed there.", event, event.getClass().getName()));
|
||||
}
|
||||
return isAdded;
|
||||
}
|
||||
@@ -202,7 +202,7 @@ public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
|
||||
revokeIfNecessary(event);
|
||||
notifyListenersAboutReceive(event);
|
||||
} else {
|
||||
logger.warning(String.format("%s (%s) was not added to log. Ignoring", event, event.getClass().getName()));
|
||||
logger.fine(String.format("%s (%s) was not added to log because it already eists there.", event, event.getClass().getName()));
|
||||
}
|
||||
return getEventsToDeliver(clientId, event);
|
||||
}
|
||||
|
||||
+1
-1
@@ -191,7 +191,7 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
Iterable<Competitor> competitors = createCompetitorList(startList, race.getRaceID(), race.getBoatClass());
|
||||
logger.info("Creating RaceDefinitionImpl for race "+race.getRaceID());
|
||||
BoatClass boatClass = race.getBoatClass() != null ? race.getBoatClass() : getRaceTypeFromRaceID(race.getRaceID()).getBoatClass();
|
||||
RaceDefinition result = new RaceDefinitionImpl(race.getRaceName(), domainCourse, boatClass, competitors);
|
||||
RaceDefinition result = new RaceDefinitionImpl(race.getRaceName(), domainCourse, boatClass, competitors, race.getRaceID());
|
||||
regatta.addRace(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
+8
-3
@@ -518,8 +518,9 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
|
||||
SailMasterMessage opnResponse = new SailMasterMessageImpl(receiveMessage(is));
|
||||
if (opnResponse.getType() != MessageType.OPN || !"OK".equals(opnResponse.getSections()[1])) {
|
||||
logger.info("Recevied non-OK response " + opnResponse + " in "+this+" for our request " + opnRequest
|
||||
+ ". Closing socket and trying again in 1s...");
|
||||
closeAndNullSocketAndWaitABit();
|
||||
+ ". Closing socket and stopping because we have no hope for recovery");
|
||||
stopped = true;
|
||||
closeSocket();
|
||||
} else {
|
||||
logger.info("Received " + opnResponse + " in "+this+" which seems OK. Continuing with "
|
||||
+ MessageType.LSN.name() + " request...");
|
||||
@@ -553,6 +554,11 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
|
||||
}
|
||||
|
||||
private void closeAndNullSocketAndWaitABit() throws InterruptedException {
|
||||
closeSocket();
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
private void closeSocket() {
|
||||
if (socket != null) {
|
||||
try {
|
||||
socket.close();
|
||||
@@ -561,7 +567,6 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
|
||||
}
|
||||
socket = null;
|
||||
}
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-1
@@ -68,7 +68,11 @@ public class SailMasterMessageImpl implements SailMasterMessage {
|
||||
} else {
|
||||
typeAsString = typeAsStringWithOptionalSuffix.substring(0, typeAsStringWithOptionalSuffix.length()-1);
|
||||
}
|
||||
return MessageType.valueOf(typeAsString);
|
||||
try {
|
||||
return MessageType.valueOf(typeAsString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.swisstimingreplayadapter.test;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -195,6 +196,7 @@ public class SwissTimingReplayAdapterServiceTest {
|
||||
Iterable<? extends TrackedRace> trackedRaces = replayListener.getTrackedRaces();
|
||||
TrackedRace trackedRace = trackedRaces.iterator().next();
|
||||
for (Competitor competitor : trackedRace.getRace().getCompetitors()) {
|
||||
assertSame(DomainFactory.INSTANCE.getBaseDomainFactory().getOrCreateBoatClass("470"), competitor.getBoat().getBoatClass());
|
||||
Distance distanceToLineAtStart = trackedRace.getDistanceToStartLine(competitor, trackedRace.getStartOfRace());
|
||||
assertTrue(distanceToLineAtStart.getMeters() > 0);
|
||||
assertTrue(distanceToLineAtStart.getMeters() < 8.5);
|
||||
|
||||
+2
-2
@@ -233,7 +233,7 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter {
|
||||
short ctPoints_x10_Winner) {
|
||||
if (boatType == BoatType.Competitor) {
|
||||
Competitor competitor = domainFactory.createCompetitorWithoutID(sailNumberOrTrackerID, threeLetterIOCCode.trim(), name.trim(),
|
||||
currentRaceID, null /* boat class */);
|
||||
currentRaceID, domainFactory.getRaceTypeFromRaceID(currentRaceID).getBoatClass());
|
||||
Set<Competitor> competitorsOfCurrentRace = competitorsPerRaceID.get(currentRaceID);
|
||||
if (competitorsOfCurrentRace == null) {
|
||||
competitorsOfCurrentRace = new HashSet<>();
|
||||
@@ -306,7 +306,7 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter {
|
||||
|
||||
private void createRace() {
|
||||
final Regatta myRegatta = regatta != null ? regatta : domainFactory.getOrCreateDefaultRegatta(EmptyRaceLogStore.INSTANCE,
|
||||
currentRaceID, null /* boat class */, trackedRegattaRegistry);
|
||||
currentRaceID, domainFactory.getRaceTypeFromRaceID(currentRaceID).getBoatClass(), trackedRegattaRegistry);
|
||||
RaceDefinition race = domainFactory.createRaceDefinition(myRegatta,
|
||||
currentRaceID, competitorsPerRaceID.get(currentRaceID), currentCourseDefinition);
|
||||
racePerRaceID.put(currentRaceID, race);
|
||||
|
||||
+11
@@ -3,6 +3,10 @@ package com.sap.sailing.domain.common.test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -103,5 +107,12 @@ public class NaturalComparatorTest {
|
||||
assertTrue(comparator.compare("0.01", "0.2") < 0);
|
||||
assertTrue(comparator.compare("0.1.5b", "0.2a") < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortSailIDs() {
|
||||
List<String> list = Arrays.asList("Groupama", "GER8829", "A", "FRA 56893", "Cam", "GAC Pindar", "Grün", "a/m", "d/n");
|
||||
Collections.sort(list, new NaturalComparator(/* case sensitive */ false));
|
||||
assertTrue(list.indexOf("A") < list.indexOf("Cam"));
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@@ -97,6 +98,18 @@ public class CompetitorListenerTest extends AbstractSerializationTest {
|
||||
competitor.addCompetitorChangeListener(listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullNationality() {
|
||||
competitor.getTeam().setNationality(null);
|
||||
assertNull(competitor.getTeam().getNationality());
|
||||
competitor.getTeam().setNationality(null);
|
||||
assertNull(competitor.getTeam().getNationality());
|
||||
competitor.getTeam().setNationality(baseDomainFactory.getOrCreateNationality("GER"));
|
||||
assertEquals(baseDomainFactory.getOrCreateNationality("GER"), competitor.getTeam().getNationality());
|
||||
competitor.getTeam().setNationality(null);
|
||||
assertNull(competitor.getTeam().getNationality());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCompetitorListenerPatternForName() {
|
||||
competitor.setName("Dr. Hasso Plattner");
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ public class DummyTrackedRegattaRegistry implements TrackedRegattaRegistry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRaceBeingTracked(RaceDefinition r) {
|
||||
public boolean isRaceBeingTracked(Regatta regattaContext, RaceDefinition r) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public boolean isRaceBeingTracked(RaceDefinition r) {
|
||||
public boolean isRaceBeingTracked(Regatta regattaContext, RaceDefinition r) {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
|
||||
+35
-2
@@ -4,12 +4,16 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.test.measurements.Measurement;
|
||||
import com.sap.sailing.domain.test.measurements.MeasurementCase;
|
||||
import com.sap.sailing.domain.test.measurements.MeasurementXMLFile;
|
||||
import com.sap.sailing.util.impl.LockUtil;
|
||||
import com.sap.sailing.util.impl.NamedReentrantReadWriteLock;
|
||||
|
||||
@@ -52,17 +56,46 @@ public class LockTraceTest {
|
||||
assertFalse(lock.getReaders().contains(Thread.currentThread()));
|
||||
assertEquals(0, lock.getReadHoldCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReentrantWriteLockingWithInBetweenReadLocking() {
|
||||
NamedReentrantReadWriteLock lock = new NamedReentrantReadWriteLock("testReentrantWriteLockingWithInBetweenReadLocking-Lock", /* fair */ false);
|
||||
LockUtil.lockForWrite(lock);
|
||||
assertTrue(lock.getWriter() == Thread.currentThread());
|
||||
LockUtil.lockForRead(lock); // reentrant read while holding write
|
||||
assertTrue(lock.getReaders().contains(Thread.currentThread()));
|
||||
LockUtil.lockForWrite(lock); // reentrant write
|
||||
assertTrue(lock.getWriter() == Thread.currentThread());
|
||||
assertTrue(lock.getReaders().contains(Thread.currentThread()));
|
||||
LockUtil.unlockAfterRead(lock);
|
||||
assertFalse(lock.getReaders().contains(Thread.currentThread()));
|
||||
assertEquals(0, lock.getReadHoldCount());
|
||||
assertTrue(lock.getWriter() == Thread.currentThread());
|
||||
assertFalse(lock.getReaders().contains(Thread.currentThread()));
|
||||
assertEquals(0, lock.getReadHoldCount());
|
||||
LockUtil.unlockAfterWrite(lock);
|
||||
assertTrue(lock.getWriter() == Thread.currentThread());
|
||||
LockUtil.unlockAfterWrite(lock);
|
||||
assertFalse(lock.getWriter() == Thread.currentThread());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLockingPerformance() {
|
||||
public void testLockingPerformance() throws IOException {
|
||||
NamedReentrantReadWriteLock lock = new NamedReentrantReadWriteLock("Lock", /* fair */ true);
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i=0; i<100000; i++) {
|
||||
final int count = 100000;
|
||||
for (int i=0; i<count; i++) {
|
||||
LockUtil.lockForRead(lock);
|
||||
LockUtil.unlockAfterRead(lock);
|
||||
LockUtil.lockForWrite(lock);
|
||||
LockUtil.unlockAfterWrite(lock);
|
||||
}
|
||||
MeasurementXMLFile performanceReport = new MeasurementXMLFile(this.getClass());
|
||||
MeasurementCase performanceReportCase = performanceReport.addCase(getClass().getSimpleName());
|
||||
performanceReportCase.addMeasurement(new Measurement("Obtaining and releasing "+count+" read and write locks in ms",
|
||||
System.currentTimeMillis()-start));
|
||||
performanceReport.write();
|
||||
|
||||
System.out.println("Took "+(System.currentTimeMillis()-start)+"ms");
|
||||
}
|
||||
|
||||
|
||||
+51
-79
@@ -13,16 +13,6 @@ public class FlorianopolisMarkPassingTest extends AbstractMarkPassingTest {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace1() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace2() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace3() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("3");
|
||||
@@ -33,75 +23,57 @@ public class FlorianopolisMarkPassingTest extends AbstractMarkPassingTest {
|
||||
testRace("4");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace5() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("5");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace6() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("6");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace7() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("7");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace8() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("8");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace10() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("10");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace11() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("11");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace12() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("12");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace13() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("13");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace14() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("14");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace16() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("16");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace17() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("17");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace19() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("19");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace22() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("22");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace24() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("24");
|
||||
}
|
||||
/*
|
||||
* Test ignored on master branch to quicken the hudson build.
|
||||
*
|
||||
* @Test public void testRace1() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("1"); }
|
||||
*
|
||||
* @Test public void testRace2() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("2"); }
|
||||
*
|
||||
* @Test public void testRace5() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("5"); }
|
||||
*
|
||||
* @Test public void testRace6() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("6"); }
|
||||
*
|
||||
* @Test public void testRace7() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("7"); }
|
||||
*
|
||||
* @Test public void testRace8() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("8"); }
|
||||
*
|
||||
* @Test public void testRace10() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("10"); }
|
||||
*
|
||||
* @Test public void testRace11() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("11"); }
|
||||
*
|
||||
* @Test public void testRace12() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("12"); }
|
||||
*
|
||||
* @Test public void testRace13() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("13"); }
|
||||
*
|
||||
* @Test public void testRace14() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("14"); }
|
||||
*
|
||||
* @Test public void testRace16() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("16"); }
|
||||
*
|
||||
* @Test public void testRace17() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("17"); }
|
||||
*
|
||||
* @Test public void testRace19() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("19"); }
|
||||
*
|
||||
* @Test public void testRace22() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("22"); }
|
||||
*
|
||||
* @Test public void testRace24() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("24"); }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Alinghi acting wierd
|
||||
|
||||
+10
-10
@@ -17,16 +17,16 @@ public class KW470MarkPassingTest extends AbstractMarkPassingTest {
|
||||
public void testRace4() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("4");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace5() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("5");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRace6() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("6");
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignored on master branch
|
||||
*
|
||||
* @Test public void testRace5() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("5"); }
|
||||
*
|
||||
* @Test public void testRace6() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("6"); }
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected String getFileName() {
|
||||
|
||||
+1
-3
@@ -27,16 +27,14 @@ import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
public class MarkPassingCalculatorPerformanceTest extends AbstractMockedRaceMarkPassingTest {
|
||||
|
||||
private static LinkedHashMap<String, Long> result = new LinkedHashMap<>();
|
||||
private static String className;
|
||||
|
||||
public MarkPassingCalculatorPerformanceTest() {
|
||||
super();
|
||||
className = getClass().getName();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void createXMLFile() throws IOException {
|
||||
MeasurementXMLFile performanceReport = new MeasurementXMLFile("TEST-MarkPassingCaculatorPerformanceTest.xml", "MarkPassingCaculatorPerformanceTest", className);
|
||||
MeasurementXMLFile performanceReport = new MeasurementXMLFile(MarkPassingCalculatorPerformanceTest.class);
|
||||
for (String key : result.keySet()) {
|
||||
MeasurementCase performanceReportCase = performanceReport.addCase(key);
|
||||
performanceReportCase.addMeasurement(new Measurement(key, result.get(key)));
|
||||
|
||||
+34
-48
@@ -9,7 +9,7 @@ import org.junit.Test;
|
||||
|
||||
public class OBMR2012VRMarkPassingTest extends AbstractMarkPassingTest {
|
||||
|
||||
public OBMR2012VRMarkPassingTest() throws MalformedURLException, URISyntaxException {
|
||||
public OBMR2012VRMarkPassingTest() throws MalformedURLException, URISyntaxException {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -17,57 +17,43 @@ public class OBMR2012VRMarkPassingTest extends AbstractMarkPassingTest {
|
||||
public void testRaceFr11() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Fr_Fleet_1_1");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRaceFr12() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Fr_Fleet_1_2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRaceFr13() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Fr_Fleet_1_3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRaceFr21() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Fr_Fleet_2_1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRaceFr22() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Fr_Fleet_2_2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRaceFr23() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Fr_Fleet_2_3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRaceSaVm11() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Sa-Vm_Fleet_1_1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRaceSaVm12() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Sa-Vm_Fleet_1_2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRaceSaVm13() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Sa-Vm_Fleet_1_3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRaceSaVm21() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Sa-Vm_Fleet_2_1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRaceSaVm22() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
testRace("Sa-Vm_Fleet_2_2");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ignored on master branch.
|
||||
*
|
||||
* @Test public void testRaceFr13() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("Fr_Fleet_1_3"); }
|
||||
*
|
||||
* @Test public void testRaceFr21() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("Fr_Fleet_2_1"); }
|
||||
*
|
||||
* @Test public void testRaceFr22() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("Fr_Fleet_2_2"); }
|
||||
*
|
||||
* @Test public void testRaceFr23() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("Fr_Fleet_2_3"); }
|
||||
*
|
||||
* @Test public void testRaceSaVm11() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("Sa-Vm_Fleet_1_1"); }
|
||||
*
|
||||
* @Test public void testRaceSaVm12() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("Sa-Vm_Fleet_1_2"); }
|
||||
*
|
||||
* @Test public void testRaceSaVm13() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("Sa-Vm_Fleet_1_3"); }
|
||||
*
|
||||
* @Test public void testRaceSaVm21() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("Sa-Vm_Fleet_2_1"); }
|
||||
*
|
||||
* @Test public void testRaceSaVm22() throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
* testRace("Sa-Vm_Fleet_2_2"); }
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected String getExpectedEventName() {
|
||||
return "OBMR 2012";
|
||||
|
||||
+4
@@ -27,6 +27,10 @@ public class MeasurementXMLFile {
|
||||
private final Set<MeasurementCase> cases;
|
||||
private final String testClassName;
|
||||
|
||||
public MeasurementXMLFile(Class<?> testClass) {
|
||||
this("TEST-"+testClass.getSimpleName()+".xml", testClass.getSimpleName(), testClass.getName());
|
||||
}
|
||||
|
||||
public MeasurementXMLFile(String reportFileName, String testSuiteName, String testClassName) {
|
||||
this.reportFileName = reportFileName;
|
||||
this.testSuiteName = testSuiteName;
|
||||
|
||||
@@ -21,5 +21,4 @@ public interface RaceDefinition extends Named, WithID {
|
||||
Course getCourse();
|
||||
|
||||
Iterable<Competitor> getCompetitors();
|
||||
|
||||
}
|
||||
-1
@@ -39,7 +39,6 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem
|
||||
this.trackedRaces = new TrackedRaces();
|
||||
this.raceIdentifiers = new HashMap<Fleet, RaceIdentifier>();
|
||||
this.raceLogs = new HashMap<Fleet, RaceLog>();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-1
@@ -35,6 +35,7 @@ import com.sap.sailing.domain.leaderboard.impl.HighPointExtremeSailingSeriesOver
|
||||
import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets10LastBreaksTie;
|
||||
import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets1LastBreaksTie;
|
||||
import com.sap.sailing.domain.leaderboard.impl.HighPointLastBreaksTie;
|
||||
import com.sap.sailing.domain.leaderboard.impl.HighPointWinnerGetsFive;
|
||||
import com.sap.sailing.domain.leaderboard.impl.HighPointWinnerGetsSix;
|
||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||
import com.sap.sailing.domain.leaderboard.impl.LowPointWinnerGetsZero;
|
||||
@@ -87,6 +88,8 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain
|
||||
return new HighPointFirstGets10LastBreaksTie();
|
||||
case LOW_POINT_WINNER_GETS_ZERO:
|
||||
return new LowPointWinnerGetsZero();
|
||||
case HIGH_POINT_WINNER_GETS_FIVE:
|
||||
return new HighPointWinnerGetsFive();
|
||||
case HIGH_POINT_WINNER_GETS_SIX:
|
||||
return new HighPointWinnerGetsSix();
|
||||
}
|
||||
@@ -109,7 +112,8 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain
|
||||
// Optional: Getting the places of the race
|
||||
PlacemarkOrderDTO racePlaces = withGeoLocationData ? getRacePlaces(trackedRace) : null;
|
||||
TrackedRaceDTO trackedRaceDTO = createTrackedRaceDTO(trackedRace);
|
||||
RaceDTO raceDTO = new RaceDTO(raceIdentifier, trackedRaceDTO, trackedRegattaRegistry.isRaceBeingTracked(trackedRace.getRace()));
|
||||
RaceDTO raceDTO = new RaceDTO(raceIdentifier, trackedRaceDTO, trackedRegattaRegistry.isRaceBeingTracked(
|
||||
trackedRace.getTrackedRegatta().getRegatta(), trackedRace.getRace()));
|
||||
raceDTO.places = racePlaces;
|
||||
updateRaceDTOWithTrackedRaceData(trackedRace, raceDTO);
|
||||
return raceDTO;
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||
import com.sap.sailing.domain.racelog.RaceLogInformation;
|
||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||
import com.sap.sailing.domain.racelog.impl.RaceLogInformationImpl;
|
||||
@@ -159,11 +160,20 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
|
||||
/**
|
||||
* When de-serializing, a possibly remote {@link #raceLogStore} is ignored because it is transient. Instead, an
|
||||
* {@link EmptyRaceLogStore} is used for the de-serialized instance.
|
||||
* {@link EmptyRaceLogStore} is used for the de-serialized instance. A new {@link RaceLogInformation} is assembled
|
||||
* for this empty race log and applied to all columns.
|
||||
*/
|
||||
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
|
||||
ois.defaultReadObject();
|
||||
raceLogStore = EmptyRaceLogStore.INSTANCE;
|
||||
for (Series series : getSeries()) {
|
||||
if (series.getRaceColumns() != null) {
|
||||
for (RaceColumnInSeries column : series.getRaceColumns()) {
|
||||
column.setRaceLogInformation(new RaceLogInformationImpl(raceLogStore,
|
||||
new RaceLogOnRegattaIdentifier(this, column.getName())));
|
||||
}
|
||||
}
|
||||
}
|
||||
regattaListeners = new HashSet<RegattaListener>();
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -19,6 +19,7 @@ import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleRaceColumn;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
|
||||
import com.sap.sailing.domain.racelog.RaceLogInformation;
|
||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||
import com.sap.sailing.domain.racelog.impl.RaceLogInformationImpl;
|
||||
@@ -67,11 +68,16 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements
|
||||
/**
|
||||
* Deserialization has to be maintained in lock-step with {@link #writeObject(ObjectOutputStream) serialization}.
|
||||
* When de-serializing, a possibly remote {@link #raceLogStore} is ignored because it is transient. Instead, an
|
||||
* {@link EmptyRaceLogStore} is used for the de-serialized instance.
|
||||
* {@link EmptyRaceLogStore} is used for the de-serialized instance. A new {@link RaceLogInformation} is
|
||||
* assembled for this empty race log and applied to all columns.
|
||||
*/
|
||||
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
|
||||
ois.defaultReadObject();
|
||||
raceLogStore = EmptyRaceLogStore.INSTANCE;
|
||||
for (RaceColumn column : getRaceColumns()) {
|
||||
column.setRaceLogInformation(new RaceLogInformationImpl(raceLogStore, new RaceLogOnLeaderboardIdentifier(
|
||||
this, column.getName())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.sap.sailing.domain.leaderboard.impl;
|
||||
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
|
||||
public class HighPointWinnerGetsFive extends HighPointFirstGetsFixedScore {
|
||||
private static final long serialVersionUID = 1367473387431601943L;
|
||||
|
||||
public HighPointWinnerGetsFive() {
|
||||
super(/* scoreForRaceWinner */ 5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoringSchemeType getType() {
|
||||
return ScoringSchemeType.HIGH_POINT_WINNER_GETS_FIVE;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -44,7 +44,7 @@ public interface TrackedRegattaRegistry {
|
||||
*/
|
||||
Regatta getRememberedRegattaForRace(Serializable raceID);
|
||||
|
||||
boolean isRaceBeingTracked(RaceDefinition r);
|
||||
boolean isRaceBeingTracked(Regatta regattaContext, RaceDefinition r);
|
||||
|
||||
/**
|
||||
* Stops all {@link RaceTracker}s currently tracking <code>race</code>. Note that if the same tracker also may have
|
||||
|
||||
@@ -35,5 +35,6 @@
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>com.google.gwt.eclipse.core.gwtNature</nature>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,3 +1,3 @@
|
||||
#Fri Jan 13 22:25:34 CET 2012
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties=UTF-8
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties=UTF-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties=UTF-8
|
||||
@@ -1,59 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
||||
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
||||
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
|
||||
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
||||
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/AdminConsole.html"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.gwt.ui"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.googlecode.java-diff-utils/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.json.simple/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.udpconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.mongodb/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.operationaltransformation/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.geocoding/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server.replication/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.gwt.ui"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9997 -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/UserManagement.html com.sap.sailing.gwt.ui.UserManagement -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/TvView.html com.sap.sailing.gwt.ui.TvView -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.ui.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.VideoPopup"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -XX:MaxPermSize=512m"/>
|
||||
</launchConfiguration>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
||||
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
||||
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
|
||||
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
||||
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/AdminConsole.html"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.gwt.ui"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.googlecode.java-diff-utils/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.json.simple/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.udpconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.mongodb/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.operationaltransformation/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.geocoding/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server.replication/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.gwt.ui"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9997 -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/UserManagement.html com.sap.sailing.gwt.ui.UserManagement -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/TvView.html com.sap.sailing.gwt.ui.TvView -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.ui.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.VideoPopup"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -XX:MaxPermSize=512m"/>
|
||||
</launchConfiguration>
|
||||
@@ -1,848 +0,0 @@
|
||||
/**
|
||||
* Streamlets
|
||||
*
|
||||
* Visualizes a vector field using an animated swarm of particles
|
||||
* where each particle moves along the flow of the vector field
|
||||
*
|
||||
* - integrated with Google Maps v3
|
||||
* - support vector fields unaligned with lat/lng-grid
|
||||
* - support time-dependent vector fields
|
||||
* - integrated with GWT for Strategy Simulator
|
||||
*
|
||||
* @author Christopher Ronnewinkel (D036654)
|
||||
*
|
||||
*/
|
||||
|
||||
var Vector = function(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
};
|
||||
|
||||
Vector.prototype.length = function() {
|
||||
return Math.sqrt(this.x * this.x + this.y * this.y);
|
||||
};
|
||||
|
||||
Vector.prototype.setLength = function(length) {
|
||||
var current = this.length();
|
||||
if (current) {
|
||||
var scale = length / current;
|
||||
this.x *= scale;
|
||||
this.y *= scale;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
var Mercator = function(map, canvas, field_opt) {
|
||||
this.canvas = canvas;
|
||||
this.alpha = 0.0;
|
||||
this.beta = 0.0;
|
||||
this.gamma = 0.0;
|
||||
this.delta = 0.0;
|
||||
this.map = map;
|
||||
if (field_opt) {
|
||||
this.fieldNW = new google.maps.LatLng(field_opt.y1, field_opt.x0);
|
||||
this.fieldSE = new google.maps.LatLng(field_opt.y0, field_opt.x1);
|
||||
}
|
||||
this.calibrate();
|
||||
};
|
||||
|
||||
Mercator.prototype.calibrate = function() {
|
||||
|
||||
var pointSW;
|
||||
var pointNE;
|
||||
|
||||
if (this.fieldNW === undefined) {
|
||||
|
||||
var canvasWidth = this.map.getDiv().clientWidth;
|
||||
var canvasHeight = this.map.getDiv().clientHeight;
|
||||
|
||||
this.canvas.style.width = canvasWidth + "px";
|
||||
this.canvas.style.height = canvasHeight + "px";
|
||||
this.canvas.width = canvasWidth;
|
||||
this.canvas.height = canvasHeight;
|
||||
|
||||
var sw = swarmCanvasProjection.fromLatLngToDivPixel(this.map.getBounds()
|
||||
.getSouthWest());
|
||||
var ne = swarmCanvasProjection.fromLatLngToDivPixel(this.map.getBounds()
|
||||
.getNorthEast());
|
||||
|
||||
this.canvas.style.position = "absolute";
|
||||
this.canvas.style.left = sw.x + "px";
|
||||
this.canvas.style.top = ne.y + "px";
|
||||
|
||||
var mapSW = this.map.getBounds().getSouthWest();
|
||||
var mapNE = this.map.getBounds().getNorthEast();
|
||||
|
||||
pointSW = this.sphere2plane(mapSW.lat(), mapSW.lng());
|
||||
pointNE = this.sphere2plane(mapNE.lat(), mapNE.lng());
|
||||
|
||||
} else {
|
||||
|
||||
var fieldNWpx = swarmCanvasProjection.fromLatLngToDivPixel(this.fieldNW);
|
||||
var fieldSEpx = swarmCanvasProjection.fromLatLngToDivPixel(this.fieldSE);
|
||||
|
||||
this.canvas.style.left = fieldNWpx.x+"px";
|
||||
this.canvas.style.top = fieldNWpx.y+"px";
|
||||
var canvasWidth = fieldSEpx.x - fieldNWpx.x;
|
||||
var canvasHeight = fieldSEpx.y - fieldNWpx.y;
|
||||
this.canvas.style.width = canvasWidth + "px";
|
||||
this.canvas.style.height = canvasHeight + "px";
|
||||
this.canvas.width = canvasWidth;
|
||||
this.canvas.height = canvasHeight;
|
||||
|
||||
pointSW = this.sphere2plane(this.fieldSE.lat(), this.fieldNW.lng());
|
||||
pointNE = this.sphere2plane(this.fieldNW.lat(), this.fieldSE.lng());
|
||||
|
||||
}
|
||||
|
||||
if (pointNE.x < pointSW.x) {
|
||||
pointSW.x -= 2*Math.PI;
|
||||
}
|
||||
|
||||
this.alpha = this.canvas.height / (pointNE.y - pointSW.y);
|
||||
this.beta = pointSW.x;
|
||||
|
||||
this.gamma = - this.alpha;
|
||||
this.delta = pointNE.y;
|
||||
};
|
||||
|
||||
Mercator.prototype.sphere2plane = function(lat, lng) {
|
||||
var p = lng*Math.PI/180.0;
|
||||
var latrad = lat*Math.PI/180.0;
|
||||
var q = Math.log((1.0+Math.sin(latrad))/Math.cos(latrad));
|
||||
return {x:p, y:q};
|
||||
};
|
||||
|
||||
Mercator.prototype.plane2sphere = function(x,y) {
|
||||
var lng = x*180.0/Math.PI;
|
||||
var lat = Math.atan(Math.sinh(y))*180.0/Math.PI;
|
||||
return {lat:lat, lng:lng};
|
||||
};
|
||||
|
||||
Mercator.prototype.latlng2pixel = function(lat, lng) {
|
||||
var proj = this.sphere2plane(lat,lng);
|
||||
var x = this.alpha * (proj.x - this.beta);
|
||||
var y = this.gamma * (proj.y - this.delta);
|
||||
return {x:x, y:y};
|
||||
};
|
||||
|
||||
Mercator.prototype.pixel2latlng = function(x, y) {
|
||||
var p = x / this.alpha + this.beta;
|
||||
var q = y / this.gamma + this.delta;
|
||||
return this.plane2sphere({x:p, y:q});
|
||||
};
|
||||
|
||||
Mercator.prototype.clearCanvas = function() {
|
||||
var w = this.canvas.width;
|
||||
var h = this.canvas.height;
|
||||
var g = this.canvas.getContext('2d');
|
||||
g.clearRect(0, 0, w, h);
|
||||
};
|
||||
|
||||
var VectorField = function(data) {
|
||||
|
||||
this.data = data;
|
||||
this.step = 0;
|
||||
this.rcStart = data.rcStart;
|
||||
this.rcEnd = data.rcEnd;
|
||||
this.resY = data.resY;
|
||||
this.resX = data.resX;
|
||||
this.borderY = data.borderY;
|
||||
this.borderX = data.borderX;
|
||||
this.bdXi = (data.borderY + 0.5) / (this.resY - 1);
|
||||
this.bdPhi = 1.0 + 2*this.bdXi;
|
||||
this.bdA = { lat:this.rcEnd.lat+(this.rcEnd.lat-this.rcStart.lat)*this.bdXi, lng:this.rcEnd.lng+(this.rcEnd.lng-this.rcStart.lng)*this.bdXi };
|
||||
this.bdB = { lat:(this.rcStart.lat-this.rcEnd.lat)*this.bdPhi, lng:(this.rcStart.lng-this.rcEnd.lng)*this.bdPhi };
|
||||
this.xScale = data.xScale;
|
||||
this.x0 = data.boundsSW.lng;
|
||||
this.x1 = data.boundsNE.lng;
|
||||
this.y0 = data.boundsSW.lat;
|
||||
this.y1 = data.boundsNE.lat;
|
||||
this.visX0 = 0;
|
||||
this.visY0 = 0;
|
||||
this.visX1 = 0;
|
||||
this.visY1 = 0;
|
||||
this.maxLength = data.maxLength;
|
||||
this.numParticleFactor = 2.0;
|
||||
|
||||
var latAvg = (this.rcEnd.lat + this.rcStart.lat) / 2.;
|
||||
this.lngScale = Math.cos(latAvg * Math.PI / 180.0);
|
||||
|
||||
var difLat = this.rcEnd.lat - this.rcStart.lat;
|
||||
var difLng = (this.rcEnd.lng - this.rcStart.lng) * this.lngScale;
|
||||
var difLen = Math.sqrt(difLat*difLat + difLng*difLng);
|
||||
this.nvY = { lat: difLat/difLen/difLen*(this.resY-1), lng: difLng/difLen/difLen*(this.resY-1) };
|
||||
|
||||
var nrmLat = -difLng/difLen;
|
||||
var nrmLng = difLat/difLen;
|
||||
this.nvX = { lat: nrmLat/this.xScale/difLen*(this.resX-1), lng: nrmLng/this.xScale/difLen*(this.resX-1) };
|
||||
this.gvX = { lat: nrmLat*this.xScale*difLen, lng: nrmLng/this.lngScale*this.xScale*difLen };
|
||||
this.bdC = { lat:this.gvX.lat*(this.resX+2*this.borderX-1)/(this.resX-1), lng:this.gvX.lng*(this.resX+2*this.borderX-1)/(this.resX-1)};
|
||||
};
|
||||
|
||||
VectorField.prototype.getRandomPosition = function() {
|
||||
var rndY = Math.random();
|
||||
var rndX = Math.random() - 0.5;
|
||||
var latP = this.bdA.lat + rndY * this.bdB.lat + rndX * this.bdC.lat;
|
||||
var lngP = this.bdA.lng + rndY * this.bdB.lng + rndX * this.bdC.lng;
|
||||
|
||||
if (!this.inBounds(lngP, latP)) {
|
||||
console.log("random-position: out of bounds");
|
||||
}
|
||||
|
||||
return {lat:latP, lng:lngP};
|
||||
};
|
||||
|
||||
|
||||
VectorField.prototype.inBounds = function(lng, lat) {
|
||||
var idx = this.getIndex(lat, lng);
|
||||
var inBool = (idx.x >= 0) && (idx.x < (this.resX+2*this.borderX)) && (idx.y >= 0) && (idx.y < (this.resY+2*this.borderY));
|
||||
return inBool;
|
||||
};
|
||||
|
||||
VectorField.prototype.interpolate = function(lat, lng) {
|
||||
|
||||
var idx = this.getNeighbors(lat, lng);
|
||||
var idxOff = 0;
|
||||
|
||||
if ((idx.xTop >= (this.resX+2*this.borderX))||(idx.yTop >= (this.resY+2*this.borderY))) {
|
||||
console.log("interpolate: out of range: " + idx.xTop + " " + idx.yTop);
|
||||
}
|
||||
|
||||
var avgX = this.data.data[this.step][idx.yBot][2*idx.xBot] * (1 - idx.yMod) * (1 - idx.xMod) + this.data.data[this.step][idx.yTop][2*idx.xBot] * idx.yMod * (1 - idx.xMod)
|
||||
+ this.data.data[this.step][idx.yBot][2*idx.xTop] * (1 - idx.yMod) * idx.xMod + this.data.data[this.step][idx.yTop][2*idx.xTop] * idx.yMod * idx.xMod;
|
||||
var avgY = this.data.data[this.step][idx.yBot][2*idx.xBot+1] * (1 - idx.yMod) * (1 - idx.xMod) + this.data.data[this.step][idx.yTop][2*idx.xBot+1] * idx.yMod * (1 - idx.xMod)
|
||||
+ this.data.data[this.step][idx.yBot][2*idx.xTop+1] * (1 - idx.yMod) * idx.xMod + this.data.data[this.step][idx.yTop][2*idx.xTop+1] * idx.yMod * idx.xMod;
|
||||
|
||||
return {x:avgX / this.lngScale, y:avgY};
|
||||
};
|
||||
|
||||
VectorField.prototype.interpolate2 = function(lat, lng) {
|
||||
|
||||
var idx = this.getNeighbors(lat, lng);
|
||||
var idxOff = 0;
|
||||
|
||||
if ((idx.xTop >= (this.resX+2*this.borderX))||(idx.yTop >= (this.resY+2*this.borderY))) {
|
||||
console.log("interpolate: out of range: " + idx.xTop + " " + idx.yTop);
|
||||
}
|
||||
|
||||
var idxBase = this.step*this.resX*this.resY;
|
||||
var yBotxBot = getWindfromSimulator(idxBase + idx.yBot*this.resY + idx.xBot);
|
||||
var yTopxBot = getWindfromSimulator(idxBase + idx.yTop*this.resY + idx.xBot);
|
||||
var yBotxTop = getWindfromSimulator(idxBase + idx.yBot*this.resY + idx.xTop);
|
||||
var yTopxTop = getWindfromSimulator(idxBase + idx.yTop*this.resY + idx.xTop);
|
||||
|
||||
var avgX = yBotxBot.x * (1 - idx.yMod) * (1 - idx.xMod) + yTopxBot.x * idx.yMod * (1 - idx.xMod) + yBotxTop.x * (1 - idx.yMod) * idx.xMod + yTopxTop.x * idx.yMod * idx.xMod;
|
||||
var avgY = yBotxBot.y * (1 - idx.yMod) * (1 - idx.xMod) + yTopxBot.y * idx.yMod * (1 - idx.xMod) + yBotxTop.y * (1 - idx.yMod) * idx.xMod + yTopxTop.y * idx.yMod * idx.xMod;
|
||||
|
||||
return {x:avgX / this.lngScale, y:avgY};
|
||||
};
|
||||
|
||||
VectorField.prototype.setStep = function(step) {
|
||||
if (step < 0) {
|
||||
this.step = 0;
|
||||
} else if (step >= this.data.data.length) {
|
||||
this.step = this.data.data.length-1;
|
||||
} else {
|
||||
this.step = step;
|
||||
}
|
||||
}
|
||||
|
||||
VectorField.prototype.nextStep = function() {
|
||||
if (this.step < (this.data.data.length-1)) {
|
||||
this.step++;
|
||||
}
|
||||
}
|
||||
|
||||
VectorField.prototype.prevStep = function() {
|
||||
if (this.step > 0) {
|
||||
this.step--;
|
||||
}
|
||||
}
|
||||
|
||||
VectorField.prototype.getValue = function(lat, lng, opt_result) {
|
||||
|
||||
var v = this.interpolate(lat, lng);
|
||||
if (opt_result) {
|
||||
opt_result.x = v.x;
|
||||
opt_result.y = v.y;
|
||||
return opt_result;
|
||||
}
|
||||
return new Vector(v.x, v.y);
|
||||
};
|
||||
|
||||
VectorField.prototype.getValue2 = function(lat, lng, opt_result) {
|
||||
|
||||
var v = this.interpolate(lat, lng);
|
||||
if (opt_result) {
|
||||
opt_result.x = v.x;
|
||||
opt_result.y = v.y;
|
||||
return opt_result;
|
||||
}
|
||||
return new Vector(v.x, v.y);
|
||||
};
|
||||
|
||||
VectorField.prototype.getIndex = function(lat, lng) {
|
||||
|
||||
// calculate grid indexes
|
||||
var posR = { lat: lat - this.rcStart.lat, lng: (lng - this.rcStart.lng) * this.lngScale };
|
||||
|
||||
// closest grid point
|
||||
var yIdx = Math.round( posR.lat * this.nvY.lat + posR.lng * this.nvY.lng ) + this.borderY;
|
||||
var xIdx = Math.round( posR.lat * this.nvX.lat + posR.lng * this.nvX.lng + (this.resX - 1) / 2. ) + this.borderX;
|
||||
|
||||
return { x: xIdx, y: yIdx };
|
||||
};
|
||||
|
||||
VectorField.prototype.getNeighbors = function(lat, lng) {
|
||||
|
||||
// calculate grid indexes
|
||||
var posR = { lat: lat - this.rcStart.lat, lng: (lng - this.rcStart.lng) * this.lngScale };
|
||||
|
||||
// surrounding grid points
|
||||
var yFlt = posR.lat * this.nvY.lat + posR.lng * this.nvY.lng + this.borderY;
|
||||
var xFlt = posR.lat * this.nvX.lat + posR.lng * this.nvX.lng + (this.resX - 1) / 2. + this.borderX;
|
||||
var yBot = Math.floor( yFlt );
|
||||
var xBot = Math.floor( xFlt );
|
||||
var yTop = Math.ceil( yFlt );
|
||||
var xTop = Math.ceil( xFlt );
|
||||
var yMod = yFlt - yBot;
|
||||
var xMod = xFlt - xBot;
|
||||
|
||||
if (xBot < 0) {
|
||||
xBot = 0;
|
||||
}
|
||||
|
||||
if (yBot < 0) {
|
||||
yBot = 0;
|
||||
}
|
||||
|
||||
if (xTop >= (this.resX+2*this.borderX)) {
|
||||
xTop = this.resX+2*this.borderX-1;
|
||||
}
|
||||
|
||||
if (yTop >= (this.resY+2*this.borderY)) {
|
||||
yTop = this.resY+2*this.borderY-1;
|
||||
}
|
||||
|
||||
return { xTop: xTop, yTop:yTop, xBot:xBot, yBot:yBot, xMod:xMod, yMod:yMod };
|
||||
};
|
||||
|
||||
VectorField.prototype.motionScale = function(zoomLevel) {
|
||||
return 0.08 * Math.pow(1.6, Math.min(1.0, 6.0 - zoomLevel));
|
||||
};
|
||||
|
||||
VectorField.prototype.particleWeight = function(p,v) {
|
||||
return v.length() / this.maxLength + 0.1;
|
||||
}
|
||||
|
||||
VectorField.prototype.getColors = function() {
|
||||
var colors = [];
|
||||
var alpha = 0.7;
|
||||
var greyValue = 255;
|
||||
for (var i = 0; i < 256; i++) {
|
||||
colors[i] = 'rgba(' + (greyValue) + ',' + (greyValue) + ',' + (greyValue) + ',' + (alpha*i/255.0) + ')';
|
||||
//this.colors[i] = 'hsla(' + 360*(0.55+0.9*(0.5-i/255)) + ',' + (100) + '% ,' + (50) + '%,' + (i/255) + ')';
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
VectorField.prototype.lineWidth = function(s) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* for compatibility with vector fields aligned with lat/lng-grid
|
||||
**/
|
||||
var RectField = function(field, x0, y0, x1, y1) {
|
||||
this.x0 = x0;
|
||||
this.x1 = x1;
|
||||
this.y0 = y0;
|
||||
this.y1 = y1;
|
||||
|
||||
this.visX0 = 0;
|
||||
this.visY0 = 0;
|
||||
this.visX1 = 0;
|
||||
this.visY1 = 0;
|
||||
|
||||
this.field = field;
|
||||
this.w = field.length;
|
||||
this.h = field[0].length;
|
||||
this.maxLength = 0;
|
||||
this.numParticleFactor = 4.5;
|
||||
var mx = 0;
|
||||
var my = 0;
|
||||
for (var i = 0; i < this.w; i++) {
|
||||
for (var j = 0; j < this.h; j++) {
|
||||
if (field[i][j].length() > this.maxLength) {
|
||||
mx = i;
|
||||
my = j;
|
||||
}
|
||||
this.maxLength = Math.max(this.maxLength, field[i][j].length());
|
||||
}
|
||||
}
|
||||
mx = (mx / this.w) * (x1 - x0) + x0;
|
||||
my = (my / this.h) * (y1 - y0) + y0;
|
||||
};
|
||||
|
||||
RectField.read = function(data, correctForSphere) {
|
||||
var field = [];
|
||||
var w = data.gridWidth;
|
||||
var h = data.gridHeight;
|
||||
|
||||
var i = 0;
|
||||
for (var x = 0; x < w; x++) {
|
||||
field[x] = [];
|
||||
for (var y = 0; y < h; y++) {
|
||||
var vx = data.field[i++];
|
||||
var vy = data.field[i++];
|
||||
var v = new Vector(vx, vy);
|
||||
if (correctForSphere) {
|
||||
var uy = y / (h - 1);
|
||||
var lat = data.y0 * (1 - uy) + data.y1 * uy;
|
||||
var m = Math.PI * lat / 180;
|
||||
var length = v.length();
|
||||
v.x /= Math.cos(m);
|
||||
v.setLength(length);
|
||||
}
|
||||
field[x][y] = v;
|
||||
}
|
||||
}
|
||||
var result = new RectField(field, data.x0, data.y0, data.x1, data.y1);
|
||||
return result;
|
||||
};
|
||||
|
||||
RectField.prototype.getRandomPosition = function() {
|
||||
var rndY = Math.random();
|
||||
var rndX = Math.random();
|
||||
var y = rndY * this.visY0 + (1 - rndY) * this.visY1;
|
||||
var x = rndX * this.visX0 + (1 - rndX) * this.visX1;
|
||||
return {lat:y, lng:x};
|
||||
};
|
||||
|
||||
RectField.prototype.inBounds = function(x, y) {
|
||||
return x >= this.x0 && x < this.x1 && y >= this.y0 && y < this.y1;
|
||||
};
|
||||
|
||||
RectField.prototype.interpolate = function(a, b) {
|
||||
var na = Math.floor(a);
|
||||
var nb = Math.floor(b);
|
||||
var ma = Math.ceil(a);
|
||||
var mb = Math.ceil(b);
|
||||
var fa = a - na;
|
||||
var fb = b - nb;
|
||||
|
||||
var avgX = this.field[na][nb]['x'] * (1 - fa) * (1 - fb) + this.field[ma][nb]['x'] * fa * (1 - fb) + this.field[na][mb]['x'] * (1 - fa) * fb + this.field[ma][mb]['x'] * fa * fb;
|
||||
var avgY = this.field[na][nb]['y'] * (1 - fa) * (1 - fb) + this.field[ma][nb]['y'] * fa * (1 - fb) + this.field[na][mb]['y'] * (1 - fa) * fb + this.field[ma][mb]['y'] * fa * fb;
|
||||
|
||||
return {x:avgX, y:avgY};
|
||||
};
|
||||
|
||||
|
||||
RectField.prototype.getValue = function(y, x, opt_result) {
|
||||
var a = (this.w - 1 - 1e-6) * (x - this.x0) / (this.x1 - this.x0);
|
||||
var b = (this.h - 1 - 1e-6) * (y - this.y0) / (this.y1 - this.y0);
|
||||
var v = this.interpolate(a, b);
|
||||
if (opt_result) {
|
||||
opt_result.x = v.x;
|
||||
opt_result.y = v.y;
|
||||
return opt_result;
|
||||
}
|
||||
return new Vector(v.x, v.y);
|
||||
};
|
||||
|
||||
|
||||
RectField.prototype.motionScale = function(zoomLevel) {
|
||||
return 0.9 * Math.pow(1.7, Math.min(1.0, 6.0 - zoomLevel));
|
||||
};
|
||||
|
||||
RectField.prototype.particleWeight = function(p,v) {
|
||||
return 1.0 - v.length() / this.maxLength;
|
||||
}
|
||||
|
||||
RectField.prototype.getColors = function() {
|
||||
var colors = [];
|
||||
var alpha = 1.0;
|
||||
var greyValue = 255;
|
||||
for (var i = 0; i < 256; i++) {
|
||||
colors[i] = 'rgba(' + (greyValue) + ',' + (greyValue) + ',' + (greyValue) + ',' + (alpha*i/255.0) + ')';
|
||||
//this.colors[i] = 'hsla(' + 360*(0.55+0.9*(0.5-i/255)) + ',' + (100) + '% ,' + (50) + '%,' + (i/255) + ')';
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
RectField.prototype.lineWidth = function(s) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
var Animator = function() {
|
||||
this.animating = true;
|
||||
this.state = 'animate';
|
||||
this.pause = 0;
|
||||
this.listeners = [];
|
||||
this.dx = 0;
|
||||
this.dy = 0;
|
||||
this.scale = 1;
|
||||
this.zoomProgress = 0;
|
||||
this.scaleTarget = 1;
|
||||
this.scaleStart = 1;
|
||||
};
|
||||
|
||||
|
||||
Animator.prototype.add = function(listener) {
|
||||
this.listeners.push(listener);
|
||||
};
|
||||
|
||||
|
||||
Animator.prototype.notify = function(message) {
|
||||
if (this.animFunc && !this.animFunc()) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < this.listeners.length; i++) {
|
||||
var listener = this.listeners[i];
|
||||
if (listener[message]) {
|
||||
listener[message].call(listener, this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Animator.prototype.start = function(opt_millis) {
|
||||
var millis = opt_millis || 20;
|
||||
var self = this;
|
||||
function go() {
|
||||
var start = new Date();
|
||||
if (self.loop()) {
|
||||
return;
|
||||
}
|
||||
var time = new Date() - start;
|
||||
setTimeout(go, Math.max(10, millis - time));
|
||||
}
|
||||
go();
|
||||
};
|
||||
|
||||
|
||||
Animator.prototype.loop = function() {
|
||||
if (this.state == 'stop') {
|
||||
return true;
|
||||
}
|
||||
if (this.pause > 1) {
|
||||
this.pause--;
|
||||
} else if (this.pause == 1){
|
||||
this.state = 'animate';
|
||||
this.pause = 0;
|
||||
}
|
||||
if (this.state == 'animate') {
|
||||
this.notify('animate');
|
||||
return false;
|
||||
}
|
||||
if ((this.state == 'pause')&&(this.pause == 0)) {
|
||||
this.pause = 5;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var Particle = function(x, y, age) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.oldX = -1;
|
||||
this.oldY = -1;
|
||||
this.age = age;
|
||||
this.rnd = Math.random();
|
||||
};
|
||||
|
||||
var swarmOffScreen = false;
|
||||
|
||||
var Swarm = function(canvas, field, opt_projection) {
|
||||
this.canvas = canvas;
|
||||
this.projection = opt_projection || IDProjection;
|
||||
this.field = field;
|
||||
this.numParticles = 0;
|
||||
this.first = true;
|
||||
this.maxLength = field.maxLength;
|
||||
this.speedScale = 1;
|
||||
this.renderState = 'normal';
|
||||
|
||||
this.boundsSW = new google.maps.LatLng(this.field.y0, this.field.x0);
|
||||
this.boundsNE = new google.maps.LatLng(this.field.y1, this.field.x1);
|
||||
|
||||
this.updateBounds(null);
|
||||
|
||||
this.makeNewParticles(null, true);
|
||||
this.rgb = '40, 40, 40';
|
||||
this.background = 'rgb(' + this.rgb + ')';
|
||||
this.colors = this.field.getColors();
|
||||
|
||||
if (this.projection) {
|
||||
this.startOffsetX = this.projection.offsetX;
|
||||
this.startOffsetY = this.projection.offsetY;
|
||||
this.startScale = this.projection.scale;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Swarm.prototype.updateBounds = function() {
|
||||
|
||||
var mapNE = this.projection.map.getBounds().getNorthEast();
|
||||
var mapSW = this.projection.map.getBounds().getSouthWest();
|
||||
|
||||
var fieldNE = new google.maps.LatLng(Math.max(this.field.y0, this.field.y1), Math.max(this.field.x0, this.field.x1));
|
||||
var fieldSW = new google.maps.LatLng(Math.min(this.field.y0, this.field.y1), Math.min(this.field.x0, this.field.x1));
|
||||
|
||||
var visibleNE = this.isVisible(fieldNE);
|
||||
var visibleSW = this.isVisible(fieldSW);
|
||||
|
||||
var useBoundsNorth = (visibleNE.y == 0);
|
||||
var useBoundsEast = (visibleNE.x == 0);
|
||||
var useBoundsSouth = (visibleSW.y == 0);
|
||||
var useBoundsWest = (visibleSW.x == 0);
|
||||
|
||||
swarmOffScreen = (visibleNE.y > 0)||(visibleSW.y < 0)||(visibleNE.x < 0)||(visibleSW.x > 0);
|
||||
|
||||
if (swarmOffScreen) {
|
||||
|
||||
this.boundsNE = fieldNE;
|
||||
this.boundsSW = fieldSW;
|
||||
|
||||
} else {
|
||||
|
||||
if ((!useBoundsNorth)&&(!useBoundsEast)) {
|
||||
this.boundsNE = mapNE;
|
||||
} else if (!useBoundsNorth) {
|
||||
this.boundsNE = new google.maps.LatLng(mapNE.lat(), fieldNE.lng());
|
||||
} else if (!useBoundsEast) {
|
||||
this.boundsNE = new google.maps.LatLng(fieldNE.lat(), mapNE.lng());
|
||||
} else {
|
||||
this.boundsNE = fieldNE;
|
||||
}
|
||||
|
||||
if ((!useBoundsSouth)&&(!useBoundsWest)) {
|
||||
this.boundsSW = mapSW;
|
||||
} else if (!useBoundsSouth) {
|
||||
this.boundsSW = new google.maps.LatLng(mapSW.lat(), fieldSW.lng());
|
||||
} else if (!useBoundsWest) {
|
||||
this.boundsSW = new google.maps.LatLng(fieldSW.lat(), mapSW.lng());
|
||||
} else {
|
||||
this.boundsSW = fieldSW;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.field.visX0 = this.boundsSW.lng();
|
||||
this.field.visY0 = this.boundsSW.lat();
|
||||
this.field.visX1 = this.boundsNE.lng();
|
||||
this.field.visY1 = this.boundsNE.lat();
|
||||
|
||||
var boundsSWpx = this.projection.latlng2pixel(this.boundsSW.lat(), this.boundsSW.lng());
|
||||
var boundsNEpx = this.projection.latlng2pixel(this.boundsNE.lat(), this.boundsNE.lng());
|
||||
|
||||
var boundsWidthpx = Math.abs(boundsNEpx.x - boundsSWpx.x);
|
||||
var boundsHeightpx = Math.abs(boundsSWpx.y - boundsNEpx.y);
|
||||
|
||||
this.numParticles = Math.sqrt(boundsWidthpx * boundsHeightpx) * this.field.numParticleFactor;
|
||||
//this.numParticles = Math.sqrt(boundsWidthpx*boundsWidthpx + boundsHeightpx*boundsHeightpx) * this.field.numParticleFactor;
|
||||
console.log("numParticles: "+this.numParticles + " at " + (boundsWidthpx) +"x" + (boundsHeightpx) + "px (" + (boundsWidthpx * boundsHeightpx) + " pixels)");
|
||||
};
|
||||
|
||||
Swarm.prototype.isVisible = function(pos) {
|
||||
|
||||
// test for visibility of swarm
|
||||
var proj = this.projection.latlng2pixel(pos.lat(), pos.lng());
|
||||
|
||||
var xVisible = -(proj.x < 0) + (proj.x > this.canvas.width);
|
||||
var yVisible = -(proj.y < 0) + (proj.y > this.canvas.height);
|
||||
|
||||
return {x:xVisible, y:yVisible};
|
||||
};
|
||||
|
||||
Swarm.prototype.makeNewParticles = function() {
|
||||
this.particles = [];
|
||||
for (var i = 0; i < this.numParticles; i++) {
|
||||
particle = this.makeParticle();
|
||||
if (particle) {
|
||||
this.particles.push(particle);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Swarm.prototype.makeParticle = function() {
|
||||
var trials = 0;
|
||||
while (true) {
|
||||
var pos = this.field.getRandomPosition();
|
||||
var x = pos.lng;
|
||||
var y = pos.lat;
|
||||
var v = this.field.getValue(y, x);
|
||||
if (this.field.maxLength == 0) {
|
||||
return new Particle(x, y, 1 + 40 * Math.random());
|
||||
}
|
||||
var weight = this.field.particleWeight(pos, v);
|
||||
if (weight >= Math.random()) {
|
||||
var proj = this.projection.latlng2pixel(y, x);
|
||||
if (++trials > 10 || !(proj.x < 0 || proj.y < 0 || proj.x > this.canvas.width || proj.y > this.canvas.height)) {
|
||||
if (v.x || v.y) {
|
||||
return new Particle(x, y, 1 + 40 * Math.random());
|
||||
} else {
|
||||
return new Particle(x, y, 0); // "zombie" particles to avoid dead-lock when Google Maps is moved so that only zero-wind-area is visible
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Swarm.prototype.endMove = function() {
|
||||
this.updateBounds();
|
||||
this.makeNewParticles();
|
||||
};
|
||||
|
||||
|
||||
Swarm.prototype.animate = function() {
|
||||
if (!swarmOffScreen) {
|
||||
this.moveThings();
|
||||
this.draw();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Swarm.prototype.moveThings = function() {
|
||||
var speed = .01 * this.speedScale * this.field.motionScale(this.projection.map.getZoom());
|
||||
for (var i = 0; i < this.particles.length; i++) {
|
||||
var p = this.particles[i];
|
||||
if (p.age > 0 && this.field.inBounds(p.x, p.y)) {
|
||||
var a = this.field.getValue(p.y, p.x);
|
||||
p.x += speed * a.x;
|
||||
p.y += speed * a.y;
|
||||
p.age--;
|
||||
} else {
|
||||
this.particles[i] = this.makeParticle();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Swarm.prototype.draw = function() {
|
||||
var g = this.canvas.getContext('2d');
|
||||
var w = this.canvas.width;
|
||||
var h = this.canvas.height;
|
||||
|
||||
g.globalCompositeOperation = "destination-out";
|
||||
g.globalAlpha = 0.08;
|
||||
g.fillStyle = this.background;
|
||||
|
||||
g.fillRect(0, 0, w, h);
|
||||
|
||||
g.globalCompositeOperation = "source-over";
|
||||
g.globalAlpha = 1.0;
|
||||
|
||||
var proj; // = new Vector(0, 0);
|
||||
var val = new Vector(0, 0);
|
||||
for (var i = 0; i < this.particles.length; i++) {
|
||||
var p = this.particles[i];
|
||||
if (!this.field.inBounds(p.x, p.y)) {
|
||||
p.age = -2;
|
||||
continue;
|
||||
}
|
||||
proj = this.projection.latlng2pixel(p.y, p.x);
|
||||
if (proj.x < 0 || proj.y < 0 || proj.x > w || proj.y > h) {
|
||||
p.age = -2;
|
||||
}
|
||||
if (p.oldX != -1) {
|
||||
var wind = this.field.getValue(p.y, p.x, val);
|
||||
var s = wind.length() / this.maxLength;
|
||||
var c = 90 + Math.round(350 * s); // was 400
|
||||
if (c > 255) {
|
||||
c = 255;
|
||||
}
|
||||
g.globalAlpha = 1.0;
|
||||
g.lineWidth = this.field.lineWidth(s);
|
||||
g.strokeStyle = this.colors[c];
|
||||
g.beginPath();
|
||||
g.moveTo(proj.x, proj.y);
|
||||
g.lineTo(p.oldX, p.oldY);
|
||||
g.stroke();
|
||||
g.globalAlpha = 1.0;
|
||||
}
|
||||
p.oldX = proj.x;
|
||||
p.oldY = proj.y;
|
||||
}
|
||||
};
|
||||
|
||||
var swarmData;
|
||||
var swarmField;
|
||||
var swarmAnimator;
|
||||
var swarmProjection;
|
||||
|
||||
function initStreamlets(map, canvas) {
|
||||
|
||||
if (!map) {
|
||||
alert("Google Maps Instance required.");
|
||||
return;
|
||||
}
|
||||
if (!canvas) {
|
||||
canvas = document.getElementById('swarm-display');
|
||||
if (!canvas) {
|
||||
alert("canvas 'swarm-display' not available");
|
||||
}
|
||||
}
|
||||
|
||||
if ("windFieldSim" in window) {
|
||||
|
||||
swarmField = new VectorField(windFieldSim);
|
||||
|
||||
} else {
|
||||
|
||||
if ("swarmDataExt" in window) {
|
||||
swarmData = swarmDataExt;
|
||||
|
||||
map.setZoom(5.0);
|
||||
var center = new google.maps.LatLng((swarmData.y0+swarmData.y1)/2., (swarmData.x0+swarmData.x1)/2.);
|
||||
map.panTo(center);
|
||||
|
||||
};
|
||||
|
||||
swarmField = RectField.read(swarmData, false);
|
||||
|
||||
};
|
||||
|
||||
swarmProjection = new Mercator(map, canvas); //, field);
|
||||
|
||||
//var isMacFF = navigator.platform.indexOf('Mac') != -1 && navigator.userAgent.indexOf('Firefox') != -1;
|
||||
var isWinFF = navigator.platform.indexOf('Win') != -1 && navigator.userAgent.indexOf('Firefox') != -1;
|
||||
var isWinIE = navigator.platform.indexOf('Win') != -1 && navigator.userAgent.indexOf('MSIE') != -1;
|
||||
|
||||
var swarm = new Swarm(canvas, swarmField, swarmProjection);
|
||||
|
||||
swarmAnimator = new Animator();
|
||||
swarmAnimator.add(swarm);
|
||||
|
||||
updateStreamlets = function(upd_data) {
|
||||
if (!(upd_data === undefined)) {
|
||||
swarmAnimator.state = 'stop'
|
||||
swarmAnimator = new Animator();
|
||||
swarmField = new VectorField(windFieldSim);
|
||||
swarm = new Swarm(canvas, swarmField, swarmProjection);
|
||||
swarmAnimator.add(swarm);
|
||||
swarmAnimator.start(40);
|
||||
} else if (swarmAnimator.state == 'stop') {
|
||||
return;
|
||||
}
|
||||
swarmAnimator.state = 'pause';
|
||||
swarmProjection.clearCanvas();
|
||||
swarmProjection.calibrate();
|
||||
swarmAnimator.notify('endMove');
|
||||
};
|
||||
|
||||
stopStreamlets = function() {
|
||||
swarmAnimator.state = 'stop';
|
||||
swarmProjection.clearCanvas();
|
||||
}
|
||||
|
||||
if (swarmProjection.fieldNW === undefined) {
|
||||
google.maps.event.addListener(map, 'bounds_changed', updateStreamlets);
|
||||
} else {
|
||||
google.maps.event.addListener(map, 'zoom_changed', updateStreamlets);
|
||||
}
|
||||
|
||||
swarmAnimator.start(40);
|
||||
}
|
||||
+4
-2
@@ -58,9 +58,10 @@ public class CompetitorTableWrapper extends TableWrapper<CompetitorDTO, MultiSel
|
||||
};
|
||||
boatClassColumn.setSortable(true);
|
||||
competitorColumnListHandler.setComparator(boatClassColumn, new Comparator<CompetitorDTO>() {
|
||||
private final NaturalComparator comparator = new NaturalComparator(/* caseSensitive */ false);
|
||||
@Override
|
||||
public int compare(CompetitorDTO o1, CompetitorDTO o2) {
|
||||
return new NaturalComparator(false).compare(o1.getBoatClass().getName(), o2.getBoatClass().getName());
|
||||
return comparator.compare(o1.getBoatClass().getName(), o2.getBoatClass().getName());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -86,9 +87,10 @@ public class CompetitorTableWrapper extends TableWrapper<CompetitorDTO, MultiSel
|
||||
};
|
||||
sailIdColumn.setSortable(true);
|
||||
competitorColumnListHandler.setComparator(sailIdColumn, new Comparator<CompetitorDTO>() {
|
||||
private final NaturalComparator comparator = new NaturalComparator(/* case sensitive */ false);
|
||||
@Override
|
||||
public int compare(CompetitorDTO o1, CompetitorDTO o2) {
|
||||
return new NaturalComparator(false).compare(o1.getSailID(), o2.getSailID());
|
||||
return comparator.compare(o1.getSailID(), o2.getSailID());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
-3
@@ -39,12 +39,9 @@ public abstract class TableWrapper<T, S extends SelectionModel<T>> implements Is
|
||||
this.selectionModel = selectionModel;
|
||||
this.dataProvider = new ListDataProvider<T>();
|
||||
mainPanel = new VerticalPanel();
|
||||
|
||||
table = new CellTable<T>(10000, tableRes);
|
||||
|
||||
dataProvider.addDataDisplay(table);
|
||||
table.setSelectionModel(selectionModel);
|
||||
|
||||
mainPanel.add(table);
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -374,6 +374,7 @@ public interface StringMessages extends Messages {
|
||||
String scoringSchemeLowPointSystem();
|
||||
String scoringSchemeHighPointSystem();
|
||||
String scoringSchemeLowPointWinnerGetsZero();
|
||||
String scoringSchemeWinnerGetsFive();
|
||||
String scoringSchemeWinnerGetsSix();
|
||||
String scoringSystem();
|
||||
String createFlexibleLeaderboard();
|
||||
|
||||
+1
@@ -403,6 +403,7 @@ scoringSchemeHighPointSystem=High Point System
|
||||
scoringSchemeHighPointEssOverall=High Point System ESS Overall
|
||||
scoringSchemeHighPointLastBreaksTie=High Point System, Last Race Breaks Tie
|
||||
scoringSchemeLowPointWinnerGetsZero=Low Point System, Winner Gets Zero
|
||||
scoringSchemeWinnerGetsFive=High Point System, Winner Gets 5 Points
|
||||
scoringSchemeWinnerGetsSix=High Point System, Winner Gets 6 Points
|
||||
scoringSystem=Scoring system
|
||||
createFlexibleLeaderboard=Create flexible leaderboard
|
||||
|
||||
+1
@@ -404,6 +404,7 @@ scoringSchemeHighPointSystem=High Point System
|
||||
scoringSchemeHighPointEssOverall=High Point System ESS Gesamtwertung
|
||||
scoringSchemeHighPointLastBreaksTie=High Point System, letztes Rennen entscheidet bei Gleichstand
|
||||
scoringSchemeLowPointWinnerGetsZero=Low Point System, Gewinner erhält 0 Punkte
|
||||
scoringSchemeWinnerGetsFive=High Point System, Gewinner erhält 5 Punkte
|
||||
scoringSchemeWinnerGetsSix=High Point System, Gewinner erhält 6 Punkte
|
||||
scoringSystem=Bepunktungssystem
|
||||
createFlexibleLeaderboard=Flexible Rangliste anlegen
|
||||
|
||||
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties
Executable
+970
@@ -0,0 +1,970 @@
|
||||
# If you want new properties translated then sent this over GMR (Mark Angell <mangell@gmr.com>)
|
||||
helloWorld=Привет Мир
|
||||
kielWeel2011=Кильская Неделя 2011
|
||||
stgAccount=Счет STG
|
||||
tracTracEvents=События Трак Трак
|
||||
swissTimingEvents=События Swiss Timing
|
||||
trackedBefore=Ранее Отслеженные
|
||||
listRaces=Перечень Гонок
|
||||
wind=Ветер
|
||||
windPanelLabel=Это окно информации о ветре, которое до сих пор абсолютно пустое.
|
||||
refresh=Обновить
|
||||
remove=Удалить
|
||||
windSource=Источники информации о ветре
|
||||
dampeningInterval=Интервал ослабления
|
||||
map=Карта
|
||||
race=Гонка
|
||||
races=Гонки
|
||||
tracked=Отслежена
|
||||
time=Время
|
||||
timeTooltip=Учет времени соперника, выступавшего на этом этапе. На первом этапе учет времени ведется с начала гонки, а не при пересечении соперником линии старта.
|
||||
playSpeed=Скорость воспроизведения
|
||||
playSpeedHelp=Используйте "1" для обычной скорости воспроизведения, "2" для удвоенной скорости воспроизведения и т. д.
|
||||
playModeLive=В прямом эфире
|
||||
playModeReplay=Режим повтора
|
||||
timeDelay=Задержка
|
||||
timeDelayHelp=Не указывайте, для воспроизведения повтора в любой момент времени; введите секунды (например, "60" для одной минуты или "0" без указания) задержки перед загрузкой данных в режиме реального времени
|
||||
speedInKnots=Скорость (узлы)
|
||||
fromDeg=Начиная с (градус)
|
||||
noRacesYet=Гонок пока нет.
|
||||
total=\u03A3
|
||||
carry=Суммарная
|
||||
competitor=Соперник
|
||||
competitors=Соперники
|
||||
defaultLeaderboard=Таблица лидеров по умолчанию
|
||||
noSuchLeaderboard=Такая таблица лидеров отсутствует
|
||||
leaderboardConfiguration=Форма таблицы лидеров
|
||||
newDotDotDot=Новый...
|
||||
editScores=Изменить баллы...
|
||||
columnNamesInSelectedLeaderboard=Названия гонок в выбранной таблице лидеров
|
||||
addDotDotDot=Добавить...
|
||||
renameDotDotDot=Переименовать...
|
||||
trackedRaceConnectedToSelectedRaceName=Отслеженная гонка, соединенная с выбранным названием гонки
|
||||
linkToColumn=Соединить со столбцом
|
||||
unlink=Отсоединить
|
||||
leaderboardName=Имя таблицы лидеров
|
||||
cancel=Отмена
|
||||
pleaseEnterAName=Пожалуйста, введите имя
|
||||
pleaseEnterABoatClass=Пожалуйста, введите класс судна
|
||||
discardRacesFromHowManyStartedRacesOn=Не учитывать еще одну начинающуюся гонку в количестве начавшихся гонок
|
||||
leaderboardWithThisNameAlreadyExists=Таблица лидеров с таким именем уже существует
|
||||
discardThresholdsMustBeNumeric=Предельные значения не учитываемых должны быть выражены числом
|
||||
discardThresholdsMustBeAscending=Предельные значения не учитываемых должны быть возрастающими
|
||||
discarding=Неучет
|
||||
startingFromNumberOfRaces=Начиная с количества гонок
|
||||
renameLeaderboard=Переименовать таблицу лидеров
|
||||
addColumnToLeaderboard=Добавить столбец в таблицу лидеров
|
||||
pleaseEnterNameForNewRaceColumn=Введите, пожалуйста, имя для столбца новой гонки
|
||||
ok=OK
|
||||
medalRace=Медальная гонка
|
||||
renameRace=Переименовать гонку
|
||||
openSelectedLeaderboard=Открыть выбранную таблицу лидеров
|
||||
rank=Занимаемое место
|
||||
rankTooltip=Место, занимаемое участником в гонке
|
||||
regattaRank=Место, занимаемое в регате
|
||||
regattaRankTooltip=Место, занимаемое участником в регате
|
||||
overallRank=Итоговое место
|
||||
overallRankTooltip=Место, занимаемое участником на этапах
|
||||
totalRegattaRank=Итоговое место в регате
|
||||
collapse=-
|
||||
expand=+
|
||||
leg=L
|
||||
distanceInMeters=Расстояние
|
||||
averageSpeedInKnots=\u2205 Скорость
|
||||
averageSpeedInKnotsTooltip=Средняя скорость относительно земли в ходе этого этапа,\nрассчитывается путем деления пройденного расстояния на затраченное на это время.
|
||||
raceAverageSpeedInKnotsTooltip=Средняя скорость относительно земли в ходе этой гонки,\nрассчитывается путем деления пройденного расстояния на затраченное на это время.
|
||||
rankGain=Улучшение места
|
||||
rankGainTooltip=Разность между местом, занятым на текущем и предыдущем этапах.
|
||||
sapSailingAnalytics=Аналитическая информация парусного спорта
|
||||
leaderboard=Таблица лидеров
|
||||
leaderboards=Таблицы лидеров
|
||||
leaderboardSettings=Параметры таблицы лидеров
|
||||
settings=Параметры
|
||||
selectAtLeastOneLegDetail=Выберите хотя бы одну подробность об этапе
|
||||
currentSpeedOverGroundInKnots=Скорость относительно земли (SOG)
|
||||
currentSpeedOverGroundInKnotsTooltip=Текущая скорость относительно земли.
|
||||
estimatedTimeToNextWaypointInSeconds=Расчетное время прибытия (ETA).
|
||||
estimatedTimeToNextWaypointInSecondsTooltip= Расчетное время, необходимое участнику для прибытия в следующую промежуточную точку маршрута, исходя из скорости лавирования участника и с учетом истинного направление ветра.
|
||||
gapToLeaderInSeconds=Отставание от лидера
|
||||
gapToLeaderInSecondsTooltip=Время, необходимое участнику для достижения текущего положения лидера, исходя из скорости лавирования.
|
||||
velocityMadeGoodInKnots=Скорость лавирования (VMG)
|
||||
velocityMadeGoodInKnotsTooltip=Скорость лавирования, представляет собой скорость продвижения на ветер/ по ветру для этапов движения против ветра/ по ветру соответственно, или скорость в направлении движения при лавировании по ветру
|
||||
windwardDistanceToGoInMeters=Расстояние, которое необходимо пройти на ветер
|
||||
windwardDistanceToGoInMetersTooltip=Расстояние движения на ветер/ по ветру от текущего положения участника до конца этапа для этапов движения против ветра/ по ветру соответственно, или скорость в направлении движения при лавировании по ветру.
|
||||
windwardDistanceToLeaderInMeters=Расстояние на ветер до лидера
|
||||
windwardDistanceToLeaderInMetersTooltip=Расстояние на ветер/ под ветер от участника до лидера для этапов движения против ветра/ по ветру соответственно или скорость в направлении движения при лавировании по ветру.
|
||||
name=Имя
|
||||
leaveEmptyForDefault=Оставьте пустым по умолчанию.
|
||||
trackNewEvent=Отследить новое событие
|
||||
trackableRaces=Отслеживаемые гонки
|
||||
trackWind=Отслеживать ветер
|
||||
regattaName=Название регаты
|
||||
eventName=Название события
|
||||
event=Событие
|
||||
startTime=Время старта
|
||||
regatta=Регата
|
||||
regattas=Регаты
|
||||
startTracking=Начать отслеживание
|
||||
stopTracking=Остановить отслеживание
|
||||
connections=Подключения
|
||||
historyOfConnections=История подключений
|
||||
defineNewConnection=Определить новое подключение
|
||||
trackedRaces=Отслеженные гонки
|
||||
canSendRequests=Можно отправить запрос
|
||||
connectAndReadRaces=Подключиться и прочитать данные о гонке
|
||||
ports=Порты
|
||||
liveData=Данные в реальном времени
|
||||
storedData=Сохраненные данные
|
||||
uris=URI-адреса
|
||||
jsonUrl=JSON URL
|
||||
livePort=Порт данных в реальном времени
|
||||
storedPort=Порт сохраненных данных
|
||||
liveUri=Данные пользователя в реальном времени
|
||||
storedUri=Сохраненные данные пользователя
|
||||
eventsConnectedTo=Текущие отслеживаемые события
|
||||
hostname=Имя узла
|
||||
declinationCheckbox=Корректировка направления ветра с помощью отклонения
|
||||
raceStartTrackingColumn=Отслеживание начато
|
||||
pauseAutomaticRefresh=Приостановка автоматического обновления
|
||||
autoRefresh=Обновлять автоматически
|
||||
delayInSeconds=Задержка (и)
|
||||
delayBetweenAutoAdvances=Задержка между автоматическими обновлениями в секундах:
|
||||
delayMustBeNonNegative=Значение задержки должно быть больше нуля
|
||||
chooseUpdateIntervalOfAtLeastOneSecond=Выберите интервал обновления, он должен быть не менее одной секунды
|
||||
errorSettingWindForRace=Ошибка при настройке параметра ветер для гонки
|
||||
errorFetchingWindInformationForRace=Ошибка при получении данных о ветре для гонки
|
||||
errorWhileTryingToSetWindSourceForRace=Ошибка при попытке установить флажок «начинается встречный ветер»
|
||||
inEvent=В случае
|
||||
to=к
|
||||
showEstimatedWind=Показать оценочный ветер
|
||||
timing=Хронометраж
|
||||
raceDetailsToShow=Подробные сведения о гонке
|
||||
overallDetailsToShow=Общие сведения
|
||||
legDetailsToShow=Сведения об этапе
|
||||
columnMoveUp=Вверх
|
||||
columnMoveDown=Вниз
|
||||
port=Порт
|
||||
raceStartTimeColumn=Гонка началась
|
||||
showOnlySelectedCompetitors=Показать только выбранных участников
|
||||
showSelectedCompetitorsInfo=Показать окно краткого описания только для выбранных участников
|
||||
tailLength=Длина (с) хвоста
|
||||
selectedRaces=Какие гонки вы хотели бы отобразить?
|
||||
lengthInSeconds=Длина (с)
|
||||
stressTest=Стресс тест
|
||||
numberOfManeuvers=Маневры
|
||||
numberOfManeuversTooltip=Количество маневров, выполненных во время этого этапа.
|
||||
numberOfManeuversInRaceTooltip=Количество маневров, выполненных во время этой гонки.
|
||||
tacks=Галсы
|
||||
jibes=Перекладывания паруса
|
||||
penaltyCircles=Штрафные круги
|
||||
medalRaceIsNull=Значение медальной гонки недопустимо
|
||||
configuration=Конфигурация
|
||||
maneuverTypes=Маневры
|
||||
chooseChart=Выбрать график
|
||||
distanceTraveled=Пройденное расстояние
|
||||
distanceTraveledTooltip=Расстояние, пройденное от старта до финиша этапа\а не до текущего момента времени, если этап не завершен.
|
||||
raceDistanceTraveledTooltip=Расстояние, пройденное от старта до финиша гонки\а не до текущего момента времени, если гонка не завершена.
|
||||
velocityMadeGoodLong=Скорость лавирования
|
||||
speedOverGroundLong=Скорость относительно земли
|
||||
gapToLeaderLong=Отставание от лидера
|
||||
pointsToLoad=Баллов для нагрузки
|
||||
speed=Скорость
|
||||
distance=Расстояние
|
||||
in=в
|
||||
secondsUnit=с
|
||||
metersUnit=м
|
||||
close=Закрыть
|
||||
compareCompetitors=Сравнить участников
|
||||
description=Описание
|
||||
sailNumber=Номер на парусе
|
||||
country=Страна
|
||||
no3LetterCodes=Не удалось найти 3-х буквенные коды стран МОК.
|
||||
add=Добавить
|
||||
delete=Удалить
|
||||
showCharts=Показать графики
|
||||
raceWithThisNameAlreadyExists=Гонка с таким именем уже существует.
|
||||
raceWithThisNameAlreadyExistsInRegatta=Гонка с таким именем уже существует в этой регате.
|
||||
headUp=Заголовок
|
||||
bearAway=Поворачивать под ветер
|
||||
tack=Галс
|
||||
tackTooltip=Количество галсов совершенных во время этой гонки.
|
||||
jibe=Перебрасывать парус
|
||||
jibeTooltip=Количество перебрасываний паруса во время этой гонки.
|
||||
penaltyCircle=Штрафной круг
|
||||
penaltyCircleTooltip=Количество штрафных кругов, пройденных в ходе этой гонки.
|
||||
markPassing=Проход знака
|
||||
mark=Знак
|
||||
otherManeuver=Неизвестный маневр
|
||||
douglasPeuckerPoints=Точки алгоритма Дугласа-Пойкера
|
||||
filterRacesByName=Сортировать гонки по названию
|
||||
trackSettings=Отслеживать параметры
|
||||
actionEdit=Изменить
|
||||
actionEditCompetitors=Изменить участников
|
||||
actionEditScores=Изменить баллы
|
||||
actionOpenBrowser=Открыть в браузере
|
||||
actionRemove=Удалить
|
||||
actionEditSeries=Изменить серии
|
||||
actionRaceEdit=Изменить или переименовать гонку
|
||||
actionRaceUnlink=Отсоединить гонку
|
||||
actionRaceRemove=Удалить гонку
|
||||
actionExportXML=Экспорт в формате XML
|
||||
filterLeaderboardsByName=Сортировать таблицы лидеров по названию
|
||||
actions=Действия
|
||||
islinked=Соединен
|
||||
yes=Да
|
||||
no=Нет
|
||||
hoverOverAPoint=Наведите курсор на точку для просмотра подробных сведений
|
||||
noSelection=Ничего не выбрано
|
||||
raceIsKnownToStartUpwind=Гонка начинается с этапа с наветренной стороны
|
||||
events=События
|
||||
settingsForComponent=Параметры для {0}
|
||||
noEventsFound=События не обнаружены
|
||||
noEventSelected=События не выбраны
|
||||
noLeaderboardsFound=Талицы лидеров не обнаружены
|
||||
searchEvents=Поиск событий
|
||||
location=Местонахождение
|
||||
from=С
|
||||
until=По
|
||||
onlyLiveEvents=Только события в прямом эфире
|
||||
locationNotAvailable=Местонахождение недоступно
|
||||
startDateNotAvailable=Дата начала недоступна
|
||||
startDate=Дата начала
|
||||
endDate=Дата окончания
|
||||
unknownManeuver=Неизвестный маневр
|
||||
tailLengthMustBePositive=Число длины хвоста должно быть больше нуля.
|
||||
failedToLoadRaceInformation=Сбой при загрузке сведений о гонке: {0}
|
||||
competitorPassedMarkAtDate={0} прошли {1} в {2}
|
||||
valueForCompetitorAt={0} в {1}: {2}
|
||||
reallyRemoveRace=Вы действительно хотите удалить гонку ''{0}''? Примечание: все записи о гонке будут также удалены без возможности восстановления!
|
||||
showDetails=Показать подробности
|
||||
hideLeaderboard=Скрыть таблицу лидеров
|
||||
hideLeaderboards=Скрыть таблицы лидеров
|
||||
showLeaderboard=Показать таблицу лидеров
|
||||
hideRaces=Скрыть гонки
|
||||
showMap=Показать карту
|
||||
hideMap=Скрыть карту
|
||||
noLeaderboardSelected=Таблица лидеров не выбрана
|
||||
leaderboardGroups=Группы таблицы лидеров
|
||||
filterLeaderboardGroupsByName=Сортировать группы таблицы лидеров по имени
|
||||
createNewLeaderboardGroup=Создать группу таблицы лидеров
|
||||
leaderboardGroupConfiguration=Конфигурация группы таблицы лидеров
|
||||
legs=Этапы
|
||||
currentLeg=На этапе
|
||||
currentLegTooltip=Номер этапа, на котором находится участник в данный момент, начиная с 1
|
||||
leaderboardGroup=Группа таблицы лидеров
|
||||
pleaseEnterNonEmptyDescription=Пожалуйста, введите непустое описание
|
||||
groupWithThisNameAlreadyExists=Группа таблицы лидеров с этим именем уже существует.
|
||||
detailsOfLeaderboardGroup=Сведения о группе таблицы лидеров
|
||||
edit=Изменить
|
||||
save=Сохранить
|
||||
abort=Отмена
|
||||
noLeaderboardGroupWithNameFound=Группа таблицы лидеров с именем {0} не обнаружена
|
||||
overview=Обзор
|
||||
welcomeToSailingAnalytics=Добро пожаловать в Аналитическую информацию парусного спорта SAP
|
||||
welcomeToSailingAnalyticsBody=SAP приближает любителей парусного спорта к происходящим на воде событиям как никогда раньше.\
|
||||
\ Таблица лидеров в прямом эфире расширяет возможности для любителей, отображая в режиме реального времени место, занимаемое участником, скорости судов, а также победителей с указанием отрыва. Следите за каждой гонкой и благодаря SAP не пропускайте ни одного совершенного маневра.\
|
||||
\ Это самый простой способ наблюдать за парусной гонкой в прямом эфире, где бы вы ни находились.
|
||||
home=Главная
|
||||
clickAndDragToZoomIn=Щелкните и перетащите область графика для увеличения
|
||||
windSpeed=Скорость ветра (узлы)
|
||||
allTimesInUTC=Время указано в универсальном глобальном времени по Гринвичу (UTC)
|
||||
autoZoomTo=Автоматическое масштабирование до
|
||||
autoZoomToBoats=Суда
|
||||
autoZoomToBuoys=Буи
|
||||
autoZoomToWindSensors=Датчики ветра
|
||||
autoZoomOff=Выкл
|
||||
autoZoomToTails=Хвосты
|
||||
autoZoomSelectedCompetitors=Масштабировать только выбранных участников
|
||||
bearing=Направление (ветра)
|
||||
zoom=Масштабирование
|
||||
stepSizeMustBeGreaterThanNull=Размер шага должен быть больше 0
|
||||
stepSizeInSeconds=Размер шага в секундах
|
||||
refreshInterval=Обновить интервал (ы)
|
||||
refreshIntervalMustBeGreaterThanXSeconds=Обновление интервала должно быть больше, чем {0} секунд
|
||||
competitorCharts=Графики участника
|
||||
selectAtLeastOneCompetitor=Для отображения графиков участников, выберите хотя бы одного участника
|
||||
directionChange=Изменение направления
|
||||
speedChange=Изменение скорости
|
||||
degreesShort=градус
|
||||
untracked=Неотслеженная
|
||||
delayForLiveMode=Задержка для режима прямого эфира:
|
||||
notAvailable=Недоступно
|
||||
details=Подробности
|
||||
noGroupSelected=Группа не выбрана
|
||||
combinedWindSourceTypeName=Комбинированная
|
||||
courseBasedWindSourceTypeName=Проложенный курс
|
||||
trackBasedEstimationWindSourceTypeName=Расчетный
|
||||
expeditionWindSourceTypeName=Измеренный
|
||||
webWindSourceTypeName=Вручную
|
||||
raceCommitteeWindSourceTypeName=Гоночный комитет
|
||||
clickChartToSetTime=Щелкните по графику для установки времени
|
||||
position=Положение
|
||||
windSourcesUsed=Использованные источники информации о ветре
|
||||
errorTryingToUpdateWindSourcesToExclude=Ошибка при попытке обновления источников информации о ветре для исключения для гонки {0}: {1}
|
||||
feedback=Комментарии
|
||||
startStopPlaying=Начать/Остановить воспроизведение
|
||||
backToLive=Вернуться к моменту времени в прямом эфире
|
||||
slowPlaySpeedDown=Замедлить скорость воспроизведения или даже воспроизводить назад.
|
||||
speedPlaySpeedUp=Увеличить скорость воспроизведения или снова воспроизводить вперед.
|
||||
showHideComponent=Показать/ Скрыть {0}
|
||||
degreesBoatToTheWind=Угол к ветру
|
||||
racesInLeaderboard=Гонки в таблице лидеров
|
||||
leaderboardsInGroup=Таблицы лидеров в группе
|
||||
replication=Дублирование
|
||||
errorFetchingReplicaData=Ошибка получения данных дублирования: {0}
|
||||
averageCrossTrackErrorInMeters=\u2205 XTE
|
||||
averageCrossTrackErrorInMetersTooltip=Среднее боковое уклонение от заданного курса по большой дуге окружности, соединяющей начало и конец этапа
|
||||
raceAverageCrossTrackErrorInMetersTooltip=Среднее боковое уклонение от заданного курса по большой дуге окружности, соединяющей начало и конец этапа в течение этой гонки.
|
||||
enterMaster=Имя узла ведущего экземпляра
|
||||
errorStartingReplication=Ошибка начала повтора с узла {0} / обмена {1}: {2}
|
||||
helpLines=Вспомогательные линии
|
||||
startLine=Линия старта
|
||||
finishLine=Линия финиша
|
||||
advantageLine=Линия преимущества
|
||||
courseMiddleLine=Средняя линия курса
|
||||
messagingPortNumber=Номер порта обмена сообщениями ( по умолчанию 0)
|
||||
servletPortNumber=Номер порта сервлета
|
||||
registeredAt=Зарегистрирован в {0}
|
||||
replicatingFromMaster=Дублирование с основного {0}, порт передачи обмена сообщениями {1}, порт сервлета {2}
|
||||
showWindSpeedSeries=Показать данные о силе ветра
|
||||
showWindDirectionSeries=Показать данные о направлении ветра
|
||||
fleet=Флот
|
||||
boatClass=Класс судна
|
||||
setDelayToLive=Установить задержку от прямого эфира
|
||||
pleaseEnterNonEmptyVenue=Введите, пожалуйста, место проведения соревнования.
|
||||
pleaseEnterStartAndEndDate=Пожалуйста, введите дату начала и дату окончания.
|
||||
startDateMustBeforeEndDate=Дата начала должна предшествовать дате окончания.
|
||||
eventWithThisNameAlreadyExists=Событие с этим именем уже существует.
|
||||
venue=Место проведения
|
||||
pleaseSelectABoatClass=Выберите, пожалуйста, класс судна.
|
||||
regattaWithThisNameAlreadyExists=Регата с этим именем уже существует.
|
||||
seriesWithThisNameAlreadyExists=Серия с этим именем уже существует.
|
||||
fleetWithThisNameAlreadyExists=Флот с этим именем уже существует.
|
||||
fleets=Флоты
|
||||
series=Серии
|
||||
splitFleet=Разделить флот
|
||||
color=Цвет
|
||||
medalSeries=Медальные серии
|
||||
noColor=Цвет не указан
|
||||
pleaseSelectARegatta=Пожалуйста, выберите регату.
|
||||
addFleet=Добавить флот
|
||||
doYouReallyWantToRemoveRegatta=Вы действительно хотите удалить регату "{0}"? Это приведет к удалению без возможности восстановления всех таблиц лидеров для этой регаты!
|
||||
errorLoadingScoreCorrectionProviders=Ошибка при загрузке провайдеров для корректировки очков: {0}
|
||||
selectResultListToImportFrom=Выберите список результатов для импорта из
|
||||
of=из
|
||||
errorObtainingScoreCorrections=Ошибка получения корректировки очков от провайдера {0} и события {1} для класса судна {2} опубликованного {3}: {4}
|
||||
assignRaceNumbersToRaceColumns=Назначение номеров гонок из официальных результатов столбам гонок таблицы лидеров
|
||||
importOfficialResults=Импорт официальных результатов...
|
||||
selectAll=Выбрать все
|
||||
apply=Применить
|
||||
successfullyUpdatedScores=Очки обновлены успешно
|
||||
errorUpdatingScoresForLeaderboard=Ошибка обновления очков для таблицы лидеров {0}: {1}
|
||||
maneuverTypesToShowWhenCompetitorIsClicked=Типы маневров для отображения при нажатии на участника
|
||||
simulateWithStartTimeNow=Моделирования с "сейчас" в качестве времени начала
|
||||
boatClassDoesNotMatchSelectedRegatta=Выбранные гонки содержат классы судов не соответствующие классу судов ''{0}'' выбранной регаты.\\ Вы действительно хотите использовать регату ''{1}''?
|
||||
regattaExistForSelectedBoatClass=Есть только одна регата для выбранных классов судов.\\ Вы действительно хотите использовать выбор ''ни одной регаты''?
|
||||
reload=Перезагрузить
|
||||
addRegatta=Добавить регату...
|
||||
exchangeName=Заменить имя
|
||||
course=Курс
|
||||
courseLayout=Проложенный курс
|
||||
buoy=Буй
|
||||
gate=Ворота
|
||||
buoys=Буи
|
||||
waypoint=Точка маршрута
|
||||
showAllCompetitors=Показать всех участников
|
||||
boatTails=Лодочные хвосты
|
||||
resultImportUrls=URL-адреса импорта результатов
|
||||
errorRefreshingResultImportUrlList=Ошибка обновления списка URL-адресов импорта результатов: {0}
|
||||
successfullyUpdatedResultImportUrls=Список URL-адресов импорта результатов успешно обновлен
|
||||
errorRemovingResultImportUrls=Ошибка удаления URL-адресов импорта результатов: {0}
|
||||
pleaseEnterNonEmptyUrl=Пожалуйста, введите URL-адрес
|
||||
addResultImportUrl=Добавить URL-адрес импорта результатов
|
||||
errorAddingResultImportUrl=Ошибка добавления URL-адреса импорта результатов: {0}
|
||||
errorTryingToObtainLeaderboardContents=Ошибка попытки получения содержимого таблицы лидеров: {0}
|
||||
lastScoreUpdate=Обновление последних очков
|
||||
warningBrowserUnsupported=Этот веб-сайт не оптимизирован для вашего браузера. Пожалуйста, выберите браузер новой версии, такой как Firefox или Chrome.
|
||||
newMark=Новый знак
|
||||
controlPoint=Знак/Ворота
|
||||
errorUpdatingRaceCourse=Ошибка обновления курса гонки: {0}
|
||||
successfullyUpdatedCourse=Курс гонки успешно обновлен
|
||||
selectOneMarkOrTwoMarksForGate=Выберите одну отметку или две отметки для создания ворот
|
||||
errorTryingToObtainTheMarksOfTheRace=Ошибка попытки получения отметок дистанции гонки: {0}
|
||||
errorTryingToObtainRaceCourse=Ошибка попытки получения курса гонки: {0}
|
||||
insertWaypointBeforeSelected=Вставьте ранее выбранную точку маршрута
|
||||
insertWaypointAfterSelected=Вставьте точку маршрута, выбранную позднее
|
||||
scoringSchemeLowPointSystem=Низкобальная (линейная) система подсчета очков
|
||||
scoringSchemeHighPointSystem=Высокобальная система подсчета очков
|
||||
scoringSchemeHighPointEssOverall=Высокобальная система подсчета, итоговые баллы экстремальной серии ESS
|
||||
scoringSchemeHighPointLastBreaksTie=Высокобальная система подсчета, тай-брейк на последней гонке
|
||||
scoringSchemeLowPointWinnerGetsZero=Низкобальная система подсчета очков, победитель получает ноль очков
|
||||
scoringSchemeWinnerGetsFive=Высокобальная система подсчета, победитель получает 5 очков
|
||||
scoringSchemeWinnerGetsSix=Высокобальная система подсчета, победитель получает 6 очков
|
||||
scoringSystem=Система подсчета очков
|
||||
createFlexibleLeaderboard=Создание адаптивной таблицы лидеров
|
||||
createRegattaLeaderboard=Создание таблицы лидеров регаты
|
||||
editFlexibleLeaderboard=Изменение адаптивной таблицы лидеров
|
||||
editRegattaLeaderboard=Изменение таблицы лидеров регаты
|
||||
defaultRegatta=Регата по умолчанию
|
||||
useOverallLeaderboard=Использование общей таблицы лидеров
|
||||
overallStandings=Общий зачет
|
||||
type=Тип
|
||||
actionAddRaces=Добавить гонки
|
||||
racesWithNamePrefix=Гонки с именем-префиксом
|
||||
maximumSpeedOverGroundInKnots=Максимальная скорость относительно земли
|
||||
maximumSpeedOverGroundInKnotsTooltip=Самая большая скорость относительно земли участника, измеренная в ходе регаты.
|
||||
totalTimeSailedDownwindInSeconds=Общее время под ветером
|
||||
totalTimeSailedDownwindInSecondsTooltip=Общее время, которое в течение регаты участник шел под ветер.
|
||||
totalTimeSailedUpwindInSeconds=Общее время против ветер
|
||||
totalTimeSailedUpwindInSecondsTooltip=Общее время, которое в течение регаты участник шел против ветер.
|
||||
totalTimeSailedReachingInSeconds=Общее время лавирования по ветру
|
||||
totalTimeSailedReachingInSecondsTooltip=Общее время этапов лавирования по ветру участником в ходе регаты.
|
||||
totalTimeSailedInSeconds=Общее время
|
||||
totalTimeSailedInSecondsTooltip=Общее время, которое участник проплыл в регате.
|
||||
totalDistanceTraveled=Общее расстояние
|
||||
totalDistanceTraveledTooltip=Общее расстояние, пройденное во время регаты.
|
||||
totalAverageSpeedOverGround=\u2205 Скорость относительно земли
|
||||
totalAverageSpeedOverGroundTooltip=Средняя скорость относительно земли на протяжении регаты.
|
||||
hhmmssUnit=чч:мм:сс
|
||||
actionAddWindData=Добавить данные о ветре
|
||||
valueMustBeBetweenMinMax=Значение ''{0}''должно быть в пределах от {1} до {2}.
|
||||
optional=Дополнительно
|
||||
pleaseEnterAValue=Введите, пожалуйста, значение.
|
||||
latitude=Широта
|
||||
longitude=Долгота
|
||||
actionAddEvent=Добавить событие
|
||||
publicationUrl=URL-адрес для публикации
|
||||
suppress=скрыть
|
||||
isPublic=является открытым
|
||||
suppress=скрыть
|
||||
unsuppress=Отобразить
|
||||
suppressedCompetitors=Скрытые участники
|
||||
mediaPanel=Аудио и Видео
|
||||
url=URL
|
||||
mimeType=MIME-тип
|
||||
title=Заголовок
|
||||
duration=Продолжительность (ч:мм:сс.мс)
|
||||
addMediaTrack=Добавить аудио/видео
|
||||
addYoutubeTrack=Добавить Youtube
|
||||
youtubeId=Идентификатор Youtube
|
||||
reallyRemoveMediaTrack=Вы действительно хотите удалить медиа трек''{0}''?
|
||||
pleaseSelectASeries=Пожалуйста, выберите серию
|
||||
pleaseSelectARace=Пожалуйста, выберите гонку
|
||||
displayGroupsInReverseOrder=Отобразить группы в обратном порядке
|
||||
actionConfigureUrl=Настроить URL-адрес
|
||||
configureLeaderboardUrlDescription=Настроить таблицу лидеров и получить результирующий URL-адрес по ссылке
|
||||
embedded=Внедренный
|
||||
additionalUrlSettings=Дополнительные параметры URL-адреса
|
||||
restrictToSingleSelectedRace=Ограничить одной выбранной гонкой
|
||||
expandSelectedRace=Расширить выбранную гонку
|
||||
showRaceDetails=Разрешить подробности для гонки
|
||||
numberOfRaces=Количество гонок
|
||||
numberOfRacesMustBeNonNegativeNumber=Пожалуйста, введите количество последних гонок, которые должны отображаться
|
||||
chooseTheWayYouSelectRaces=Выберите способ выбора гонок
|
||||
selectFromAllRaces=Выбрать из всех гонок
|
||||
selectANumberOfRaces=Выбрать несколько гонок
|
||||
numberOfLastNRaces=Количество самых последних гонок для отображения
|
||||
expandLastRace=Всегда раскрывать последнюю отображенную гонку
|
||||
factor=Фактор
|
||||
errorUpdatingIsMedalRace=Ошибка обновления параметров медальной гонки: {0}
|
||||
maneuverLoss=Потеря при выполнении маневра
|
||||
averageManeuverLossInMeters=\u2205 Потеря при выполнение маневра
|
||||
averageManeuverLossInMetersTooltip=Усредненная потеря расстояния при выполнении маневра.
|
||||
averageTackLossInMeters=\u2205 Потеря при смене галса
|
||||
averageTackLossInMetersTooltip=Усредненная потеря расстояния при смене галса.
|
||||
averageJibeLossInMeters=\u2205 Потеря при перекладывании паруса
|
||||
averageJibeLossInMetersTooltip=Усредненная потеря расстояния при перекладывании паруса.
|
||||
shape=Форма
|
||||
pattern=Модель
|
||||
legend=Легенда
|
||||
live=прямой эфир
|
||||
swissTimingArchiveConnector=события SwissTiming, помещенные в архив
|
||||
errorFetchingChartData=Ошибка получения данных графика: {0}
|
||||
loadingCompetitorData=Загрузка данных участника...
|
||||
competitorRegattaDataAfterRaceN={0} после гонки {1}
|
||||
rankChart=Рейтинг
|
||||
totalPoints=Итоговое количество очков
|
||||
raceTotalPointsTooltip=Итоговое количество очков участника в гонке
|
||||
regattaTotalPointsTooltip=Итоговое количество очков участника в регате
|
||||
showRankChart=Показать таблицу рейтинга
|
||||
overallLeaderboardSelection=Итоговая таблица лидеров
|
||||
errorTryingToObtainOverallLeaderboards=Ошибка получения итоговых таблиц лидеров: {0}
|
||||
finished=Завершившиеся
|
||||
passedTo=Переданные в {0}
|
||||
gapChangeSinceLegStartInSeconds=Изменение отставания
|
||||
gapChangeSinceLegStartInSecondsTooltip=Изменение отставания от лидера с начала последнего этапа.\nОтрицательное число означает, что отставание уменьшилось;\nположительное число означает, что отставание увеличилось.
|
||||
sideToWhichMarkAtLegStartWasRounded=Отметка округленная до
|
||||
sideToWhichMarkAtLegStartWasRoundedTooltip=Сторона в которую округляется отметка на старте этапа.
|
||||
raceIsLive=Гонка {0} в прямом эфире
|
||||
racesAreLive=Гонки {0} в прямом эфире
|
||||
knotsUnit=Узлы
|
||||
scoringSchemeHighPointFirstGetsOne=Самый лучший результат, победитель получает 1 очко
|
||||
scoringSchemeHighPointFirstGetsTen=Самый лучший результат, победитель получает 10 очков
|
||||
knotsUnit=Узлы
|
||||
generatePolarSheet=Создать полярную электронную таблицу
|
||||
polars=Полярная диаграмма
|
||||
polarSheetChart=Полярная электронная таблица
|
||||
polarSheetMinimumDataSizePerGraph=Минимальное количество данных на графике
|
||||
polarSheetMinimumDataSizePerGraphTooltip=Все графики с меньшим количеством точек данных визуально не отображаются.\nТаким образом, не отображаются отвлекающие внимание диаграммы для \nскоростей ветра, в которых отсутствует достаточный объем данных.
|
||||
polarSheetMinimumDataSizePerAngle=Минимальное количество точек данных в расчете на угол
|
||||
polarSheetMinimumDataSizePerAngleTooltip=На каждом графике будут отображаться только данные об углах с указанным числом\nбазовых точек данных. Не имеющие важного значения\nчасти графика могут быть скрыты с помощью задания этой пороговой величины.
|
||||
polarSheetMinimumWindConfidence=Минимальное значение достоверных данных о ветре
|
||||
polarSheetMinimumWindConfidenceTooltip=Только фиксированные значения ветра с достоверностью, превышающей указанное пороговое значение\nприменяются. Эта достоверность от 0 до 1.
|
||||
polarSheetMinimumConfidenceMeasure=Минимально допустимое измерение достоверности
|
||||
polarSheetMinimumConfidenceMeasureTooltip=Минимальная степень достоверности для точки, указанной на графике.\nЕсли она ниже установленного порогового значения, то точка не отображается.\nЗначение лежит от 0 до 1 и детерминируется \nс использованием статистических мер.
|
||||
polarSheetUseOnlyWindGaugeData=Для определения скорости ветра используйте только данные, полученные с помощью анемометра
|
||||
polarSheetUseOnlyWindGaugeDataTooltip=Благодаря учету данных о скорости ветра, полученных с помощью анемометра\nмы исключаем примерные значения скорости ветра, введенные вручную, которые могли бы исказить данные, отображенные на полярной диаграмме.
|
||||
polarSheetUseOnlyEstimationData=Используйте, определенные на глаз значения только для направления ветра
|
||||
polarSheetUseOnlyEstimationDataTooltip=Использование точных расчетных значений о направлении ветра,\nпозволяет нам устранить ошибки полярных диаграмм, которые вращаются из-за неправильных данных, полученных с анемометра\n.
|
||||
polarSheetRemoveOutliers=Удалите сильно отличающиеся значения (Подход основан на расстоянии)
|
||||
polarSheetRemoveOutliersTooltip=Сильно отличающиеся значения удаляются с помощью применения подхода, основанного на расстоянии.\nПараметры могут быть отрегулированы ниже.
|
||||
polarSheetOutlierDetectionRadius=Соседний радиус, определяющий сильно отличающееся значение
|
||||
polarSheetOutlierDetectionRadiusTooltip=Радиус, используемый в алгоритме определения сильно отличающегося значения\nна основании расстояния.
|
||||
polarSheetOutlierDetectionMinimumPerc=Минимальный процент соседних точек, определяющий сильно отличающееся значение
|
||||
polarSheetOutlierDetectionMinimumPercTooltip=Процент соседних точек данных /всего точек данных\nдолжен быть ниже указанного значения для того, чтобы считаться сильно отличающимся значением.
|
||||
polarSheetNumberOfHistogramColumns=Количество столбцов гистограммы
|
||||
polarSheetWindSteppingInKnots=Шаг значения ветра в узлах
|
||||
polarSheetWindSteppingMaxDistance=Максимальное расстояние до уровня ветра
|
||||
polarSheetWindSteppingMaxDistanceTooltip=Устанавливает максимальный радиус, для которого уровни ветра будут фиксированными.
|
||||
polarSheetSplitByWindGauges=Разделить источники данных о ветре
|
||||
polarSheetSplitByWindGaugesTooltip=Разделение источников данных о ветре позволяет найти неисправные анемометры.\nСтатистическая правильность не гарантируется. Такое исправление может \nбыть учтено в полярной диаграмме результатов несколько раз (для разных анемомтеров).
|
||||
pleaseSeeToolTips=Пожалуйста, наведите курсор на свойства, чтобы ознакомиться с всплывающими подсказками, при их наличии.
|
||||
competitorColumnTooltip=Имена членов команды этого участника.
|
||||
sailIdColumnTooltip=Отображает флаг страны и номер на парусе участника.
|
||||
rankColumnTooltip=Итоговое место этого участника в регате.
|
||||
carryColumnTooltip=Очки, перенесенные из предыдущих гонок.
|
||||
totalsColumnTooltip=Итоговое количество очков участника в регате.
|
||||
windData=Данные о ветре
|
||||
gpsData=GPS-данные
|
||||
status=Статус
|
||||
noDataFound=Данные не обнаружены
|
||||
displayName=Отобразить имя
|
||||
histogram=Гистограмма
|
||||
numberOfDataPoints=Количество точек данных
|
||||
angleAndTotalNumberOfDataPointsAndCovAndCm=Угол: {0}; Общее количество точек данных: {1}; Коэффициент отклонения: {2}; Степень достоверности: {3}
|
||||
buoyZone=Зона буя
|
||||
radiusInMeters=Радиус (м)
|
||||
filterRegattasByName=Сортировка регат по имени
|
||||
noRegattasYet=Пока регат нет.
|
||||
addCourseArea=Добавить зону курса
|
||||
courseAreas=Зоны курса
|
||||
courseArea=Зона курса
|
||||
pleaseEnterNonEmptyCourseArea=Пожалуйста, выведите зону курса.
|
||||
pleaseSelectACourseArea=Пожалуйста, выберите зону курса.
|
||||
radiusInMeters=Радиус (м)
|
||||
lastUpperFlag=Верхний флажок
|
||||
lastLowerFlag=Нижний флажок
|
||||
cannotAddRacesToRegattaLeaderboardButOnlyToRegatta=Это таблица лидеров регаты. Вы можете добавлять гонки в эту таблицу лидеров только непосредственно в определении регаты.
|
||||
correctScore=Исправить очки
|
||||
correctScoreFor=Исправить очки для участника {0} в гонке {1}
|
||||
penaltyOrRedress=Штраф/Корректировка
|
||||
netScore=Чистые очки
|
||||
timePointMustBeAfterStartOfTracking=Момент времени должен быть после начала отслеживания.
|
||||
timePointMustBeBeforeEndOfTracking=Момент времени должен быть до окончания отслеживания.
|
||||
regattaUsedForTheTrackedRace=Регата, используемая для отслеживаемой гонки
|
||||
tracTracUpdateUrl=Обновление URl-адреса сервера ТракТрак
|
||||
passingInstructions=Инструкции по передаче
|
||||
refreshNow=Обновить сейчас
|
||||
stopUpdating=Остановить обновление
|
||||
startUpdating=Начать обновление
|
||||
currentTime=Текущее время:
|
||||
tractracUsername=Имя пользователя ТракТрак
|
||||
tractracPassword=Пароль ТракТрак
|
||||
operatorEquals=Равно
|
||||
operatorNotEqualTo=Не равно
|
||||
operatorLessThan=Меньше
|
||||
operatorLessThanEquals=Меньше или равно
|
||||
operatorGreaterThan=Больше чем
|
||||
operatorGreaterThanEquals=Больше или равно
|
||||
operatorContains=Содержит
|
||||
operatorNotContains=Не содержит
|
||||
operatorStartsWith=Начинается с
|
||||
operatorEndsWith=Заканчивается на
|
||||
nationality=Гражданство
|
||||
numberMustBePositive=Цифра должна быть больше нуля.
|
||||
distanceToLineAtRaceStart=Расстояние до линии «Старт»
|
||||
distanceToLineFiveSecondsBeforeStart=Расстояние до линии 5с до старта
|
||||
speedOverGroundAtRaceStart=Скорость относительно земли на линии «Старт»
|
||||
speedOverGroundFiveSecondsBeforeStart=Скорость относительно земли на линии 5с до старта
|
||||
speedOverGroundWhenPassingStart=Скорость относительно земли во время старта
|
||||
distanceToLineAtRaceStartTooltip=Расстояние до стартовой линии во время начала гонки
|
||||
distanceToLineFiveSecondsBeforeStartTooltip=Расстояние до стартовой линии за пять секунд до начала гонки
|
||||
speedOverGroundAtRaceStartTooltip=Скорость относительно земли во время начала гонки
|
||||
speedOverGroundFiveSecondsBeforeStartTooltip=Скорость относительно земли за пять секунд до начала гонки
|
||||
speedOverGroundWhenPassingStartTooltip=Скорость относительно земли при пересечении участником линии старта
|
||||
startTack=Сменить галс
|
||||
startTackTooltip=галс, на котором участник начал
|
||||
portTack=Левый галс
|
||||
starboardTack=Правый галс
|
||||
portSide=Левый борт
|
||||
starboardSide=Правый борт
|
||||
pleaseEnterANumber=Пожалуйста, введите номер.
|
||||
competitorsFilter=Сортировать участников
|
||||
flagStatus=Флажок состояния
|
||||
additionalInformation=Информация
|
||||
windFixListingDescription=Исправления для ветра (первые 3, последние 3, фактические значения)
|
||||
noWindFixesAvailable=Исправления для ветра недоступны.
|
||||
distanceToStarboardEndOfStartlineWhenPassingStart=Расстояние от линии до правого борта во время прохождения старта
|
||||
distanceToStarboardEndOfStartlineWhenPassingStartTooltip=Расстояние до правого борта от стартовой линии или одной отметки начала, когда участник пересек линию старта
|
||||
actionAddFilter=Добавить фильтр
|
||||
actionEditFilter=Изменить фильтр
|
||||
availableFilters=Доступные фильтры
|
||||
createFilterHint=Создать набор фильтров для сортировки списка участников.
|
||||
filterThisNameAlreadyExists=Фильтр с таким именем уже существует.
|
||||
addAtLeastOneFilterCriteria=Добавьте хотя бы один критерий сортировки.
|
||||
filterCriteria=Критерий сортировки
|
||||
selectAFilterCriteria=Выбрать критерий сортировки
|
||||
filterName=Имя фильтра
|
||||
operator=Оператор
|
||||
value=Значение
|
||||
nationalityMustBeISOorIOCcode=Гражданство должно содержать двухбуквенный код МОК или трехбуквенный код МОК.
|
||||
raceRank=Рейтинг гонки
|
||||
waypoints=Точки маршрута
|
||||
disableRaceFilter=Отключить фильтр
|
||||
enableRaceFilter=Включить фильтр
|
||||
raceStatusColumn=Статус гонки
|
||||
loading=Загрузка (при медленном соединении с Интернетом процесс может занять несколько минут)...
|
||||
racesWithHiddenState=Гонки со статусом «СКРЫТЫ»
|
||||
mediaDateFormatError=Недействительный формат даты. Использовать: {0}
|
||||
selectedCompetitors=Выбранные участники
|
||||
filterNothing=Нечего сортировать
|
||||
topNCompetitorsByRaceRank=Лидеры гонки {0}
|
||||
topNCompetitorsByTotalRank=Лидеры в общем зачете {0}
|
||||
simulator=Модель
|
||||
optionsBar=Панель опций
|
||||
simulateButton=Прогнозировать
|
||||
setup=Установка
|
||||
strength=Сила (в узлах)
|
||||
oscillation=Колебание
|
||||
oscillating=Колеблющийся
|
||||
amplitude=Амплитуда(в градусах)
|
||||
frequency=Частота (в 1/ч)
|
||||
noise=Шум
|
||||
sailing=Плавание под парусом
|
||||
optimality=Оптимальность
|
||||
maximumTurns=Максимальное количество галсов
|
||||
raceDirection=Направление гонки
|
||||
upWind=Против ветра
|
||||
downWind=По ветру
|
||||
strategies=Стратегии
|
||||
omniscient=Всезнающий
|
||||
opportunistic=Оппортунист
|
||||
mixed=Смешанный
|
||||
maps=Карты
|
||||
startEnd=Старт-Финиш
|
||||
racecourse=Курс
|
||||
summary=Сводная информация
|
||||
replay=Повтор
|
||||
display=Отобразить
|
||||
simulatorPolarHeader = Полярная диаграмма
|
||||
show=Показать
|
||||
hide=скрыть
|
||||
leftWind=Ветер слева
|
||||
rightWind=Ветер справа
|
||||
strategyOption1=стратегияВариант1
|
||||
strategyOption2=стратегияВариант2
|
||||
strategyOption3=стратегияВариант3
|
||||
legLabel=Этап
|
||||
raceLabel=Гонка
|
||||
competitorLabel=Участник
|
||||
freemode=Сохранять направления
|
||||
whatIfCourse=Что если курс
|
||||
editRegatta=Изменить регату...
|
||||
selectSailingEvent=Пожалуйста, выберите событие парусного спорта...
|
||||
selectCourseArea=Пожалуйста, выберите зону курса..
|
||||
courseAreaOverview=Обзор зоны
|
||||
courseDesignOverview=Обзор создания курса
|
||||
regattaOverview=Обзор регаты
|
||||
additionalSettings=Дополнительные параметры
|
||||
showFollowingCourseAreas=Показать следующие зоны курса
|
||||
showFollowingRegattas=Показать следующие регаты
|
||||
showOnlyRacesOfSameDay=Показать только гонки, проходившие в один и тот же день
|
||||
showOnlyCurrentlyRunningRaces=Показать только проходящие гонки
|
||||
seriesDefinesResultDiscardingRule=Серии определяют правила исключения результатов
|
||||
addSeries=Все серии
|
||||
regattaDefinesResultDiscardingRules=Регата определяет правила исключения результатов
|
||||
startsWithZeroScore=Серия начинается с нуля очков
|
||||
masterDataImportPanel=Импорт основных данных
|
||||
importSuccess=Успех\nСозданная {0} группа таблиц (ы) лидеров и {1} таблиц (ы) и {2} события (й) и {3} регат (ы).
|
||||
importSuccessOverwriteInfo=Пришлось перезаписать следующие регаты, необходимо повторно проложить их гонки:
|
||||
regattaOverviewConfiguration=Обзор конфигурации регаты
|
||||
firstRaceIsNonDiscardableCarryForward=Начиная с не исключаемых переносов в другую графу
|
||||
addReplicationMaster=Подключение к главному серверу дублирования
|
||||
connect=Подключиться
|
||||
connectToMaster=Подключиться к Главному
|
||||
exchangeHost=Имя узла обмена сообщениями
|
||||
explainExchangeHostName=Имя узла, где сообщения ставятся в очередь ожидания.
|
||||
explainReplicationHostname=Имя узла, где работает главный сервер дублирования.
|
||||
explainReplicationExchangeName=Имя очереди ожидания обмена сообщениями. Она должна быть настроена как главный сервер.
|
||||
explainReplicationExchangePort=Порт очереди ожидания обмена сообщениями. Он используется после первоначальной загрузки для всех данных.
|
||||
explainReplicationServletPort=Номер порта сервлета, используемого для подключения для регистрации этой копии и получения первоначальной загрузки.
|
||||
explainReplicasRegistered=Копии зарегистрированы (этот сервер главный ):
|
||||
explainConnectionsToMaster=Подключения к главному серверу (это сервер копий):
|
||||
explainNoConnectionsToMaster=Не настроенных подключений к главному серверу.Для настройки одного соединения щелкните «Подключиться к главному серверу» .
|
||||
explainNoConnectionsFromReplicas=Подключений к серверу копий не обнаружено. Копии можно подключить используя их Консоль администрирования.
|
||||
stopConnectionToMaster=Остановить копирование
|
||||
asLink=Как ссылка
|
||||
noStarttimeAnnouncedYet=Ожидание
|
||||
raceIsRunning=Проходящая
|
||||
raceIsFinishing=Завершающаяся
|
||||
raceIsFinished=Завершенная
|
||||
raceIsScheduled=Запланированная
|
||||
raceIsInStartphase=Этап старта
|
||||
generalRecall=Общая отмена
|
||||
startPostponed=Отложенная
|
||||
raceAbandoned=Прекращенная
|
||||
stopAllReplicas=Разъединить соединение со всеми копиями (Опасно!)
|
||||
warningServerIsReplica=ВНИМАНИЕ: Этот сервер настроек может быть сервером копий. НЕ ВНОСИТЕ никаких изменений или это приведет к нежелательным последствиям!
|
||||
dropReplicaConnection=Разъединить соединение
|
||||
timePanelName=Контроль времени
|
||||
competitorFilterExplanation=Фильтр отображает всех участников, соответствующих критериям:
|
||||
dropReplicaConnection=Разъединить соединения
|
||||
protestTimeFinishesAt=Срок подачи протеста истекает в
|
||||
protestTimeFinishedAt=Срок подачи протеста истек в
|
||||
flags=Флаги
|
||||
lastUpdate=Последние обновления
|
||||
noMoreRacingToday=Сегодня больше нет гонок
|
||||
furtherSignalsAshore=Дальнейшие сигналы на берегу
|
||||
earlyStarters=Совершивших фальшстар
|
||||
showingDetailsOfRace=Отобразить подробности для гонки {0}
|
||||
startAt=Старт в
|
||||
finishAt=Финиш в
|
||||
protestEndsAt=Срок подачи протеста завершается в
|
||||
unknown=Неизвестно
|
||||
earlyStarters=Совершивших фальшстарт
|
||||
raceLog=Запись о гонке
|
||||
refreshRaceLog=Обновить запись о гонке
|
||||
raceLogReloaded=Запись о гонке успешно повторно загружена из базы данных
|
||||
reloadAllRaceLogs=Повторно загрузить все записи о гонке
|
||||
export=Эскпорт
|
||||
sideline=Боковая линия
|
||||
classAndGolfUp=Флаг поднят – восемь минут до старта – процедура старта – через стартовые ворота
|
||||
classDisplayed=Флаг поднят – пять минут до старта
|
||||
papaDisplayed=Флаг режима старта четыре минуты до старта
|
||||
blackDisplayed=Флаг режима старта – дисквалификация совершивших фальшстарт – четыре минуты до старта
|
||||
zuluIndiaDisplayed=Флаг режима старта – штрафы для совершивших фальшстарт – четыре минуты до старта
|
||||
papaRemoved=Флаг режима старта - одна минута до старта
|
||||
blackRemoved=Флаг режима старта – дисквалификация для совершивших фальшстарт - одна минута до старта
|
||||
zuluIndiaRemoved=Флаг режима старта – старт со штрафами совершившим фальшстарт – одна минута до старта
|
||||
classFlagRemoved=Флаг убран – сигнал начала гонки
|
||||
xray=Индивидуальная отмена – есть совершившие фальшстарт
|
||||
firstSubstitute=Общая отмена – слишком много совершивших фальшстарт – процедура старта будет повторена
|
||||
blueFlagDisplayed=Флаг отображается – первый участник пересек линию финиша
|
||||
blueFlagRemoved=Флаг убран – последний участник пересек линию финиша или предельное время финиша прошло
|
||||
golfRemoved=Флаг убран –ворота закрыты
|
||||
answeringPennantOverAlphaDisplayed=Флаг отображается - старт отложен - сегодня больше нет гонок
|
||||
answeringPennantOverHotelDisplayed=Флаг отображается – старт отложен - дальнейшие сигналы на берегу
|
||||
answeringPennantDisplayed=Флаг отображается – старт отложен
|
||||
answeringPennantRemoved=Флаг убран – процедура старта начинается через одну минуту
|
||||
novemberOverAlphaDisplayed=Флаг поднят - гонка отменена – сегодня гонок больше нет
|
||||
novemberOverHotelDisplayed=Флаг поднят – гонка отменена - дальнейшие сигналы на берегу
|
||||
novemberDisplayed=Флаг поднят – гонка отменена
|
||||
bravoDisplayed=Срок подачи протеста начался
|
||||
bravoRemoved=Срок подачи протеста закончился
|
||||
essThreeDisplayed=Три минуты до старта
|
||||
essTwoDisplayed=Две минуты до старта
|
||||
essOneDisplayed=Одна минуты до старта
|
||||
essOneRemoved=Сигнал начала гонки
|
||||
dataBeforeAfter=Данные до/после гонки
|
||||
rawFixes=Все значения (включая сильно отличающиеся значения)
|
||||
importRemoteHost=Удаленный узел:
|
||||
importFetchRemoteLgs=Получить список группы таблицы лидеров
|
||||
importUrlInvalid=Недействительный URL-адрес для получения групп таблицы лидеров: {0}
|
||||
importGetLeaderboardsFailed=Запрос ПОЛУЧИТЬ группы таблиц лидеров выполнить не удалось для узла {0} с ошибкой {1}
|
||||
importNoDataReturned=Данные сервером не возвращены
|
||||
importServerError=Запрос ПОЛУЧИТЬ группы таблиц лидеров выполнить не удалось с ошибкой Сервера. Дополнительные сведения, см. в журнале сервера.
|
||||
importLeaderboardGroups=Группы таблиц лидеров:
|
||||
importOverrideSwitchLabel=Перезаписать существующие данные, если имена и идентификационные данные совпадают
|
||||
importSelectedLeaderboardGroups=Импорт выбранных групп таблиц лидеров
|
||||
importSelectAtLeastOne=Нужно выбрать хотя бы одну группу таблиц лидеров для импорта
|
||||
deselectAll=Отменить выбор всех
|
||||
polarDiagramButton=Полярная диаграмма
|
||||
ratioBetweenTimeSinceLastPositionFixAndAverageSamplingInterval=Запаздывание GPS
|
||||
ratioBetweenTimeSinceLastPositionFixAndAverageSamplingIntervalTooltip=Соотношение между последними полученными с помощью GPS данными о положении и усредненным интервалом выборки
|
||||
trackingQuality=Качество отслеживания
|
||||
legType=Тип этапа
|
||||
sailID=Номер на парусе
|
||||
seriesLeaderboard=Серия таблиц лидеров
|
||||
regattaLeaderboards=Таблица лидеров регаты
|
||||
clearSelection=Отменить выбор
|
||||
running=Проходящая в настоящее время
|
||||
runAsSubstantive=Начать
|
||||
done=Готово
|
||||
lastFinished=Последняя завершенная
|
||||
run=Начать
|
||||
times=раз
|
||||
numberOfGPSFixes=Количество точек фиксации GPS
|
||||
averageCleanedServerTime=\u2205 Чистое время на сервере
|
||||
averageCleanedOverallTime=\u2205 Чистое итоговое время
|
||||
dataMiningBenchmarkResults=Результаты сравнительного теста сбора данных
|
||||
serverTime=Время на сервере
|
||||
confidenceShouldBeBetween=Достоверность данных должна быть от 0 до 1.
|
||||
minDataValuesNeedToBeAtLeastZero=Минимальные значения объема данных не могут быть отрицательными.
|
||||
numberOfColumnsAtLeast2=Количество столбцов гистограммы должно быть больше одного.
|
||||
outlierRadiusNeedsToBePositiveString=Сильно отличающееся значение радиуса должно быть положительным числом.
|
||||
outlierMinimumNeighborhoodPctString=Сильно отличающееся значение в процентах соседней точки должно быть положительным и максимально равно 1.
|
||||
oneOrMoreParametersAreEmpty=Поле параметра не может быть пустым.
|
||||
errorWhileAddingSeriesToChart=При добавлении \nновой серии в график возникла ошибка
|
||||
generatingPolarSheet=Создание полярной таблицы...
|
||||
dataCount=Объем данных
|
||||
generationFinished=Создание завершено!
|
||||
generating=Создание
|
||||
removeAllSheets=Удалить все листы
|
||||
removeAll=Удалить все
|
||||
selectSheet=Выбрать лист
|
||||
cleanedServerTime=Чистое время на сервере
|
||||
overallTime=Общее время
|
||||
cleanedOverallTime=Чистое итоговое время
|
||||
dataMiningResult=Результат сбора данных
|
||||
groupBy=Группировать по
|
||||
statisticToCalculate=Рассчитать статистику
|
||||
queryResultsChartSubtitle=Обработанные {1}/{0} элементы данных через {2} секунд
|
||||
noQuerySelected=Запросы не выбраны
|
||||
runAutomatically=Запустить автоматически
|
||||
windImport_Upload=Загрузить
|
||||
windImport_Title=Импортировать данные о ветре от экспедиции
|
||||
windImport_BoatId=Идентификационный номер судна:
|
||||
windImport_SelectedRacesWarning=Вы действительно хотите импортировать данные о ветре в выбранные {0} гонки?\nЭто в любом случае повлияет только на гонки с применимым временным окном.
|
||||
windImport_AllRacesWarning=Вы действительно хотите импортировать данные о ветре во все гонки?\nЭто в любом случае повлияет только на гонки с применимым временным окном.
|
||||
windImport_ResultHeader=Импортированные данные с: {0} по: {1}. {2} повлияли на гонки.
|
||||
windImport_ResultEntry=Гонка: {0} ({1}) - {2} корректировка с: {3} по: {4}
|
||||
windImport_ResultError=Ошибка: {0}
|
||||
showWindSpeedSeriesTooltip=Переключает видимость скорости ветра для всех источников данных
|
||||
showWindDirectionSeriesTooltip=Переключает видимость направления ветра для всех источников данных
|
||||
combinedWindSourceTypeTooltip=Объединяет данные из всех других источников данных о ветре в один набор данных
|
||||
courseBasedWindSourceTypeTooltip=Значение основано на прокладке курса гонки (с учетом предположения, что гонка начнется с этапа против ветра)
|
||||
trackBasedEstimationWindSourceTypeTooltip=Расчетные данные из маршрута участника
|
||||
expeditionWindSourceTypeTooltip=Данные, полученные из мобильных систем измерения
|
||||
webWindSourceTypeTooltip=Значения данных, установленные вручную
|
||||
raceCommitteeWindSourceTypeTooltip=Значения данных, установленные вручную, полученные от официальных лиц гонки
|
||||
sheetName=Имя листа
|
||||
sheetNameTooltip=Вы можете присвоить имя своему полярному листу используя текстовое поле.\nИмя будет создано с использованием класса судна\nесли имя не предоставлено.
|
||||
timeDownwind=Время по ветру
|
||||
timeReaching=Время лавирования по ветру
|
||||
timeUpwind=Время против ветра
|
||||
raceTimeTooltip=Общее время затраченное в этой гонке
|
||||
raceTimeDownwindTooltip=Общее время движения по ветру в этой гонке
|
||||
raceTimeReachingTooltip=Общее время лавирования по ветру в этой гонке
|
||||
raceTimeUpwindTooltip=Общее время движения против ветра в этой гонке
|
||||
noStatisticSelectedError=Статистических данных для расчета не выбрано
|
||||
noCustomGrouperScriptTextError=Скрипт блока группирования пустой
|
||||
noDimensionToGroupBySelectedError=Размер для группировки по не выбран
|
||||
noGrouperSelectedError=Тип блока группирования не выбран
|
||||
queryNotValidBecause=Запрос не возможен, т.к.
|
||||
dataMining=Сбор данных
|
||||
errorRunningDataMiningQuery=Ошибка при выполнении запроса
|
||||
hideToolbar=Скрыть панель инструментов
|
||||
showSeriesLeaderboards=Показать таблицу лидеров серии
|
||||
showOverallLeaderboard=Показать общую таблицу лидеров
|
||||
lineAngleToWindAndAdvantage=длина: {0}м; угол к ветру: {1}градус; {2} борт {3}м имеет преимущество
|
||||
doYouReallyWantToRemoveEvents=Вы действительно хотите удалить все события?
|
||||
doYouReallyWantToRemoveEvent=Вы действительно хотите удалить событие {0}?
|
||||
line=Строка
|
||||
offset=Смещение
|
||||
doYouReallyWantToRemoveCompetitors=Вы действительно хотите удалить всех выбранных участников?
|
||||
doYouReallyWantToRemoveCompetitor=Вы действительно хотите удалить выбранного участника {0}?
|
||||
filterCompetitors=Сортировать по имени, классу судна или номеру на парусе
|
||||
editCompetitor=Изменить участника
|
||||
pleaseEnterASailNumber=Пожалуйста, введите номер на парусе
|
||||
successfullyAllowedCompetitorReset=Перезагрузка участника (ов) {0} разрешена.
|
||||
id=Идентификатор
|
||||
allowReload=Разрешить перезагрузку
|
||||
compress=Сжать
|
||||
compressTooltip=Используйте только, если на экземпляре сервера, с которого выполняется экспорт, хотя бы\nзапущена операция подтверждения 0fbf6071dea125bec4a56dee55d61c99def4a62e.
|
||||
queryRunner=Отправка запросов
|
||||
rerunQueryAfterRefresh=Повторно выполнить запрос после обновления
|
||||
refreshIntervalMustntBeEmpty=Интервал обновления не может быть пустым
|
||||
selectionTables=Выбор таблиц
|
||||
addConfiguration=Добавить конфигурацию
|
||||
noConfigurations=Конфигурации отсутствуют.
|
||||
errorRetrievingConfiguration=Ошибка получения данных о конфигурации с сервера.
|
||||
allowedCourseAreas=Разрешить зоны курса
|
||||
minimumRoundsForCourse=Минимальное количество кругов для курса гонки
|
||||
maximumRoundsForCourse=Максимальное количество кругов для курса гонки
|
||||
resultsMailRecipient=Результаты получателя почты
|
||||
deviceConfiguration=Конфигурация устройства
|
||||
none=Ни одного
|
||||
courseDesignerMode=Создатель курсов
|
||||
racingProcedure=Процедура гонки
|
||||
courseNames=Имена курсов гонок
|
||||
generate=Создать
|
||||
dontoverwrite=Не перезаписывать
|
||||
setRacingProcedureConfiguration=Настроить конфигурацию регаты
|
||||
racingProcedureConfiguration=Конфигурация регаты
|
||||
activateIndividualRecall=Активировать индивидуальную отмену
|
||||
rrs26Start=RRS26 старт
|
||||
setConfiguration=Активировать конфигурацию
|
||||
classFlag=Флаг класса
|
||||
classFlagHelpText=Устанавливает флаг класса, используемый для {0}. Выберите ''Не перезаписывать''для активации флага по умолчанию для процедуры.
|
||||
individualRecallHelpText=После активации можно обратиться к официальному лицу гонки для индивидуальной отмены.
|
||||
startmodeFlags=Флаги режима старта
|
||||
startmodeFlagsHelpText=Устанавливает доступные флаги для режима старта. Выберите «ни один» из предложенных, для включения флагов по умолчанию для этой процедуры.
|
||||
gateStart=Ворота старта
|
||||
activatePathfinder=Активировать «Следопыт»
|
||||
pathfinderHelpText=После активации официальное лицо гонки может настроить судно «Следопыт».
|
||||
essStart=Старт ESS
|
||||
basicStart=Основной старт
|
||||
configured=Настроенный
|
||||
overwriteRacingProceduresConfiguration=Активировать конфигурацию регаты
|
||||
overwriteRacingProceduresConfigurationHelpText=Включение этой опции предоставляет базовую конфигурацию регаты для всех опций, не настроенных в специальной конфигурации регаты.
|
||||
setStartTime=Установить время старта
|
||||
currentPass=Текущий пропуск
|
||||
setStartTimeDescription=Выбрать новое время старта для гонки
|
||||
hasAdditionalGolfDownTime=Активировать дополнительное время отсчета
|
||||
additionalGolfDownTimeHelpText=Активировать дополнительное время отсчета
|
||||
invalidColor=Недействительный цвет: {0}
|
||||
igtimiAccounts=Учетные записи Igtimi
|
||||
errorFetchingIgtimiAccounts=Ошибка получения всех Igtimi учетных записей: {0}
|
||||
addIgtimiAccount=Добавить учетную запись Igtimi
|
||||
errorAuthorizingAccessToIgtimiUser=Ошибка авторизации доступа к Igtimi пользователю {0}: {1}
|
||||
successfullyAuthorizedAccessToIgtimiUser=Успешная авторизация доступа к Igtimi пользователю {0}
|
||||
couldNotAuthorizedAccessToIgtimiUser=Невозможно авторизовать пользователя {0}; недействительное имя пользователя или пароль
|
||||
errorGettingIgtimiAuthorizationUrl=Ошибка получения URL-адреса для авторизации Igtimi: {0}
|
||||
addIgtimiUser=Добавить пользователя Igtimi
|
||||
doYouReallyWantToRemoveLeaderboards=Вы действительно хотите удалить таблицы лидеров?
|
||||
errorTryingToRemoveIgtimiAccount=Ошибка попытки удаления учетной записи Igtimi для пользователя {0}
|
||||
successfullyRemoveIgtimiAccount=Учетная запись Igtimi для пользователя {0} удалена успешно
|
||||
eMailMustNotBeEmpty=Адрес электронной почты не должен быть пустым
|
||||
emailAddress=адрес электронной почты
|
||||
password=Пароль
|
||||
doYouReallyWantToRemoveLeaderboard=Вы действительно хотите удалить таблицу лидеров: ''{0}''?
|
||||
metaLeaderboardCannotBeChanged=Это мета таблица лидеров. Ее нельзя изменить здесь.
|
||||
failedToSetNewStartTime=Ошибка при установке нового времени старта.
|
||||
doYouReallyWantToRemoveIgtimiAccount=Вы действительно хотите удалить учетную запись Igtimi, предоставляющую доступ к данным пользователя {0}?
|
||||
igtimiWindImport=Импорт данных о ветре из Igtimi
|
||||
seeIgtimiTabForAccountSettings=См. вкладку ''Igtimi'' для параметров учетной записи, определяющих какие данные из Igtimi будут учитываться.
|
||||
importWindFromIgtimi=Импорт данных о ветре из Igtimi
|
||||
errorImportingIgtimiWind=Ошибка импорта данных о ветре из Igtimi: {0}
|
||||
resultFromIgtimiWindImport=Следующее количество фиксированных точек было импортировано для перечисленных гонок: {0}
|
||||
timeToStart={0} до старта
|
||||
timeSinceStart={0} со старта
|
||||
distanceToLine=Растояние до линии старта
|
||||
beatAngleTooltip=Угол между направлением движения участника и ветром
|
||||
beatAngle=Угол лавирования
|
||||
runAutomaticallyTooltip=Запустить запрос автоматически, например, после изменения статистических данных или группировки.
|
||||
rerunQueryAfterRefreshTooltip=Повторно запускает запрос после обновления таблиц.
|
||||
queryDefinitionProvider=Поставщик определения запроса
|
||||
statisticProvider=Поставщик статистических данных
|
||||
toCalculateThe=для расчета
|
||||
use=Использовать
|
||||
groupingProvider=Поставщик группировки
|
||||
releaseNotes=Новости и история выпусков
|
||||
hasSplitFleetContiguousScoring=Разделить флоты, имеющие близкие количества очков
|
||||
overallProgress=Итоговое улучшение
|
||||
eventOverview=Обзор события
|
||||
start=Старт
|
||||
showAddedScores=Показать добавленные очки для каждой записи таблицы лидеров
|
||||
ratio=коэффициент
|
||||
importWind=Имопрт данных о ветре
|
||||
importWindTooltip=Снятие флажка с этой опции значительно снизит объем передаваемых данных.
|
||||
authorName=Имя автора
|
||||
authorPriority=Приоритет автора
|
||||
removeDenotation=Remove Denotation
|
||||
competitorRegistrationsMissingProceed=At least one of the selected races ({0}) is missing competitor registrations. Proceed anyway?
|
||||
pleaseSelectAControlPoint=Please select a control point
|
||||
twoMarkControlPoint=2-mark-controlpoint
|
||||
registeredCompetitors=Registered Competitors
|
||||
competitorPool=Competitor Pool
|
||||
selectAtLeastOne=Select at least one
|
||||
selectRaces=Select the Races
|
||||
importFixes=Import Fixes
|
||||
+2
@@ -20,6 +20,8 @@ public class ScoringSchemeTypeFormatter {
|
||||
return stringMessages.scoringSchemeHighPointFirstGetsTen();
|
||||
case LOW_POINT_WINNER_GETS_ZERO:
|
||||
return stringMessages.scoringSchemeLowPointWinnerGetsZero();
|
||||
case HIGH_POINT_WINNER_GETS_FIVE:
|
||||
return stringMessages.scoringSchemeWinnerGetsFive();
|
||||
case HIGH_POINT_WINNER_GETS_SIX:
|
||||
return stringMessages.scoringSchemeWinnerGetsSix();
|
||||
}
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
}
|
||||
|
||||
private CheckBox addLeaderboardEnablerButton() {
|
||||
final CheckBox checkBox = new CheckBox("Leaderboard");
|
||||
final CheckBox checkBox = new CheckBox(stringMessages.leaderboard());
|
||||
|
||||
checkBox.getElement().getStyle().setFloat(Style.Float.LEFT);
|
||||
|
||||
|
||||
+5
-4
@@ -900,7 +900,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
trackedRaceDTO = getBaseDomainFactory().createTrackedRaceDTO(trackedRace);
|
||||
}
|
||||
RaceWithCompetitorsDTO raceDTO = new RaceWithCompetitorsDTO(raceIdentifier, convertToCompetitorDTOs(r.getCompetitors()),
|
||||
trackedRaceDTO, getService().isRaceBeingTracked(r));
|
||||
trackedRaceDTO, getService().isRaceBeingTracked(regatta, r));
|
||||
if (trackedRace != null) {
|
||||
getBaseDomainFactory().updateRaceDTOWithTrackedRaceData(trackedRace, raceDTO);
|
||||
}
|
||||
@@ -2099,9 +2099,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
raceColumn.getFactor(), fleetDTO, raceColumn.isMedalRace(), raceIdentifier, raceDTO);
|
||||
|
||||
RaceLog raceLog = raceColumn.getRaceLog(fleet);
|
||||
RaceLogTrackingState raceLogTrackingState = new RaceLogTrackingStateAnalyzer(raceLog).analyze();
|
||||
boolean raceLogTrackerExists = getService().getRaceTrackerById(raceLog.getId()) != null;
|
||||
boolean competitorRegistrationsExist = ! new RegisteredCompetitorsAnalyzer(raceLog).analyze().isEmpty();
|
||||
RaceLogTrackingState raceLogTrackingState = raceLog == null ? RaceLogTrackingState.NOT_A_RACELOG_TRACKED_RACE :
|
||||
new RaceLogTrackingStateAnalyzer(raceLog).analyze();
|
||||
boolean raceLogTrackerExists = raceLog == null ? false : getService().getRaceTrackerById(raceLog.getId()) != null;
|
||||
boolean competitorRegistrationsExist = raceLog == null ? false : !new RegisteredCompetitorsAnalyzer(raceLog).analyze().isEmpty();
|
||||
RaceLogTrackingInfoDTO raceLogTrackingInfo = new RaceLogTrackingInfoDTO(raceLogTrackerExists,
|
||||
competitorRegistrationsExist, raceLogTrackingState);
|
||||
raceColumnDTO.setRaceLogTrackingInfo(fleetDTO, raceLogTrackingInfo);
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ public class PathLegendCanvasOverlay extends FullCanvasOverlay {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCanvasSettings() {
|
||||
public void setCanvasSettings() {
|
||||
super.setCanvasSettings();
|
||||
canvas.getElement().getStyle().setZIndex(100000); // make legend float on-top of all overlays
|
||||
}
|
||||
|
||||
+10
-2
@@ -15,6 +15,7 @@ import com.sap.sailing.gwt.ui.client.LogoAndTitlePanel;
|
||||
import com.sap.sailing.gwt.ui.client.RemoteServiceMappingConstants;
|
||||
import com.sap.sailing.gwt.ui.client.SimulatorService;
|
||||
import com.sap.sailing.gwt.ui.client.SimulatorServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.simulator.streamlets.SimulatorJSBundle;
|
||||
import com.sap.sailing.simulator.util.SailingSimulatorConstants;
|
||||
|
||||
public class SimulatorEntryPoint extends AbstractEntryPoint {
|
||||
@@ -25,6 +26,7 @@ public class SimulatorEntryPoint extends AbstractEntryPoint {
|
||||
private int xRes = 40;
|
||||
private int yRes = 20;
|
||||
private int border = 0;
|
||||
private int particles = 0;
|
||||
private boolean autoUpdate = false;
|
||||
private char mode = SailingSimulatorConstants.ModeEvent; // default mode: 'e'vent
|
||||
private char event = SailingSimulatorConstants.EventKielerWoche; // default event: 'k'ieler woche
|
||||
@@ -75,6 +77,12 @@ public class SimulatorEntryPoint extends AbstractEntryPoint {
|
||||
} else {
|
||||
this.border = Integer.parseInt(border);
|
||||
}
|
||||
String particlesStr = Window.Location.getParameter("particles");
|
||||
if (particlesStr == null || particlesStr.isEmpty()) {
|
||||
logger.config("Using default particles " + this.particles);
|
||||
} else {
|
||||
this.particles = Integer.parseInt(particlesStr);
|
||||
}
|
||||
String autoUpdateStr = Window.Location.getParameter("autoUpdate");
|
||||
if (autoUpdateStr == null || autoUpdateStr.isEmpty()) {
|
||||
logger.config("Using default auto update " + autoUpdate);
|
||||
@@ -132,7 +140,7 @@ public class SimulatorEntryPoint extends AbstractEntryPoint {
|
||||
showStreamlets2 = true;
|
||||
injectWindDataJS = true;
|
||||
}
|
||||
if ((showStreamlets2)&&(this.border==0)) {
|
||||
if ((showStreamlets2)&&(border==null)) {
|
||||
this.border = 10;
|
||||
}
|
||||
if (windDisplayStr.contains("b")) {
|
||||
@@ -163,7 +171,7 @@ public class SimulatorEntryPoint extends AbstractEntryPoint {
|
||||
}
|
||||
|
||||
private void createSimulatorPanel() {
|
||||
SimulatorMainPanel simulatorPanel = new SimulatorMainPanel(simulatorService, stringMessages, this, xRes, yRes, border,
|
||||
SimulatorMainPanel simulatorPanel = new SimulatorMainPanel(simulatorService, stringMessages, this, xRes, yRes, border, particles,
|
||||
autoUpdate, mode, event, showGrid, showLines, seedLines, showArrows, showStreamlets, showStreamlets2, injectWindDataJS);
|
||||
|
||||
DockLayoutPanel p = new DockLayoutPanel(Unit.PX);
|
||||
|
||||
+6
-2
@@ -71,7 +71,9 @@ public class SimulatorMainPanel extends SimplePanel {
|
||||
simulatorMap.getMap().triggerResize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int particles;
|
||||
|
||||
private DockLayoutPanel mainPanel;
|
||||
private FlowPanel leftPanel;
|
||||
private ResizableFlowPanel rightPanel;
|
||||
@@ -225,10 +227,12 @@ public class SimulatorMainPanel extends SimplePanel {
|
||||
return NumberFormat.getFormat("0.0").format(value);
|
||||
}
|
||||
|
||||
public SimulatorMainPanel(SimulatorServiceAsync svc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, int border, boolean autoUpdate,
|
||||
public SimulatorMainPanel(SimulatorServiceAsync svc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, int border, int particles, boolean autoUpdate,
|
||||
char mode, char event, boolean showGrid, boolean showLines, char seedLines, boolean showArrows, boolean showStreamlets, boolean showStreamlets2, boolean injectWindDataJS) {
|
||||
super();
|
||||
|
||||
this.particles = particles;
|
||||
|
||||
this.simulatorSvc = svc;
|
||||
this.stringMessages = stringMessages;
|
||||
this.errorReporter = errorReporter;
|
||||
|
||||
+57
-7
@@ -7,6 +7,7 @@ import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.event.logical.shared.ResizeEvent;
|
||||
import com.google.gwt.event.logical.shared.ResizeHandler;
|
||||
import com.google.gwt.maps.client.LoadApi;
|
||||
@@ -19,6 +20,8 @@ import com.google.gwt.maps.client.controls.MapTypeStyle;
|
||||
import com.google.gwt.maps.client.controls.PanControlOptions;
|
||||
import com.google.gwt.maps.client.controls.ScaleControlOptions;
|
||||
import com.google.gwt.maps.client.controls.ZoomControlOptions;
|
||||
import com.google.gwt.maps.client.events.bounds.BoundsChangeMapEvent;
|
||||
import com.google.gwt.maps.client.events.bounds.BoundsChangeMapHandler;
|
||||
import com.google.gwt.maps.client.events.click.ClickMapEvent;
|
||||
import com.google.gwt.maps.client.events.click.ClickMapHandler;
|
||||
import com.google.gwt.maps.client.events.idle.IdleMapEvent;
|
||||
@@ -208,9 +211,13 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
legendCanvasOverlay.setCurrent(result.getWindField().curSpeed,result.getWindField().curBearing);
|
||||
|
||||
if (timePanel != null) {
|
||||
timePanel.setMinMax(new Date(startTime), new Date(startTime + maxDurationTime), true);
|
||||
Date endDate = new Date(startTime + maxDurationTime);
|
||||
timePanel.setMinMax(new Date(startTime), endDate, true);
|
||||
timePanel.resetTimeSlider();
|
||||
timePanel.timeChanged(windParams.getStartTime(), null);
|
||||
if (windParams.isShowStreamlets2()) {
|
||||
windStreamletsCanvasOverlay.setEndDate(endDate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,7 +376,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
|
||||
if (windParams.isShowStreamlets2()) {
|
||||
|
||||
mapTypeStyles = new MapTypeStyle[7];
|
||||
mapTypeStyles = new MapTypeStyle[11];
|
||||
|
||||
// hide all transit lines including ferry lines
|
||||
mapTypeStyles[0] = GoogleMapStyleHelper.createHiddenStyle(MapTypeStyleFeatureType.TRANSIT);
|
||||
@@ -379,18 +386,45 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
mapTypeStyles[2] = GoogleMapStyleHelper.createSimplifiedStyle(MapTypeStyleFeatureType.ROAD);
|
||||
// set water color
|
||||
mapTypeStyles[3] = GoogleMapStyleHelper.createColorStyle(MapTypeStyleFeatureType.WATER, new RGBColor(0, 136, 255), -50, -50);
|
||||
mapTypeStyles[4] = GoogleMapStyleHelper.createColorStyle(MapTypeStyleFeatureType.LANDSCAPE, new RGBColor(255, 255, 255), 0, -70);
|
||||
mapTypeStyles[5] = GoogleMapStyleHelper.createElementStyleOnlyLightness(MapTypeStyleFeatureType.ROAD, MapTypeStyleElementType.ALL, -40);
|
||||
mapTypeStyles[4] = GoogleMapStyleHelper.createColorStyle(MapTypeStyleFeatureType.LANDSCAPE, new RGBColor(255, 255, 255), -100, -70);
|
||||
mapTypeStyles[5] = GoogleMapStyleHelper.createColorStyle(MapTypeStyleFeatureType.POI, new RGBColor(255, 255, 255), -100, -70);
|
||||
mapTypeStyles[6] = GoogleMapStyleHelper.createElementStyleOnlyLightness(MapTypeStyleFeatureType.ROAD, MapTypeStyleElementType.ALL, -40);
|
||||
|
||||
MapTypeStyle mapStyle = MapTypeStyle.newInstance();
|
||||
mapStyle.setFeatureType(MapTypeStyleFeatureType.ADMINISTRATIVE);
|
||||
mapStyle.setElementType(MapTypeStyleElementType.LABELS);
|
||||
mapStyle.setElementType(MapTypeStyleElementType.LABELS__TEXT__FILL);
|
||||
MapTypeStyler[] typeStylers = new MapTypeStyler[1];
|
||||
typeStylers[0] = MapTypeStyler.newInvertLightnessStyler(true);
|
||||
mapStyle.setStylers(typeStylers);
|
||||
mapTypeStyles[6] = mapStyle;
|
||||
mapTypeStyles[7] = mapStyle;
|
||||
|
||||
mapStyle = MapTypeStyle.newInstance();
|
||||
mapStyle.setFeatureType(MapTypeStyleFeatureType.ADMINISTRATIVE);
|
||||
mapStyle.setElementType(MapTypeStyleElementType.LABELS__TEXT__STROKE);
|
||||
typeStylers = new MapTypeStyler[1];
|
||||
typeStylers[0] = MapTypeStyler.newInvertLightnessStyler(true);
|
||||
mapStyle.setStylers(typeStylers);
|
||||
mapTypeStyles[8] = mapStyle;
|
||||
|
||||
mapStyle = MapTypeStyle.newInstance();
|
||||
mapStyle.setFeatureType(MapTypeStyleFeatureType.ADMINISTRATIVE);
|
||||
mapStyle.setElementType(MapTypeStyleElementType.GEOMETRY__FILL);
|
||||
typeStylers = new MapTypeStyler[3];
|
||||
typeStylers[0] = MapTypeStyler.newHueStyler("#ffffff");
|
||||
typeStylers[1] = MapTypeStyler.newLightnessStyler(-70);
|
||||
typeStylers[2] = MapTypeStyler.newSaturationStyler(-100);
|
||||
mapStyle.setStylers(typeStylers);
|
||||
mapTypeStyles[9] = mapStyle;
|
||||
|
||||
} else {
|
||||
mapStyle = MapTypeStyle.newInstance();
|
||||
mapStyle.setFeatureType(MapTypeStyleFeatureType.ADMINISTRATIVE);
|
||||
mapStyle.setElementType(MapTypeStyleElementType.GEOMETRY__STROKE);
|
||||
typeStylers = new MapTypeStyler[1];
|
||||
typeStylers[0] = MapTypeStyler.newLightnessStyler(-70);
|
||||
mapStyle.setStylers(typeStylers);
|
||||
mapTypeStyles[10] = mapStyle;
|
||||
|
||||
} else {
|
||||
|
||||
mapTypeStyles = new MapTypeStyle[4];
|
||||
|
||||
@@ -433,6 +467,22 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
||||
add(map, 0, 0);
|
||||
map.setSize("100%", "100%");
|
||||
|
||||
if (windParams.isShowStreamlets2()) {
|
||||
map.addBoundsChangeHandler(new BoundsChangeMapHandler() {
|
||||
@Override
|
||||
public void onEvent(BoundsChangeMapEvent event) {
|
||||
// improve browser performance by deferred scheduling of redraws
|
||||
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
|
||||
public void execute() {
|
||||
if (windStreamletsCanvasOverlay.getSwarm() != null) {
|
||||
windStreamletsCanvasOverlay.getSwarm().onBoundsChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*map.addZoomChangeHandler(new ZoomChangeMapHandler() {
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -263,7 +263,7 @@ public class WindLineCanvasOverlay extends FullCanvasOverlay implements TimeList
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCanvasSettings() {
|
||||
public void setCanvasSettings() {
|
||||
if (corners != null && corners.length == 4) {
|
||||
final Point corner0 = getPointInDivPixel(corners[0]);
|
||||
final Point corner1 = getPointInDivPixel(corners[1]);
|
||||
|
||||
+48
-34
@@ -14,6 +14,7 @@ import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindFieldDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindFieldGenParamsDTO;
|
||||
import com.sap.sailing.gwt.ui.simulator.racemap.FullCanvasOverlay;
|
||||
import com.sap.sailing.gwt.ui.simulator.streamlets.Swarm;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
|
||||
/**
|
||||
@@ -32,6 +33,10 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
|
||||
private boolean visible = false;
|
||||
private Timer timer;
|
||||
private Date endDate;
|
||||
|
||||
private int nParticles;
|
||||
private Swarm swarm;
|
||||
|
||||
private static Logger logger = Logger.getLogger(WindStreamletsCanvasOverlay.class.getName());
|
||||
|
||||
@@ -42,17 +47,23 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
this.timer = timer;
|
||||
this.windParams = windParams;
|
||||
|
||||
this.nParticles = this.simulatorMap.getMainPanel().particles;
|
||||
|
||||
|
||||
windFieldDTO = null;
|
||||
|
||||
getCanvas().getElement().setId("swarm-display");
|
||||
|
||||
/*if (!this.isSwarmDataExt()) {
|
||||
// random test windfield
|
||||
JavaScriptObject swarmData = this.getJSONRandomWindData();
|
||||
this.setSwarmData(swarmData);
|
||||
}*/
|
||||
}
|
||||
|
||||
public WindFieldDTO getWindFieldDTO() {
|
||||
return this.windFieldDTO;
|
||||
}
|
||||
|
||||
public WindFieldGenParamsDTO getWindParams() {
|
||||
return this.windParams;
|
||||
}
|
||||
|
||||
public JavaScriptObject getJSONRandomWindData() {
|
||||
|
||||
JSONObject jsonWindData = new JSONObject();
|
||||
@@ -137,24 +148,22 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
$wnd.swarmCanvasProjection = instance;
|
||||
}-*/;
|
||||
|
||||
public native void startStreamlets() /*-{
|
||||
if ($wnd.swarmAnimator) {
|
||||
$wnd.swarmUpdData = true;
|
||||
$wnd.updateStreamlets($wnd.swarmUpdData);
|
||||
} else {
|
||||
$wnd.initStreamlets($wnd.swarmMap);
|
||||
public void startStreamlets() {
|
||||
if (swarm == null) {
|
||||
this.swarm = new Swarm(this,map);
|
||||
}
|
||||
}-*/;
|
||||
this.swarm.start(40, windFieldDTO);
|
||||
}
|
||||
|
||||
public void setStreamletsStep(int step) {
|
||||
this.swarm.getField().setStep(step);
|
||||
}
|
||||
|
||||
public native void setStreamletsStep(int step) /*-{
|
||||
$wnd.swarmField.setStep(step);
|
||||
}-*/;
|
||||
|
||||
public native void stopStreamlets() /*-{
|
||||
if ($wnd.stopStreamlets) {
|
||||
$wnd.stopStreamlets();
|
||||
};
|
||||
}-*/;
|
||||
public void stopStreamlets() {
|
||||
if (swarm != null) {
|
||||
this.swarm.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void extendWindDataJSON() {
|
||||
|
||||
@@ -198,17 +207,12 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
|
||||
}
|
||||
|
||||
public void setEndDate(Date endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public void setWindField(final WindFieldDTO windFieldDTO) {
|
||||
this.windFieldDTO = windFieldDTO;
|
||||
|
||||
this.extendWindDataJSON();
|
||||
this.setWindDataJSON(this.windFieldDTO.windDataJSON);
|
||||
|
||||
//this.getJSNIWind(this);
|
||||
|
||||
this.setMapInstance(this.simulatorMap.getMap().getJso());
|
||||
this.setCanvasProjectionInstance(this.simulatorMap.getRegattaAreaCanvasOverlay().getMapProjection());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -254,13 +258,23 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
@Override
|
||||
protected void draw() {
|
||||
super.draw();
|
||||
if (mapProjection != null && windFieldDTO != null) {
|
||||
// drawing is done by external JavaScript for Streamlets
|
||||
if (mapProjection != null) {
|
||||
if ((nParticles > 0)&&(swarm == null)) {
|
||||
this.swarm = new Swarm(this,map);
|
||||
this.swarm.start(40, null);
|
||||
}
|
||||
if (windFieldDTO != null) {
|
||||
// drawing is done by external JavaScript for Streamlets
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Swarm getSwarm() {
|
||||
return this.swarm;
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
this.stopStreamlets();
|
||||
this.stopStreamlets();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -271,7 +285,7 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
|
||||
|
||||
@Override
|
||||
public boolean shallStop() {
|
||||
if (timer.getTime().getTime() >= this.windParams.getEndTime().getTime()) {
|
||||
if (timer.getTime().getTime() >= this.endDate.getTime()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public abstract class FullCanvasOverlay extends CanvasOverlayV3 implements Requi
|
||||
/**
|
||||
* Set the canvas to be the size of the map and set it to the top left corner of the map
|
||||
*/
|
||||
protected void setCanvasSettings() {
|
||||
public void setCanvasSettings() {
|
||||
int canvasWidth = getMap().getDiv().getClientWidth();
|
||||
int canvasHeight = getMap().getDiv().getClientHeight();
|
||||
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.sap.sailing.gwt.ui.simulator.streamlets;
|
||||
|
||||
public class Index {
|
||||
|
||||
public long x;
|
||||
public long y;
|
||||
|
||||
public Index(long x, long y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package com.sap.sailing.gwt.ui.simulator.streamlets;
|
||||
|
||||
import com.google.gwt.canvas.dom.client.Context2d;
|
||||
import com.google.gwt.maps.client.MapWidget;
|
||||
import com.google.gwt.maps.client.base.LatLng;
|
||||
import com.google.gwt.maps.client.base.Point;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.gwt.ui.simulator.racemap.FullCanvasOverlay;
|
||||
|
||||
public class Mercator {
|
||||
|
||||
private FullCanvasOverlay canvas;
|
||||
private MapWidget map;
|
||||
|
||||
private double alpha;
|
||||
private double beta;
|
||||
private double gamma;
|
||||
private double delta;
|
||||
|
||||
public Mercator(FullCanvasOverlay canvas, MapWidget map) {
|
||||
this.canvas = canvas;
|
||||
this.alpha = 0.0;
|
||||
this.beta = 0.0;
|
||||
this.gamma = 0.0;
|
||||
this.delta = 0.0;
|
||||
this.map = map;
|
||||
this.calibrate();
|
||||
}
|
||||
|
||||
public void calibrate() {
|
||||
|
||||
Vector pointSW;
|
||||
Vector pointNE;
|
||||
|
||||
int canvasHeight = canvas.getCanvas().getOffsetHeight();
|
||||
|
||||
Position mapSW = new DegreePosition(this.map.getBounds().getSouthWest().getLatitude(), this.map.getBounds().getSouthWest().getLongitude());
|
||||
Position mapNE = new DegreePosition(this.map.getBounds().getNorthEast().getLatitude(), this.map.getBounds().getNorthEast().getLongitude());
|
||||
|
||||
pointSW = this.sphere2plane(mapSW);
|
||||
pointNE = this.sphere2plane(mapNE);
|
||||
|
||||
if (pointNE.x < pointSW.x) {
|
||||
pointSW.x -= 2*Math.PI;
|
||||
}
|
||||
|
||||
this.alpha = canvasHeight / (pointNE.y - pointSW.y);
|
||||
this.beta = pointSW.x;
|
||||
|
||||
this.gamma = - this.alpha;
|
||||
this.delta = pointNE.y;
|
||||
}
|
||||
|
||||
public Vector sphere2plane(Position p) {
|
||||
Vector result = new Vector();
|
||||
result.x = p.getLngDeg()*Math.PI/180.0;
|
||||
double latsin = Math.sin(p.getLatDeg()*Math.PI/180.0);
|
||||
result.y = 0.5*Math.log((1.0+latsin)/(1.0-latsin));
|
||||
return result;
|
||||
}
|
||||
|
||||
public LatLng plane2sphere(Point px) {
|
||||
double lng = px.getX()*180.0/Math.PI;
|
||||
double lat = Math.atan(Math.sinh(px.getY()))*180.0/Math.PI;
|
||||
return LatLng.newInstance(lat, lng);
|
||||
}
|
||||
|
||||
public Vector latlng2pixel(Position p) {
|
||||
Vector proj = this.sphere2plane(p);
|
||||
proj.x = this.alpha * (proj.x - this.beta);
|
||||
proj.y = this.gamma * (proj.y - this.delta);
|
||||
return proj;
|
||||
}
|
||||
|
||||
public LatLng pixel2latlng(Point px) {
|
||||
double p = px.getX() / this.alpha + this.beta;
|
||||
double q = px.getY() / this.gamma + this.delta;
|
||||
return this.plane2sphere(Point.newInstance(p, q));
|
||||
}
|
||||
|
||||
public void clearCanvas() {
|
||||
double w = this.canvas.getCanvas().getOffsetWidth();
|
||||
double h = this.canvas.getCanvas().getOffsetHeight();
|
||||
Context2d g = this.canvas.getCanvas().getContext2d();
|
||||
g.clearRect(0, 0, w, h);
|
||||
};
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.sap.sailing.gwt.ui.simulator.streamlets;
|
||||
|
||||
public class Neighbors {
|
||||
|
||||
public int xBot;
|
||||
public int xTop;
|
||||
public double xMod;
|
||||
public int yBot;
|
||||
public int yTop;
|
||||
public double yMod;
|
||||
|
||||
public Neighbors(int xTop, int yTop, int xBot, int yBot, double xMod, double yMod) {
|
||||
this.xTop = xTop;
|
||||
this.yTop = yTop;
|
||||
this.xBot = xBot;
|
||||
this.yBot = yBot;
|
||||
this.xMod = xMod;
|
||||
this.yMod = yMod;
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.sap.sailing.gwt.ui.simulator.streamlets;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
|
||||
|
||||
public class Particle {
|
||||
|
||||
public Position pos;
|
||||
public Vector pxOld;
|
||||
public int alpha;
|
||||
public int age;
|
||||
public Vector v;
|
||||
|
||||
}
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
package com.sap.sailing.gwt.ui.simulator.streamlets;
|
||||
|
||||
import com.google.gwt.json.client.JSONObject;
|
||||
import com.google.gwt.json.client.JSONParser;
|
||||
import com.google.gwt.maps.client.base.LatLng;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
|
||||
public class RectField implements VectorField {
|
||||
|
||||
private Vector[][] field;
|
||||
|
||||
public double x0;
|
||||
public double x1;
|
||||
public double y0;
|
||||
public double y1;
|
||||
|
||||
//public double visX0;
|
||||
public double visX1;
|
||||
public double visY0;
|
||||
public double visY1;
|
||||
|
||||
public Position visSW;
|
||||
public Position visNE;
|
||||
|
||||
private int w;
|
||||
private int h;
|
||||
|
||||
private double maxLength;
|
||||
public double particleFactor;
|
||||
|
||||
public RectField(Vector[][] field, double x0, double y0, double x1, double y1) {
|
||||
this.x0 = x0;
|
||||
this.x1 = x1;
|
||||
this.y0 = y0;
|
||||
this.y1 = y1;
|
||||
|
||||
this.visSW = new DegreePosition(0.0, 0.0);
|
||||
this.visNE = new DegreePosition(0.0, 0.0);
|
||||
|
||||
this.field = field;
|
||||
this.w = field.length;
|
||||
this.h = field[0].length;
|
||||
this.maxLength = 0;
|
||||
this.particleFactor = 4.5;
|
||||
|
||||
double mx = 0;
|
||||
double my = 0;
|
||||
for (int i = 0; i < this.w; i++) {
|
||||
for (int j = 0; j < this.h; j++) {
|
||||
if (field[i][j].length() > this.maxLength) {
|
||||
mx = i;
|
||||
my = j;
|
||||
}
|
||||
this.maxLength = Math.max(this.maxLength, field[i][j].length());
|
||||
}
|
||||
}
|
||||
mx = (mx / this.w) * (x1 - x0) + x0;
|
||||
my = (my / this.h) * (y1 - y0) + y0;
|
||||
}
|
||||
|
||||
public static RectField read(String jsonData, boolean correctForSphere) {
|
||||
JSONObject data = JSONParser.parseLenient(jsonData).isObject();
|
||||
int w = (int)data.get("gridWidth").isNumber().doubleValue();
|
||||
int h = (int)data.get("gridHeight").isNumber().doubleValue();
|
||||
Vector[][] field = new Vector[w][h];
|
||||
|
||||
int i = 0;
|
||||
for (int x = 0; x < w; x++) {
|
||||
for (int y = 0; y < h; y++) {
|
||||
Vector v = new Vector();
|
||||
v.x = data.get("field").isArray().get(i++).isNumber().doubleValue();
|
||||
v.y = data.get("field").isArray().get(i++).isNumber().doubleValue();
|
||||
if (correctForSphere) {
|
||||
double uy = y / (h - 1);
|
||||
double lat = data.get("y0").isNumber().doubleValue() * (1 - uy) + data.get("y1").isNumber().doubleValue() * uy;
|
||||
double m = Math.PI * lat / 180;
|
||||
double length = v.length();
|
||||
v.x = v.x / Math.cos(m);
|
||||
v.setLength(length);
|
||||
}
|
||||
field[x][y] = v;
|
||||
}
|
||||
}
|
||||
RectField result = new RectField(field, data.get("x0").isNumber().doubleValue(), data.get("y0").isNumber().doubleValue(), data.get("x1").isNumber().doubleValue(), data.get("y1").isNumber().doubleValue());
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setStep(int step) {
|
||||
}
|
||||
|
||||
public void nextStep() {
|
||||
}
|
||||
|
||||
public void prevStep() {
|
||||
}
|
||||
|
||||
public Position getRandomPosition() {
|
||||
double rndY = Math.random();
|
||||
double rndX = Math.random();
|
||||
double latDeg = rndY * this.visSW.getLatDeg() + (1 - rndY) * this.visNE.getLatDeg();
|
||||
double lngDeg = rndX * this.visSW.getLngDeg() + (1 - rndX) * this.visNE.getLngDeg();
|
||||
return new DegreePosition(latDeg, lngDeg);
|
||||
}
|
||||
|
||||
public boolean inBounds(Position p) {
|
||||
return p.getLngDeg() >= this.x0 && p.getLngDeg() < this.x1 && p.getLatDeg() >= this.y0 && p.getLatDeg() < this.y1;
|
||||
}
|
||||
|
||||
public Vector interpolate(Position p) {
|
||||
int na = (int)Math.floor(p.getLngDeg());
|
||||
int nb = (int)Math.floor(p.getLatDeg());
|
||||
int ma = (int)Math.ceil(p.getLngDeg());
|
||||
int mb = (int)Math.ceil(p.getLatDeg());
|
||||
double fa = p.getLngDeg() - na;
|
||||
double fb = p.getLatDeg() - nb;
|
||||
|
||||
Vector result = new Vector();
|
||||
result.x = this.field[na][nb].x * (1 - fa) * (1 - fb) + this.field[ma][nb].x * fa * (1 - fb) + this.field[na][mb].x * (1 - fa) * fb + this.field[ma][mb].x * fa * fb;
|
||||
result.y = this.field[na][nb].y * (1 - fa) * (1 - fb) + this.field[ma][nb].y * fa * (1 - fb) + this.field[na][mb].y * (1 - fa) * fb + this.field[ma][mb].y * fa * fb;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public Vector getVector(Position p) {
|
||||
double lngDeg = (this.w - 1 - 1e-6) * (p.getLngDeg() - this.x0) / (this.x1 - this.x0);
|
||||
double latDeg = (this.h - 1 - 1e-6) * (p.getLatDeg() - this.y0) / (this.y1 - this.y0);
|
||||
if ((lngDeg < 0)||(lngDeg > (this.w-1))||(latDeg < 0)||(latDeg > (this.h-1))) {
|
||||
return null;
|
||||
} else {
|
||||
Position q = new DegreePosition(latDeg, lngDeg);
|
||||
return this.interpolate(q);
|
||||
}
|
||||
}
|
||||
|
||||
public LatLng getCenter() {
|
||||
return LatLng.newInstance((y0+y1)/2.0, (x0+x1)/2.0);
|
||||
}
|
||||
|
||||
public double getMaxLength() {
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
public double motionScale(int zoomLevel) {
|
||||
return 0.9 * Math.pow(1.7, Math.min(1.0, 6.0 - zoomLevel));
|
||||
}
|
||||
|
||||
public double particleWeight(Position p, Vector v) {
|
||||
return 1.0 - v.length() / this.maxLength;
|
||||
}
|
||||
|
||||
public String[] getColors() {
|
||||
String[] colors = new String[256];
|
||||
double alpha = 1.0;
|
||||
int greyValue = 255;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
colors[i] = "rgba(" + (greyValue) + "," + (greyValue) + "," + (greyValue) + "," + (alpha*i/255.0) + ")";
|
||||
//this.colors[i] = 'hsla(' + 360*(0.55+0.9*(0.5-i/255)) + ',' + (100) + '% ,' + (50) + '%,' + (i/255) + ')';
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
public double lineWidth(int alpha) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public Position getFieldNE() {
|
||||
return new DegreePosition(Math.max(this.y0, this.y1), Math.max(this.x0, this.x1));
|
||||
}
|
||||
|
||||
public Position getFieldSW() {
|
||||
return new DegreePosition(Math.min(this.y0, this.y1), Math.min(this.x0, this.x1));
|
||||
}
|
||||
|
||||
public void setVisNE(Position visNE) {
|
||||
this.visNE = visNE;
|
||||
}
|
||||
|
||||
public void setVisSW(Position visSW) {
|
||||
this.visSW = visSW;
|
||||
}
|
||||
|
||||
public double getParticleFactor() {
|
||||
return this.particleFactor;
|
||||
}
|
||||
}
|
||||
+295
@@ -0,0 +1,295 @@
|
||||
package com.sap.sailing.gwt.ui.simulator.streamlets;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.json.client.JSONObject;
|
||||
import com.google.gwt.json.client.JSONParser;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindFieldDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindFieldGenParamsDTO;
|
||||
|
||||
public class SimulatorField implements VectorField {
|
||||
|
||||
private boolean swarmDebug = false;
|
||||
|
||||
private Position rcStart;
|
||||
private Position rcEnd;
|
||||
|
||||
private int resY;
|
||||
private int resX;
|
||||
|
||||
private int borderY;
|
||||
private int borderX;
|
||||
|
||||
private double bdXi;
|
||||
private double bdPhi;
|
||||
|
||||
private Position bdA;
|
||||
private Position bdB;
|
||||
private Position bdC;
|
||||
|
||||
private double xScale;
|
||||
|
||||
private double x0;
|
||||
private double x1;
|
||||
private double y0;
|
||||
private double y1;
|
||||
|
||||
public Position visSW;
|
||||
public Position visNE;
|
||||
|
||||
private double maxLength;
|
||||
private double particleFactor;
|
||||
|
||||
private double lngScale;
|
||||
|
||||
private Position nvY;
|
||||
private Position nvX;
|
||||
private Position gvX;
|
||||
|
||||
private double[][][] data;
|
||||
private int step;
|
||||
|
||||
public SimulatorField(WindFieldDTO windData, WindFieldGenParamsDTO windParams) {
|
||||
|
||||
this.step = 0;
|
||||
|
||||
String parseString = windData.windDataJSON.substring(18, windData.windDataJSON.length()-1) + "}";
|
||||
JSONObject baseData = JSONParser.parseLenient(parseString).isObject();
|
||||
|
||||
this.rcStart = new DegreePosition(baseData.get("rcStart").isObject().get("lat").isNumber().doubleValue(), baseData.get("rcStart").isObject().get("lng").isNumber().doubleValue());
|
||||
this.rcEnd = new DegreePosition(baseData.get("rcEnd").isObject().get("lat").isNumber().doubleValue(), baseData.get("rcEnd").isObject().get("lng").isNumber().doubleValue());
|
||||
|
||||
this.resY = (int)baseData.get("resY").isNumber().doubleValue();
|
||||
this.resX = (int)baseData.get("resX").isNumber().doubleValue();
|
||||
|
||||
this.borderY = (int)baseData.get("borderY").isNumber().doubleValue();
|
||||
this.borderX = (int)baseData.get("borderX").isNumber().doubleValue();
|
||||
|
||||
this.bdXi = (this.borderY + 0.5) / (this.resY - 1);
|
||||
this.bdPhi = 1.0 + 2*this.bdXi;
|
||||
this.bdA = new DegreePosition(this.rcEnd.getLatDeg()+(this.rcEnd.getLatDeg()-this.rcStart.getLatDeg())*this.bdXi, this.rcEnd.getLngDeg()+(this.rcEnd.getLngDeg()-this.rcStart.getLngDeg())*this.bdXi);
|
||||
this.bdB = new DegreePosition((this.rcStart.getLatDeg()-this.rcEnd.getLatDeg())*this.bdPhi, (this.rcStart.getLngDeg()-this.rcEnd.getLngDeg())*this.bdPhi);
|
||||
|
||||
this.xScale = baseData.get("xScale").isNumber().doubleValue();
|
||||
|
||||
this.x0 = baseData.get("boundsSW").isObject().get("lng").isNumber().doubleValue();
|
||||
this.x1 = baseData.get("boundsNE").isObject().get("lng").isNumber().doubleValue();
|
||||
this.y0 = baseData.get("boundsSW").isObject().get("lat").isNumber().doubleValue();
|
||||
this.y1 = baseData.get("boundsNE").isObject().get("lat").isNumber().doubleValue();
|
||||
|
||||
this.visSW = new DegreePosition(0.0, 0.0);
|
||||
this.visNE = new DegreePosition(0.0, 0.0);
|
||||
|
||||
List<SimulatorWindDTO> gridData = windData.getMatrix();
|
||||
|
||||
int p = 0;
|
||||
int imax = windParams.getyRes() + 2*windParams.getBorderY();
|
||||
int jmax = windParams.getxRes() + 2*windParams.getBorderX();
|
||||
int steps = gridData.size() / (imax * jmax);
|
||||
|
||||
this.data = new double[steps][imax][2*jmax];
|
||||
|
||||
double maxWindSpeed = 0;
|
||||
for(int s=0; s<steps; s++) {
|
||||
for(int i=0; i<imax; i++) {
|
||||
for(int j=0; j<jmax; j++) {
|
||||
SimulatorWindDTO wind = gridData.get(p);
|
||||
p++;
|
||||
if (wind.trueWindSpeedInKnots > maxWindSpeed) {
|
||||
maxWindSpeed = wind.trueWindSpeedInKnots;
|
||||
}
|
||||
|
||||
this.data[s][i][2*j+1] = wind.trueWindSpeedInKnots*Math.cos(wind.trueWindBearingDeg*Math.PI/180.0);
|
||||
this.data[s][i][2*j] = wind.trueWindSpeedInKnots*Math.sin(wind.trueWindBearingDeg*Math.PI/180.0);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
this.maxLength = maxWindSpeed;
|
||||
|
||||
this.particleFactor = 2.0;
|
||||
|
||||
double latAvg = (this.rcEnd.getLatDeg() + this.rcStart.getLatDeg()) / 2.;
|
||||
this.lngScale = Math.cos(latAvg * Math.PI / 180.0);
|
||||
|
||||
double difLat = this.rcEnd.getLatDeg() - this.rcStart.getLatDeg();
|
||||
double difLng = (this.rcEnd.getLngDeg() - this.rcStart.getLngDeg()) * this.lngScale;
|
||||
double difLen = Math.sqrt(difLat*difLat + difLng*difLng);
|
||||
this.nvY = new DegreePosition(difLat/difLen/difLen*(this.resY-1), difLng/difLen/difLen*(this.resY-1));
|
||||
|
||||
double nrmLat = -difLng/difLen;
|
||||
double nrmLng = difLat/difLen;
|
||||
this.nvX = new DegreePosition( nrmLat/this.xScale/difLen*(this.resX-1), nrmLng/this.xScale/difLen*(this.resX-1) );
|
||||
this.gvX = new DegreePosition( nrmLat*this.xScale*difLen, nrmLng/this.lngScale*this.xScale*difLen );
|
||||
this.bdC = new DegreePosition( this.gvX.getLatDeg()*(this.resX+2*this.borderX-1)/(this.resX-1), this.gvX.getLngDeg()*(this.resX+2*this.borderX-1)/(this.resX-1) );
|
||||
}
|
||||
|
||||
public static native void console(String msg) /*-{
|
||||
console.log(msg);
|
||||
}-*/;
|
||||
|
||||
public Position getRandomPosition() {
|
||||
double rndY = Math.random();
|
||||
double rndX = Math.random() - 0.5;
|
||||
|
||||
double latDeg = this.bdA.getLatDeg() + rndY * this.bdB.getLatDeg() + rndX * this.bdC.getLatDeg();
|
||||
double lngDeg = this.bdA.getLngDeg() + rndY * this.bdB.getLngDeg() + rndX * this.bdC.getLngDeg();
|
||||
Position result = new DegreePosition(latDeg, lngDeg);
|
||||
|
||||
if (swarmDebug&&(!this.inBounds(result))) {
|
||||
console("random-position: out of bounds");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public boolean inBounds(Position p) {
|
||||
Index idx = this.getIndex(p);
|
||||
boolean inBool = (idx.x >= 0) && (idx.x < (this.resX+2*this.borderX)) && (idx.y >= 0) && (idx.y < (this.resY+2*this.borderY));
|
||||
return inBool;
|
||||
}
|
||||
|
||||
|
||||
public Vector interpolate(Position p) {
|
||||
|
||||
Neighbors idx = this.getNeighbors(p);
|
||||
|
||||
if (swarmDebug&&((idx.xTop >= (this.resX+2*this.borderX))||(idx.yTop >= (this.resY+2*this.borderY)))) {
|
||||
console("interpolate: out of range: " + idx.xTop + " " + idx.yTop);
|
||||
}
|
||||
|
||||
//System.out.println("neighbors:"+idx.xBot+","+idx.xTop+","+idx.yBot+","+idx.yTop);
|
||||
|
||||
double avgX = this.data[this.step][idx.yBot][2*idx.xBot] * (1 - idx.yMod) * (1 - idx.xMod) + this.data[this.step][idx.yTop][2*idx.xBot] * idx.yMod * (1 - idx.xMod)
|
||||
+ this.data[this.step][idx.yBot][2*idx.xTop] * (1 - idx.yMod) * idx.xMod + this.data[this.step][idx.yTop][2*idx.xTop] * idx.yMod * idx.xMod;
|
||||
double avgY = this.data[this.step][idx.yBot][2*idx.xBot+1] * (1 - idx.yMod) * (1 - idx.xMod) + this.data[this.step][idx.yTop][2*idx.xBot+1] * idx.yMod * (1 - idx.xMod)
|
||||
+ this.data[this.step][idx.yBot][2*idx.xTop+1] * (1 - idx.yMod) * idx.xMod + this.data[this.step][idx.yTop][2*idx.xTop+1] * idx.yMod * idx.xMod;
|
||||
|
||||
return new Vector(avgX / this.lngScale, avgY);
|
||||
}
|
||||
|
||||
public void setStep(int step) {
|
||||
if (step < 0) {
|
||||
this.step = 0;
|
||||
} else if (step >= this.data.length) {
|
||||
this.step = this.data.length-1;
|
||||
} else {
|
||||
this.step = step;
|
||||
}
|
||||
}
|
||||
|
||||
public void nextStep() {
|
||||
if (this.step < (this.data.length-1)) {
|
||||
this.step++;
|
||||
}
|
||||
}
|
||||
|
||||
public void prevStep() {
|
||||
if (this.step > 0) {
|
||||
this.step--;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector getVector(Position p) {
|
||||
return this.interpolate(p);
|
||||
}
|
||||
|
||||
public Index getIndex(Position p) {
|
||||
|
||||
// calculate grid indexes
|
||||
Position posR = new DegreePosition( p.getLatDeg() - this.rcStart.getLatDeg(), (p.getLngDeg() - this.rcStart.getLngDeg()) * this.lngScale );
|
||||
|
||||
// closest grid point
|
||||
long yIdx = Math.round( posR.getLatDeg() * this.nvY.getLatDeg() + posR.getLngDeg() * this.nvY.getLngDeg() ) + this.borderY;
|
||||
long xIdx = Math.round( posR.getLatDeg() * this.nvX.getLatDeg() + posR.getLngDeg() * this.nvX.getLngDeg() + (this.resX - 1) / 2. ) + this.borderX;
|
||||
|
||||
return new Index( xIdx, yIdx );
|
||||
}
|
||||
|
||||
public Neighbors getNeighbors(Position p) {
|
||||
|
||||
// calculate grid indexes
|
||||
Position posR = new DegreePosition( p.getLatDeg() - this.rcStart.getLatDeg(), (p.getLngDeg() - this.rcStart.getLngDeg()) * this.lngScale );
|
||||
|
||||
// surrounding grid points
|
||||
double yFlt = posR.getLatDeg() * this.nvY.getLatDeg() + posR.getLngDeg() * this.nvY.getLngDeg() + this.borderY;
|
||||
double xFlt = posR.getLatDeg() * this.nvX.getLatDeg() + posR.getLngDeg() * this.nvX.getLngDeg() + (this.resX - 1) / 2. + this.borderX;
|
||||
double yBot = Math.floor( yFlt );
|
||||
double xBot = Math.floor( xFlt );
|
||||
double yTop = Math.ceil( yFlt );
|
||||
double xTop = Math.ceil( xFlt );
|
||||
double yMod = yFlt - yBot;
|
||||
double xMod = xFlt - xBot;
|
||||
|
||||
if (xBot < 0) {
|
||||
xBot = 0;
|
||||
}
|
||||
|
||||
if (yBot < 0) {
|
||||
yBot = 0;
|
||||
}
|
||||
|
||||
if (xTop >= (this.resX+2*this.borderX)) {
|
||||
xTop = this.resX+2*this.borderX-1;
|
||||
}
|
||||
|
||||
if (yTop >= (this.resY+2*this.borderY)) {
|
||||
yTop = this.resY+2*this.borderY-1;
|
||||
}
|
||||
|
||||
//System.out.println("neighbors:"+xFlt+","+xBot+","+xTop+","+yFlt+","+yBot+","+yTop);
|
||||
|
||||
return new Neighbors((int)xTop, (int)yTop, (int)xBot, (int)yBot, xMod, yMod );
|
||||
}
|
||||
|
||||
public double getMaxLength() {
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
public double motionScale(int zoomLevel) {
|
||||
return 0.08 * Math.pow(1.6, Math.min(1.0, 6.0 - zoomLevel));
|
||||
}
|
||||
|
||||
public double particleWeight(Position p, Vector v) {
|
||||
return v.length() / this.maxLength + 0.1;
|
||||
}
|
||||
|
||||
public String[] getColors() {
|
||||
String[] colors = new String[256];
|
||||
double alpha = 0.7;
|
||||
int greyValue = 255;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
colors[i] = "rgba(" + (greyValue) + "," + (greyValue) + "," + (greyValue) + "," + (alpha*i/255.0) + ")";
|
||||
//this.colors[i] = 'hsla(' + 360*(0.55+0.9*(0.5-i/255)) + ',' + (100) + '% ,' + (50) + '%,' + (i/255) + ')';
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
public double lineWidth(int alpha) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public Position getFieldNE() {
|
||||
return new DegreePosition(Math.max(this.y0, this.y1), Math.max(this.x0, this.x1));
|
||||
}
|
||||
|
||||
public Position getFieldSW() {
|
||||
return new DegreePosition(Math.min(this.y0, this.y1), Math.min(this.x0, this.x1));
|
||||
}
|
||||
|
||||
public void setVisNE(Position visNE) {
|
||||
this.visNE = visNE;
|
||||
}
|
||||
|
||||
public void setVisSW(Position visSW) {
|
||||
this.visSW = visSW;
|
||||
}
|
||||
|
||||
public double getParticleFactor() {
|
||||
return this.particleFactor;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.gwt.ui.simulator;
|
||||
package com.sap.sailing.gwt.ui.simulator.streamlets;
|
||||
|
||||
import com.google.gwt.resources.client.ClientBundle;
|
||||
import com.google.gwt.resources.client.TextResource;
|
||||
@@ -8,7 +8,7 @@ public interface SimulatorJSBundle extends ClientBundle {
|
||||
//@Source("wind-streamlets.js")
|
||||
//TextResource windStreamletsJS();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/simulator/wind-data.js")
|
||||
@Source("com/sap/sailing/gwt/ui/simulator/streamlets/wind-data.js")
|
||||
TextResource windStreamletsDataJS();
|
||||
|
||||
}
|
||||
+292
@@ -0,0 +1,292 @@
|
||||
package com.sap.sailing.gwt.ui.simulator.streamlets;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.google.gwt.canvas.client.Canvas;
|
||||
import com.google.gwt.canvas.dom.client.Context2d;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.maps.client.MapWidget;
|
||||
import com.google.gwt.user.client.Timer;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.gwt.ui.shared.WindFieldDTO;
|
||||
import com.sap.sailing.gwt.ui.simulator.WindStreamletsCanvasOverlay;
|
||||
import com.sap.sailing.gwt.ui.simulator.racemap.FullCanvasOverlay;
|
||||
|
||||
public class Swarm {
|
||||
|
||||
protected FullCanvasOverlay fullcanvas;
|
||||
protected Canvas canvas;
|
||||
protected MapWidget map;
|
||||
|
||||
private Timer loopTimer;
|
||||
private String[] color;
|
||||
private Mercator projection;
|
||||
private VectorField field;
|
||||
private int nParticles;
|
||||
private Particle[] particles;
|
||||
private boolean swarmOffScreen = false;
|
||||
private int swarmPause = 0;
|
||||
private boolean swarmContinue = true;
|
||||
private Position boundsNE;
|
||||
private Position boundsSW;
|
||||
|
||||
public Swarm(FullCanvasOverlay fullcanvas, MapWidget map) {
|
||||
this.fullcanvas = fullcanvas;
|
||||
this.canvas = fullcanvas.getCanvas();
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public void start(int animationDuration, WindFieldDTO windField) {
|
||||
|
||||
projection = new Mercator(fullcanvas, map);
|
||||
|
||||
if (windField == null) {
|
||||
|
||||
SimulatorJSBundle bundle = GWT.create(SimulatorJSBundle.class);
|
||||
String jsonStr = bundle.windStreamletsDataJS().getText();
|
||||
field = RectField.read(jsonStr.substring(19, jsonStr.length()-1), false);
|
||||
|
||||
map.setZoom(5);
|
||||
map.panTo(((RectField)field).getCenter());
|
||||
|
||||
projection.calibrate();
|
||||
|
||||
} else {
|
||||
|
||||
field = new SimulatorField(((WindStreamletsCanvasOverlay)fullcanvas).getWindFieldDTO(), ((WindStreamletsCanvasOverlay)fullcanvas).getWindParams());
|
||||
fullcanvas.setCanvasSettings();
|
||||
projection.calibrate();
|
||||
|
||||
}
|
||||
|
||||
this.updateBounds();
|
||||
|
||||
color = field.getColors();
|
||||
|
||||
Context2d ctxt = canvas.getContext2d();
|
||||
ctxt.setFillStyle("red");
|
||||
|
||||
/*Vector p = this.projection.latlng2pixel(this.field.getFieldNE());
|
||||
ctxt.fillRect(p.x,p.y,5.0,5.0);
|
||||
|
||||
p = this.projection.latlng2pixel(this.field.getFieldSW());
|
||||
ctxt.fillRect(p.x,p.y,5.0,5.0);*/
|
||||
|
||||
particles = this.createParticles();
|
||||
|
||||
this.swarmContinue = true;
|
||||
startLoop(animationDuration);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
this.swarmContinue = false;
|
||||
}
|
||||
|
||||
public Particle createParticle() {
|
||||
Particle particle = new Particle();
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
particle.pos = field.getRandomPosition();
|
||||
Vector v = field.getVector(particle.pos);
|
||||
double weight = field.particleWeight(particle.pos, v);
|
||||
if (weight >= Math.random()) {
|
||||
if (v.length() == 0) {
|
||||
particle.age = 0;
|
||||
} else {
|
||||
particle.age = 1 + (int)Math.round(Math.random()*40);
|
||||
}
|
||||
particle.pxOld = projection.latlng2pixel(particle.pos);
|
||||
particle.alpha = 0;
|
||||
particle.v = v;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
return particle;
|
||||
}
|
||||
|
||||
public Particle[] createParticles() {
|
||||
|
||||
Particle[] newParticles = new Particle[nParticles];
|
||||
for(int idx=0; idx<newParticles.length; idx++) {
|
||||
newParticles[idx] = this.createParticle();
|
||||
}
|
||||
|
||||
return newParticles;
|
||||
}
|
||||
|
||||
public void onBoundsChanged() {
|
||||
projection.clearCanvas();
|
||||
swarmPause = 5;
|
||||
}
|
||||
|
||||
public void onMoveEnd() {
|
||||
|
||||
}
|
||||
|
||||
public static native void console(String msg) /*-{
|
||||
console.log(msg);
|
||||
}-*/;
|
||||
|
||||
public void updateBounds() {
|
||||
|
||||
Position mapNE = new DegreePosition(map.getBounds().getNorthEast().getLatitude(), map.getBounds().getNorthEast().getLongitude());
|
||||
Position mapSW = new DegreePosition(map.getBounds().getSouthWest().getLatitude(), map.getBounds().getSouthWest().getLongitude());
|
||||
|
||||
Position fieldNE = this.field.getFieldNE();
|
||||
Position fieldSW = this.field.getFieldSW();
|
||||
|
||||
Vector visibleNE = this.isVisible(fieldNE);
|
||||
Vector visibleSW = this.isVisible(fieldSW);
|
||||
|
||||
boolean useBoundsNorth = (visibleNE.y == 0);
|
||||
boolean useBoundsEast = (visibleNE.x == 0);
|
||||
boolean useBoundsSouth = (visibleSW.y == 0);
|
||||
boolean useBoundsWest = (visibleSW.x == 0);
|
||||
|
||||
swarmOffScreen = (visibleNE.y > 0)||(visibleSW.y < 0)||(visibleNE.x < 0)||(visibleSW.x > 0);
|
||||
|
||||
if (swarmOffScreen) {
|
||||
|
||||
this.boundsNE = fieldNE;
|
||||
this.boundsSW = fieldSW;
|
||||
|
||||
} else {
|
||||
|
||||
if ((!useBoundsNorth)&&(!useBoundsEast)) {
|
||||
this.boundsNE = mapNE;
|
||||
} else if (!useBoundsNorth) {
|
||||
this.boundsNE = new DegreePosition(mapNE.getLatDeg(), fieldNE.getLngDeg());
|
||||
} else if (!useBoundsEast) {
|
||||
this.boundsNE = new DegreePosition(fieldNE.getLatDeg(), mapNE.getLngDeg());
|
||||
} else {
|
||||
this.boundsNE = fieldNE;
|
||||
}
|
||||
|
||||
if ((!useBoundsSouth)&&(!useBoundsWest)) {
|
||||
this.boundsSW = mapSW;
|
||||
} else if (!useBoundsSouth) {
|
||||
this.boundsSW = new DegreePosition(mapSW.getLatDeg(), fieldSW.getLngDeg());
|
||||
} else if (!useBoundsWest) {
|
||||
this.boundsSW = new DegreePosition(fieldSW.getLatDeg(), mapSW.getLngDeg());
|
||||
} else {
|
||||
this.boundsSW = fieldSW;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.field.setVisSW(this.boundsSW);
|
||||
this.field.setVisNE(this.boundsNE);
|
||||
|
||||
Vector boundsSWpx = this.projection.latlng2pixel(this.boundsSW);
|
||||
Vector boundsNEpx = this.projection.latlng2pixel(this.boundsNE);
|
||||
|
||||
double boundsWidthpx = Math.abs(boundsNEpx.x - boundsSWpx.x);
|
||||
double boundsHeightpx = Math.abs(boundsSWpx.y - boundsNEpx.y);
|
||||
|
||||
this.nParticles = (int)Math.round(Math.sqrt(boundsWidthpx * boundsHeightpx) * this.field.getParticleFactor());
|
||||
//console("#particles: "+this.nParticles + " at " + (boundsWidthpx) +"x" + (boundsHeightpx) + "px (" + (boundsWidthpx * boundsHeightpx) + " pixels)");
|
||||
};
|
||||
|
||||
public Vector isVisible(Position pos) {
|
||||
|
||||
// test for visibility of swarm
|
||||
Vector proj = this.projection.latlng2pixel(pos);
|
||||
|
||||
Vector result = new Vector();
|
||||
result.x = (proj.x < 0 ? -1 : 0) + (proj.x > canvas.getOffsetWidth() ? 1 : 0);
|
||||
result.y = (proj.y < 0 ? -1 : 0) + (proj.y > canvas.getOffsetHeight() ? 1 : 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void startLoop(final int millis) {
|
||||
|
||||
// Create animation-loop based on timer timeout
|
||||
loopTimer = new com.google.gwt.user.client.Timer() {
|
||||
public void run() {
|
||||
Date time0 = new Date();
|
||||
if (swarmPause > 1) {
|
||||
swarmPause--;
|
||||
} else if (swarmPause == 1) {
|
||||
fullcanvas.setCanvasSettings();
|
||||
projection.calibrate();
|
||||
updateBounds();
|
||||
particles = createParticles();
|
||||
swarmPause = 0;
|
||||
}
|
||||
//console("swarmOffScreen:"+swarmOffScreen);
|
||||
if ((!swarmOffScreen)&&(swarmPause == 0)) {
|
||||
execute();
|
||||
}
|
||||
Date time1 = new Date();
|
||||
//console("delta:"+(time1.getTime()-time0.getTime())+"/"+millis);
|
||||
if (swarmContinue) {
|
||||
loopTimer.schedule((int)Math.max(10, millis - (time1.getTime()-time0.getTime())));
|
||||
} else {
|
||||
projection.clearCanvas();
|
||||
}
|
||||
}
|
||||
};
|
||||
loopTimer.schedule(millis);
|
||||
}
|
||||
|
||||
public void drawSwarm() {
|
||||
|
||||
Context2d ctxt = canvas.getContext2d();
|
||||
|
||||
ctxt.setGlobalAlpha(0.08);
|
||||
ctxt.setGlobalCompositeOperation("destination-out");
|
||||
ctxt.setFillStyle("black");
|
||||
ctxt.fillRect(0, 0, canvas.getOffsetWidth(), canvas.getOffsetHeight());
|
||||
ctxt.setGlobalAlpha(1.0);
|
||||
ctxt.setGlobalCompositeOperation("source-over");
|
||||
ctxt.setFillStyle("white");
|
||||
for(int idx=0; idx<particles.length; idx++) {
|
||||
Particle particle = particles[idx];
|
||||
if (particle.age == 0) {
|
||||
continue;
|
||||
}
|
||||
ctxt.setLineWidth(field.lineWidth(particle.alpha));
|
||||
ctxt.setStrokeStyle(color[particle.alpha]);
|
||||
ctxt.beginPath();
|
||||
ctxt.moveTo(particle.pxOld.x, particle.pxOld.y);
|
||||
particle.pxOld = projection.latlng2pixel(particle.pos);
|
||||
ctxt.lineTo(particle.pxOld.x, particle.pxOld.y);
|
||||
ctxt.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean execute() {
|
||||
|
||||
double speed = 0.01*field.motionScale(map.getZoom());
|
||||
|
||||
for(int idx=0; idx<particles.length; idx++) {
|
||||
Particle particle = particles[idx];
|
||||
if ((particle.age > 0) && (particle.v != null)) {
|
||||
double latDeg = particle.pos.getLatDeg() + speed*particle.v.y;
|
||||
double lngDeg = particle.pos.getLngDeg() + speed*particle.v.x;
|
||||
particle.pos = new DegreePosition(latDeg, lngDeg);
|
||||
double s = particle.v.length() / field.getMaxLength();
|
||||
particle.alpha = (int)Math.min(255, 90 + Math.round(350 * s));
|
||||
particle.age--;
|
||||
if ((particle.age > 0) && (this.field.inBounds(particle.pos))) {
|
||||
particle.v = field.getVector(particle.pos);
|
||||
} else {
|
||||
particle.v = null;
|
||||
}
|
||||
} else {
|
||||
particles[idx] = this.createParticle();
|
||||
}
|
||||
}
|
||||
|
||||
drawSwarm();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public VectorField getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.sap.sailing.gwt.ui.simulator.streamlets;
|
||||
|
||||
public class Vector {
|
||||
|
||||
public double x;
|
||||
public double y;
|
||||
|
||||
public Vector() {
|
||||
}
|
||||
|
||||
public Vector(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public double length() {
|
||||
return Math.sqrt(x*x + y*y);
|
||||
}
|
||||
|
||||
public Vector setLength(double length) {
|
||||
double current = this.length();
|
||||
if (current > 0) {
|
||||
double scale = length / current;
|
||||
this.x *= scale;
|
||||
this.y *= scale;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.sap.sailing.gwt.ui.simulator.streamlets;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
|
||||
|
||||
public interface VectorField {
|
||||
|
||||
public Position getRandomPosition();
|
||||
|
||||
public boolean inBounds(Position p);
|
||||
|
||||
public Vector interpolate(Position p);
|
||||
|
||||
public Vector getVector(Position p);
|
||||
|
||||
public double getMaxLength();
|
||||
|
||||
public double motionScale(int zoomLevel);
|
||||
|
||||
public double particleWeight(Position p, Vector v);
|
||||
|
||||
public String[] getColors();
|
||||
|
||||
public double lineWidth(int alpha);
|
||||
|
||||
public Position getFieldNE();
|
||||
|
||||
public Position getFieldSW();
|
||||
|
||||
public void setVisNE(Position visNE);
|
||||
|
||||
public void setVisSW(Position visSW);
|
||||
|
||||
public double getParticleFactor();
|
||||
|
||||
public void setStep(int step);
|
||||
|
||||
public void nextStep();
|
||||
|
||||
public void prevStep();
|
||||
|
||||
}
|
||||
File renamed without changes.
+3
-2
@@ -55,8 +55,9 @@
|
||||
<set-property name="gwt.logging.popupHandler" value="DISABLED" />
|
||||
<set-property name="gwt.logging.systemHandler" value="ENABLED" />
|
||||
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<extend-property name="locale" values="de"/>
|
||||
<extend-property name="locale" values="de"/>
|
||||
<extend-property name="locale" values="ru"/>
|
||||
|
||||
<source path='client'/>
|
||||
<source path='controls'/>
|
||||
<source path='components'/>
|
||||
|
||||
+1
@@ -21,6 +21,7 @@
|
||||
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<extend-property name="locale" values="de" />
|
||||
<extend-property name="locale" values="ru"/>
|
||||
|
||||
<source path="client" />
|
||||
<source path="datamining" />
|
||||
|
||||
+4
-1
@@ -29,8 +29,11 @@
|
||||
|
||||
<!-- Specify the app entry point class. -->
|
||||
<entry-point class='com.sap.sailing.gwt.ui.leaderboard.LeaderboardEntryPoint'/>
|
||||
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<extend-property name="locale" values="de"/>
|
||||
<extend-property name="locale" values="de"/>
|
||||
<extend-property name="locale" values="ru"/>
|
||||
|
||||
<source path='client'/>
|
||||
<source path='leaderboard'/>
|
||||
<source path='adminconsole'/>
|
||||
|
||||
+2
@@ -33,6 +33,8 @@
|
||||
<entry-point class='com.sap.sailing.gwt.ui.raceboard.RaceBoardEntryPoint'/>
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<extend-property name="locale" values="de"/>
|
||||
<extend-property name="locale" values="ru"/>
|
||||
|
||||
<source path='client'/>
|
||||
<source path='controls'/>
|
||||
<source path='raceboard'/>
|
||||
|
||||
+2
@@ -42,6 +42,8 @@
|
||||
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<extend-property name="locale" values="de"/>
|
||||
<extend-property name="locale" values="ru"/>
|
||||
|
||||
<source path='client'/>
|
||||
<source path='controls'/>
|
||||
<source path='components'/>
|
||||
|
||||
+2
@@ -31,6 +31,8 @@
|
||||
<entry-point class='com.sap.sailing.gwt.ui.simulator.SimulatorEntryPoint'/>
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<extend-property name="locale" values="de"/>
|
||||
<extend-property name="locale" values="ru"/>
|
||||
|
||||
<source path='shared'/>
|
||||
<source path='client'/>
|
||||
<source path='actions'/>
|
||||
|
||||
+2
@@ -29,6 +29,8 @@
|
||||
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<extend-property name="locale" values="de"/>
|
||||
<extend-property name="locale" values="ru"/>
|
||||
|
||||
<source path='client'/>
|
||||
<source path='shared'/>
|
||||
<source path='spectator'/>
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
<entry-point class='com.sap.sailing.gwt.ui.tv.TVEntryPoint'/>
|
||||
<!-- Specify the paths for translatable code -->
|
||||
<extend-property name="locale" values="de"/>
|
||||
<extend-property name="locale" values="ru"/>
|
||||
|
||||
<source path='client'/>
|
||||
<source path='tv'/>
|
||||
<source path='leaderboard'/>
|
||||
|
||||
+2
@@ -599,8 +599,10 @@ public class RegattasResource extends AbstractSailingServerResource {
|
||||
try {
|
||||
Integer numberOfTacks = trackedLegOfCompetitor.getNumberOfTacks(timePoint);
|
||||
Integer numberOfJibes = trackedLegOfCompetitor.getNumberOfJibes(timePoint);
|
||||
Integer numberOfPenaltyCircles = trackedLegOfCompetitor.getNumberOfPenaltyCircles(timePoint);
|
||||
jsonCompetitorInLeg.put("tacks", numberOfTacks);
|
||||
jsonCompetitorInLeg.put("jibes", numberOfJibes);
|
||||
jsonCompetitorInLeg.put("penaltyCircles", numberOfPenaltyCircles);
|
||||
} catch (NoWindException e) {
|
||||
}
|
||||
|
||||
|
||||
+14
-13
@@ -15,6 +15,7 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -50,7 +51,7 @@ public class RaceTrackerStartStopTest {
|
||||
private RacingEventServiceImplMock racingEventService;
|
||||
private Regatta regatta;
|
||||
private BoatClass boatClass;
|
||||
private Set<RaceTracker> raceTrackerSet = new HashSet<RaceTracker>();
|
||||
private Set<RaceTracker> raceTrackerSet = Collections.newSetFromMap(new ConcurrentHashMap<RaceTracker, Boolean>());
|
||||
|
||||
private RaceDefinition raceDef1;
|
||||
private RaceDefinition raceDef2;
|
||||
@@ -66,10 +67,10 @@ public class RaceTrackerStartStopTest {
|
||||
boatClass = new BoatClassImpl(BOATCLASSNAME, /* typicallyStartsUpwind */ true);
|
||||
regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EVENTNAME, boatClass, /* trackedRegattaRegistry */ null,
|
||||
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), UUID.randomUUID(), null);
|
||||
racingEventService.getEventsByName().put(EVENTNAME, regatta);
|
||||
racingEventService.getRegattasByName().put(EVENTNAME, regatta);
|
||||
TrackedRegatta trackedRegatta1 = racingEventService.getOrCreateTrackedRegatta(regatta);
|
||||
racingEventService.getEventsByNameMap().put(EVENTNAME, regatta);
|
||||
raceTrackerSet = new HashSet<RaceTracker>();
|
||||
racingEventService.getRegattasByName().put(EVENTNAME, regatta);
|
||||
raceTrackerSet = Collections.newSetFromMap(new ConcurrentHashMap<RaceTracker, Boolean>());
|
||||
raceDef1 = new RaceDefinitionImpl(RACENAME1, new CourseImpl("Course1", new ArrayList<Waypoint>()), boatClass, new ArrayList<Competitor>());
|
||||
raceDef2 = new RaceDefinitionImpl(RACENAME2, new CourseImpl("Course2", new ArrayList<Waypoint>()), boatClass, new ArrayList<Competitor>());
|
||||
raceDef3 = new RaceDefinitionImpl(RACENAME3, new CourseImpl("Course3", new ArrayList<Waypoint>()), boatClass, new ArrayList<Competitor>());
|
||||
@@ -100,7 +101,7 @@ public class RaceTrackerStartStopTest {
|
||||
raceTrackerSet.add(raceTracker1);
|
||||
raceTrackerSet.add(raceTracker2);
|
||||
raceTrackerSet.add(raceTracker3);
|
||||
racingEventService.getRaceTrackersByEventMap().put(regatta, raceTrackerSet);
|
||||
racingEventService.getRaceTrackersByRegattaMap().put(regatta, raceTrackerSet);
|
||||
racingEventService.getRaceTrackersByIDMap().put(trackerID1, raceTracker1);
|
||||
racingEventService.getRaceTrackersByIDMap().put(trackerID2, raceTracker2);
|
||||
racingEventService.getRaceTrackersByIDMap().put(trackerID3, raceTracker3);
|
||||
@@ -136,8 +137,8 @@ public class RaceTrackerStartStopTest {
|
||||
assertFalse(racingEventService.getRaceTrackersByIDMap().containsValue(raceTracker3));
|
||||
// The RaceTrakcersByEvent map should contain a tracker with a set of RaceDefinitions, containing the
|
||||
// raceDefinition1
|
||||
assertEquals(1, racingEventService.getRaceTrackersByEventMap().size());
|
||||
Iterator<RaceTracker> raceTrackerIter = racingEventService.getRaceTrackersByEventMap().get(regatta).iterator();
|
||||
assertEquals(1, racingEventService.getRaceTrackersByRegattaMap().size());
|
||||
Iterator<RaceTracker> raceTrackerIter = racingEventService.getRaceTrackersByRegattaMap().get(regatta).iterator();
|
||||
while (raceTrackerIter.hasNext()) {
|
||||
RaceTracker currentTracker = raceTrackerIter.next();
|
||||
assertSame(raceTracker1, currentTracker);
|
||||
@@ -165,9 +166,9 @@ public class RaceTrackerStartStopTest {
|
||||
}
|
||||
assertFalse(foundTrackedRaceForRaceDef2);
|
||||
// The trackers map should still contain the raceTrackers
|
||||
assertTrue(racingEventService.getRaceTrackersByEventMap().get(regatta).contains(raceTracker1));
|
||||
assertTrue(racingEventService.getRaceTrackersByEventMap().get(regatta).contains(raceTracker2));
|
||||
assertTrue(racingEventService.getRaceTrackersByEventMap().get(regatta).contains(raceTracker3));
|
||||
assertTrue(racingEventService.getRaceTrackersByRegattaMap().get(regatta).contains(raceTracker1));
|
||||
assertTrue(racingEventService.getRaceTrackersByRegattaMap().get(regatta).contains(raceTracker2));
|
||||
assertTrue(racingEventService.getRaceTrackersByRegattaMap().get(regatta).contains(raceTracker3));
|
||||
// The raceTrackerMap should still contain the raceTrackers. These raceTracker should not contain the raceDefinition raceDef2 anymore
|
||||
assertTrue(racingEventService.getRaceTrackersByIDMap().containsValue(raceTracker1));
|
||||
assertTrue(racingEventService.getRaceTrackersByIDMap().containsValue(raceTracker2));
|
||||
@@ -193,9 +194,9 @@ public class RaceTrackerStartStopTest {
|
||||
racingEventService.removeRace(regatta, raceDef1);
|
||||
racingEventService.removeRace(regatta, raceDef2);
|
||||
// The event map should still contain the raceTrackers except of raceTracker1 and raceTracker2
|
||||
assertFalse(racingEventService.getRaceTrackersByEventMap().get(regatta).contains(raceTracker1));
|
||||
assertFalse(racingEventService.getRaceTrackersByEventMap().get(regatta).contains(raceTracker2));
|
||||
assertTrue(racingEventService.getRaceTrackersByEventMap().get(regatta).contains(raceTracker3));
|
||||
assertFalse(racingEventService.getRaceTrackersByRegattaMap().get(regatta).contains(raceTracker1));
|
||||
assertFalse(racingEventService.getRaceTrackersByRegattaMap().get(regatta).contains(raceTracker2));
|
||||
assertTrue(racingEventService.getRaceTrackersByRegattaMap().get(regatta).contains(raceTracker3));
|
||||
// The RaceTrackerByID map should still contain raceTracker3, but not raceTracker1 and raceTracker2 anymore
|
||||
assertFalse(racingEventService.getRaceTrackersByIDMap().containsValue(raceTracker1));
|
||||
assertFalse(racingEventService.getRaceTrackersByIDMap().containsValue(raceTracker2));
|
||||
|
||||
+2
-6
@@ -22,11 +22,7 @@ public class RacingEventServiceImplMock extends RacingEventServiceImpl {
|
||||
lock.addProgress(dataImportProgressImpl.getOperationId(), dataImportProgressImpl);
|
||||
}
|
||||
|
||||
public Map<String, Regatta> getEventsByNameMap() {
|
||||
return regattasByName;
|
||||
}
|
||||
|
||||
public Map<Regatta, Set<RaceTracker>> getRaceTrackersByEventMap() {
|
||||
public Map<Regatta, Set<RaceTracker>> getRaceTrackersByRegattaMap() {
|
||||
return raceTrackersByRegatta;
|
||||
}
|
||||
|
||||
@@ -34,7 +30,7 @@ public class RacingEventServiceImplMock extends RacingEventServiceImpl {
|
||||
return raceTrackersByID;
|
||||
}
|
||||
|
||||
public Map<String, Regatta> getEventsByName() {
|
||||
public Map<String, Regatta> getRegattasByName() {
|
||||
return regattasByName;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,6 @@
|
||||
<booleanAttribute key="tracing" value="false"/>
|
||||
<booleanAttribute key="useCustomFeatures" value="false"/>
|
||||
<booleanAttribute key="useDefaultConfigArea" value="false"/>
|
||||
<stringAttribute key="workspace_bundles" value="com.google.gwt.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:true,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@5:true,com.sap.sailing.domain.swisstimingreplayadapter@5:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@5:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@default:default,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.operationaltransformation@default:default,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@default:default,com.sap.sailing.server.gateway.serialization@default:default,com.sap.sailing.server.gateway@default:default,com.sap.sailing.server.replication@default:default,com.sap.sailing.server.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@default:default,com.sap.sailing.www@default:default,com.sap.sailing.xmlexport@default:default,com.sap.sailing.xrr.resultimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.gwt@default:default,com.tractrac.clientmodule@default:default,org.json.simple@default:default,org.moxieapps.gwt.highcharts@default:default"/>
|
||||
<stringAttribute key="workspace_bundles" value="com.google.gwt.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:true,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@5:true,com.sap.sailing.domain.swisstimingreplayadapter@5:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@5:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@default:default,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.operationaltransformation@default:default,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@default:default,com.sap.sailing.server.gateway.serialization@default:default,com.sap.sailing.server.gateway@default:default,com.sap.sailing.server.replication@default:default,com.sap.sailing.server.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@default:default,com.sap.sailing.www@default:default,com.sap.sailing.xmlexport@default:default,com.sap.sailing.xrr.resultimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.gwt@default:default,com.tractrac.clientmodule@default:default,net.sf.marineapi@default:default,org.json.simple@default:default,org.moxieapps.gwt.highcharts@default:default"/>
|
||||
<stringAttribute key="yk-options" value=" additional-options2=onexit\=snapshot "/>
|
||||
</launchConfiguration>
|
||||
@@ -26,6 +26,6 @@
|
||||
<booleanAttribute key="tracing" value="false"/>
|
||||
<booleanAttribute key="useCustomFeatures" value="false"/>
|
||||
<booleanAttribute key="useDefaultConfigArea" value="false"/>
|
||||
<stringAttribute key="workspace_bundles" value="com.google.gwt.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:true,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@5:true,com.sap.sailing.domain.swisstimingreplayadapter@5:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@5:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@default:default,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.operationaltransformation@default:default,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@default:default,com.sap.sailing.server.gateway.serialization@default:default,com.sap.sailing.server.gateway@default:default,com.sap.sailing.server.replication@default:default,com.sap.sailing.server.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@default:default,com.sap.sailing.www@default:default,com.sap.sailing.xrr.resultimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.gwt@default:default,com.tractrac.clientmodule@default:default,org.json.simple@default:default,org.moxieapps.gwt.highcharts@default:default"/>
|
||||
<stringAttribute key="workspace_bundles" value="com.google.gwt.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.mongodb.driver@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:true,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@5:true,com.sap.sailing.domain.swisstimingreplayadapter@5:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@5:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@default:default,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.mongodb@default:default,com.sap.sailing.operationaltransformation@default:default,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@default:default,com.sap.sailing.server.gateway.serialization@default:default,com.sap.sailing.server.gateway@default:default,com.sap.sailing.server.replication@default:default,com.sap.sailing.server.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@default:default,com.sap.sailing.www@default:default,com.sap.sailing.xrr.resultimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.gwt@default:default,com.tractrac.clientmodule@default:default,net.sf.marineapi@default:default,org.json.simple@default:default,org.moxieapps.gwt.highcharts@default:default"/>
|
||||
<stringAttribute key="yk-options" value=" additional-options2=onexit\=snapshot "/>
|
||||
</launchConfiguration>
|
||||
@@ -269,6 +269,9 @@ class MediaLibrary {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a non-live copy of the media tracks
|
||||
*/
|
||||
Collection<MediaTrack> allTracks() {
|
||||
readLock.lock();
|
||||
try {
|
||||
|
||||
+392
-275
File diff suppressed because it is too large.
Load diff
@@ -1,5 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh
|
||||
target="`dirname \"$0\"`"
|
||||
pwd=`pwd`
|
||||
echo "$target" | grep "^/"
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh
|
||||
target="`dirname \"$0\"`"
|
||||
pwd=`pwd`
|
||||
echo "$target" | grep "^/"
|
||||
if [ "$0" != "0" ]; then
|
||||
# no leading slash, therefore no absolute path; prepend pwd
|
||||
target="$pwd/$target"
|
||||
fi
|
||||
target=c:/data/SAP/sailing/workspace/java/target
|
||||
echo target is $target
|
||||
cd "$target/../com.sap.sailing.feature.p2build/bin/products/raceanalysis.product.id/win32/win32/x86_64"
|
||||
echo pwd is now `pwd`
|
||||
classpath="`find plugins -name 'com.sap.sailing.expeditionconnector_*.jar' | sort | tail -1`;`find plugins -name 'com.sap.sailing.domain.common_*.jar' | sort | tail -1`"
|
||||
echo Using classpath $classpath
|
||||
"$JAVA_HOME/bin/java" -cp "$classpath" -Djava.util.logging.config.file=$target/configuration/logging.properties com.sap.sailing.expeditionconnector.FromHttpToUdpMirror $*
|
||||
#!/bin/sh
|
||||
target="`dirname \"$0\"`"
|
||||
pwd=`pwd`
|
||||
echo "$target" | grep "^/"
|
||||
if [ "$0" != "0" ]; then
|
||||
# no leading slash, therefore no absolute path; prepend pwd
|
||||
target="$pwd/$target"
|
||||
fi
|
||||
target=c:/data/SAP/sailing/workspace/java/target
|
||||
echo target is $target
|
||||
cd "$target/../com.sap.sailing.feature.p2build/bin/products/raceanalysis.product.id/win32/win32/x86_64"
|
||||
echo pwd is now `pwd`
|
||||
classpath="`find plugins -name 'com.sap.sailing.expeditionconnector_*.jar' | sort | tail -1`;`find plugins -name 'com.sap.sailing.domain.common_*.jar' | sort | tail -1`"
|
||||
echo Using classpath $classpath
|
||||
"$JAVA_HOME/bin/java" -cp "$classpath" -Djava.util.logging.config.file=$target/configuration/logging.properties com.sap.sailing.expeditionconnector.FromHttpToUdpMirror $*
|
||||
Reference in new issue
Block a user