diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CourseMarkOverlay.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CourseMarkOverlay.java index a0a973708a5..8645ad390d9 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CourseMarkOverlay.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CourseMarkOverlay.java @@ -9,13 +9,16 @@ 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.google.gwt.maps.client.base.Size; +import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.MarkType; import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.impl.MeterDistance; +import com.sap.sailing.gwt.ui.shared.CoursePositionsDTO; import com.sap.sailing.gwt.ui.shared.MarkDTO; import com.sap.sailing.gwt.ui.shared.racemap.CanvasOverlayV3; import com.sap.sailing.gwt.ui.shared.racemap.MarkVectorGraphics; +import com.sap.sailing.gwt.ui.shared.racemap.MarkVectorGraphicsFactory; import com.sap.sse.common.Util; /** @@ -26,6 +29,8 @@ public class CourseMarkOverlay extends CanvasOverlayV3 { * The course mark to draw */ private final MarkDTO mark; + + private CoursePositionsDTO coursePositionsDTO; private Position position; @@ -45,18 +50,22 @@ public class CourseMarkOverlay extends CanvasOverlayV3 { private Boolean lastShowBuoyZone; private Boolean lastIsSelected; private Distance lastBuoyZoneRadius; + + private MarkVectorGraphicsFactory markVectorGraphicsFactory; - public CourseMarkOverlay(MapWidget map, int zIndex, MarkDTO markDTO, CoordinateSystem coordinateSystem) { + public CourseMarkOverlay(MapWidget map, int zIndex, MarkDTO markDTO, CoordinateSystem coordinateSystem, CoursePositionsDTO coursePositionsDTO) { super(map, zIndex, coordinateSystem); this.mark = markDTO; + this.coursePositionsDTO = coursePositionsDTO; this.position = markDTO.position; this.buoyZoneRadius = new MeterDistance(0.0); this.showBuoyZone = false; - markVectorGraphics = new MarkVectorGraphics(markDTO.type, markDTO.color, markDTO.shape, markDTO.pattern); - markScaleAndSizePerZoomCache = new HashMap>(); + this.markScaleAndSizePerZoomCache = new HashMap>(); + this.markVectorGraphicsFactory = new MarkVectorGraphicsFactory(); + this.markVectorGraphics = markVectorGraphicsFactory.getMarkVectorGraphics(markDTO); setCanvasSize(50, 50); } - + @Override protected void draw() { if (mapProjection != null && mark != null && position != null) { @@ -104,6 +113,10 @@ public class CourseMarkOverlay extends CanvasOverlayV3 { lastWidth = canvasWidth; lastHeight = canvasHeight; } + final Bearing rotation = markVectorGraphics.getRotationInDegrees(coursePositionsDTO); + if (rotation != null) { + setCanvasRotation(rotation.getDegrees()); + } Point buoyPositionInPx = mapProjection.fromLatLngToDivPixel(coordinateSystem.toLatLng(position)); if (showBuoyZone && isMarkWithBuoyZone(mark) && buoyZoneRadiusInPixel > MIN_BUOYZONE_RADIUS_IN_PX) { setCanvasPosition(buoyPositionInPx.getX() - buoyZoneRadiusInPixel, buoyPositionInPx.getY() - buoyZoneRadiusInPixel); @@ -112,7 +125,7 @@ public class CourseMarkOverlay extends CanvasOverlayV3 { } } } - + private boolean isMarkWithBuoyZone(MarkDTO mark) { return mark.type == null || mark.type == MarkType.BUOY || mark.type == MarkType.STARTBOAT || mark.type == MarkType.FINISHBOAT || mark.type == MarkType.LANDMARK; @@ -159,6 +172,10 @@ public class CourseMarkOverlay extends CanvasOverlayV3 { public void setShowBuoyZone(boolean showBuoyZone) { this.showBuoyZone = showBuoyZone; } + + public void setCourse(CoursePositionsDTO coursePositionsDTO) { + this.coursePositionsDTO = coursePositionsDTO; + } public MarkDTO getMark() { return mark; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java index cf0841873e9..4b48619d7c3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java @@ -1125,7 +1125,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe } CourseMarkOverlay courseMarkOverlay = courseMarkOverlays.get(markDTO.getName()); if (courseMarkOverlay == null) { - courseMarkOverlay = new CourseMarkOverlay(map, RaceMapOverlaysZIndexes.COURSEMARK_ZINDEX, markDTO, coordinateSystem); + courseMarkOverlay = new CourseMarkOverlay(map, RaceMapOverlaysZIndexes.COURSEMARK_ZINDEX, markDTO, coordinateSystem, courseDTO); courseMarkOverlay.setShowBuoyZone(settings.getHelpLinesSettings().isVisible(HelpLineTypes.BUOYZONE)); courseMarkOverlay.setBuoyZoneRadius(settings.getBuoyZoneRadius()); courseMarkOverlay.setSelected(isSelected); @@ -1138,6 +1138,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe courseMarkOverlay.setShowBuoyZone(settings.getHelpLinesSettings().isVisible(HelpLineTypes.BUOYZONE)); courseMarkOverlay.setBuoyZoneRadius(settings.getBuoyZoneRadius()); courseMarkOverlay.setSelected(isSelected); + courseMarkOverlay.setCourse(courseDTO); courseMarkOverlay.draw(); toRemoveCourseMarks.remove(markDTO.getName()); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/AbstractMarkVectorGraphics.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/AbstractMarkVectorGraphics.java new file mode 100644 index 00000000000..c2fb3578a39 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/AbstractMarkVectorGraphics.java @@ -0,0 +1,199 @@ +package com.sap.sailing.gwt.ui.shared.racemap; + +import com.google.gwt.canvas.dom.client.CanvasGradient; +import com.google.gwt.canvas.dom.client.Context2d; +import com.sap.sailing.domain.common.Bearing; +import com.sap.sailing.domain.common.Distance; +import com.sap.sailing.domain.common.MarkType; +import com.sap.sailing.domain.common.impl.MeterDistance; +import com.sap.sailing.gwt.ui.shared.CoursePositionsDTO; + +/** + * A class for course mark graphics based on SVG graphics drawn to a HTML5 canvas + * The SVG files for the drawing can be found in the package com.sap.sailing.gwt.ui.svg.buoys + * A general description how to convert SVG files to 'drawing commands' can be found at http://wiki.sapsailing.com/wiki/howto/development/boatgraphicssvg + * @author Frank + * + */ +public abstract class AbstractMarkVectorGraphics implements MarkVectorGraphics { + protected Distance markHeightInMeters; + protected Distance markWidthInMeters; + + protected final String color; + protected final String shape; + protected final String pattern; + protected final MarkType type; + + protected static final double doublePi = 2 * Math.PI; + + protected double anchorPointX = 0.44; + protected double anchorPointY = 1.67; + + protected final static String DEFAULT_MARK_COLOR = "#f9ac00"; + protected final static String DEFAULT_MARK_BG_COLOR = "#f0f0f0"; + + public AbstractMarkVectorGraphics(MarkType type, String color, String shape, String pattern) { + this.type = type; + this.color = color; + this.shape = shape; + this.pattern = pattern; + this.markHeightInMeters = new MeterDistance(2.1); + this.markWidthInMeters = new MeterDistance(1.5); + } + + public void drawMarkToCanvas(Context2d ctx, boolean isSelected, double width, double height, double scaleFactor) { + ctx.save(); + ctx.clearRect(0, 0, width, height); + ctx.translate(width / 2.0, height / 2.0); + ctx.scale(scaleFactor, scaleFactor); + ctx.translate(-anchorPointX * 100,- anchorPointY * 100); + String markColor = color != null ? color : DEFAULT_MARK_COLOR; + drawMark(ctx, isSelected, markColor); + ctx.restore(); + } + + public Distance getMarkHeight() { + return markHeightInMeters; + } + + public Distance getMarkWidth() { + return markWidthInMeters; + } + + protected void drawMark(Context2d ctx, boolean isSelected, String color) { + if (isSelected) { + drawMarkSelection(ctx); + } + this.drawMarkBody(ctx, isSelected, color); + } + + protected void drawMarkSelection(Context2d ctx) { + ctx.save(); + + this.setUpScaleAndTranslateForMarkSelection(ctx); + + CanvasGradient g1 = ctx.createLinearGradient(77.8, 188, 165, 219); + g1.addColorStop(0, "rgba(240, 240, 240, 1)"); + g1.addColorStop(1, "rgba(240, 240, 240, 0)"); + ctx.setFillStyle(g1); + ctx.beginPath(); + ctx.moveTo(170, 181); + ctx.translate(44.000168893718424, 180.79369636814624); + ctx.rotate(0); + ctx.scale(1, 1); + ctx.arc(0, 0, 126, 0.0016373311430805408, 0.5254904360229328, false); + ctx.scale(1, 1); + ctx.rotate(0); + ctx.translate(-44.000168893718424, -180.79369636814624); + ctx.lineTo(44.2, 181); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + + CanvasGradient g2 = ctx.createLinearGradient(51, 203, 77.3, 302); + g2.addColorStop(0, "rgba(255, 255, 255, 1)"); + g2.addColorStop(1, "rgba(255, 255, 255, 0)"); + ctx.setFillStyle(g2); + ctx.beginPath(); + ctx.moveTo(107, 290); + ctx.translate(43.79222318749837, 181.0010231680087); + ctx.rotate(0); + ctx.scale(1, 1); + ctx.arc(0, 0, 126, 1.0452923752792398, 1.5667663411841573, false); + ctx.scale(1, 1); + ctx.rotate(0); + ctx.translate(-43.79222318749837, -181.0010231680087); + ctx.lineTo(44.2, 181); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + + CanvasGradient g3 = ctx.createLinearGradient(26.8, 197, -46.5, 269); + g3.addColorStop(0, "rgba(255, 255, 255, 1)"); + g3.addColorStop(1, "rgba(255, 255, 255, 0)"); + ctx.setFillStyle(g3); + ctx.beginPath(); + ctx.moveTo(-18.3, 290); + ctx.translate(43.72636289026038, 180.32443158749652); + ctx.rotate(0); + ctx.scale(1, 1); + ctx.arc(0, 0, 126, 2.0854951576078884, 2.611791628699119, false); + ctx.scale(1, 1); + ctx.rotate(0); + ctx.translate(-43.72636289026038, -180.32443158749652); + ctx.lineTo(44.2, 181); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + + CanvasGradient g4 = ctx.createLinearGradient(18.7, 172, -76.3, 140); + g4.addColorStop(0, "rgba(255, 255, 255, 1)"); + g4.addColorStop(1, "rgba(255, 255, 255, 0)"); + ctx.setFillStyle(g4); + ctx.beginPath(); + ctx.moveTo(-81.8, 179); + ctx.translate(44.19920011832349, 178.55103503179944); + ctx.rotate(0); + ctx.scale(1, 1); + ctx.arc(0, 0, 126, 3.1380294320163484, 3.670248678643417, false); + ctx.scale(1, 1); + ctx.rotate(0); + ctx.translate(-44.19920011832349, -178.55103503179944); + ctx.lineTo(44.2, 179); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + + CanvasGradient g5 = ctx.createLinearGradient(37.9, 147, 13.6, 58.6); + g5.addColorStop(0, "rgba(255, 255, 255, 1)"); + g5.addColorStop(1, "rgba(255, 255, 255, 0)"); + ctx.setFillStyle(g5); + ctx.beginPath(); + ctx.moveTo(-18.7, 71.8); + ctx.translate(44.160311222571984, 180.99973110315514); + ctx.rotate(0); + ctx.scale(1, 1); + ctx.arc(0, 0, 126, -2.0931154263055687, -1.5728622903484606, false); + ctx.scale(1, 1); + ctx.rotate(0); + ctx.translate(-44.160311222571984, -180.99973110315514); + ctx.lineTo(44.199999999999996, 181); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + + CanvasGradient g6 = ctx.createLinearGradient(80.8, 139, 134, 91.9); + g6.addColorStop(0, "rgba(240, 240, 240, 1)"); + g6.addColorStop(1, "rgba(240, 240, 240, 0)"); + ctx.setFillStyle(g6); + ctx.beginPath(); + ctx.moveTo(108, 72.1); + ctx.translate(43.50304481630927, 180.3411325330301); + ctx.rotate(0); + ctx.scale(1, 1); + ctx.arc(0, 0, 126, -1.0334238189446499, -0.5175711746742696, false); + ctx.scale(1, 1); + ctx.rotate(0); + ctx.translate(-43.50304481630927, -180.3411325330301); + ctx.lineTo(44.2, 181); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + + ctx.translate(-49.5, 17.2); + ctx.restore(); + } + + protected void setUpScaleAndTranslateForMarkSelection(Context2d ctx) { + ctx.scale(1.2,1.2); + ctx.translate(-10,-30); + } + + protected abstract void drawMarkBody(Context2d ctx, boolean isSelected, String color); + + @Override + public Bearing getRotationInDegrees(CoursePositionsDTO coursePositionsDTO) { + // by default, no rotation for marks + return null; + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/BoatMarkVectorGraphics.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/BoatMarkVectorGraphics.java new file mode 100644 index 00000000000..9668f195925 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/BoatMarkVectorGraphics.java @@ -0,0 +1,136 @@ +package com.sap.sailing.gwt.ui.shared.racemap; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.google.gwt.canvas.dom.client.Context2d; +import com.sap.sailing.domain.common.Bearing; +import com.sap.sailing.domain.common.Distance; +import com.sap.sailing.domain.common.MarkType; +import com.sap.sailing.domain.common.PassingInstruction; +import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.impl.MeterDistance; +import com.sap.sailing.gwt.ui.shared.CoursePositionsDTO; +import com.sap.sailing.gwt.ui.shared.MarkDTO; +import com.sap.sailing.gwt.ui.shared.WaypointDTO; + +public class BoatMarkVectorGraphics extends AbstractMarkVectorGraphics { + + private final static Distance BOAT_MARK_HEIGHT_IN_METERS = new MeterDistance(6.2); + private final static Distance BOAT_MARK_WIDTH_IN_METERS = new MeterDistance(3.5); + private final static double BOAT_MARK_SELECTION_SCALE = 3.5; + private final static double BOAT_MARK_SELECTION_TRANSLATE_X = -10; + private final static double BOAT_MARK_SELECTION_TRANSLATE_Y = -30; + private final String markIdAsString; + + public BoatMarkVectorGraphics(MarkType type, String color, String shape, String pattern, String markIdAsString) { + super(type, color, shape, pattern); + this.anchorPointX = BOAT_MARK_HEIGHT_IN_METERS.getMeters() / 2; + this.anchorPointY = BOAT_MARK_WIDTH_IN_METERS.getMeters() / 2; + this.markHeightInMeters = BOAT_MARK_HEIGHT_IN_METERS; + this.markWidthInMeters = BOAT_MARK_WIDTH_IN_METERS; + this.markIdAsString = markIdAsString; + } + + protected void setUpScaleAndTranslateForMarkSelection(Context2d ctx) { + ctx.scale(BOAT_MARK_SELECTION_SCALE, BOAT_MARK_SELECTION_SCALE); + ctx.translate(BOAT_MARK_SELECTION_TRANSLATE_X, BOAT_MARK_SELECTION_TRANSLATE_Y); + } + + @Override + protected void drawMarkBody(Context2d ctx, boolean isSelected, String color) { + ctx.beginPath(); + ctx.setFillStyle("#000000"); + ctx.setStrokeStyle("#FFFFFF"); + ctx.setLineWidth(30.0); + ctx.setLineCap("butt"); + ctx.setLineJoin("miter"); + ctx.setMiterLimit(3.0); + ctx.moveTo(33, 30.36); + ctx.quadraticCurveTo(103.47, 18.96, 194.65, 18.55); + ctx.quadraticCurveTo(285.83, 18.13, 370.62, 34.74); + ctx.quadraticCurveTo(455.42, 51.34, 520.29, 87.99); + ctx.quadraticCurveTo(585.16, 124.64, 603, 187.36); + ctx.quadraticCurveTo(584.67, 244.84, 520.84, 277.54); + ctx.quadraticCurveTo(457, 310.24, 372.97, 324.79); + ctx.quadraticCurveTo(288.94, 339.34, 197.37, 339.08); + ctx.quadraticCurveTo(105.8, 338.81, 32, 330.36); + ctx.lineTo(33, 30.362205); + ctx.fill(); + ctx.stroke(); + + ctx.setFillStyle("#FFFFFF"); + ctx.beginPath(); + ctx.beginPath(); + ctx.setLineWidth(1.0); + ctx.setLineJoin("miter"); + ctx.setMiterLimit(4.0); + ctx.moveTo(81, 78); + ctx.lineTo(349, 78); + ctx.lineTo(349, 291); + ctx.lineTo(81, 291); + ctx.lineTo(81, 78); + ctx.fill(); + ctx.stroke(); + + ctx.setFillStyle("#000000"); + ctx.beginPath(); + ctx.moveTo(337, 186.36); + ctx.quadraticCurveTo(337, 180.56, 334.76, 175.46); + ctx.quadraticCurveTo(332.52, 170.36, 328.65, 166.56); + ctx.quadraticCurveTo(324.78, 162.76, 319.59, 160.56); + ctx.quadraticCurveTo(314.4, 158.36, 308.5, 158.36); + ctx.quadraticCurveTo(302.6, 158.36, 297.41, 160.56); + ctx.quadraticCurveTo(292.22, 162.76, 288.35, 166.56); + ctx.quadraticCurveTo(284.48, 170.36, 282.24, 175.46); + ctx.quadraticCurveTo(280, 180.56, 280, 186.36); + ctx.quadraticCurveTo(280, 192.16, 282.24, 197.26); + ctx.quadraticCurveTo(284.48, 202.36, 288.35, 206.16); + ctx.quadraticCurveTo(292.22, 209.96, 297.41, 212.16); + ctx.quadraticCurveTo(302.6, 214.36, 308.5, 214.36); + ctx.quadraticCurveTo(314.4, 214.36, 319.59, 212.16); + ctx.quadraticCurveTo(324.78, 209.96, 328.65, 206.16); + ctx.quadraticCurveTo(332.52, 202.36, 334.76, 197.26); + ctx.quadraticCurveTo(337, 192.16, 337, 186.36); + ctx.stroke(); + ctx.fill(); + ctx.beginPath(); + } + + @Override + public Bearing getRotationInDegrees(CoursePositionsDTO coursePositionsDTO) { + List lineMarkPositions = new ArrayList(); + MarkDTO firstMark = null; + MarkDTO secondMark = null; + for (WaypointDTO currentWaypoint : coursePositionsDTO.course.waypoints) { + if (currentWaypoint.passingInstructions == PassingInstruction.Line) { + Iterator marks = currentWaypoint.controlPoint.getMarks().iterator(); + firstMark = marks.next(); + if (marks.hasNext()) { + secondMark = marks.next(); + if (markIdAsString.equals(firstMark.getIdAsString()) + || markIdAsString.equals(secondMark.getIdAsString())) { + lineMarkPositions.add(firstMark.position); + lineMarkPositions.add(secondMark.position); + break; + } + } + } + } + return getLineBearing(lineMarkPositions); + } + + private Bearing getLineBearing(List markPositions) { + Bearing result = null; + if (markPositions.size() > 1) { + Position firstPosition = markPositions.get(0); + Position secondPosition = markPositions.get(1); + if (firstPosition != null) { + result = firstPosition.getBearingGreatCircle(secondPosition); + } + } + return result; + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/ConicalBuoyMarkVectorGraphics.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/ConicalBuoyMarkVectorGraphics.java new file mode 100644 index 00000000000..7f7ec139df5 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/ConicalBuoyMarkVectorGraphics.java @@ -0,0 +1,85 @@ +package com.sap.sailing.gwt.ui.shared.racemap; + +import com.google.gwt.canvas.dom.client.Context2d; +import com.sap.sailing.domain.common.MarkType; + +public class ConicalBuoyMarkVectorGraphics extends AbstractMarkVectorGraphics implements MarkVectorGraphics { + + public ConicalBuoyMarkVectorGraphics(MarkType type, String color, String shape, String pattern) { + super(type, color, shape, pattern); + } + + @Override + protected void drawMarkBody(Context2d ctx, boolean isSelected, String color) { + ctx.setStrokeStyle("rgba(0,0,0,0)"); + + ctx.save(); + ctx.setFillStyle(color); + ctx.transform(12.5, 0, 0, 12.5, -578, 22.2); + ctx.beginPath(); + ctx.arc(49.7, 12.8, 2.66, 0, doublePi, false); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.transform(12.5, 0, 0, 12.5, -578, 22.2); + ctx.beginPath(); + ctx.arc(49.7, 11.3, 3.37, 0, doublePi, false); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(color); + ctx.transform(12.5, 0, 0, 12.5, -578, 22.2); + ctx.beginPath(); + ctx.arc(49.6, 10.6, 2.66, 0, doublePi, false); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.beginPath(); + ctx.moveTo(36.9, 98); + ctx.lineTo(47.5, 98); + ctx.quadraticCurveTo(47.5, 98, 47.5, 98); + ctx.lineTo(47.5, 154.5); + ctx.quadraticCurveTo(47.5, 154.5, 47.5, 154.5); + ctx.lineTo(36.9, 154.5); + ctx.quadraticCurveTo(36.9, 154.5, 36.9, 154.5); + ctx.lineTo(36.9, 98); + ctx.quadraticCurveTo(36.9, 98, 36.9, 98); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.beginPath(); + ctx.moveTo(43.6, 0.372); + ctx.lineTo(87.3, 102); + ctx.lineTo(-0.714, 102); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(color); + ctx.beginPath(); + ctx.moveTo(43.6, 14.7); + ctx.lineTo(78.5, 96.6); + ctx.lineTo(8.07, 96.6); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/FinishFlagMarkVectorGraphics.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/FinishFlagMarkVectorGraphics.java new file mode 100644 index 00000000000..774167d58fc --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/FinishFlagMarkVectorGraphics.java @@ -0,0 +1,180 @@ +package com.sap.sailing.gwt.ui.shared.racemap; + +import com.google.gwt.canvas.dom.client.Context2d; +import com.sap.sailing.domain.common.MarkType; + +public class FinishFlagMarkVectorGraphics extends AbstractMarkVectorGraphics implements MarkVectorGraphics { + + public FinishFlagMarkVectorGraphics(MarkType type, String color, String shape, String pattern) { + super(type, color, shape, pattern); + } + + @Override + protected void drawMarkBody(Context2d ctx, boolean isSelected, String color) { + ctx.setStrokeStyle("rgba(0,0,0,0)"); + + ctx.save(); + ctx.setFillStyle(color); + ctx.transform(12.5, 0, 0, 12.5, -578, 22.2); + ctx.beginPath(); + ctx.arc(49.7, 12.8, 2.66, 0, doublePi, false); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.transform(12.5, 0, 0, 12.5, -578, 22.2); + ctx.beginPath(); + ctx.arc(49.7, 11.3, 3.37, 0, doublePi, false); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(color); + ctx.transform(12.5, 0, 0, 12.5, -578, 22.2); + ctx.beginPath(); + ctx.arc(49.6, 10.6, 2.66, 0, doublePi, false); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.transform(4.98, 0, 0, 10.8, -205, 50.4); + ctx.beginPath(); + ctx.moveTo(50.8, 9.84); + ctx.lineTo(48.5, 9.84); + ctx.lineTo(48.5, 1.44); + ctx.lineTo(50.8, 1.9); + ctx.lineTo(50.8, 9.84); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.beginPath(); + ctx.moveTo(36.9, -0.5); + ctx.lineTo(141.9, -0.5); + ctx.quadraticCurveTo(141.9, -0.5, 141.9, -0.5); + ctx.lineTo(141.9, 71.2); + ctx.quadraticCurveTo(141.9, 71.2, 141.9, 71.2); + ctx.lineTo(36.9, 71.2); + ctx.quadraticCurveTo(36.9, 71.2, 36.9, 71.2); + ctx.lineTo(36.9, -0.5); + ctx.quadraticCurveTo(36.9, -0.5, 36.9, -0.5); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(color); + ctx.beginPath(); + ctx.moveTo(46, 4.04); + ctx.lineTo(76.3, 4.04); + ctx.quadraticCurveTo(76.3, 4.04, 76.3, 4.04); + ctx.lineTo(76.3, 34.34); + ctx.quadraticCurveTo(76.3, 34.34, 76.3, 34.34); + ctx.lineTo(46, 34.34); + ctx.quadraticCurveTo(46, 34.34, 46, 34.34); + ctx.lineTo(46, 4.04); + ctx.quadraticCurveTo(46, 4.04, 46, 4.04); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.beginPath(); + ctx.moveTo(46.1, 34.3); + ctx.lineTo(76.4, 34.3); + ctx.quadraticCurveTo(76.4, 34.3, 76.4, 34.3); + ctx.lineTo(76.4, 64.6); + ctx.quadraticCurveTo(76.4, 64.6, 76.4, 64.6); + ctx.lineTo(46.1, 64.6); + ctx.quadraticCurveTo(46.1, 64.6, 46.1, 64.6); + ctx.lineTo(46.1, 34.3); + ctx.quadraticCurveTo(46.1, 34.3, 46.1, 34.3); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.beginPath(); + ctx.moveTo(76, 3.95); + ctx.lineTo(106.3, 3.95); + ctx.quadraticCurveTo(106.3, 3.95, 106.3, 3.95); + ctx.lineTo(106.3, 34.25); + ctx.quadraticCurveTo(106.3, 34.25, 106.3, 34.25); + ctx.lineTo(76, 34.25); + ctx.quadraticCurveTo(76, 34.25, 76, 34.25); + ctx.lineTo(76, 3.95); + ctx.quadraticCurveTo(76, 3.95, 76, 3.95); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(color); + ctx.beginPath(); + ctx.moveTo(76.1, 34.2); + ctx.lineTo(106.4, 34.2); + ctx.quadraticCurveTo(106.4, 34.2, 106.4, 34.2); + ctx.lineTo(106.4, 64.5); + ctx.quadraticCurveTo(106.4, 64.5, 106.4, 64.5); + ctx.lineTo(76.1, 64.5); + ctx.quadraticCurveTo(76.1, 64.5, 76.1, 64.5); + ctx.lineTo(76.1, 34.2); + ctx.quadraticCurveTo(76.1, 34.2, 76.1, 34.2); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(color); + ctx.beginPath(); + ctx.moveTo(106, 3.96); + ctx.lineTo(136.3, 3.96); + ctx.quadraticCurveTo(136.3, 3.96, 136.3, 3.96); + ctx.lineTo(136.3, 34.26); + ctx.quadraticCurveTo(136.3, 34.26, 136.3, 34.26); + ctx.lineTo(106, 34.26); + ctx.quadraticCurveTo(106, 34.26, 106, 34.26); + ctx.lineTo(106, 3.96); + ctx.quadraticCurveTo(106, 3.96, 106, 3.96); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.beginPath(); + ctx.moveTo(106, 34.3); + ctx.lineTo(136.3, 34.3); + ctx.quadraticCurveTo(136.3, 34.3, 136.3, 34.3); + ctx.lineTo(136.3, 64.6); + ctx.quadraticCurveTo(136.3, 64.6, 136.3, 64.6); + ctx.lineTo(106, 64.6); + ctx.quadraticCurveTo(106, 64.6, 106, 64.6); + ctx.lineTo(106, 34.3); + ctx.quadraticCurveTo(106, 34.3, 106, 34.3); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + ctx.restore(); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/LandMarkVectorGraphics.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/LandMarkVectorGraphics.java new file mode 100644 index 00000000000..dd604da5644 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/LandMarkVectorGraphics.java @@ -0,0 +1,77 @@ +package com.sap.sailing.gwt.ui.shared.racemap; + +import com.google.gwt.canvas.dom.client.Context2d; +import com.sap.sailing.domain.common.MarkType; + +public class LandMarkVectorGraphics extends AbstractMarkVectorGraphics implements MarkVectorGraphics { + + public LandMarkVectorGraphics(MarkType type, String color, String shape, String pattern) { + super(type, color, shape, pattern); + } + + @Override + protected void drawMarkBody(Context2d ctx, boolean isSelected, String color) { + ctx.setStrokeStyle("rgba(0,0,0,0)"); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.transform(4.98, 0, 0, 10.8, -205, 50.4); + ctx.beginPath(); + ctx.moveTo(50.8, 9.84); + ctx.lineTo(48.5, 9.84); + ctx.lineTo(48.5, 1.44); + ctx.lineTo(50.8, 1.9); + ctx.lineTo(50.8, 9.84); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.transform(12.5, 0, 0, 12.5, -570, 22.2); + ctx.save(); + ctx.setFillStyle(color); + ctx.beginPath(); + ctx.moveTo(48.8, 3.82); + ctx.lineTo(48.8, -1.32); + ctx.lineTo(57, 1.05); + ctx.lineTo(48.8, 3.82); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.beginPath(); + ctx.moveTo(48.5, 4.16); + ctx.lineTo(48.5, -1.65); + ctx.lineTo(57.8, 1.03); + ctx.lineTo(48.5, 4.16); + ctx.closePath(); + ctx.moveTo(49, -0.994); + ctx.lineTo(49, 3.47); + ctx.lineTo(56.2, 1.07); + ctx.lineTo(49, -0.994); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(color); + ctx.beginPath(); + ctx.moveTo(83.9, 209); + ctx.bezierCurveTo(83.9, 209, 68.6, 183, 43.0, 183); + ctx.bezierCurveTo(12.3, 183, 7.1, 209, 7.1, 209); + ctx.lineTo(7.1, 157); + ctx.lineTo(83.9, 157); + ctx.lineTo(83.9, 209); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + ctx.restore(); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/MarkVectorGraphics.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/MarkVectorGraphics.java index 5d61b9799f5..cdf8ad1366d 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/MarkVectorGraphics.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/MarkVectorGraphics.java @@ -1,783 +1,24 @@ package com.sap.sailing.gwt.ui.shared.racemap; -import com.google.gwt.canvas.dom.client.CanvasGradient; import com.google.gwt.canvas.dom.client.Context2d; +import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Distance; -import com.sap.sailing.domain.common.MarkType; -import com.sap.sailing.domain.common.impl.MeterDistance; +import com.sap.sailing.gwt.ui.shared.CoursePositionsDTO; -/** - * A class for course mark graphics based on SVG graphics drawn to a HTML5 canvas - * The SVG files for the drawing can be found in the package com.sap.sailing.gwt.ui.svg.buoys - * A general description how to convert SVG files to 'drawing commands' can be found at http://wiki.sapsailing.com/wiki/howto/development/boatgraphicssvg - * @author Frank - * - */ -public class MarkVectorGraphics { - protected Distance markHeightInMeters; - protected Distance markWidthInMeters; - - private final String color; - private final String shape; - private final String pattern; - private final MarkType type; - - private static final double doublePi = 2 * Math.PI; +public interface MarkVectorGraphics { + void drawMarkToCanvas(Context2d ctx, boolean isSelected, double width, double height, double scaleFactor); - private double anchorPointX = 0.44; - private double anchorPointY = 1.67; - - private final static String DEFAULT_MARK_COLOR = "#f9ac00"; - private final static String DEFAULT_MARK_BG_COLOR = "#f0f0f0"; + Distance getMarkHeight(); - public MarkVectorGraphics(MarkType type, String color, String shape, String pattern) { - this.type = type; - this.color = color; - this.shape = shape; - this.pattern = pattern; - this.markHeightInMeters = new MeterDistance(2.1); - this.markWidthInMeters = new MeterDistance(1.5); - } - - public void drawMarkToCanvas(Context2d ctx, boolean isSelected, double width, double height, double scaleFactor) { - ctx.save(); - ctx.clearRect(0, 0, width, height); - ctx.translate(width / 2.0, height / 2.0); - ctx.scale(scaleFactor, scaleFactor); - ctx.translate(-anchorPointX * 100,- anchorPointY * 100); - String markColor = color != null ? color : DEFAULT_MARK_COLOR; - drawMark(ctx, isSelected, markColor); - ctx.restore(); - } + Distance getMarkWidth(); - protected void drawMark(Context2d ctx, boolean isSelected, String color) { - final MarkType markType = type==null ? MarkType.BUOY : type; - switch(markType) { - case BUOY: - if(isSelected) { - drawMarkSelection(ctx); - } - if(shape != null) { - if(Shape.CYLINDER.name().equalsIgnoreCase(shape) && pattern != null && Pattern.CHECKERED.name().equalsIgnoreCase(pattern)) { - drawBuoyWithFinishFlag(ctx, isSelected, color); - } else if (Shape.CONICAL.name().equalsIgnoreCase(shape)) { - drawConicalBuoy(ctx, isSelected, color); - } else { - drawSimpleBuoy(ctx, isSelected, color); - } - } else { - drawSimpleBuoy(ctx, isSelected, color); - } - break; - case FINISHBOAT: - drawFinishBoat(ctx, isSelected, color); - break; - case LANDMARK: - if(isSelected) { - drawMarkSelection(ctx); - } - drawLandmark(ctx, isSelected, color); - break; - case STARTBOAT: - drawStartBoat(ctx, isSelected, color); - break; - case UMPIREBOAT: - case CAMERABOAT: - // umpire and camera boats are not course marks -> see TrackedAssetVectorGraphics - break; - default: - break; - } - } - - private void drawMarkSelection(Context2d ctx) { - ctx.save(); - - ctx.scale(1.2,1.2); - ctx.translate(-10,-30); - - CanvasGradient g1=ctx.createLinearGradient(77.8,188,165,219); - g1.addColorStop(0,"rgba(240, 240, 240, 1)"); - g1.addColorStop(1,"rgba(240, 240, 240, 0)"); - ctx.setFillStyle(g1); - ctx.beginPath(); - ctx.moveTo(170,181); - ctx.translate(44.000168893718424,180.79369636814624); - ctx.rotate(0); - ctx.scale(1,1); - ctx.arc(0,0,126,0.0016373311430805408,0.5254904360229328,false); - ctx.scale(1,1); - ctx.rotate(0); - ctx.translate(-44.000168893718424,-180.79369636814624); - ctx.lineTo(44.2,181); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - - CanvasGradient g2=ctx.createLinearGradient(51,203,77.3,302); - g2.addColorStop(0,"rgba(255, 255, 255, 1)"); - g2.addColorStop(1,"rgba(255, 255, 255, 0)"); - ctx.setFillStyle(g2); - ctx.beginPath(); - ctx.moveTo(107,290); - ctx.translate(43.79222318749837,181.0010231680087); - ctx.rotate(0); - ctx.scale(1,1); - ctx.arc(0,0,126,1.0452923752792398,1.5667663411841573,false); - ctx.scale(1,1); - ctx.rotate(0); - ctx.translate(-43.79222318749837,-181.0010231680087); - ctx.lineTo(44.2,181); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - - CanvasGradient g3=ctx.createLinearGradient(26.8,197,-46.5,269); - g3.addColorStop(0,"rgba(255, 255, 255, 1)"); - g3.addColorStop(1,"rgba(255, 255, 255, 0)"); - ctx.setFillStyle(g3); - ctx.beginPath(); - ctx.moveTo(-18.3,290); - ctx.translate(43.72636289026038,180.32443158749652); - ctx.rotate(0); - ctx.scale(1,1); - ctx.arc(0,0,126,2.0854951576078884,2.611791628699119,false); - ctx.scale(1,1); - ctx.rotate(0); - ctx.translate(-43.72636289026038,-180.32443158749652); - ctx.lineTo(44.2,181); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - - CanvasGradient g4=ctx.createLinearGradient(18.7,172,-76.3,140); - g4.addColorStop(0,"rgba(255, 255, 255, 1)"); - g4.addColorStop(1,"rgba(255, 255, 255, 0)"); - ctx.setFillStyle(g4); - ctx.beginPath(); - ctx.moveTo(-81.8,179); - ctx.translate(44.19920011832349,178.55103503179944); - ctx.rotate(0); - ctx.scale(1,1); - ctx.arc(0,0,126,3.1380294320163484,3.670248678643417,false); - ctx.scale(1,1); - ctx.rotate(0); - ctx.translate(-44.19920011832349,-178.55103503179944); - ctx.lineTo(44.2,179); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - - CanvasGradient g5=ctx.createLinearGradient(37.9,147,13.6,58.6); - g5.addColorStop(0,"rgba(255, 255, 255, 1)"); - g5.addColorStop(1,"rgba(255, 255, 255, 0)"); - ctx.setFillStyle(g5); - ctx.beginPath(); - ctx.moveTo(-18.7,71.8); - ctx.translate(44.160311222571984,180.99973110315514); - ctx.rotate(0); - ctx.scale(1,1); - ctx.arc(0,0,126,-2.0931154263055687,-1.5728622903484606,false); - ctx.scale(1,1); - ctx.rotate(0); - ctx.translate(-44.160311222571984,-180.99973110315514); - ctx.lineTo(44.199999999999996,181); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - - CanvasGradient g6=ctx.createLinearGradient(80.8,139,134,91.9); - g6.addColorStop(0,"rgba(240, 240, 240, 1)"); - g6.addColorStop(1,"rgba(240, 240, 240, 0)"); - ctx.setFillStyle(g6); - ctx.beginPath(); - ctx.moveTo(108,72.1); - ctx.translate(43.50304481630927,180.3411325330301); - ctx.rotate(0); - ctx.scale(1,1); - ctx.arc(0,0,126,-1.0334238189446499,-0.5175711746742696,false); - ctx.scale(1,1); - ctx.rotate(0); - ctx.translate(-43.50304481630927,-180.3411325330301); - ctx.lineTo(44.2,181); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - - ctx.translate(-49.5,17.2); - ctx.restore(); - } - - void drawSimpleBuoy(Context2d ctx, boolean isSelected, String color) { - ctx.setStrokeStyle("rgba(0,0,0,0)"); - - ctx.save(); - ctx.setFillStyle(color); - ctx.transform(12.5,0,0,12.5,-578,22.2); - - ctx.beginPath(); - ctx.arc(49.7,12.8,2.66,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.7,11.3,3.37,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(color); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.6,10.6,2.66,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.transform(4.98,0,0,10.8,-205,50.4); - ctx.beginPath(); - ctx.moveTo(50.8,9.84); - ctx.lineTo(48.5,9.84); - ctx.lineTo(48.5,1.44); - ctx.lineTo(50.8,1.9); - ctx.lineTo(50.8,9.84); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.transform(12.5,0,0,12.5,-570,22.2); - ctx.save(); - ctx.setFillStyle(color); - ctx.beginPath(); - ctx.moveTo(48.8,3.82); - ctx.lineTo(48.8,-1.32); - ctx.lineTo(57,1.05); - ctx.lineTo(48.8,3.82); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.beginPath(); - ctx.moveTo(48.5,4.16); - ctx.lineTo(48.5,-1.65); - ctx.lineTo(57.8,1.03); - ctx.lineTo(48.5,4.16); - ctx.closePath(); - ctx.moveTo(49,-0.994); - ctx.lineTo(49,3.47); - ctx.lineTo(56.2,1.07); - ctx.lineTo(49,-0.994); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - ctx.restore(); - } - - protected void drawBuoyWithFinishFlag(Context2d ctx, boolean isSelected, String color) { - ctx.setStrokeStyle("rgba(0,0,0,0)"); - - ctx.save(); - ctx.setFillStyle(color); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.7,12.8,2.66,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.7,11.3,3.37,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(color); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.6,10.6,2.66,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.transform(4.98,0,0,10.8,-205,50.4); - ctx.beginPath(); - ctx.moveTo(50.8,9.84); - ctx.lineTo(48.5,9.84); - ctx.lineTo(48.5,1.44); - ctx.lineTo(50.8,1.9); - ctx.lineTo(50.8,9.84); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.beginPath(); - ctx.moveTo(36.9,-0.5); - ctx.lineTo(141.9,-0.5); - ctx.quadraticCurveTo(141.9,-0.5,141.9,-0.5); - ctx.lineTo(141.9,71.2); - ctx.quadraticCurveTo(141.9,71.2,141.9,71.2); - ctx.lineTo(36.9,71.2); - ctx.quadraticCurveTo(36.9,71.2,36.9,71.2); - ctx.lineTo(36.9,-0.5); - ctx.quadraticCurveTo(36.9,-0.5,36.9,-0.5); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(color); - ctx.beginPath(); - ctx.moveTo(46,4.04); - ctx.lineTo(76.3,4.04); - ctx.quadraticCurveTo(76.3,4.04,76.3,4.04); - ctx.lineTo(76.3,34.34); - ctx.quadraticCurveTo(76.3,34.34,76.3,34.34); - ctx.lineTo(46,34.34); - ctx.quadraticCurveTo(46,34.34,46,34.34); - ctx.lineTo(46,4.04); - ctx.quadraticCurveTo(46,4.04,46,4.04); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.beginPath(); - ctx.moveTo(46.1,34.3); - ctx.lineTo(76.4,34.3); - ctx.quadraticCurveTo(76.4,34.3,76.4,34.3); - ctx.lineTo(76.4,64.6); - ctx.quadraticCurveTo(76.4,64.6,76.4,64.6); - ctx.lineTo(46.1,64.6); - ctx.quadraticCurveTo(46.1,64.6,46.1,64.6); - ctx.lineTo(46.1,34.3); - ctx.quadraticCurveTo(46.1,34.3,46.1,34.3); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.beginPath(); - ctx.moveTo(76,3.95); - ctx.lineTo(106.3,3.95); - ctx.quadraticCurveTo(106.3,3.95,106.3,3.95); - ctx.lineTo(106.3,34.25); - ctx.quadraticCurveTo(106.3,34.25,106.3,34.25); - ctx.lineTo(76,34.25); - ctx.quadraticCurveTo(76,34.25,76,34.25); - ctx.lineTo(76,3.95); - ctx.quadraticCurveTo(76,3.95,76,3.95); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(color); - ctx.beginPath(); - ctx.moveTo(76.1,34.2); - ctx.lineTo(106.4,34.2); - ctx.quadraticCurveTo(106.4,34.2,106.4,34.2); - ctx.lineTo(106.4,64.5); - ctx.quadraticCurveTo(106.4,64.5,106.4,64.5); - ctx.lineTo(76.1,64.5); - ctx.quadraticCurveTo(76.1,64.5,76.1,64.5); - ctx.lineTo(76.1,34.2); - ctx.quadraticCurveTo(76.1,34.2,76.1,34.2); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(color); - ctx.beginPath(); - ctx.moveTo(106,3.96); - ctx.lineTo(136.3,3.96); - ctx.quadraticCurveTo(136.3,3.96,136.3,3.96); - ctx.lineTo(136.3,34.26); - ctx.quadraticCurveTo(136.3,34.26,136.3,34.26); - ctx.lineTo(106,34.26); - ctx.quadraticCurveTo(106,34.26,106,34.26); - ctx.lineTo(106,3.96); - ctx.quadraticCurveTo(106,3.96,106,3.96); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.beginPath(); - ctx.moveTo(106,34.3); - ctx.lineTo(136.3,34.3); - ctx.quadraticCurveTo(136.3,34.3,136.3,34.3); - ctx.lineTo(136.3,64.6); - ctx.quadraticCurveTo(136.3,64.6,136.3,64.6); - ctx.lineTo(106,64.6); - ctx.quadraticCurveTo(106,64.6,106,64.6); - ctx.lineTo(106,34.3); - ctx.quadraticCurveTo(106,34.3,106,34.3); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - ctx.restore(); - } - - protected void drawLandmark(Context2d ctx, boolean isSelected, String color) { - ctx.setStrokeStyle("rgba(0,0,0,0)"); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.transform(4.98,0,0,10.8,-205,50.4); - ctx.beginPath(); - ctx.moveTo(50.8,9.84); - ctx.lineTo(48.5,9.84); - ctx.lineTo(48.5,1.44); - ctx.lineTo(50.8,1.9); - ctx.lineTo(50.8,9.84); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.transform(12.5,0,0,12.5,-570,22.2); - ctx.save(); - ctx.setFillStyle(color); - ctx.beginPath(); - ctx.moveTo(48.8,3.82); - ctx.lineTo(48.8,-1.32); - ctx.lineTo(57,1.05); - ctx.lineTo(48.8,3.82); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.beginPath(); - ctx.moveTo(48.5,4.16); - ctx.lineTo(48.5,-1.65); - ctx.lineTo(57.8,1.03); - ctx.lineTo(48.5,4.16); - ctx.closePath(); - ctx.moveTo(49,-0.994); - ctx.lineTo(49,3.47); - ctx.lineTo(56.2,1.07); - ctx.lineTo(49,-0.994); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(color); - ctx.beginPath(); - ctx.moveTo(83.9,209); - ctx.bezierCurveTo(83.9,209,68.6,183,43.0,183); - ctx.bezierCurveTo(12.3,183,7.1,209,7.1,209); - ctx.lineTo(7.1,157); - ctx.lineTo(83.9,157); - ctx.lineTo(83.9,209); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - ctx.restore(); - } - - protected void drawConicalBuoy(Context2d ctx, boolean isSelected, String color) { - ctx.setStrokeStyle("rgba(0,0,0,0)"); - - ctx.save(); - ctx.setFillStyle(color); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.7,12.8,2.66,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.7,11.3,3.37,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(color); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.6,10.6,2.66,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.beginPath(); - ctx.moveTo(36.9,98); - ctx.lineTo(47.5,98); - ctx.quadraticCurveTo(47.5,98,47.5,98); - ctx.lineTo(47.5,154.5); - ctx.quadraticCurveTo(47.5,154.5,47.5,154.5); - ctx.lineTo(36.9,154.5); - ctx.quadraticCurveTo(36.9,154.5,36.9,154.5); - ctx.lineTo(36.9,98); - ctx.quadraticCurveTo(36.9,98,36.9,98); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.beginPath(); - ctx.moveTo(43.6,0.372); - ctx.lineTo(87.3,102); - ctx.lineTo(-0.714,102); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(color); - ctx.beginPath(); - ctx.moveTo(43.6,14.7); - ctx.lineTo(78.5,96.6); - ctx.lineTo(8.07,96.6); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - } - - protected void drawStartBoat(Context2d ctx, boolean isSelected, String color2) { - ctx.setStrokeStyle("rgba(0,0,0,0)"); - - ctx.save(); - ctx.setFillStyle(color); - ctx.transform(12.5,0,0,12.5,-578,22.2); - - ctx.beginPath(); - ctx.arc(49.7,12.8,2.66,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.7,11.3,3.37,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(color); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.6,10.6,2.66,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.transform(4.98,0,0,10.8,-205,50.4); - ctx.beginPath(); - ctx.moveTo(50.8,9.84); - ctx.lineTo(48.5,9.84); - ctx.lineTo(48.5,1.44); - ctx.lineTo(50.8,1.9); - ctx.lineTo(50.8,9.84); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.transform(12.5,0,0,12.5,-570,22.2); - ctx.save(); - ctx.setFillStyle(color); - ctx.beginPath(); - ctx.moveTo(48.8,3.82); - ctx.lineTo(48.8,-1.32); - ctx.lineTo(57,1.05); - ctx.lineTo(48.8,3.82); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.beginPath(); - ctx.moveTo(48.5,4.16); - ctx.lineTo(48.5,-1.65); - ctx.lineTo(57.8,1.03); - ctx.lineTo(48.5,4.16); - ctx.closePath(); - ctx.moveTo(49,-0.994); - ctx.lineTo(49,3.47); - ctx.lineTo(56.2,1.07); - ctx.lineTo(49,-0.994); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - ctx.restore(); - } - - protected void drawFinishBoat(Context2d ctx, boolean isSelected, String color2) { - ctx.setStrokeStyle("rgba(0,0,0,0)"); - - ctx.save(); - ctx.setFillStyle(color); - ctx.transform(12.5,0,0,12.5,-578,22.2); - - ctx.beginPath(); - ctx.arc(49.7,12.8,2.66,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.7,11.3,3.37,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(color); - ctx.transform(12.5,0,0,12.5,-578,22.2); - ctx.beginPath(); - ctx.arc(49.6,10.6,2.66,0,doublePi,false); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.transform(4.98,0,0,10.8,-205,50.4); - ctx.beginPath(); - ctx.moveTo(50.8,9.84); - ctx.lineTo(48.5,9.84); - ctx.lineTo(48.5,1.44); - ctx.lineTo(50.8,1.9); - ctx.lineTo(50.8,9.84); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.transform(12.5,0,0,12.5,-570,22.2); - ctx.save(); - ctx.setFillStyle(color); - ctx.beginPath(); - ctx.moveTo(48.8,3.82); - ctx.lineTo(48.8,-1.32); - ctx.lineTo(57,1.05); - ctx.lineTo(48.8,3.82); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); - ctx.beginPath(); - ctx.moveTo(48.5,4.16); - ctx.lineTo(48.5,-1.65); - ctx.lineTo(57.8,1.03); - ctx.lineTo(48.5,4.16); - ctx.closePath(); - ctx.moveTo(49,-0.994); - ctx.lineTo(49,3.47); - ctx.lineTo(56.2,1.07); - ctx.lineTo(49,-0.994); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - ctx.restore(); - } - - public Distance getMarkHeight() { - return markHeightInMeters; - } - - public Distance getMarkWidth() { - return markWidthInMeters; - } - - public String getColor() { - return color; - } - - public String getShape() { - return shape; - } - - public String getPattern() { - return pattern; - } - - public MarkType getType() { - return type; - } + /** + * If this graphical representation requires different rotations based on its state, this method can be implemented + * to compute the rotation desired. It is called after the drawing to the canvas, if it was necessary, has been + * updated. + * + * @return {@code null} if no rotation is desired; this will save the application of a CSS rotation; otherwise, a + * rotation as an angle + */ + Bearing getRotationInDegrees(CoursePositionsDTO coursePositionsDTO); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/MarkVectorGraphicsFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/MarkVectorGraphicsFactory.java new file mode 100644 index 00000000000..cfb6aa0acce --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/MarkVectorGraphicsFactory.java @@ -0,0 +1,44 @@ +package com.sap.sailing.gwt.ui.shared.racemap; + +import com.sap.sailing.domain.common.MarkType; +import com.sap.sailing.gwt.ui.shared.MarkDTO; + +public class MarkVectorGraphicsFactory { + public MarkVectorGraphics getMarkVectorGraphics(MarkDTO markDTO) { + final MarkType markType = markDTO.type; + final MarkVectorGraphics result; + switch (markType) { + case BUOY: + result = createBuoyMarkVectorGraphics(markDTO); + break; + case STARTBOAT: + case FINISHBOAT: + result = new BoatMarkVectorGraphics(markDTO.type, markDTO.color, markDTO.shape, markDTO.pattern, markDTO.getIdAsString()); + break; + case LANDMARK: + result = new LandMarkVectorGraphics(markDTO.type, markDTO.color, markDTO.shape, markDTO.pattern); + break; + default: + result = createBuoyMarkVectorGraphics(markDTO); + break; + } + return result; + } + + private MarkVectorGraphics createBuoyMarkVectorGraphics(MarkDTO markDTO) { + final MarkVectorGraphics result; + if (markDTO.shape != null) { + if (Shape.CYLINDER.name().equalsIgnoreCase(markDTO.shape) && markDTO.pattern != null + && Pattern.CHECKERED.name().equalsIgnoreCase(markDTO.pattern)) { + result = new FinishFlagMarkVectorGraphics(markDTO.type, markDTO.color, markDTO.shape, markDTO.pattern); + } else if (Shape.CONICAL.name().equalsIgnoreCase(markDTO.shape)) { + result = new ConicalBuoyMarkVectorGraphics(markDTO.type, markDTO.color, markDTO.shape, markDTO.pattern); + } else { + result = new SimpleBuoyMarkVectorGraphics(markDTO.type, markDTO.color, markDTO.shape, markDTO.pattern); + } + } else { + result = new SimpleBuoyMarkVectorGraphics(markDTO.type, markDTO.color, markDTO.shape, markDTO.pattern); + } + return result; + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/SimpleBuoyMarkVectorGraphics.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/SimpleBuoyMarkVectorGraphics.java new file mode 100644 index 00000000000..09c8be2a180 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/SimpleBuoyMarkVectorGraphics.java @@ -0,0 +1,93 @@ +package com.sap.sailing.gwt.ui.shared.racemap; + +import com.google.gwt.canvas.dom.client.Context2d; +import com.sap.sailing.domain.common.MarkType; + +public class SimpleBuoyMarkVectorGraphics extends AbstractMarkVectorGraphics implements MarkVectorGraphics { + + public SimpleBuoyMarkVectorGraphics(MarkType type, String color, String shape, String pattern) { + super(type, color, shape, pattern); + } + + @Override + protected void drawMarkBody(Context2d ctx, boolean isSelected, String color) { + ctx.setStrokeStyle("rgba(0,0,0,0)"); + + ctx.save(); + ctx.setFillStyle(color); + ctx.transform(12.5, 0, 0, 12.5, -578, 22.2); + + ctx.beginPath(); + ctx.arc(49.7, 12.8, 2.66, 0, doublePi, false); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.transform(12.5, 0, 0, 12.5, -578, 22.2); + ctx.beginPath(); + ctx.arc(49.7, 11.3, 3.37, 0, doublePi, false); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(color); + ctx.transform(12.5, 0, 0, 12.5, -578, 22.2); + ctx.beginPath(); + ctx.arc(49.6, 10.6, 2.66, 0, doublePi, false); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.transform(4.98, 0, 0, 10.8, -205, 50.4); + ctx.beginPath(); + ctx.moveTo(50.8, 9.84); + ctx.lineTo(48.5, 9.84); + ctx.lineTo(48.5, 1.44); + ctx.lineTo(50.8, 1.9); + ctx.lineTo(50.8, 9.84); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.transform(12.5, 0, 0, 12.5, -570, 22.2); + ctx.save(); + ctx.setFillStyle(color); + ctx.beginPath(); + ctx.moveTo(48.8, 3.82); + ctx.lineTo(48.8, -1.32); + ctx.lineTo(57, 1.05); + ctx.lineTo(48.8, 3.82); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.setFillStyle(DEFAULT_MARK_BG_COLOR); + ctx.beginPath(); + ctx.moveTo(48.5, 4.16); + ctx.lineTo(48.5, -1.65); + ctx.lineTo(57.8, 1.03); + ctx.lineTo(48.5, 4.16); + ctx.closePath(); + ctx.moveTo(49, -0.994); + ctx.lineTo(49, 3.47); + ctx.lineTo(56.2, 1.07); + ctx.lineTo(49, -0.994); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + ctx.restore(); + ctx.restore(); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/svg/buoys/boat_mark.svg b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/svg/buoys/boat_mark.svg new file mode 100644 index 00000000000..ebd344fd9f1 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/svg/buoys/boat_mark.svg @@ -0,0 +1,77 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + +