Merge branch 'master' into bug3968

This commit is contained in:
Kai Boernert committed 2016-11-08 15:50:49 +01:00
commit 3e2486cffd
11 files changed
+930 -780

No files matched your search

@@ -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<Integer, Util.Pair<Double,Size>>();
this.markScaleAndSizePerZoomCache = new HashMap<Integer, Util.Pair<Double,Size>>();
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;
@@ -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());
}
@@ -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;
}
}
@@ -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<Position> lineMarkPositions = new ArrayList<Position>();
MarkDTO firstMark = null;
MarkDTO secondMark = null;
for (WaypointDTO currentWaypoint : coursePositionsDTO.course.waypoints) {
if (currentWaypoint.passingInstructions == PassingInstruction.Line) {
Iterator<MarkDTO> 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<Position> 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;
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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);
}
@@ -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;
}
}
@@ -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();
}
}
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="startboat.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="335"
inkscape:cy="920"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="805"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 33,30.362205 C 220.909,-0.03804342 555.4225,20.091415 603,187.3622 c -48.87849,153.28628 -374.20184,165.5204 -571,143 z"
id="path3336"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<rect
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect3338"
width="268"
height="213"
x="81"
y="78.362206"
ry="0" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path3340"
cx="308.5"
cy="186.3622"
rx="28.5"
ry="28" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB