diff --git a/src/main/java/pikelake/Marnage.java b/src/main/java/pikelake/Marnage.java index 3831836fbe335e3074295f908edf033694e23b3e..9d785961355d7609b76dcbfa0d29f3138ee05279 100644 --- a/src/main/java/pikelake/Marnage.java +++ b/src/main/java/pikelake/Marnage.java @@ -1,74 +1,78 @@ -package pikelake; - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.Scanner; -import java.util.StringTokenizer; - -import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess; -import pikelake.environment.FichierMarnage; -import pikelake.environment.Time; -import pikelake.pikes.Pike; -import pikelake.pikes.PikesGroup; - -public class Marnage extends AquaNismsGroupProcess<Pike,PikesGroup> { - - public static String marnageOld = null, marnageNew = null; - public static String saison = ""; - - @Override - public void doProcess(PikesGroup object) { - Grid grid = (Grid) pilot.getAquaticWorld().getEnvironment(); - grid = grid.getGrid(); - marnageNew = FichierMarnage.dateMarnage[Time.jourMois][Time.mois][Time.heure]; - if (!marnageNew.equals(marnageOld) | !saison.equals(Time.getSeason())) - majCote(grid); - } - - public void majCote (Grid grid) { - - StringTokenizer sLigne; - @SuppressWarnings("unused") - double hsiStd = 0, hsiMoy = 0; - int idCell = 0, yPike = 0, xPike = 0; - marnageOld = marnageNew; - saison = Time.getSeason(); - - // Initialisation de toute la grille avec hsi = -1 - for (int cptCell = 0; cptCell < (grid.getGridWidth() * grid.getGridHeight() - 1); cptCell++) - grid.setCell(cptCell, -1); - // Lecture fichier contenant les HSI de toutes les mailles - String filePath = "data/input/HSI/hsi_BRO" + Time.getSeason() + marnageNew + ".txt"; - Scanner scanner; - try { - scanner = new Scanner(new File(filePath)); - String line = scanner.nextLine(); - // On boucle sur chaque ligne detectée - while (scanner.hasNextLine()) { - line = scanner.nextLine(); - // Decoupage ligne : id, hsiStd, hsiMoy - sLigne = new StringTokenizer (line); - if (sLigne.hasMoreTokens()) - idCell = Integer.parseInt(sLigne.nextToken())-1; - if (sLigne.hasMoreTokens()) - hsiStd = Double.parseDouble(sLigne.nextToken()); - if (sLigne.hasMoreTokens()) - hsiMoy = Double.parseDouble(sLigne.nextToken()); - // Conversion idCell en coordonnees (x, y) - // (x, y) avec les id de cellules de 0 à n-1 - yPike = (int) Math.floor(idCell / grid.getGridWidth()); - xPike = (int) idCell - (yPike * grid.getGridWidth()); - // Inversion des coordonnees en Y (place l'origine en bas à gauche) - yPike = (grid.getGridHeight()-1) - yPike ; - // Conversion des coordonnees (x, y) en idCell - idCell = xPike + yPike * grid.getGridWidth(); - // Initialisation du hsi de la cellule(idCell) - grid.setCell(idCell, hsiMoy); - } - scanner.close(); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } -} +package pikelake; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Scanner; +import java.util.StringTokenizer; + +import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess; +import pikelake.environment.FichierMarnage; +import pikelake.environment.Time; +import pikelake.pikes.Pike; +import pikelake.pikes.PikesGroup; + +public class Marnage extends AquaNismsGroupProcess<Pike,PikesGroup> { + + public static String marnageOld = null, marnageNew = null; + public static String saison = ""; + + @Override + public void doProcess(PikesGroup object) { + Grid grid = (Grid) pilot.getAquaticWorld().getEnvironment(); + grid = grid.getGrid(); + marnageNew = FichierMarnage.dateMarnage[Time.jourMois][Time.mois][Time.heure]; + + if (!marnageNew.equals(marnageOld)) { + synchronized (grid) { // synchronization to be sure that graphical observer read synchronized values + majCote(grid); + } + } + } + + public void majCote (Grid grid) { + + StringTokenizer sLigne; + @SuppressWarnings("unused") + double hsiStd = 0, hsiMoy = 0; + int idCell = 0, yPike = 0, xPike = 0; + marnageOld = marnageNew; + saison = Time.getSeason(); + + // Initialisation de toute la grille avec hsi = -1 + for (int cptCell = 0; cptCell < (grid.getGridWidth() * grid.getGridHeight() - 1); cptCell++) + grid.setCell(cptCell, -1); + // Lecture fichier contenant les HSI de toutes les mailles + String filePath = "data/input/HSI/hsi_BRO" + Time.getSeason() + marnageNew + ".txt"; + Scanner scanner; + try { + scanner = new Scanner(new File(filePath)); + String line = scanner.nextLine(); + // On boucle sur chaque ligne detectée + while (scanner.hasNextLine()) { + line = scanner.nextLine(); + // Decoupage ligne : id, hsiStd, hsiMoy + sLigne = new StringTokenizer (line); + if (sLigne.hasMoreTokens()) + idCell = Integer.parseInt(sLigne.nextToken())-1; + if (sLigne.hasMoreTokens()) + hsiStd = Double.parseDouble(sLigne.nextToken()); + if (sLigne.hasMoreTokens()) + hsiMoy = Double.parseDouble(sLigne.nextToken()); + // Conversion idCell en coordonnees (x, y) + // (x, y) avec les id de cellules de 0 à n-1 + yPike = (int) Math.floor(idCell / grid.getGridWidth()); + xPike = (int) idCell - (yPike * grid.getGridWidth()); + // Inversion des coordonnees en Y (place l'origine en bas à gauche) + yPike = (grid.getGridHeight()-1) - yPike ; + // Conversion des coordonnees (x, y) en idCell + idCell = xPike + yPike * grid.getGridWidth(); + // Initialisation du hsi de la cellule(idCell) + grid.setCell(idCell, hsiMoy); + } + scanner.close(); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/src/main/java/pikelake/environment/Movement2DWithinShapeObserver.java b/src/main/java/pikelake/environment/Movement2DWithinShapeObserver.java index ceda3bc5481b0eabde7d0979088526741d284bfc..edc034e5de76699628ebc36efbb73f22f6985c4c 100644 --- a/src/main/java/pikelake/environment/Movement2DWithinShapeObserver.java +++ b/src/main/java/pikelake/environment/Movement2DWithinShapeObserver.java @@ -35,6 +35,11 @@ import org.geotools.data.simple.SimpleFeatureSource; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.MultiPolygon; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Arrays; +import javax.swing.Timer; +import pikelake.Cell; import pikelake.Grid; import pikelake.Marnage; @@ -44,8 +49,6 @@ import pikelake.pikes.PikesGroup; public class Movement2DWithinShapeObserver extends ObserverListener implements Configurable, Drawable { - private transient Grid grid; - private transient JComponent display; private transient GeneralPath generalPath; @@ -159,8 +162,17 @@ public class Movement2DWithinShapeObserver extends ObserverListener implements C groupsColors.add(Color.YELLOW); groupsColors.add(Color.CYAN); groupsColors.add(Color.GRAY); - display.repaint(); display.setVisible(true); + // auto-repaint 20 times / second + Timer timer = new Timer(50, new ActionListener() { + + @Override + public void actionPerformed(ActionEvent ae) { + display.repaint(); + } + + }); + timer.start(); } @@ -177,7 +189,6 @@ public class Movement2DWithinShapeObserver extends ObserverListener implements C if (groups.isEmpty() && instance != null) { groups.add((PikesGroup) instance); } - display.repaint(); display.setVisible(true); } @@ -226,11 +237,7 @@ public class Movement2DWithinShapeObserver extends ObserverListener implements C // rescale the generalPath generalPath.transform (AffineTransform.getScaleInstance (rescaleFactor, rescaleFactor)); } - // Draw Background - g.setColor(bgColor); - g.fillRect(0, 0, getWidth(), getHeight()); Iterator<Color> colorsIterator = groupsColors.iterator(); - // Draw aquanisms g.setColor(pikeColor); double widthMax = 0, heightMax = 0; @@ -238,29 +245,29 @@ public class Movement2DWithinShapeObserver extends ObserverListener implements C widthMax = generalPath.getBounds().getWidth(); heightMax = generalPath.getBounds().getHeight(); - boolean oneShot = false; for (PikesGroup group : groups) { - - if (oneShot == false) { - grid = group.getEnvironment(); - + final Grid grid = group.getEnvironment(); + if (oneShot == false) { + Cell[] cells; + // synchronization to be sure that graphical observer read synchronized values (without interference of marnage update process) + synchronized (grid) { + cells = Arrays.copyOf(grid.getCells(), grid.getCells().length); + } 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) { + if (cells[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())); - - g.setColor(new Color(0.43f, (float) (Math.min(1,grid.getCell(cptCell).getHabitatQuality()/hsiMaxValueThreshold)), 0.13f)); + g.setColor(new Color(0.43f, (float) (Math.max(0, Math.min(1,grid.getCell(cptCell).getHabitatQuality()/hsiMaxValueThreshold))), 0.13f)); g2d.fillRect((int) xHSI2, (int) yHSI2, 3, 3); - - xx[cptCell] = xHSI2; + xx[cptCell] = xHSI2; yy[cptCell] = yHSI2; } } @@ -282,7 +289,6 @@ public class Movement2DWithinShapeObserver extends ObserverListener implements C } } - // Annotations DecimalFormat df = new DecimalFormat("00"); g.setColor(textColor);