From 1ee43eec4a3af19d2beed265aa6fe4d3c8d62ef9 Mon Sep 17 00:00:00 2001 From: Nidhi Sawhney Date: Fri, 19 Oct 2012 11:29:02 +0200 Subject: [PATCH] WindGridCanvasOverlay now shows shades of grey. --- .../gwt/ui/test/WindGridColorPaletteTest.java | 22 +++++++ .../META-INF/MANIFEST.MF | 3 +- .../ui/simulator/WindGridCanvasOverlay.java | 64 +++++++++--------- .../simulator/util/WindGridColorPalette.java | 65 +++++++++++++++++++ 4 files changed, 123 insertions(+), 31 deletions(-) create mode 100644 java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/WindGridColorPaletteTest.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/util/WindGridColorPalette.java diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/WindGridColorPaletteTest.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/WindGridColorPaletteTest.java new file mode 100644 index 00000000000..746a246ee47 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/WindGridColorPaletteTest.java @@ -0,0 +1,22 @@ +package com.sap.sailing.gwt.ui.test; + +import static org.junit.Assert.*; + +import org.junit.Test; +import com.sap.sailing.gwt.ui.simulator.util.*; + +public class WindGridColorPaletteTest { + + @Test + public void test() { + int min = 10; + int max = 100; + WindGridColorPalette cp = new WindGridColorPalette(min,max); + + assertEquals("Lightest color", "#FFFFFF", cp.getColor(min)); + assertEquals("Darkest color", "#000000", cp.getColor(max)); + + assertEquals("In between color", "#7F7F7F", cp.getColor((max+min)/2)); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF b/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF index 2814ee20ab2..e6c00bbd781 100755 --- a/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF @@ -42,7 +42,8 @@ Export-Package: com.sap.sailing.gwt.ui.adminconsole;x-friends:="com.sap.sailing. com.sap.sailing.simulator.util, com.sap.sailing.gwt.ui.simulator.util, com.google.gwt.maps.client.overlay, - com.google.gwt.user.client.ui" + com.google.gwt.user.client.ui", + com.sap.sailing.gwt.ui.simulator.util Import-Package: javax.jms;version="1.1.0", javax.servlet;version="2.5.0", javax.servlet.http;version="2.5.0", diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/WindGridCanvasOverlay.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/WindGridCanvasOverlay.java index a582d63d3db..11d61b177b7 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/WindGridCanvasOverlay.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/WindGridCanvasOverlay.java @@ -1,11 +1,9 @@ package com.sap.sailing.gwt.ui.simulator; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Date; -import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -24,7 +22,15 @@ import com.sap.sailing.gwt.ui.shared.PositionDTO; import com.sap.sailing.gwt.ui.shared.WindDTO; import com.sap.sailing.gwt.ui.shared.WindFieldDTO; import com.sap.sailing.gwt.ui.shared.racemap.FullCanvasOverlay; +import com.sap.sailing.gwt.ui.simulator.util.WindGridColorPalette; +/** + * A google map overlay based on a HTML5 canvas for representing a wind field as a heat map. + * The overlay covers the whole map and colors the cells of the field based on the trueWindSpeedInKnots + * + * @author Nidhi Sawhney(D054070) + * + */ public class WindGridCanvasOverlay extends FullCanvasOverlay implements TimeListenerWithStoppingCriteria { /* The wind field that is to be displayed in the overlay */ protected WindFieldDTO wl; @@ -38,6 +44,7 @@ public class WindGridCanvasOverlay extends FullCanvasOverlay implements TimeList private int xRes; private int yRes; private WindDTO[][] windMatrix; + private WindGridColorPalette colorPalette; private static Logger logger = Logger.getLogger(WindFieldCanvasOverlay.class.getName()); @@ -47,7 +54,7 @@ public class WindGridCanvasOverlay extends FullCanvasOverlay implements TimeList public PositionDTO topLeft; public PositionDTO topRight; - double windSpeedInKnots; + public double windSpeedInKnots; public GridCell(PositionDTO bl, PositionDTO br, PositionDTO tl, PositionDTO tr, Double windSpeedInKnots) { this.bottomLeft = bl; @@ -58,6 +65,15 @@ public class WindGridCanvasOverlay extends FullCanvasOverlay implements TimeList } } + private class SortByWindSpeed implements Comparator { + + @Override + public int compare(WindDTO w1, WindDTO w2) { + return Double.compare(w1.trueWindSpeedInKnots , w2.trueWindSpeedInKnots); + } + + } + private class SortByLatitude implements Comparator { @Override @@ -93,7 +109,7 @@ public class WindGridCanvasOverlay extends FullCanvasOverlay implements TimeList private void init() { wl = null; timePointWindDTOMap = new TreeMap>(); - + colorPalette = null; } public void setWindField(WindFieldDTO wl) { @@ -109,6 +125,14 @@ public class WindGridCanvasOverlay extends FullCanvasOverlay implements TimeList } } + SortByWindSpeed windSpeedSorter = new SortByWindSpeed(); + double maxSpeed = Collections.max(wl.getMatrix(), windSpeedSorter).trueWindSpeedInKnots; + double minSpeed = Collections.min(wl.getMatrix(), windSpeedSorter).trueWindSpeedInKnots; + System.out.println("minSpeed: " + minSpeed + " maxSpeed: " + maxSpeed); + + colorPalette = new WindGridColorPalette(minSpeed,maxSpeed); + logger.fine("Color minSpeed: " + colorPalette.getColor(minSpeed)); + logger.fine("Color maxSpeed: " + colorPalette.getColor(maxSpeed)); } @Override @@ -199,23 +223,7 @@ public class WindGridCanvasOverlay extends FullCanvasOverlay implements TimeList } createPositionGrid(windDTOList); createGridCell(); - /* - double width = getGridWidth(windDTOList); - double height = getGridHeight(windDTOList); - logger.info("In drawWindGrid width = " + width + " height = " + height); - Iterator windDTOIter = windDTOList.iterator(); - - while (windDTOIter.hasNext()) { - WindDTO windDTO = windDTOIter.next(); - PositionDTO position = windDTO.position; - LatLng positionLatLng = LatLng.newInstance(position.latDeg, position.lngDeg); - Point canvasPositionInPx = getMap().convertLatLngToDivPixel(positionLatLng); - - int x = canvasPositionInPx.getX() - this.getWidgetPosLeft(); - int y = canvasPositionInPx.getY() - this.getWidgetPosTop(); - drawRectangle(x-width/2,y-height/2,width,height,"Grey"); - } - */ + String title = "Wind Grid at " + windDTOList.size() + " points."; getCanvas().setTitle(title); } @@ -281,12 +289,7 @@ public class WindGridCanvasOverlay extends FullCanvasOverlay implements TimeList } this.windMatrix = new WindDTO[yRes][xRes]; Iterator windDTOIter = windDTOList.iterator(); - /* - SortByLatitude sortLatitude = new SortByLatitude(); - Collections.sort(windDTOList,sortLatitude); - SortByLongitude sortLongitude = new SortByLongitude(); - Collections.sort(windDTOList,sortLongitude); - */ + for(int i = 0; i < yRes; ++i) { for (int j = 0; j < xRes; ++j) { windMatrix[i][j] = windDTOIter.next(); @@ -328,15 +331,16 @@ public class WindGridCanvasOverlay extends FullCanvasOverlay implements TimeList positionLatLng = LatLng.newInstance(cell.topRight.latDeg, cell.topRight.lngDeg); Point trPoint = getMap().convertLatLngToDivPixel(positionLatLng); + /* Uncomment to see the center of the grid for debug drawCircle(blPoint.getX()-this.getWidgetPosLeft(), blPoint.getY()-this.getWidgetPosTop(),2,"red"); drawCircle(brPoint.getX()-this.getWidgetPosLeft(), brPoint.getY()-this.getWidgetPosTop(),2,"red"); drawCircle(tlPoint.getX()-this.getWidgetPosLeft(), tlPoint.getY()-this.getWidgetPosTop(),2,"red"); drawCircle(trPoint.getX()-this.getWidgetPosLeft(), trPoint.getY()-this.getWidgetPosTop(),2,"red"); - + */ Context2d context2d = canvas.getContext2d(); context2d.setLineWidth(1); context2d.setStrokeStyle("Black"); - context2d.setFillStyle("Grey"); + context2d.setFillStyle(colorPalette.getColor(cell.windSpeedInKnots)); context2d.beginPath(); context2d.moveTo(blPoint.getX()-this.getWidgetPosLeft(), blPoint.getY()-this.getWidgetPosTop()); @@ -347,7 +351,7 @@ public class WindGridCanvasOverlay extends FullCanvasOverlay implements TimeList context2d.closePath(); context2d.fill(); - context2d.stroke(); + //context2d.stroke(); // Dont show the lines } private PositionDTO getCenter(PositionDTO a, PositionDTO b, PositionDTO c, PositionDTO d) { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/util/WindGridColorPalette.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/util/WindGridColorPalette.java new file mode 100644 index 00000000000..a346f4aa809 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/util/WindGridColorPalette.java @@ -0,0 +1,65 @@ +package com.sap.sailing.gwt.ui.simulator.util; + +/** + * Class to provide a color for a given double value, much like in a heat map. + * The heat map is created over the range of minColor and maxColor. + * Currently this implementation only provides shades of grey hence RGB have the same + * value. + */ +public class WindGridColorPalette implements ColorPalette { + + /*White is 255 or FF */ + public int minColor = 255; + /*Black is 0 or 00 */ + public int maxColor = 0; + + private double min; + private double max; + + /** + * Provide the range of values for which the colors are to be generated + * @param min + * @param max + */ + public WindGridColorPalette(double min, double max) { + this.min = min; + this.max = max; + } + + @Override + public String getNextColor() { + throw new UnsupportedOperationException(); + } + + @Override + public String getColor(int idx) { + return getColor(idx*1.0); + } + + @Override + public void reset() { + throw new UnsupportedOperationException(); + } + + /** + * + * @param value + * @return a color representation in hex prefixed with a # corresponding to the value + * Currently only shades of grea are supported hence RGB have the same values + * if the value is in th range [min,max], returns null otherwise + */ + public String getColor(double value) { + if (min <= value && value <= max) { + + int colorValue = (int)(minColor + (value-min)/Math.max(1,(max - min)) * (maxColor - minColor)); + String colorValueHex = Integer.toHexString(colorValue).toUpperCase(); + if (colorValueHex.length() < 2) { + colorValueHex = "0" + colorValueHex; + } + String rgb = "#" + colorValueHex + colorValueHex + colorValueHex; + return rgb; + } + return null; + } + +}