Movement2DWithinShapeObserver.java 11.99 KiB
package pikelake.environment;
import fr.cemagref.observation.gui.Configurable;
import fr.cemagref.observation.gui.Drawable;
import fr.cemagref.observation.kernel.ObservablesHandler;
import fr.cemagref.observation.kernel.ObserverListener;
import fr.cemagref.ohoui.annotations.Description;
import fr.cemagref.ohoui.filters.NoTransientField;
import fr.cemagref.ohoui.swing.OhOUI;
import fr.cemagref.ohoui.swing.OhOUIDialog;
import fr.cemagref.simaqualife.kernel.util.TransientParameters;
import fr.cemagref.simaqualife.pilot.Pilot;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JComponent;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.MultiPolygon;
import pikelake.Grid;
import pikelake.pikes.Pike;
import pikelake.pikes.PikesGroup;
public class Movement2DWithinShapeObserver extends ObserverListener implements Configurable, Drawable {
	private transient Grid grid;
    private transient JComponent display;
    private transient GeneralPath generalPath;
    private transient List<PikesGroup> groups;
    private String title;
    // TODO supress transient when list will be supported by AutOUI
    @Description (name="Groups colors",tooltip="Colors af aquanisms groups")
    private transient List<Color> groupsColors;
    @Description (name="Background color",tooltip="Background color")
    private Color bgColor;
    @Description (name="Pikes color",tooltip="Pikes color")
    private Color pikeColor;
    @Description (name="River color",tooltip="River color")
    private Color shapeColor;
    @Description (name="HSI color",tooltip="HSI color")
    private Color hsiColor;
    private int margin;
//    private int sizeOfDisplayedIndividuals;
    // use for determine if generalPath must be rescaled
    private transient int displayWidthBak,displayHeightBak;
    // used for coordinates rescaling
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
private transient double repositioningTranslateX,repositioningTranslateY; private transient double shapeOriginalWidth, shapeOriginalHeight; private transient double shapeAspectRatio; @SuppressWarnings("unused") private transient double rescaleFactorWithOriginal; public Movement2DWithinShapeObserver(int margin) { this(margin,Color.BLACK,Color.BLUE); } public Movement2DWithinShapeObserver() { this(Color.BLACK,Color.BLUE); } public Movement2DWithinShapeObserver(Color bgColor,Color shapeColor) { this(0,bgColor,shapeColor); } public Movement2DWithinShapeObserver(int margin,Color bgColor,Color shapeColor) { this.margin = margin; this.bgColor = bgColor; this.shapeColor = shapeColor; } public String getTitle() { return title; } public JComponent getDisplay() { return display; } @TransientParameters.InitTransientParameters public void init(Pilot pilot) { display = new DisplayComponent(); display.setVisible(false); display.setDoubleBuffered(true); displayWidthBak = 0; displayHeightBak = 0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// File file = new File("data/input/shape/513_5.shp"); FileDataStore store; try { store = FileDataStoreFinder.getDataStore(file); SimpleFeatureSource featureSource = store.getFeatureSource(); SimpleFeatureIterator iterator = featureSource.getFeatures().features(); MultiPolygon p = (MultiPolygon) iterator.next().getDefaultGeometry(); iterator.close(); Path2D.Double shape = new Path2D.Double(); shape.moveTo(p.getCoordinates()[0].x, p.getCoordinates()[0].y); for (int i = 1; i < p.getCoordinates().length; i++) { Coordinate coord = p.getCoordinates()[i]; shape.lineTo(coord.x, coord.y); } this.generalPath = new GeneralPath(shape); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// //this.generalPath = new GeneralPath((Shape) ((AsShapeConvertible) pilot.getAquaticWorld().getEnvironment()).getShape()); // original dimension storage this.shapeOriginalWidth = this.generalPath.getBounds().getWidth();
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
this.shapeOriginalHeight = this.generalPath.getBounds().getHeight(); this.shapeAspectRatio = shapeOriginalWidth / shapeOriginalHeight; // repositionning the shape to (0,0) this.repositioningTranslateX = - this.generalPath.getBounds().getX(); this.repositioningTranslateY = - this.generalPath.getBounds().getY(); this.generalPath.transform(AffineTransform.getTranslateInstance(this.margin+repositioningTranslateX,this.margin+repositioningTranslateY)); // vertical flip this.generalPath.transform(AffineTransform.getScaleInstance(1,-1)); this.generalPath.transform(AffineTransform.getTranslateInstance(0,shapeOriginalHeight)); this.groups = new ArrayList<PikesGroup>(); groupsColors = new ArrayList<Color>(); groupsColors.add(Color.RED); groupsColors.add(Color.GREEN); groupsColors.add(Color.YELLOW); groupsColors.add(Color.CYAN); groupsColors.add(Color.GRAY); display.repaint(); display.setVisible(true); } public void disable() { display.setVisible(false); } @Override public void addObservable(ObservablesHandler classObservable) { // nothing to do } public void valueChanged(ObservablesHandler clObservable, Object instance, long t) { if (groups.isEmpty() && instance != null) { groups.add((PikesGroup) instance); } display.repaint(); display.setVisible(true); } public static interface AsShapeConvertible { public Shape getShape(); } public void configure() { OhOUIDialog dialog = OhOUI.getDialog(null,this,new NoTransientField()); dialog.setSize(new Dimension(480, 200)); dialog.setVisible(true); display.repaint(); } public void addObservable(ObserverListener classObservable) { // nothing to do } public void close() { // nothing to do } private class DisplayComponent extends JComponent { /** * */ private static final long serialVersionUID = 1L; protected synchronized void paintComponent(Graphics g) { super.paintComponents(g);
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
Graphics2D g2d = (Graphics2D)g; // determine if generalPath must be rescaled if ( (this.getWidth() != displayWidthBak) || (this.getHeight() != displayHeightBak) ) { // backup for comparaison in the next loop displayWidthBak = this.getWidth(); displayHeightBak = this.getHeight(); // compute the rescale factor with keeping the aspect ratio double rescaleFactor; // TODO calcul faux quand margin > 0 if ( ((double)displayWidthBak/displayHeightBak) < shapeAspectRatio ) { rescaleFactor = displayWidthBak / (generalPath.getBounds().getWidth()); rescaleFactorWithOriginal = displayWidthBak / shapeOriginalWidth; } else { rescaleFactor = displayHeightBak / (generalPath.getBounds().getHeight()); rescaleFactorWithOriginal = displayHeightBak / shapeOriginalHeight; } // rescale the generalPath generalPath.transform (AffineTransform.getScaleInstance (rescaleFactor, rescaleFactor)); } // Draw Background g.setColor(bgColor); g.fillRect(0, 0, getWidth(), getHeight()); // Draw the generalPath //g.setColor(shapeColor); //g2d.fill(generalPath); //g.setColor(aquanismsColor); Iterator<Color> colorsIterator = groupsColors.iterator(); // Draw aquanisms g.setColor(pikeColor); double widthMax = 0, heightMax = 0; double xPike = 0, yPike = 0, xPike2 = 0, yPike2 = 0; widthMax = generalPath.getBounds().getWidth(); heightMax = generalPath.getBounds().getHeight(); //g2d.fillRect(widthMax, heightMax, 1, 1); //System.out.println(generalPath.getBounds2D()); //System.out.println(widthMax); //System.out.println(heightMax); //Grid grid = new Grid[]; //Grid grid = (Grid) pilot.getAquaticWorld().getEnvironment(); boolean oneShot = false; for (PikesGroup group : groups) { if (oneShot == false) { grid = group.getEnvironment(); int xHSI = 0, yHSI = 0, xHSI2 = 0, yHSI2 = 0; int xx[] = new int [(grid.getGridHeight() * grid.getGridWidth())-1], yy[] = new int [(grid.getGridHeight() * grid.getGridWidth())-1]; g.setColor(hsiColor); for (int cptCell = 0; cptCell < (grid.getGridHeight() * grid.getGridWidth())-1; cptCell++) { if (grid.getCell(cptCell).getHabitatQuality() > 0) { yHSI = (int) Math.floor(cptCell / grid.getGridWidth()); xHSI = (int) cptCell - (yHSI * grid.getGridWidth()); xHSI2 = (int) (xHSI * (widthMax / grid.getGridWidth())); yHSI2 = (int) (yHSI * (heightMax / grid.getGridHeight())); g2d.fillRect((int) xHSI2, (int) yHSI2, 3, 3); xx[cptCell] = xHSI2; yy[cptCell] = yHSI2;
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
} } oneShot = true; } if (colorsIterator.hasNext()) g.setColor(colorsIterator.next()); for (Pike aquanism : group.getAquaNismsList() ) { ////for (Pike pike : group.getAquaNismsList()){ // Calcul de la maille occupe sur une grille de 216*244 yPike = (aquanism.getPosition().getIndex() / grid.getGridWidth()); xPike = (aquanism.getPosition().getIndex() - (yPike * grid.getGridWidth())); // Calcul dela maille occupe sur la grille redimensionnee (dynamique) xPike2 = xPike * (widthMax / grid.getGridWidth()); yPike2 = yPike * (heightMax / grid.getGridHeight()); // Affichage de chaque individu g2d.drawRect((int) xPike2, (int) yPike2, 1, 1); //System.out.println(aquanism.getPosition().getIndex()); //System.out.println(" X = " + xPike + " Y = " + yPike); //System.out.println(" X = " + xPike2 + " Y = " + yPike2 + "\n"); } } } } @Override public void init() { // TODO Auto-generated method stub } }