[Xulu-commits] r56 - in trunk: dist src/edu/bonn/xulu/plugin/model src/edu/bonn/xulu/plugin/model/sleuth
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Thu Sep 10 16:02:23 CEST 2009
Author: rgoetzke
Date: 2009-09-10 16:02:19 +0200 (Thu, 10 Sep 2009)
New Revision: 56
Added:
trunk/src/edu/bonn/xulu/plugin/model/sleuth/
trunk/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLU.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLUContentManager.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidation.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidationContentManager.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthContentManager.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibration.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationContentManager.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModification.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModificationContentManager.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelContentManager.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifying.java
trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifyingContentManager.java
Modified:
trunk/dist/xulu-doc.zip
Log:
SLEUTH 1. Version, wird noch geupdated
Modified: trunk/dist/xulu-doc.zip
===================================================================
(Binary files differ)
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLU.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLU.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLU.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,94 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.model.AbstractStepModel;
+import appl.util.RasterUtil;
+
+public class CopyUrbanInActualLU extends AbstractStepModel {
+
+
+ protected CopyUrbanInActualLUContentManager contManager;
+
+ private PropertyReadAccess RA_ActualLuMap = null;
+ private PropertyReadAccess RA_ActualUrbanMap = null;
+ private PropertyWriteAccess WA_ActualUrbanMap = null; // Output Grid
+ private PropertyReadAccess RA_UrbanLUClass = null;
+
+ private WritableGrid ActualLuMap = null;
+ private WritableGrid ActualUrbanMap = null;
+ private PropertyReadAccess UrbanLUClass = null;
+
+ protected int step = 0;
+
+ public CopyUrbanInActualLU() {
+ super(new CopyUrbanInActualLUContentManager());
+ this.contManager = (CopyUrbanInActualLUContentManager) super.contManager;
+ }
+
+ @Override
+ public void performModelInit() {
+ // TODO Auto-generated method stub
+ if (contManager == null)
+ return;
+ RA_ActualLuMap = null;
+ if (contManager.getResource(0).getData() != null)
+ RA_ActualLuMap = ((ScalarProperty) contManager.getResource(0)
+ .getData()).getReadAccess(this);
+ RA_ActualUrbanMap = null;
+ if (contManager.getResource(1).getData() != null)
+ RA_ActualUrbanMap = ((ScalarProperty) contManager.getResource(1)
+ .getData()).getReadAccess(this);
+ WA_ActualUrbanMap = null;
+ if (contManager.getResource(1).getData() != null)
+ WA_ActualUrbanMap = ((ScalarProperty) contManager.getResource(1)
+ .getData()).getWriteAccess(this);
+ RA_UrbanLUClass = null;
+ if (contManager.getResource(2).getData() != null)
+ RA_UrbanLUClass = ((ScalarProperty) contManager.getResource(2).getData())
+ .getReadAccess(this);
+
+ ActualLuMap = (WritableGrid) RA_ActualLuMap.getValue();
+ ActualUrbanMap = (WritableGrid) RA_ActualUrbanMap.getValue();
+ UrbanLUClass = RA_UrbanLUClass;
+ this.stepCount = 1;
+ }
+
+ @Override
+ public void performModelDispose() {
+ // TODO Auto-generated method stub
+ releaseAccess(RA_ActualLuMap);
+ releaseAccess(RA_ActualUrbanMap);
+ releaseAccess(WA_ActualUrbanMap);
+ }
+
+
+ @Override
+ public void performModelStep(int stepNo) {
+ // TODO Auto-generated method stub
+ statusOut.println("Starting Copy ...");
+
+ boolean[][] tmpGrid = new boolean[ActualLuMap.getWidth()][ActualLuMap.getHeight()];
+
+ for (int x = 0; x < ActualLuMap.getWidth(); x++)
+ for (int y = 0; y < ActualLuMap.getHeight(); y++) {
+ float LU = ActualLuMap.getRasterSampleAsFloat(x, y);
+ float Urban = ActualUrbanMap.getRasterSampleAsFloat(x, y);
+ if (!Float.isNaN(LU) && !Float.isNaN(Urban)){
+ if ((int)Urban == 1){
+ tmpGrid[x][y] = true;
+ ActualLuMap.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,x ,y);
+ }
+
+ }
+ }
+
+ statusOut.println("Copy finished.");
+ }
+
+
+
+
+}
\ No newline at end of file
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLUContentManager.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLUContentManager.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLUContentManager.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,26 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+
+public class CopyUrbanInActualLUContentManager extends AbstractModelContentManager {
+
+ /**
+ * Erzeugt einen neuen ContentManager fuer das Modell {@linkplain AverageNeighborhoodParallelDemoModel}.
+ */
+ public CopyUrbanInActualLUContentManager() {
+
+ super(3);
+ // ActualLU (CLUE-S)
+ resource[0] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"ActualLU",ScalarProperty.class,WritableGrid.class,false);
+ // ActualUrban (UGM)
+ resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"ActualUrban",ScalarProperty.class,WritableGrid.class,false);
+ // Urban LU Class
+ resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"UrbanLUClass",ScalarProperty.class,Integer.class,false);
+ }
+
+}
+
\ No newline at end of file
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidation.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidation.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidation.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,286 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ListPropertyWriteAccess;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+import edu.bonn.xulu.plugin.model.parallel.demo.AVNTuned;
+import edu.bonn.xulu.plugin.model.parallel.demo.AverageNeighborhoodContentManager;
+import edu.bonn.xulu.plugin.model.parallel.demo.AverageNeighborhoodParallelDemoModel;
+
+/**
+ * This very simple model looks at every grid cell and takes the average
+ * over a the surrounding cells in a specified neighborhood. It was implemented
+ * as demonstration of the Xulu / V functionality. You can see the parallel version
+ * of this model in {@link AverageNeighborhoodParallelDemoModel} and also a tuned
+ * version using late-merging support in {@link AVNTuned}.
+ * <ol>
+ * <li><b>Input Grid ({@code inputGrid}):</b> A grid with input values </li>
+ * <li><b>Output Grid ({@code outputGrid}):</b> A grid where the output is
+ * stored </li>
+ * <li><b>Number of steps ({@code steps}):</b> the number of steps to
+ * compute. </li>
+ * </ol>
+ *
+ * @see AverageNeighborhoodContentManager
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class MultipleResolutionValidation extends AbstractStepModel {
+
+ /**
+ * the width/height of the neighborhood region over which the algorithm takes
+ * the average
+ */
+ //private int neighborhoodRange = 8;
+ private int neighborhoodRange = 0;
+ private float[][] resultArray;
+ /**
+ * Speichert den ContentManager fuer das Modell.
+ *
+ * @see AverageNeighborhoodContentManager
+ */
+ protected MultipleResolutionValidationContentManager contManager;
+
+ // ********** Lese/Schreibrechte, die fuer den gesamten ***********
+ // ********** Modellanlauf gehalten werden muessen ***********
+ private PropertyReadAccess RA_steps = null;
+ private PropertyReadAccess RA_referenceMap = null; // Reference Map
+ private PropertyReadAccess RA_simulationMap = null; //Simulation Map
+ private PropertyWriteAccess WA_actualValidation = null; // Output Grid
+ private PropertyWriteAccess WA_outStep = null; // Step Results
+ private ListPropertyWriteAccess WA_outResults = null; //Output Validation Results
+
+ // **************** Variablen mit denen gearbeitet wird *******************
+ private PropertyReadAccess steps = null; // Number of steps
+ private WritableGrid referenceMap = null; // Reference Map
+ private WritableGrid simulationMap = null; // Simulation Map
+ private WritableGrid actualValidation = null; // Output Grid
+ private MultiGrid outStep = null; //Step Results
+ private ListPropertyWriteAccess outResults = null; //Output Validation Results
+
+
+ /**
+ * Erzeugt eine neue Instanz des Modells.
+ */
+ public MultipleResolutionValidation() {
+ super(new MultipleResolutionValidationContentManager());
+ this.contManager = (MultipleResolutionValidationContentManager) super.contManager;
+ }
+
+
+ /**
+ * Initializes the model. Like in the init method of every {@link XuluModel}
+ * the resources are initalized.
+ */
+ public void performModelInit() {
+ if (contManager == null)
+ return;
+ // Zugriffsrechte aus Ressourcen/Propertys holen
+ RA_steps = null;
+ if (contManager.getResource(0).getData() != null)
+ RA_steps = ((ScalarProperty) contManager.getResource(0).getData())
+ .getReadAccess(this);
+ RA_referenceMap = null;
+ if (contManager.getResource(1).getData() != null)
+ RA_referenceMap = ((ScalarProperty) contManager.getResource(1)
+ .getData()).getReadAccess(this);
+ RA_simulationMap = null;
+ if (contManager.getResource(2).getData() != null)
+ RA_simulationMap = ((ScalarProperty) contManager.getResource(2)
+ .getData()).getReadAccess(this);
+ WA_actualValidation = null;
+ if (contManager.getResource(3).getData() != null)
+ WA_actualValidation = ((ScalarProperty) contManager.getResource(3)
+ .getData()).getWriteAccess(this);
+ WA_outResults = null;
+ if (contManager.getResource(5).getData() != null)
+ WA_outResults = ((ListProperty) contManager.getResource(5)
+ .getData()).getWriteAccess(this);
+
+ // Variablen belegen mit denen gearbeitet wird
+ steps = RA_steps;
+ referenceMap = (WritableGrid) RA_referenceMap.getValue();
+ simulationMap = (WritableGrid) RA_simulationMap.getValue();
+ actualValidation = (WritableGrid) WA_actualValidation.getValue();
+
+ this.stepCount = steps.getValueAsInt();
+ outStep = (MultiGrid)contManager.getResource(4).getData();
+ outResults = WA_outResults;
+ }
+
+ /**
+ * like in every model: frees the resources
+ */
+ public void performModelDispose() {
+
+ // Ressourcen wieder freigeben
+ releaseAccess(RA_steps);
+ releaseAccess(RA_referenceMap);
+ releaseAccess(RA_simulationMap);
+ releaseAccess(WA_actualValidation);
+ releaseAccess(WA_outStep);
+ releaseAccess(WA_outResults);
+ }
+
+ /**
+ * This very simple model looks at every grid cell and takes the average
+ * over a the surrounding cells in a specified neighborhood.
+ *
+ * @param stepNo
+ * zu modellierender Schritt (beginnend bei 1!)
+ */
+ public void performModelStep(int stepNo) {
+
+ statusOut.println("Starting step " + stepNo + "...");
+
+
+ /***********************************************************************
+ * the overallsum is simply the sum over ALL grid elements. it can be used to
+ * compare the result of this model with e.g. the parallel version of
+ * this algorithm.
+ **********************************************************************/
+ int RoverallSum = 0;
+ int RnumClasses = 0;
+ int SoverallSum = 0;
+ int SnumClasses = 0;
+ int correct = 0;
+ double fractionCorrect = 0f;
+
+
+ long localStartTime = System.currentTimeMillis();
+ //iterate over all cells
+
+ neighborhoodRange = (int) Math.sqrt(referenceMap.getWidth()*referenceMap.getHeight()); //maximal mögliche Zellengröße
+ statusOut.println(neighborhoodRange);
+ resultArray = new float[1][13];
+ //Fraction correct for original Resolution
+ for (int x = 0; x < referenceMap.getWidth(); x++)
+ for (int y = 0; y < referenceMap.getHeight(); y++) {
+ float Rtmp = referenceMap.getRasterSampleAsFloat(x, y);
+ float Stmp = simulationMap.getRasterSampleAsFloat(x, y);
+ if (!Float.isNaN(Rtmp) && !Float.isNaN(Stmp)){
+ RoverallSum ++;
+ SoverallSum ++;
+ if (Rtmp > RnumClasses)
+ RnumClasses = (int) Rtmp;
+ if (Stmp > SnumClasses)
+ SnumClasses = (int) Stmp;
+ if (Rtmp == Stmp)
+ correct++;
+ }
+ }
+ fractionCorrect = (double) correct / (double) RoverallSum;
+
+ //Anzahl der Pixel pro Klasse
+ for (int i = 1; i <= RnumClasses; i++){
+ int Rj = 0;
+ int Sj = 0;
+ for (int x = 0; x < referenceMap.getWidth(); x++)
+ for (int y = 0; y < referenceMap.getHeight(); y++){
+ float Rtmp = referenceMap.getRasterSampleAsFloat(x, y);
+ float Stmp = simulationMap.getRasterSampleAsFloat(x, y);
+ if (!Float.isNaN(Rtmp))
+ if ((int) Rtmp == i)
+ Rj++;
+ if (!Float.isNaN(Stmp))
+ if ((int) Stmp == i)
+ Sj++;
+ }
+ statusOut.println("Klasse "+i+": Referenz("+Rj+"), Simulation("+Sj+")");
+ }
+
+ int ngrids = 0;
+ for (int r = 1; r <= neighborhoodRange; r = r+r){ //für Zellengröße 1 bis zur max. möglichen Zellengröße wird Statistik durchgeführt
+ statusOut.println(r);
+ ngrids++;
+ outStep.addGrid();
+ float SumWn = 0f; //Summe der gewichteten Mittelwerte
+ int SumCells = 0; //Summe der Zellen
+ float totalAgreement = 0f; //Endergebnis
+ for (int x = 0; x < referenceMap.getWidth(); x = x+r) //für jeden größer werdenden Zellenbereich...
+ for (int y = 0; y < referenceMap.getHeight(); y = y+r){
+ int nCells = 0; //Anzahl Zellen pro größerer Zelle
+ float SumMinRS = 0f; //Summe der Min-Werte bei Vergleich zweier Raster
+ float Wn = 0; //Gewichtete Zelle
+ for(int x2 = x; x2 < x+r; x2++) //für jede kleinere Zelle innerhalb der größeren...
+ for(int y2 = y; y2 < y+r; y2++){
+ if ( x2 < referenceMap.getMinX() || y2 < referenceMap.getMinY() || x2 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y2 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+ Float.isNaN(referenceMap.getRasterSampleAsFloat(x2,y2)))
+ continue;
+ nCells++; //zähle "positive" Zellen
+ }
+ for (int i = 0; i <= RnumClasses; i++){ //für jede Klasse i
+ int Rn = 0; //Anzahl in Referenzkarte
+ int Sn = 0; //Anzahl in Simulationskarte
+ float Rnj = 0f; //Anteil in Referenzkarte
+ float Snj = 0f; //Anteil in Simulationskarte
+ float MinRS = 0f; //Min des Vergleichs zwischen beiden Karten
+ for(int x3 = x; x3 < x+r; x3++) //für jede kleinere Zelle pro größerer Zelle...
+ for(int y3 = y; y3 < y+r; y3++){
+ if ( x3 < referenceMap.getMinX() || y3 < referenceMap.getMinY() || x3 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y3 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+ Float.isNaN(referenceMap.getRasterSampleAsFloat(x3,y3)))
+ continue;
+ float Rtmp = referenceMap.getRasterSampleAsFloat(x3, y3); //hole Wert aus Referenz-Karte und
+ float Stmp = simulationMap.getRasterSampleAsFloat(x3, y3); //Simulationskarte
+ if ((int) Rtmp == i)
+ Rn++; //zähle in Referenzkarte Zellen, die zu Klasse i gehören
+ if ((int) Stmp == i)
+ Sn++; //und in Simulationskarte
+ }
+ if(nCells > 0){ //wenn positive Zellen vorhanden sind...
+ Rnj = (float)Rn / (float)nCells; //berechne Anteile pro größerer Zelle
+ Snj = (float)Sn / (float)nCells;
+ }
+ MinRS = Math.min(Rnj, Snj); //nehme Minimum-Wert des Vergleichs beider Karten
+ SumMinRS += MinRS; //summiere die Minimum-Werte auf
+ // statusOut.println(i+" Min"+MinRS+" Anzahl: "+nCells);
+
+ }
+ Wn = (float)nCells * SumMinRS;
+
+ // statusOut.println(SumMinRS+", gewichtet: "+Wn);
+ //Erstelle Output-Karten
+ float WnCell = 0f;
+ for(int x4 = x; x4 < x+r; x4++) //für jede kleinere Zelle pro größerer Zelle...
+ for(int y4 = y; y4 < y+r; y4++){
+ if ( x4 < referenceMap.getMinX() || y4 < referenceMap.getMinY() || x4 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y4 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+ Float.isNaN(referenceMap.getRasterSampleAsFloat(x4,y4)))
+ continue;
+ WnCell = Wn / (float)nCells; //pro Zelle wird Mittelwert des Vergleichs genommen
+ actualValidation.setRasterSample( WnCell ,x4 ,y4);
+ outStep.getGrid(ngrids-1).setRasterSample(WnCell,x4,y4);
+ }
+
+ SumCells += (float)nCells; //Summiere alle Zellen auf
+ SumWn += Wn; //Summiere die gewichteten Anteile auf
+ }
+ //Total Agreement:
+ //siehe Pontius...
+ statusOut.println(SumWn+" / "+SumCells);
+ totalAgreement = SumWn / (float)SumCells; //Ergebnisformel
+ statusOut.println(totalAgreement);
+ outResults.addValue(totalAgreement);
+ resultArray[0][ngrids] = totalAgreement;
+ // statusOut.println("Gesamt-Pixel: "+RoverallSum);
+ // statusOut.println("Anzahl Klassen: "+RnumClasses);
+ // statusOut.println("Fraction Correct: "+fractionCorrect);
+ }
+
+
+ System.out.println(resultArray[0][1]+","+resultArray[0][2]+","+resultArray[0][3]+","+
+ resultArray[0][4]+","+resultArray[0][5]+","+resultArray[0][6]+
+ ","+resultArray[0][7]+","+resultArray[0][8]+","+resultArray[0][9]+","+resultArray[0][10]+","+resultArray[0][11]+","+resultArray[0][12]);
+
+ System.out.print("Finished step " + (stepNo) + " in "
+ + ((System.currentTimeMillis() - localStartTime)) + " ms");
+ localStartTime = System.currentTimeMillis();
+ System.out.println(" with sum (local calculated): " + RoverallSum);
+
+ }
+}
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidationContentManager.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidationContentManager.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidationContentManager.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,47 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.DefaultModelResource;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.PropertiesResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+import edu.bonn.xulu.plugin.model.clue.ClueModelContentManager;
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ScalarProperty;
+
+
+/**
+ * This class defines and handle the three resources for the models
+ * <ol>
+ * <li><b> </li>
+ * <li><b> {@link AverageNeighborhoodSerialDemoModel}</b></li>
+ * <li><b> {@link AverageNeighborhoodParallelDemoModel}</b></li>
+ * <li><b> {@link AVNTuned}</b></li>
+ * </ol>
+ * @see ClueModelContentManager
+ * @author automatically generated using {@link edu.bonn.xulu.plugin.appl.GeoModelCodeGenerator}
+ * @version 1.0
+ */
+public class MultipleResolutionValidationContentManager extends AbstractModelContentManager {
+
+ /**
+ * Erzeugt einen neuen ContentManager fuer das Modell {@linkplain AverageNeighborhoodParallelDemoModel}.
+ */
+ public MultipleResolutionValidationContentManager() {
+ super(6);
+ // Steps
+ resource[0] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+ // Reference Map
+ resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Reference Map",ScalarProperty.class,WritableGrid.class,false);
+ // Simulation Map
+ resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Simulation Map",ScalarProperty.class,WritableGrid.class,false);
+ // Actual Validation
+ resource[3] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Actual Validation",ScalarProperty.class,WritableGrid.class,false);
+ // Map for every Resolution
+ resource[4] = new DefaultModelResource(ModelResource.CATEGORY_OUTPUT,"Step Results",MultiGrid.class,false);
+ // Output Values
+ resource[5] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Validation Results",ListProperty.class,Double.class,false);
+ }
+}
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthContentManager.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthContentManager.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthContentManager.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,37 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.model.clue.ClueModelContentManager;
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ScalarProperty;
+
+
+/**
+ * This class defines and handle the three resources for the models
+ * <ol>
+ * <li><b> </li>
+ * <li><b> {@link AverageNeighborhoodSerialDemoModel}</b></li>
+ * <li><b> {@link AverageNeighborhoodParallelDemoModel}</b></li>
+ * <li><b> {@link AVNTuned}</b></li>
+ * </ol>
+ * @see ClueModelContentManager
+ * @author automatically generated using {@link edu.bonn.xulu.plugin.appl.GeoModelCodeGenerator}
+ * @version 1.0
+ */
+public class UrbanGrowthContentManager extends AbstractModelContentManager {
+
+ /**
+ * Erzeugt einen neuen ContentManager fuer das Modell {@linkplain AverageNeighborhoodParallelDemoModel}.
+ */
+ public UrbanGrowthContentManager() {
+ super(3);
+ // Input Grid
+ resource[0] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Input Grid",ScalarProperty.class,WritableGrid.class,false);
+ // Output Grid
+ resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Output Grid",ScalarProperty.class,WritableGrid.class,false);
+ // Number of steps
+ resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+ }
+}
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,839 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import java.awt.Rectangle;
+import java.util.HashMap;
+
+import org.geotools.feature.Feature;
+
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+
+/**
+ * This very simple model looks at every grid cell and takes the average
+ * over a the surrounding cells in a specified neighborhood. It was implemented
+ * as demonstration of the Xulu / V functionality. You can see the parallel version
+ * of this model in {@link AverageNeighborhoodParallelDemoModel} and also a tuned
+ * version using late-merging support in {@link AVNTuned}. Beachte die Methode {@link #calculateNeighbors(int, int, float)}.
+ *
+ *
+ * <ol>
+ * <li><b>Input Grid ({@code inputGrid}):</b> A grid with input values </li>
+ * <li><b>Output Grid ({@code outputGrid}):</b> A grid where the output is
+ * stored </li>
+ * <li><b>Number of steps ({@code steps}):</b> the number of steps to
+ * compute. </li>
+ * </ol>
+ *
+ * @see AverageNeighborhoodContentManager
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class UrbanGrowthModel extends AbstractStepModel {
+
+ /**
+ * the width/height of the neighborhood region over which the algorithm takes
+ * the average
+ */
+// private int neighborhoodRange = 1;
+
+ /**
+ * Speichert den ContentManager fuer das Modell.
+ *
+ * @see AverageNeighborhoodContentManager
+ */
+ protected UrbanGrowthModelContentManager contManager;
+
+ // ********** Lese/Schreibrechte, die fuer den gesamten ***********
+ // ********** Modellanlauf gehalten werden muessen ***********
+ private PropertyReadAccess RA_inputGrid = null; // Input Grid
+ private PropertyWriteAccess WA_outputGrid = null; // Output Grid
+ private PropertyReadAccess RA_steps = null; // Number of steps
+ private PropertyReadAccess RA_areaRestr = null; //Area Restrictions
+ private PropertyReadAccess RA_spread = null; //Spread-Koeffizient
+ private PropertyReadAccess RA_disp = null; //Dispersions-Koeffizient
+ private PropertyReadAccess RA_breed = null; //Breed-Koeffizient
+ private PropertyReadAccess RA_roadGravity = null; //Road-Gravity-Koeffizient
+ private PropertyReadAccess RA_slope = null; //Slope-Koeffizient
+ private PropertyReadAccess RA_criticalSlope = null; //Critical Slope Value
+ private PropertyReadAccess RA_roadGrid = null; //Road Grid
+ private PropertyReadAccess RA_slopeGrid = null; //Slope Grid
+ private PropertyWriteAccess WA_outStep = null; // Step Results
+
+ // **************** Variablen mit denen gearbeitet wird *******************
+ private WritableGrid inputGrid = null; // Input Grid
+ private WritableGrid outputGrid = null; // Output Grid
+ private PropertyReadAccess steps = null; // Number of steps
+ private WritableGrid areaRestr = null; //Area Restrictions
+ protected double spread = 0; //Spread-Koeffizient
+ protected double disp = 0; //Dispersions-Koeffizient
+ protected double breed = 0; //Breed-Koeffizient
+ protected double roadGravity = 0; //Road-Gravity-Koeffizient
+ protected double slope = 0; //Slope-Koeffizient
+ protected double criticalSlope = 0; //Critical Slope Value
+ private WritableGrid roadGrid = null; //Road Grid
+ private WritableGrid slopeGrid = null; //Slope Grid
+ private MultiGrid outStep = null; //Step Results
+
+ private static final int[][] NEIGHBOR = new int[][] {
+ {-1,-1}, {0,-1}, {1,-1},
+ {-1, 0}, {1, 0},
+ {-1, 1}, {0, 1}, {1, 1}
+ };
+
+ protected HashMap<Number,Number> slopeLUT;
+
+ /**
+ * Erzeugt eine neue Instanz des Modells.
+ */
+ public UrbanGrowthModel() {
+ super(new UrbanGrowthModelContentManager());
+ this.contManager = (UrbanGrowthModelContentManager) super.contManager;
+ }
+
+
+ /**
+ * Initializes the model. Like in the init method of every {@link XuluModel}
+ * the resources are initalized.
+ */
+ public void performModelInit() {
+ if (contManager == null)
+ return;
+ // Zugriffsrechte aus Ressourcen/Propertys holen
+ RA_inputGrid = null;
+ if (contManager.getResource(0).getData() != null)
+ RA_inputGrid = ((ScalarProperty) contManager.getResource(0)
+ .getData()).getReadAccess(this);
+ WA_outputGrid = null;
+ if (contManager.getResource(1).getData() != null)
+ WA_outputGrid = ((ScalarProperty) contManager.getResource(1)
+ .getData()).getWriteAccess(this);
+ RA_steps = null;
+ if (contManager.getResource(2).getData() != null)
+ RA_steps = ((ScalarProperty) contManager.getResource(2).getData())
+ .getReadAccess(this);
+ RA_areaRestr = null;
+ if (contManager.getResource(3).getData() != null)
+ RA_areaRestr = ((ScalarProperty) contManager.getResource(3)
+ .getData()).getReadAccess(this);
+ RA_spread = null;
+ if (contManager.getResource(4).getData() != null)
+ RA_spread = ((ScalarProperty) contManager.getResource(4).getData())
+ .getReadAccess(this);
+ RA_disp = null;
+ if (contManager.getResource(5).getData() != null)
+ RA_disp = ((ScalarProperty) contManager.getResource(5).getData())
+ .getReadAccess(this);
+ RA_breed = null;
+ if (contManager.getResource(6).getData() != null)
+ RA_breed = ((ScalarProperty) contManager.getResource(6).getData())
+ .getReadAccess(this);
+ RA_roadGravity = null;
+ if (contManager.getResource(7).getData() != null)
+ RA_roadGravity = ((ScalarProperty) contManager.getResource(7).getData())
+ .getReadAccess(this);
+ RA_slope = null;
+ if (contManager.getResource(8).getData() != null)
+ RA_slope = ((ScalarProperty) contManager.getResource(8).getData())
+ .getReadAccess(this);
+ RA_criticalSlope = null;
+ if (contManager.getResource(9).getData() != null)
+ RA_criticalSlope = ((ScalarProperty) contManager.getResource(9).getData())
+ .getReadAccess(this);
+ RA_roadGrid = null;
+ if (contManager.getResource(10).getData() != null)
+ RA_roadGrid = ((ScalarProperty) contManager.getResource(10)
+ .getData()).getReadAccess(this);
+ RA_slopeGrid = null;
+ if (contManager.getResource(11).getData() != null)
+ RA_slopeGrid = ((ScalarProperty) contManager.getResource(11)
+ .getData()).getReadAccess(this);
+
+ // Variablen belegen mit denen gearbeitet wird
+ inputGrid = (WritableGrid) RA_inputGrid.getValue();
+ outputGrid = (WritableGrid) WA_outputGrid.getValue();
+ steps = RA_steps;
+ areaRestr = (WritableGrid) RA_areaRestr.getValue();
+
+ this.stepCount = steps.getValueAsInt();
+ // this.spread = RA_spread.getValueAsFloat();
+ spread = RA_spread.getValueAsDouble();
+ disp = RA_disp.getValueAsDouble();
+ breed = RA_breed.getValueAsDouble();
+ roadGravity = RA_roadGravity.getValueAsDouble();
+ slope = RA_slope.getValueAsDouble();
+ criticalSlope = RA_criticalSlope.getValueAsDouble();
+ roadGrid = (WritableGrid) RA_roadGrid.getValue();
+ slopeGrid = (WritableGrid) RA_slopeGrid.getValue();
+ outStep = (MultiGrid)contManager.getResource(12).getData();
+
+
+ int startAnz = 0;
+ for (int i = 0; i < inputGrid.getWidth();i++ ) {
+ for (int ii = 0; ii < inputGrid.getHeight(); ii++ ) {
+ //if (inputGrid.getRasterSampleAsFloat(i,ii) == 1f);
+ float val = inputGrid.getRasterSampleAsFloat(i,ii);
+ if (val == 1.0 ) {
+ val = 1f;
+ startAnz++;
+ }
+ else val = 0f;
+
+ //inputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+ outputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+ }
+ }
+ statusOut.println("Anzahl der startenden Individuen: "+startAnz);
+ statusOut.println(NEIGHBOR.length);
+
+ int slopeMax = 0;
+ for (int s = 0; s < inputGrid.getWidth();s++){
+ for(int ss = 0; ss < inputGrid.getHeight();ss++){
+ float slopeVal = slopeGrid.getRasterSampleAsFloat(s,ss);
+ if (slopeVal > slopeMax){
+ slopeMax = (int) slopeVal;
+ }
+ }
+ }
+ statusOut.println("Maximale Hangneigung: "+slopeMax);
+
+
+ //Erstellt einen Lookup-Table
+ slopeLUT = new HashMap<Number,Number>();
+
+ int MaxSlopeResistance = 0;
+ double exp = 0.0;
+ MaxSlopeResistance = 100;
+ exp = (slope / (MaxSlopeResistance / 2));
+ double[] lookup = new double[slopeMax+1];
+ Number key = 0;
+
+ for (int i = 0;i <= slopeMax;i++){
+ if (i <= criticalSlope){
+ double val = (criticalSlope - i) / criticalSlope;
+ lookup[i] = 1 - Math.pow(val,exp);
+ key = i;
+ } else{
+ lookup[i] = 1;
+ key = i;
+ }
+ slopeLUT.put(key,lookup[i]);
+ statusOut.println(slopeLUT.get(key));
+ }
+ }
+
+ /**
+ * like in every model: frees the resources
+ */
+ public void performModelDispose() {
+
+ // Ressourcen wieder freigeben
+ releaseAccess(RA_inputGrid);
+ releaseAccess(WA_outputGrid);
+ releaseAccess(RA_steps);
+ releaseAccess(RA_areaRestr);
+ releaseAccess(RA_spread);
+ releaseAccess(RA_disp);
+ releaseAccess(RA_breed);
+ releaseAccess(RA_roadGravity);
+ releaseAccess(RA_slope);
+ releaseAccess(RA_criticalSlope);
+ releaseAccess(RA_roadGrid);
+ releaseAccess(RA_slopeGrid);
+ releaseAccess(WA_outStep);
+ }
+
+ /**
+ * This very simple model looks at every grid cell and takes the average
+ * over a the surrounding cells in a specified neighborhood.
+ * @exception IllegalArgumentException wenn das dadad
+ * @param stepNo
+ * zu modellierender Schritt (beginnend bei 1!)
+ */
+ public void performModelStep(int stepNo) {
+
+ statusOut.println("Starting step " + stepNo + "...");
+ Number number = slopeLUT.get(79);
+ statusOut.println(number);
+
+ int areaMinX = inputGrid.getMinX(); //Dimensionen des Rasters
+ int areaMinY = inputGrid.getMinY();
+ int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+ int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+ int areaWidth = inputGrid.getWidth();
+ int areaHeight = inputGrid.getHeight();
+
+ long localStartTime = System.currentTimeMillis();
+ boolean anyBodyAlive = false;
+
+ boolean[][] tmpGrid = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];
+ Float actUrb = null;
+
+ int nbX = 0; // X-Koordinate einer Nachbarzelle
+ int nbY = 0; // Y-Koordinate einer Nachbarzelle
+ int[] nbCell = null;
+
+ int anzSpreadTreffer = 0;
+ int anzDispTreffer = 0;
+ int anzBreedTreffer = 0;
+
+ //DISPERSION
+ double disp_value = Math.round((disp*0.005)* Math.sqrt(Math.pow(inputGrid.getWidth(), 2)+(Math.pow(inputGrid.getHeight(), 2))));
+
+ int dispRandX = 0;
+ int dispRandY = 0;
+ float slopeRandDisp = 0;
+
+ //ROAD GRAVITY
+ double max_RG_value = 100.0;
+ double rg_value = Math.round((roadGravity/max_RG_value)*((areaWidth + areaHeight)/16));
+ double max_search_index = Math.round(4*((int)rg_value*(1+(int)rg_value)));
+ statusOut.println("RG-Value:"+rg_value);
+ statusOut.println("Max-SearchIndex"+max_search_index);
+
+
+ /*****************************************************************
+ * DISPERSION and BREED
+ *****************************************************************/
+
+ int p = 0; //Verteile soviel neue Pixel zufällig in geeigneten Bereichen, bis disp_value erreicht ist
+ do{
+ dispRandX = Math.round((float) Math.random()*areaWidth); //Zufallsposition in X-Richtung
+ dispRandY = Math.round((float) Math.random()*areaHeight); //Zufallsposition in Y-Richtung
+ if ( dispRandX < areaMinX || dispRandY < areaMinY || dispRandX > areaMaxX || dispRandY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(dispRandX,dispRandY) != 0 || outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY) == 1)
+ continue; //wenn in Area Restriction oder wenn schon Siedlung da ist, mach weiter
+ slopeRandDisp = (float) Math.random(); //Zufallszahl zum Abgleich mit Slope-Koeffizient
+ int getSlope = (int) slopeGrid.getRasterSampleAsFloat(dispRandX,dispRandY); //holt sich den Slope-Wert aus dem Slope-Raster
+ Double doubleObj = (Double)slopeLUT.get(getSlope); //holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+ double slopeDouble = doubleObj.doubleValue(); //konvertiert Double-Objekt in double-Wert
+ statusOut.println(getSlope+","+slopeDouble+"----Random: "+slopeRandDisp);
+ if(slopeDouble < slopeRandDisp){
+ tmpGrid[dispRandX][dispRandY] = true; //true wird ins temporäre Raster geschrieben
+ anzDispTreffer++;
+ //BREED
+ float breedRnd = (float) Math.random()*100;
+ int nbBreedX = 0;
+ int nbBreedY = 0;
+ int breedNb = 0;
+ float NbValue = 0f;
+ if (tmpGrid[dispRandX][dispRandY] == true && breedRnd < breed)
+ breedNb = calculateNeighbors(dispRandX,dispRandY,NbValue);
+
+ int RNBreed1 = 0;
+ int RNBreed2 = 0;
+ float RNBreedSlope = 0f;
+
+ if (breedNb >= 2 && tmpGrid[dispRandX][dispRandY] == true){
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNBreed1 = 1 + Math.round((float)Math.random()*(breedNb-1));
+ RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));
+ if (RNBreed2 == RNBreed1)
+ RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+ nbBreedX = dispRandX+NEIGHBOR[cellBreed][0];
+ nbBreedY = dispRandY+NEIGHBOR[cellBreed][1];
+ if ( nbBreedX < areaMinX || nbBreedY < areaMinY || nbBreedX > areaMaxX || nbBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbBreedX,nbBreedY) != 0)
+ continue;
+ RNBreedSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY);
+ if (breedSample == 0f){
+ anzBreedTemp++;
+ nbPossibleBreedUrban = new int[] {nbBreedX,nbBreedY,anzBreedTemp};
+ if (nbPossibleBreedUrban[2] == RNBreed1 || nbPossibleBreedUrban[2] == RNBreed2 && slopeDoubleNb < RNBreedSlope){
+ tmpGrid[nbBreedX][nbBreedY] = true;
+ anzBreedTreffer++;
+ }
+ }
+ }
+ }
+ }
+ p++;
+
+ } while (p < disp_value); //while, statt for-Schleife, da Überprüfung erst am Ende vorgenommen werden kann
+ //am Anfang der Schleife ist noch nicht klar, ob alle Pixel verteilt werden können
+ //da ein Teil in Ausschlussflächen etc. landen würde
+
+ /*********************************************************************
+ * EDGE
+ *********************************************************************/
+
+ //iterate over all cells
+ for (int x = 0; x < inputGrid.getWidth(); x++)
+ for (int y = 0; y < inputGrid.getHeight(); y++) { //für jede Zelle in x/y-Richtung
+
+ int areaMinXadd = areaMinX + x; //Dimensionen des Rasters
+ int areaMinYadd = areaMinY + y;
+
+ int anzNachbarn = 0;
+ int noNachbarn = 0;
+
+
+ for (int nbCellIdx = 0; nbCellIdx < NEIGHBOR.length; nbCellIdx++) {
+ checkBreakingCommands();
+ nbX = x+NEIGHBOR[nbCellIdx][0]; //Nachbarschaft der Zellen
+ nbY = y+NEIGHBOR[nbCellIdx][1];
+ nbCell = new int[] {nbX,nbY}; //jede Nachbarzelle
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);
+ if (rasterSample > 0f) //ist Nachbarzelle urban (1), wird sie gezählt
+ anzNachbarn++;
+ if (rasterSample == 0f)
+ noNachbarn++;
+ }
+
+ boolean lebt = outputGrid.getRasterSampleAsFloat(areaMinXadd , areaMinYadd ) > 0f; //eine Zelle lebt, wenn sie 1 ist
+
+ //hier ist die Abfrage wieviele Nachbarzellen am Leben sind
+ //daraus ergibt sich, ob im tmpGrid die entsprechende Zelle
+ //true oder false ist
+
+ float SpR = (float) Math.random()*100; //eine Zufallszahl zwischen 0 und 1
+ int RN = 0; //hier wird eine Integer-Zufallszahl reingeschrieben
+
+ if (lebt && (anzNachbarn>=2) && (SpR < spread) && (noNachbarn >=1)) { //wenn eine Zelle lebt, mindestens 2 lebende Nachbarzellen hat, der Spread-Koeffizient größer als die für die Zelle berechnete Zufallszahl und mindestens einen nicht lebenden Nachbarn hat
+ int anzTemp = 0;
+ int[] nbPossibleUrban = null;
+ RN = 1 + Math.round((float)Math.random()*(noNachbarn-1));
+ float RNEdgeSlope = 0;
+ int nbUrbanX = 0;
+ int nbUrbanY = 0;
+ for (int nbCellChange = 0; nbCellChange < NEIGHBOR.length; nbCellChange++){ //dann starte eine Schleife
+ checkBreakingCommands();
+ nbX = x+NEIGHBOR[nbCellChange][0];
+ nbY = y+NEIGHBOR[nbCellChange][1];
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ RNEdgeSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbX,nbY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY); //holt die Werte aus den jeweiligen Nachbarzellen
+ if (rasterSample == 0f){ //wenn der Wert 0 ist
+ anzTemp++; //wird Anzahl der möglichen Zellen erhöht
+ nbPossibleUrban = new int[] {nbX,nbY,anzTemp}; //Koordinaten und Nummern dieser Zellen werden in Array geschrieben
+ int urbanNbTemp = 0;
+ float NbValueEdge = 1f;
+ if (nbPossibleUrban[2] == RN){ //wenn Nummer im "PossibleUrban"-Array der Zufallszahl entspricht, die zwischen 1 und Anzahl der möglichen Zellen liegt...
+ //damit die Städte nicht zu sehr "ausfransen" steht eine Zelle nur zur Umwandlung zur Verfügung, wenn auch sie mind. 2 urbane Nachbarn hat
+ urbanNbTemp = calculateNeighbors(nbX,nbY,NbValueEdge);
+ if (urbanNbTemp >= 2 && tmpGrid[nbX][nbY]==false && slopeDoubleNb < RNEdgeSlope){
+ tmpGrid[nbX][nbY] = true; //wird true ins temporäre Raster geschrieben
+ anzSpreadTreffer++;
+ }
+ }
+ }
+ nbCell = new int[] {nbX,nbY,(int) rasterSample};
+ }
+ }
+ if (anzNachbarn>0) anyBodyAlive = true;
+ }
+
+ /*********************************************************************
+ * ROAD
+ *********************************************************************/
+
+ int anzGesamt = 0;
+ int[] cellValue = null;
+
+ //For-Schleife zählt alle als true markierten Zellen im Temp-Raster
+ for (int x = 0; x < inputGrid.getWidth();x++)
+ for(int y = 0; y < inputGrid.getHeight();y++){
+ int X = inputGrid.getMinX() + x;
+ int Y = inputGrid.getMinY() + y;
+ if (tmpGrid[X][Y]==true){
+ anzGesamt++;
+ }
+ }
+
+ int RSearchRoad = 0;
+ int r = 1; //Verteile soviel neue Pixel zufällig in geeigneten Bereichen, bis disp_value erreicht ist
+
+ Rectangle gridBounds = new Rectangle(0, 0, inputGrid.getWidth(), inputGrid.getHeight()); //ein Rechteck wird definiert
+ do{
+ RSearchRoad = Math.round((float)Math.random()*anzGesamt); //Zufallszahl zwischen 1 und Anzahl aller bisher neu hinzugekommener Pixel
+ int anzTruePixels = 0;
+ int roadNeighborhoodRange = 0;
+ int RSearchNbRoad = 0;
+ for (int x = 0; x < inputGrid.getWidth();x++){ //gesamtes Raster wird durchsucht
+ for(int y = 0; y < inputGrid.getHeight();y++){
+ int X = inputGrid.getMinX() + x;
+ int Y = inputGrid.getMinY() + y;
+ if (tmpGrid[X][Y]==true){
+ anzTruePixels++; //wird true-Pixel gefunden, wird anzTruePixels hochgezählt
+ cellValue = new int[] {X,Y,anzTruePixels}; //und Koordinaten in Array geschrieben
+ int tempRoadCell[] = null;
+ int tempNbRoadCell[] = null;
+ if (cellValue[2] == RSearchRoad){
+ //statusOut.println(cellValue[0]+","+cellValue[1]+","+cellValue[2]);
+ //statusOut.println(r+","+RSearchRoad);
+ r++;
+ //JETZT NACH STRAßE SUCHEN!!
+ float roadValue = roadGrid.getRasterSampleAsFloat(X,Y);
+ statusOut.println(roadValue);
+ if (roadValue > 0.0){
+ tempRoadCell = new int[] {X,Y};
+ statusOut.println("Strasse in Entfernung 0: "+tempRoadCell[0]+","+tempRoadCell[1]);
+ //roadWalk(tempRoadCell[0],tempRoadCell[1]);
+ int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1]);
+ if(nbCellNew != null){
+ tmpGrid[nbCellNew[0]][nbCellNew[1]] = true;
+ statusOut.println(nbCellNew.length);
+ statusOut.println("Neue Zelle: "+nbCellNew[0]+","+nbCellNew[1]);
+ statusOut.println("++++++++++++++++++++++++++++++++++++++++");
+ float nbRoadBreed = 0f;
+ int nbRoadBreedNeighbors = 0;
+ nbRoadBreedNeighbors = calculateNeighbors(nbCellNew[0],nbCellNew[1],nbRoadBreed);
+ int RNRoadBreed1 = 0;
+ int RNRoadBreed2 = 0;
+ int nbRoadBreedX = 0;
+ int nbRoadBreedY = 0;
+ int anzRoadBreedTreffer = 0;
+
+ if (nbRoadBreedNeighbors >= 2){
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNRoadBreed1 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ float RNRoadBreedSlope = 0f;
+
+ if (RNRoadBreed2 == RNRoadBreed1)
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+ nbRoadBreedX = nbCellNew[0]+NEIGHBOR[cellBreed][0];
+ nbRoadBreedY = nbCellNew[1]+NEIGHBOR[cellBreed][1];
+ if ( nbRoadBreedX < areaMinX || nbRoadBreedY < areaMinY || nbRoadBreedX > areaMaxX || nbRoadBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY) != 0)
+ continue;
+ RNRoadBreedSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ if (breedSample == 0f){
+ anzBreedTemp++;
+ nbPossibleBreedUrban = new int[] {nbRoadBreedX,nbRoadBreedY,anzBreedTemp};
+ if (nbPossibleBreedUrban[2] == RNRoadBreed1 || nbPossibleBreedUrban[2] == RNRoadBreed2 && slopeDoubleNb < RNRoadBreedSlope){
+ tmpGrid[nbRoadBreedX][nbRoadBreedY] = true;
+ anzRoadBreedTreffer++;
+ statusOut.println("Road-Breed-Treffer: "+anzRoadBreedTreffer);
+ }
+ }
+ }
+
+
+ }
+
+ } else{
+ statusOut.println("Keine neue Zelle gefunden");
+ }
+ } else{
+ int anzRoadNb = 0;
+
+ //HIER MIT FOR SCHLEIFE RECHTECK WACHSEN LASSEN!!!
+ for (int roadSearch = 0; roadSearch <= rg_value; roadSearch++){
+ if (anzRoadNb > 0)
+ continue;
+ for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++){
+ for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){
+ if (gridBounds.contains(nbRoadCellsX, nbRoadCellsY))
+ if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY) != 0)
+ continue;
+ float roadValueNb = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY);
+ if (roadValueNb > 0f){
+ anzRoadNb++;
+ }
+ //statusOut.println("Strasse in Entfernung 1: "+anzRoadNb+","+nbRoadCellsX+","+nbRoadCellsY);
+ }
+ }
+ roadNeighborhoodRange++;
+ RSearchNbRoad = Math.round((float)Math.random()*anzRoadNb);
+ //statusOut.println("--> Zyklus "+roadNeighborhoodRange+"Nachbarn: "+anzRoadNb);
+ //statusOut.println(RSearchNbRoad);
+ int anzTempRoadNb = 0;
+ for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++){
+ for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){
+ statusOut.println("TEST-ROAD: "+nbRoadCellsX+","+nbRoadCellsY);
+ if (gridBounds.contains(nbRoadCellsX, nbRoadCellsY))
+ if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY) != 0)
+ continue;
+ float roadValueNbTemp = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY);
+ if (roadValueNbTemp > 0f){
+ anzTempRoadNb++;
+ tempNbRoadCell = new int[] {nbRoadCellsX,nbRoadCellsY,anzTempRoadNb};
+ if (tempNbRoadCell[2]==RSearchNbRoad){
+ //statusOut.println("Treffer: "+tempNbRoadCell[0]+","+tempNbRoadCell[1]+","+tempNbRoadCell[2]);
+ tempRoadCell = tempNbRoadCell;
+ statusOut.println("Strasse in Entfernung "+roadSearch+": "+tempRoadCell[0]+","+tempRoadCell[1]+","+tempRoadCell[2]);
+ //roadWalk(tempRoadCell[0],tempRoadCell[1]);
+ int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1]);
+ if(nbCellNew != null){
+ tmpGrid[nbCellNew[0]][nbCellNew[1]] = true;
+ statusOut.println(nbCellNew.length);
+ statusOut.println("Neue Zelle: "+nbCellNew[0]+","+nbCellNew[1]);
+ statusOut.println("++++++++++++++++++++++++++++++++++++++++");
+
+ float nbRoadBreed = 0f;
+ int nbRoadBreedNeighbors = 0;
+ nbRoadBreedNeighbors = calculateNeighbors(nbCellNew[0],nbCellNew[1],nbRoadBreed);
+ int RNRoadBreed1 = 0;
+ int RNRoadBreed2 = 0;
+ int nbRoadBreedX = 0;
+ int nbRoadBreedY = 0;
+ int anzRoadBreedTreffer = 0;
+
+ if (nbRoadBreedNeighbors >= 2){
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNRoadBreed1 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ float RNRoadBreedSlope = 0f;
+ if (RNRoadBreed2 == RNRoadBreed1)
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+ nbRoadBreedX = nbCellNew[0]+NEIGHBOR[cellBreed][0];
+ nbRoadBreedY = nbCellNew[1]+NEIGHBOR[cellBreed][1];
+ if ( nbRoadBreedX < areaMinX || nbRoadBreedY < areaMinY || nbRoadBreedX > areaMaxX || nbRoadBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY) != 0)
+ continue;
+ RNRoadBreedSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ if (breedSample == 0f){
+ anzBreedTemp++;
+ nbPossibleBreedUrban = new int[] {nbRoadBreedX,nbRoadBreedY,anzBreedTemp};
+ if (nbPossibleBreedUrban[2] == RNRoadBreed1 || nbPossibleBreedUrban[2] == RNRoadBreed2 && slopeDoubleNb < RNRoadBreedSlope){
+ tmpGrid[nbRoadBreedX][nbRoadBreedY] = true;
+ anzRoadBreedTreffer++;
+ statusOut.println("Road-Breed-Treffer: "+anzRoadBreedTreffer);
+ }
+ }
+ }
+
+
+ }
+ } else{
+ statusOut.println("Keine neue Zelle gefunden");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ } while (r <= breed);
+
+ statusOut.println("Spread-Treffer: "+anzSpreadTreffer);
+ statusOut.println("Dispersion-Treffer: "+anzDispTreffer);
+ statusOut.println("Breed-Treffer: "+anzBreedTreffer);
+ statusOut.println("Treffer gesamt: "+anzGesamt);
+
+ outStep.addGrid();
+
+
+ // TempGrid auf das echte Grid schreiben
+ for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+ for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+
+ int X = inputGrid.getMinX() + x;
+ int Y = inputGrid.getMinY() + y;
+
+ boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f; //eine Zelle lebt, wenn sie 1 ist
+ if (tmpGrid[x][y] == false) //wenn im temporären Raster nichts drinsteht...
+ tmpGrid[x][y] = lebt; //wird der Wert aus dem Ausgangsraster übernommen
+
+
+ outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);
+ actUrb = (Float)outputGrid.getRasterSample(x,y);
+ outStep.getGrid(stepNo-1).setRasterSample(actUrb,x,y);
+ }
+ }
+
+
+ if (!anyBodyAlive) {
+ stepCount = stepNo;
+ statusOut.println("Lebt keiner mehr... höre hier auf!");
+ }
+
+
+ System.out.println("Finished step " + (stepNo) + " in "
+ + ((System.currentTimeMillis() - localStartTime)) + " ms\n");
+ localStartTime = System.currentTimeMillis();
+ }
+
+ private int[] roadWalk(int X,int Y){
+// statusOut.println(X+","+Y);
+ boolean end_of_road;
+ end_of_road = false;
+ int run = 0;
+ int run_value = 0;
+ int[] nbCellNew = null;
+ int[] nbCellTemp = null;
+ while(!end_of_road){
+ end_of_road = true;
+ int nbRoadX = 0;
+ int nbRoadY = 0;
+ int areaMinX = inputGrid.getMinX(); //Dimensionen des Rasters
+ int areaMinY = inputGrid.getMinY();
+ int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+ int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+ int roadNb = 0;
+ int roadNbTemp = 0;
+ int RN = 0;
+
+ int[] nbCell = null;
+ for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){
+ nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+ nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+ if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ //if (areaRestr.getRasterSampleAsFloat(nbRoadX,nbRoadY) != 0)
+ // continue;
+ float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);
+ if (roadSample > 0f)
+ roadNb++;
+ }
+ // statusOut.println("Nachbarn von temporaerer Strassenzelle: "+roadNb);
+
+ if (roadNb > 0){
+ RN = 1 + Math.round((float)Math.random()*(roadNb-1));
+
+ for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){
+ nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+ nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+ if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);
+ if (roadSample > 0f){
+ roadNbTemp++;
+ nbCell = new int[] {nbRoadX,nbRoadY,roadNbTemp};
+ if (nbCell[2] == RN){
+ statusOut.println("Nachbarzelle gefunden: "+nbCell[0]+","+nbCell[1]+","+nbCell[2]);
+ end_of_road = false;
+ run++;
+ X = nbRoadX;
+ Y = nbRoadY;
+ float roadSample2 = roadGrid.getRasterSampleAsFloat(X,Y);
+ run_value = (int) (roadSample2 / 100 * disp);
+ // statusOut.println("Run: "+run);
+ // statusOut.println("Run_Value: "+run_value);
+ // statusOut.println(X+","+Y+","+roadSample2);
+ if (run > run_value){
+ end_of_road = true;
+ // statusOut.println("Endzelle erreicht!! Run:"+run+"RunValue: "+run_value);
+ float NbValue = 0f;
+ int Nb = calculateNeighbors(X,Y,NbValue);
+ // statusOut.println("moegliche Nachbarzellen nach RoadWalk: "+Nb);
+ RN = 1 + Math.round((float)Math.random()*(Nb-1));
+ // statusOut.println("Random: "+RN);
+ if (Nb > 0){
+ int nbUrbanizeX = 0;
+ int nbUrbanizeY = 0;
+ int NbTemp = 0;
+ float RNRoadSlope = 0f;
+ // statusOut.println(X+","+Y);
+ for (int urbanizeCells = 0; urbanizeCells < NEIGHBOR.length; urbanizeCells++){
+ nbUrbanizeX = X+NEIGHBOR[urbanizeCells][0];
+ nbUrbanizeY = Y+NEIGHBOR[urbanizeCells][1];
+ if ( nbUrbanizeX < areaMinX || nbUrbanizeY < areaMinY || nbUrbanizeX > areaMaxX || nbUrbanizeY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);
+ RNRoadSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ if (rasterSample == 0f){
+ NbTemp++;
+ nbCellTemp = new int[] {nbUrbanizeX,nbUrbanizeY,NbTemp};
+ if (nbCellTemp[2] == RN && slopeDoubleNb < RNRoadSlope){
+ nbCellNew = new int[] {nbCellTemp[0],nbCellTemp[1],nbCellTemp[2]};
+ }
+ }
+ }
+
+ } else{
+ nbCellNew = null;
+ } break;
+ }
+
+ }
+
+ }
+ }
+
+ }
+ }
+ return nbCellNew;
+ }
+
+ private int calculateNeighbors(int X, int Y, float NbValue){
+ int nbX = 0;
+ int nbY = 0;
+ int areaMinX = inputGrid.getMinX(); //Dimensionen des Rasters
+ int areaMinY = inputGrid.getMinY();
+ int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+ int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+ int Nb = 0;
+ for (int nbCells = 0; nbCells < NEIGHBOR.length; nbCells++){
+ nbX = X+NEIGHBOR[nbCells][0];
+ nbY = Y+NEIGHBOR[nbCells][1];
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);
+ if (rasterSample == NbValue)
+ Nb++;
+ }
+ // statusOut.println("..."+Nb+"...");
+ return Nb;
+ }
+
+ protected static boolean checkNoData(int x, int y, WritableGrid grid) {
+ return Float.isNaN(grid.getRasterSampleAsFloat(x,y));
+ }
+}
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibration.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibration.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibration.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,1167 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import java.awt.Rectangle;
+import java.util.HashMap;
+
+import appl.util.RasterUtil;
+
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ListPropertyWriteAccess;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+
+/**
+ * @see AverageNeighborhoodContentManager
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class UrbanGrowthModelCalibration extends AbstractStepModel {
+
+ private int neighborhoodRange = 0;
+ private float[] resultArray;
+ private float[][] resultArrayFinal;
+ /**
+ * Speichert den ContentManager fuer das Modell.
+ */
+ protected UrbanGrowthModelCalibrationContentManager contManager;
+
+ // ********** Lese/Schreibrechte, die fuer den gesamten ***********
+ // ********** Modellanlauf gehalten werden muessen ***********
+ private PropertyReadAccess RA_steps = null; // Number of steps
+ private PropertyReadAccess RA_MonteCarlo = null; //Number of MonteCarlo Iterations
+ private PropertyReadAccess RA_inputGrid = null; // Input Grid
+ private PropertyWriteAccess WA_outputGrid = null; // Output Grid
+ private PropertyReadAccess RA_areaRestr = null; //Area Restrictions
+ private PropertyReadAccess RA_spreadStart = null; //Spread-Koeffizient
+ private PropertyReadAccess RA_spreadStep = null; //Spread-Koeffizient
+ private PropertyReadAccess RA_spreadEnd = null; //Spread-Koeffizient
+ private PropertyReadAccess RA_dispStart = null; //Dispersions-Koeffizient
+ private PropertyReadAccess RA_dispStep = null; //Dispersions-Koeffizient
+ private PropertyReadAccess RA_dispEnd = null; //Dispersions-Koeffizient
+ private PropertyReadAccess RA_breedStart = null; //Breed-Koeffizient
+ private PropertyReadAccess RA_breedStep = null; //Breed-Koeffizient
+ private PropertyReadAccess RA_breedEnd = null; //Breed-Koeffizient
+ private PropertyReadAccess RA_roadGravityStart = null; //Road-Gravity-Koeffizient
+ private PropertyReadAccess RA_roadGravityStep = null; //Road-Gravity-Koeffizient
+ private PropertyReadAccess RA_roadGravityEnd = null; //Road-Gravity-Koeffizient
+ private PropertyReadAccess RA_slopeStart = null; //Slope-Koeffizient
+ private PropertyReadAccess RA_slopeStep = null; //Slope-Koeffizient
+ private PropertyReadAccess RA_slopeEnd = null; //Slope-Koeffizient
+ private PropertyReadAccess RA_criticalSlope = null; //Critical Slope Value
+ private PropertyReadAccess RA_roadGrid = null; //Road Grid
+ private PropertyReadAccess RA_slopeGrid = null; //Slope Grid
+ private PropertyReadAccess RA_referenceGrid = null; //Observed Validation Grid
+ private ListPropertyWriteAccess WA_outResults = null; //Output Validation Results
+
+ // **************** Variablen mit denen gearbeitet wird *******************
+ private WritableGrid inputGrid = null; // Input Grid
+ private WritableGrid outputGrid = null; // Output Grid
+ private int steps = 0; // Number of steps
+ private int MonteCarlo = 0; //Number of Monte Carlo Iterations
+ private WritableGrid areaRestr = null; //Area Restrictions
+ protected double spreadStart = 0; //Spread-Koeffizient
+ protected double spreadStep = 0; //Spread-Koeffizient
+ protected double spreadEnd = 0; //Spread-Koeffizient
+ protected double dispStart = 0; //Dispersions-Koeffizient
+ protected double dispStep = 0; //Dispersions-Koeffizient
+ protected double dispEnd = 0; //Dispersions-Koeffizient
+ protected double breedStart = 0; //Breed-Koeffizient
+ protected double breedStep = 0; //Breed-Koeffizient
+ protected double breedEnd = 0; //Breed-Koeffizient
+ protected double roadGravityStart = 0; //Road-Gravity-Koeffizient
+ protected double roadGravityStep = 0; //Road-Gravity-Koeffizient
+ protected double roadGravityEnd = 0; //Road-Gravity-Koeffizient
+ protected double slopeStart = 0; //Slope-Koeffizient
+ protected double slopeStep = 0; //Slope-Koeffizient
+ protected double slopeEnd = 0; //Slope-Koeffizient
+ protected double criticalSlope = 0; //Critical Slope Value
+ private WritableGrid roadGrid = null; //Road Grid
+ private WritableGrid slopeGrid = null; //Slope Grid
+ private WritableGrid referenceGrid = null; //Observed Validation Grid
+ private ListPropertyWriteAccess outResults = null; //Output Validation Results
+
+ private static final int[][] NEIGHBOR = new int[][] {
+ {-1,-1}, {0,-1}, {1,-1},
+ {-1, 0}, {1, 0},
+ {-1, 1}, {0, 1}, {1, 1}
+ };
+
+ protected HashMap<Number,Number> slopeLUT;
+
+ /**
+ * Erzeugt eine neue Instanz des Modells.
+ */
+ public UrbanGrowthModelCalibration() {
+ super(new UrbanGrowthModelCalibrationContentManager());
+ this.contManager = (UrbanGrowthModelCalibrationContentManager) super.contManager;
+ }
+
+
+ /**
+ * Initializes the model. Like in the init method of every {@link XuluModel}
+ * the resources are initalized.
+ */
+ public void performModelInit() {
+ if (contManager == null)
+ return;
+ // Zugriffsrechte aus Ressourcen/Propertys holen
+ RA_steps = null;
+ if (contManager.getResource(0).getData() != null)
+ RA_steps = ((ScalarProperty) contManager.getResource(0).getData())
+ .getReadAccess(this);
+ RA_MonteCarlo = null;
+ if (contManager.getResource(1).getData() != null)
+ RA_MonteCarlo = ((ScalarProperty) contManager.getResource(1).getData())
+ .getReadAccess(this);
+ RA_inputGrid = null;
+ if (contManager.getResource(2).getData() != null)
+ RA_inputGrid = ((ScalarProperty) contManager.getResource(2)
+ .getData()).getReadAccess(this);
+ WA_outputGrid = null;
+ if (contManager.getResource(3).getData() != null)
+ WA_outputGrid = ((ScalarProperty) contManager.getResource(3)
+ .getData()).getWriteAccess(this);
+ RA_areaRestr = null;
+ if (contManager.getResource(4).getData() != null)
+ RA_areaRestr = ((ScalarProperty) contManager.getResource(4)
+ .getData()).getReadAccess(this);
+ RA_roadGrid = null;
+ if (contManager.getResource(5).getData() != null)
+ RA_roadGrid = ((ScalarProperty) contManager.getResource(5)
+ .getData()).getReadAccess(this);
+ RA_slopeGrid = null;
+ if (contManager.getResource(6).getData() != null)
+ RA_slopeGrid = ((ScalarProperty) contManager.getResource(6)
+ .getData()).getReadAccess(this);
+ RA_referenceGrid = null;
+ if(contManager.getResource(7).getData() != null)
+ RA_referenceGrid = ((ScalarProperty) contManager.getResource(7)
+ .getData()).getReadAccess(this);
+ RA_spreadStart = null;
+ if (contManager.getResource(8).getData() != null)
+ RA_spreadStart = ((ScalarProperty) contManager.getResource(8).getData())
+ .getReadAccess(this);
+ RA_spreadStep = null;
+ if (contManager.getResource(9).getData() != null)
+ RA_spreadStep = ((ScalarProperty) contManager.getResource(9).getData())
+ .getReadAccess(this);
+ RA_spreadEnd = null;
+ if (contManager.getResource(10).getData() != null)
+ RA_spreadEnd = ((ScalarProperty) contManager.getResource(10).getData())
+ .getReadAccess(this);
+ RA_dispStart = null;
+ if (contManager.getResource(11).getData() != null)
+ RA_dispStart = ((ScalarProperty) contManager.getResource(11).getData())
+ .getReadAccess(this);
+ RA_dispStep = null;
+ if (contManager.getResource(12).getData() != null)
+ RA_dispStep = ((ScalarProperty) contManager.getResource(12).getData())
+ .getReadAccess(this);
+ RA_dispEnd = null;
+ if (contManager.getResource(13).getData() != null)
+ RA_dispEnd = ((ScalarProperty) contManager.getResource(13).getData())
+ .getReadAccess(this);
+ RA_breedStart = null;
+ if (contManager.getResource(14).getData() != null)
+ RA_breedStart = ((ScalarProperty) contManager.getResource(14).getData())
+ .getReadAccess(this);
+ RA_breedStep = null;
+ if (contManager.getResource(15).getData() != null)
+ RA_breedStep = ((ScalarProperty) contManager.getResource(15).getData())
+ .getReadAccess(this);
+ RA_breedEnd = null;
+ if (contManager.getResource(16).getData() != null)
+ RA_breedEnd = ((ScalarProperty) contManager.getResource(16).getData())
+ .getReadAccess(this);
+ RA_roadGravityStart = null;
+ if (contManager.getResource(17).getData() != null)
+ RA_roadGravityStart = ((ScalarProperty) contManager.getResource(17).getData())
+ .getReadAccess(this);
+ RA_roadGravityStep = null;
+ if (contManager.getResource(18).getData() != null)
+ RA_roadGravityStep = ((ScalarProperty) contManager.getResource(18).getData())
+ .getReadAccess(this);
+ RA_roadGravityEnd = null;
+ if (contManager.getResource(19).getData() != null)
+ RA_roadGravityEnd = ((ScalarProperty) contManager.getResource(19).getData())
+ .getReadAccess(this);
+ RA_slopeStart = null;
+ if (contManager.getResource(20).getData() != null)
+ RA_slopeStart = ((ScalarProperty) contManager.getResource(20).getData())
+ .getReadAccess(this);
+ RA_slopeStep = null;
+ if (contManager.getResource(21).getData() != null)
+ RA_slopeStep = ((ScalarProperty) contManager.getResource(21).getData())
+ .getReadAccess(this);
+ RA_slopeEnd = null;
+ if (contManager.getResource(22).getData() != null)
+ RA_slopeEnd = ((ScalarProperty) contManager.getResource(22).getData())
+ .getReadAccess(this);
+ RA_criticalSlope = null;
+ if (contManager.getResource(23).getData() != null)
+ RA_criticalSlope = ((ScalarProperty) contManager.getResource(23).getData())
+ .getReadAccess(this);
+ WA_outResults = null;
+ if (contManager.getResource(24).getData() != null)
+ WA_outResults = ((ListProperty) contManager.getResource(24)
+ .getData()).getWriteAccess(this);
+
+ // Variablen belegen mit denen gearbeitet wird
+ steps = RA_steps.getValueAsInt();
+ MonteCarlo = RA_MonteCarlo.getValueAsInt();
+ inputGrid = (WritableGrid) RA_inputGrid.getValue();
+ outputGrid = (WritableGrid) WA_outputGrid.getValue();
+ areaRestr = (WritableGrid) RA_areaRestr.getValue();
+
+ //this.stepCount = steps.getValueAsInt();
+ stepCount = 1;
+ spreadStart = RA_spreadStart.getValueAsDouble();
+ spreadStep = RA_spreadStep.getValueAsDouble();
+ spreadEnd = RA_spreadEnd.getValueAsDouble();
+ dispStart = RA_dispStart.getValueAsDouble();
+ dispStep = RA_dispStep.getValueAsDouble();
+ dispEnd = RA_dispEnd.getValueAsDouble();
+ breedStart = RA_breedStart.getValueAsDouble();
+ breedStep = RA_breedStep.getValueAsDouble();
+ breedEnd = RA_breedEnd.getValueAsDouble();
+ roadGravityStart= RA_roadGravityStart.getValueAsDouble();
+ roadGravityStep = RA_roadGravityStep.getValueAsDouble();
+ roadGravityEnd = RA_roadGravityEnd.getValueAsDouble();
+ slopeStart = RA_slopeStart.getValueAsDouble();
+ slopeStep = RA_slopeStep.getValueAsDouble();
+ slopeEnd = RA_slopeEnd.getValueAsDouble();
+ criticalSlope = RA_criticalSlope.getValueAsDouble();
+ roadGrid = (WritableGrid) RA_roadGrid.getValue();
+ slopeGrid = (WritableGrid) RA_slopeGrid.getValue();
+ referenceGrid = (WritableGrid) RA_referenceGrid.getValue();
+ outResults = WA_outResults;
+
+ int startAnz = 0;
+ for (int i = 0; i < inputGrid.getWidth();i++ ) {
+ for (int ii = 0; ii < inputGrid.getHeight(); ii++ ) {
+ //if (inputGrid.getRasterSampleAsFloat(i,ii) == 1f);
+ float val = inputGrid.getRasterSampleAsFloat(i,ii);
+ if (val == 1.0 ) {
+ val = 1f;
+ startAnz++;
+ }
+ else val = 0f;
+
+ inputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+ outputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+ }
+ }
+ }
+
+ /**
+ * like in every model: frees the resources
+ */
+ public void performModelDispose() {
+
+ // Ressourcen wieder freigeben
+ releaseAccess(RA_steps);
+ releaseAccess(RA_MonteCarlo);
+ releaseAccess(RA_inputGrid);
+ releaseAccess(WA_outputGrid);
+ releaseAccess(RA_areaRestr);
+ releaseAccess(RA_spreadStart);
+ releaseAccess(RA_spreadStep);
+ releaseAccess(RA_spreadEnd);
+ releaseAccess(RA_dispStart);
+ releaseAccess(RA_dispStep);
+ releaseAccess(RA_dispEnd);
+ releaseAccess(RA_breedStart);
+ releaseAccess(RA_breedStep);
+ releaseAccess(RA_breedEnd);
+ releaseAccess(RA_roadGravityStart);
+ releaseAccess(RA_roadGravityStep);
+ releaseAccess(RA_roadGravityEnd);
+ releaseAccess(RA_slopeStart);
+ releaseAccess(RA_slopeStep);
+ releaseAccess(RA_slopeEnd);
+ releaseAccess(RA_criticalSlope);
+ releaseAccess(RA_roadGrid);
+ releaseAccess(RA_slopeGrid);
+ releaseAccess(WA_outResults);
+ }
+
+
+ public void performModelStep(int stepNo) {
+
+ /**
+ * Ermitteln der maximalen Hangneigung
+ */
+ int slopeMax = 0;
+ for (int s = 0; s < inputGrid.getWidth();s++){
+ for(int ss = 0; ss < inputGrid.getHeight();ss++){
+ float slopeVal = slopeGrid.getRasterSampleAsFloat(s,ss);
+ if (slopeVal > slopeMax){
+ slopeMax = (int) slopeVal; //Maximale Hangneigung im Slope-Bild
+ }
+ }
+ }
+
+ /**
+ * Definition von Variablen, die als Output des gesamten Kalibrierungsdurchlaufs benötigt werden
+ */
+ float MCtotalAgreementResult = 0f;
+ int ngrids = 0;
+ int slopeOut = 0;
+ int spreadOut = 0;
+ int dispOut = 0;
+ int breedOut = 0;
+ int roadGravityOut = 0;
+
+ /**
+ * Start des gesamten Kalibrierungsdurchlaufs:
+ * 1. Für jeden Slope-Wert zwischen Start und End...
+ * 2. Für jeden Spread-Wert zwischen Start und End...
+ * 3. Für jeden Dispersion-Wert zwischen Start und End...
+ * 4. Für jeden Breed-Wert zwischen Start und End...
+ */
+
+ for(int slope = (int)slopeStart;slope <= (int)slopeEnd; slope = slope+(int)slopeStep){
+
+ //Variablendefinitionen bzgl. Slope-Berechnungen
+ slopeOut = slope; //slopeOut wird als Ausgabewert benötigt und erhält am Anfang der Schleife den Wert von slope
+ slopeLUT = new HashMap<Number,Number>(); //Definition eines Lookup-Tables (HashMap --> jeder Indexwert bekommt einen Wert zugewiesen)
+ int MaxSlopeResistance = 100; //Hangneigung kann maximal 100% betragen
+ double exp = 0.0;
+ exp = (slope / (MaxSlopeResistance / 2));
+ double[] lookup = new double[slopeMax+1]; //ein Array, das slopeMax+1 Stellen lang ist (+1, da Arrays mit der Zahl 0 beginnen)
+ Number key = 0; //die Zahl key nimmt den Wert des Index für den Lookup-Table an
+
+ //Aufbau des Lookup-Tables
+ for (int i = 0;i <= slopeMax;i++){ //Für jede Hangneigung zwischen 0% und dem maximal im Bild vorhandenen Wert
+ if (i <= criticalSlope){ //der kleiner als criticalSlope ist
+ double val = (criticalSlope - i) / criticalSlope; //berechne den Wert val
+ lookup[i] = 1 - Math.pow(val,exp); //und füge den Wert val hoch exp an der Stelle i in das Array lookup ein
+ key = i; //Index-Wert ist key
+ } else{ //Ist der Wert größer als criticalSlope
+ lookup[i] = 1; //wird der Wert 1 in das Array eingefügt
+ key = i;
+ }
+ slopeLUT.put(key,lookup[i]); //put platziert die Werte key und den entsprechenden Wert aus dem Array lookup in die HashMap-Tabelle
+// statusOut.println(slopeLUT.get(key));
+ }
+
+
+ for(int spread = (int)spreadStart; spread <= (int)spreadEnd; spread = spread+(int)spreadStep){
+ spreadOut = spread; //spreadOut wird als Ausgabewert benötigt und erhält am Anfang der Schleife den Wert von spread
+ for(int disp = (int)dispStart; disp <= (int)dispEnd; disp = disp+(int)dispStep){
+ dispOut = disp; //dispOut wird als Ausgabewert benötigt und erhält am Anfang der Schleife den Wert von disp
+ for(int breed = (int)breedStart; breed <= (int)breedEnd+1; breed = breed+(int)breedStep){
+ breedOut = breed; //breedOut wird als Ausgabewert benötigt und erhält am Anfang der Schleife den Wert von breed
+ for(int roadGravity = (int)roadGravityStart; roadGravity <=(int)roadGravityEnd; roadGravity = roadGravity+(int)roadGravityStep){
+ roadGravityOut = roadGravity; //roadGravityOut wird als Ausgabewert benötigt und erhält am Anfang der Schleife den Wert von roadGravity
+
+ /**
+ * An dieser Stelle beginnt der eigentliche Modellalgorithmus des UrbanGrowth-Modells.
+ * Da bei der Kalibrierung das Modell durch jede mögliche Kombination an Werten durchiteriert,
+ * wird der Algorithmus x-mal durchlaufen.
+ * Da häufig Zufallswerte in das Modell eingebaut sind, ist es sinnvoll jeden Iterationsschritt mehrfach durchzuführen
+ * und die Ergebnisse zu mitteln. Dies geschieht "Monte-Carlo"-mal (Wert wird in Modellparametern angegeben).
+ * Das bedeutet, dass der Modellalgorithmus zusätzlich in die folgende for-Schleife eingebunden ist.
+ */
+ float pos1 = 0; //das hier ist nicht optimal gelöst. Für jede Stelle im Result Array eine eigene Variable definiert, die später ausgelesen wird. Habs nur auf die Schnelle nicht besser hinbekommen
+ float pos2 = 0;
+ float pos3 = 0;
+ float pos4 = 0;
+ float pos5 = 0;
+ float pos6 = 0;
+ float pos7 = 0;
+ float pos8 = 0;
+ float pos9 = 0;
+ float pos10 = 0;
+ float pos11 = 0;
+ float pos12 = 0;
+ for(int MC = 1; MC <= MonteCarlo; MC++){ //führe den Modellalgorithmus 1 bis MC-mal durch
+ RasterUtil.copyInto(inputGrid, outputGrid); //starte dabei aber mit dem Eingabebild (das Ausgabebild verändert sich nach jedem Modellschritt!!)
+// statusOut.println("Starting step " + stepNo + "...");
+// statusOut.println(steps);
+
+ /**
+ * Der Modelllauf muss so oft wiederholt werden, wie Jahre für den Kalibrierungsmodus angegeben wurden.
+ * Für die anschließende Bewertung der Ergebnisse zählt nur das Bild des Schlussjahres
+ */
+ for(int timeSteps = 1;timeSteps <=steps;timeSteps++){
+ //Dimensionen des Rasters werden definiert
+ int areaMinX = outputGrid.getMinX();
+ int areaMinY = outputGrid.getMinY();
+ int areaMaxX = outputGrid.getMinX() + outputGrid.getWidth() - 1;
+ int areaMaxY = outputGrid.getMinY() + outputGrid.getHeight() - 1;
+ int areaWidth = outputGrid.getWidth();
+ int areaHeight = outputGrid.getHeight();
+
+ //weitere Variablendefinitionen
+ long localStartTime = System.currentTimeMillis();
+ boolean anyBodyAlive = false;
+
+ boolean[][] tmpGrid = new boolean[outputGrid.getWidth()][outputGrid.getHeight()]; //temporäres Raster, in das true und false geschrieben wird, je nachdem ob Siedlung nach Modellschritt vorhanden ist oder nicht
+ Float actUrb = null;
+
+ int nbX = 0; // X-Koordinate einer Nachbarzelle
+ int nbY = 0; // Y-Koordinate einer Nachbarzelle
+ int[] nbCell = null;
+
+ int anzSpreadTreffer = 0;
+ int anzDispTreffer = 0;
+ int anzBreedTreffer = 0;
+
+ // Variablen, die für den DISPERSION Bereich benötigt werden
+ double disp_value = Math.round((disp*0.005)* Math.sqrt(Math.pow(outputGrid.getWidth(), 2)+(Math.pow(outputGrid.getHeight(), 2))));
+ int dispRandX = 0;
+ int dispRandY = 0;
+ float slopeRandDisp = 0;
+
+ // Variablen, die für den ROAD GRAVITY Bereich benötigt werden
+ double max_RG_value = 100.0;
+ double rg_value = Math.round((roadGravity/max_RG_value)*((areaWidth + areaHeight)/16));
+ double max_search_index = Math.round(4*((int)rg_value*(1+(int)rg_value)));
+// statusOut.println("RG-Value:"+rg_value);
+// statusOut.println("Max-SearchIndex"+max_search_index);
+
+
+ /*****************************************************************
+ * DISPERSION and BREED
+ *****************************************************************/
+
+ //Verteile soviel neue Pixel zufällig in geeigneten Bereichen, bis disp_value erreicht ist
+ //-->Beginn einer do-while-Schleife
+ int p = 0;
+ do{
+ dispRandX = Math.round((float) Math.random()*areaWidth); //Zufallsposition in X-Richtung
+ dispRandY = Math.round((float) Math.random()*areaHeight); //Zufallsposition in Y-Richtung
+ if ( dispRandX < areaMinX || dispRandY < areaMinY || dispRandX > areaMaxX || dispRandY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(dispRandX,dispRandY) != 0 || outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY) == 1)
+ continue; //wenn in Area Restriction oder wenn schon Siedlung da ist, mach weiter
+ slopeRandDisp = (float) Math.random(); //Zufallszahl zum Abgleich mit Slope-Koeffizient
+ int getSlope = (int) slopeGrid.getRasterSampleAsFloat(dispRandX,dispRandY); //holt sich den Slope-Wert aus dem Slope-Raster
+ Double doubleObj = (Double)slopeLUT.get(getSlope); //holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+ double slopeDouble = doubleObj.doubleValue(); //konvertiert Double-Objekt in double-Wert
+ // statusOut.println(getSlope+","+slopeDouble+"----Random: "+slopeRandDisp);
+ if(slopeDouble < slopeRandDisp){ //wenn der Slope-Wert kleiner als der Wert der Zufallszahl ist
+ tmpGrid[dispRandX][dispRandY] = true; //wird "true" ins temporäre Raster geschrieben (neue Siedlung entsteht!!)
+ anzDispTreffer++; //Anzahl der Disp-Treffer wird hochgezählt
+
+ //
+ //hier beginnt der BREED Bereich
+ //
+ //Variablendefinitionen
+ float breedRnd = (float) Math.random()*100;
+ int nbBreedX = 0;
+ int nbBreedY = 0;
+ int breedNb = 0;
+ float NbValue = 0f;
+ if (tmpGrid[dispRandX][dispRandY] == true && breedRnd < breed) //wenn durch DISPERSION neue Zellen entstanden sind UND der Breed-Zufallswert kleiner als der Breed-Wert ist
+ breedNb = calculateNeighbors(dispRandX,dispRandY,NbValue); //werden die Nachbarzellen dieser neuen Zellen gezählt, und zwar alle, die zur weiteren Besiedlung zur Verfügung stehen (--> Funktion calculateNeighbors)
+
+ int RNBreed1 = 0;
+ int RNBreed2 = 0;
+ float RNBreedSlope = 0f;
+
+ if (breedNb >= 2 && tmpGrid[dispRandX][dispRandY] == true){ //sind mehr als 2 Nachbarzellen verfügbar und die Koordinate X/Y true...
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNBreed1 = 1 + Math.round((float)Math.random()*(breedNb-1)); //werden 2 Zufallszahlen zwischen 1 und breedNb erzeugt
+ RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));
+ if (RNBreed2 == RNBreed1) //falls beide Zufallszahlen den gleichen Wert haben sollten, wird die zweite Zahl nochmal erzeugt
+ RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){ //die Nachbarn jeder Zelle müssen nochmal durchgezählt werden, um zu bestimmen, welche per Zufallswert in Siedlung umgewandelt werden soll
+ nbBreedX = dispRandX+NEIGHBOR[cellBreed][0];
+ nbBreedY = dispRandY+NEIGHBOR[cellBreed][1];
+ if ( nbBreedX < areaMinX || nbBreedY < areaMinY || nbBreedX > areaMaxX || nbBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbBreedX,nbBreedY) != 0)
+ continue;
+ RNBreedSlope = (float)Math.random(); //Zufallszahl zum Abgleich mit Slope-Koeffizient
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY); //holt sich den Slope-Wert aus dem Slope-Raster
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb); //holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+ double slopeDoubleNb = doubleObjNb.doubleValue(); //konvertiert Double-Objekt in double-Wert
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY); //holt den Wert aus dem Output-Raster
+ if (breedSample == 0f){ //ist der Wert aus dem Output-Raster 0
+ anzBreedTemp++; //wird die Zahl der zur Verfügung stehenden Zellen hochgezählt
+ nbPossibleBreedUrban = new int[] {nbBreedX,nbBreedY,anzBreedTemp}; //und die Nummer und Koordinaten der jeweiligen Zellen in ein Array geschrieben
+ if (nbPossibleBreedUrban[2] == RNBreed1 || nbPossibleBreedUrban[2] == RNBreed2 && slopeDoubleNb < RNBreedSlope){ //entspricht die Nummer einer der zuvor erstellten Zufallswerte...
+ tmpGrid[nbBreedX][nbBreedY] = true; //wird in das temporäre Raster "true" geschrieben (--> neue Siedlung durch BREED entstanden!!)
+ anzBreedTreffer++; //die Anzahl der BREED-Treffer wird gezählt
+ }
+ }
+ }
+ }
+ } p++; //der Wert p wird hochgezählt, bis der Disp-Wert erreicht ist
+
+ } while (p < disp_value); //while, statt for-Schleife, da Überprüfung erst am Ende vorgenommen werden kann
+ //am Anfang der Schleife ist noch nicht klar, ob alle Pixel verteilt werden können
+ //da ein Teil in Ausschlussflächen etc. landen würde
+ //ENDE DISPERSION UND BREED WACHSTUM
+
+ /*********************************************************************
+ * EDGE
+ *********************************************************************/
+
+ //iterate over all cells
+ for (int x = 0; x < outputGrid.getWidth(); x++)
+ for (int y = 0; y < outputGrid.getHeight(); y++) { //für jede Zelle in x/y-Richtung
+
+ //Dimensionen des Rasters
+ int areaMinXadd = areaMinX + x;
+ int areaMinYadd = areaMinY + y;
+
+ //Variablendefinitionen
+ int anzNachbarn = 0;
+ int noNachbarn = 0;
+
+ for (int nbCellIdx = 0; nbCellIdx < NEIGHBOR.length; nbCellIdx++) { //zählt alle Nachbarn jeder Rasterzelle durch
+ checkBreakingCommands();
+ nbX = x+NEIGHBOR[nbCellIdx][0]; //Nachbarschaft der Zellen
+ nbY = y+NEIGHBOR[nbCellIdx][1];
+ nbCell = new int[] {nbX,nbY}; //jede Nachbarzelle
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);
+ if (rasterSample > 0f) //ist Nachbarzelle urban (1), wird sie als anzNachbarn gezählt
+ anzNachbarn++;
+ if (rasterSample == 0f) //ist sie nicht urban (0), wird sie als noNachbarn gezählt
+ noNachbarn++;
+ }
+
+ boolean lebt = outputGrid.getRasterSampleAsFloat(areaMinXadd , areaMinYadd ) > 0f; //eine Zelle lebt, wenn sie 1 ist
+
+ //hier ist die Abfrage wieviele Nachbarzellen am Leben sind
+ //daraus ergibt sich, ob im tmpGrid die entsprechende Zelle
+ //true oder false ist
+
+ float SpR = (float) Math.random()*100; //eine Zufallszahl zwischen 0 und 1
+ int RN = 0; //hier wird eine Integer-Zufallszahl reingeschrieben
+
+ if (lebt && (anzNachbarn>=2) && (SpR < spread) && (noNachbarn >=1)) { //wenn eine Zelle lebt, mindestens 2 lebende Nachbarzellen hat, der Spread-Koeffizient größer als die für die Zelle berechnete Zufallszahl und mindestens einen nicht lebenden Nachbarn hat
+
+ //Variablendefinitionen
+ int anzTemp = 0;
+ int[] nbPossibleUrban = null;
+ RN = 1 + Math.round((float)Math.random()*(noNachbarn-1));
+ float RNEdgeSlope = 0;
+ int nbUrbanX = 0;
+ int nbUrbanY = 0;
+
+ for (int nbCellChange = 0; nbCellChange < NEIGHBOR.length; nbCellChange++){ //dann starte eine Schleife
+ checkBreakingCommands();
+ nbX = x+NEIGHBOR[nbCellChange][0];
+ nbY = y+NEIGHBOR[nbCellChange][1];
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ RNEdgeSlope = (float)Math.random(); //Zufallszahl zum Abgleich mit Slope-Koeffizient
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbX,nbY); //holt sich den Slope-Wert aus dem Slope-Raster
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb); //holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+ double slopeDoubleNb = doubleObjNb.doubleValue(); //konvertiert Double-Objekt in double-Wert
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY); //holt die Werte aus den jeweiligen Nachbarzellen
+ if (rasterSample == 0f){ //wenn der Wert 0 ist
+ anzTemp++; //wird Anzahl der möglichen Zellen erhöht
+ nbPossibleUrban = new int[] {nbX,nbY,anzTemp}; //Koordinaten und Nummern dieser Zellen werden in Array geschrieben
+ int urbanNbTemp = 0;
+ float NbValueEdge = 1f;
+ if (nbPossibleUrban[2] == RN){ //wenn Nummer im "PossibleUrban"-Array der Zufallszahl entspricht, die zwischen 1 und Anzahl der möglichen Zellen liegt...
+ //damit die Städte nicht zu sehr "ausfransen" steht eine Zelle nur zur Umwandlung zur Verfügung, wenn auch sie mind. 2 urbane Nachbarn hat
+ urbanNbTemp = calculateNeighbors(nbX,nbY,NbValueEdge);
+ if (urbanNbTemp >= 2 && tmpGrid[nbX][nbY]==false && slopeDoubleNb < RNEdgeSlope){
+ tmpGrid[nbX][nbY] = true; //wird true ins temporäre Raster geschrieben
+ anzSpreadTreffer++; //und die Anzahl der Spread-Treffer gezählt
+ }
+ }
+ }
+ nbCell = new int[] {nbX,nbY,(int) rasterSample}; //die Nummer und Koordinaten der jeweiligen Zellen wird in ein Array geschrieben
+ }
+ }
+ if (anzNachbarn>0) anyBodyAlive = true;
+ } //ENDE EDGE-WACHSTUM
+
+ /*********************************************************************
+ * ROAD
+ *********************************************************************/
+
+ //Variablendefinitionen
+ int anzGesamt = 0;
+ int[] cellValue = null;
+ int RSearchRoad = 0;
+ int r = 1; //Verteile soviel neue Pixel zufällig in geeigneten Bereichen, bis disp_value erreicht ist
+ //Rectangle gridBounds = new Rectangle(0, 0, outputGrid.getWidth(), outputGrid.getHeight()); //ein Rechteck wird definiert
+
+ //For-Schleife zählt alle als true markierten Zellen im Temp-Raster
+ for (int x = 0; x < outputGrid.getWidth();x++)
+ for(int y = 0; y < outputGrid.getHeight();y++){
+ int X = outputGrid.getMinX() + x;
+ int Y = outputGrid.getMinY() + y;
+ if (tmpGrid[X][Y]==true){
+ anzGesamt++;
+ }
+ }
+
+ //Beginn einer do-while-Schleife
+ do{
+ //Variablendefinitionen
+ RSearchRoad = Math.round((float)Math.random()*anzGesamt); //Zufallszahl zwischen 1 und Anzahl aller bisher neu hinzugekommener Pixel
+ int anzTruePixels = 0;
+ int roadNeighborhoodRange = 0;
+ int RSearchNbRoad = 0;
+ for (int x = 0; x < outputGrid.getWidth();x++){ //gesamtes Raster wird durchsucht
+ for(int y = 0; y < outputGrid.getHeight();y++){
+ int X = outputGrid.getMinX() + x;
+ int Y = outputGrid.getMinY() + y;
+ if (tmpGrid[X][Y]==true){
+ anzTruePixels++; //wird true-Pixel gefunden, wird anzTruePixels hochgezählt
+ cellValue = new int[] {X,Y,anzTruePixels}; //und Koordinaten in Array geschrieben
+ int tempRoadCell[] = null;
+ int tempNbRoadCell[] = null;
+ if (cellValue[2] == RSearchRoad){ //eins der neu entstandenen Pixel wird nach Zufallsprinzip ausgewählt
+ //statusOut.println(cellValue[0]+","+cellValue[1]+","+cellValue[2]);
+ //statusOut.println(r+","+RSearchRoad);
+ r++; //Anzahl der so gefundenen Zellen wird hochgezählt, bis Road-Koeffizient erreicht wird
+ //JETZT NACH STRAßE SUCHEN!!
+ float roadValue = roadGrid.getRasterSampleAsFloat(X,Y); //An Koordinate X/Y wird Wert aus roadGrid geholt
+ // statusOut.println(roadValue);
+ if (roadValue > 0.0){ //wenn Wert > 0 ist...
+ tempRoadCell = new int[] {X,Y}; //wird an Koordinate X/Y eine temporäre Straßenzelle platziert (bzw. Koordinaten in Array geschrieben
+ // statusOut.println("Strasse in Entfernung 0: "+tempRoadCell[0]+","+tempRoadCell[1]);
+ int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1],disp); //von dieser Koordinate aus wird ein Road-Walk gestartete (siehe Funktion roadWalk!!)
+ if(nbCellNew != null){ //kommt nach roadWalk ein Wert zurück (d.h. wurde potenziell zu besiedelndes Pixel gefunden)...
+ tmpGrid[nbCellNew[0]][nbCellNew[1]] = true; //wird "true" ins temporäre Raster geschrieben (neue Siedlungszelle gefunden!!)
+ // statusOut.println(nbCellNew.length);
+ // statusOut.println("Neue Zelle: "+nbCellNew[0]+","+nbCellNew[1]);
+ // statusOut.println("++++++++++++++++++++++++++++++++++++++++");
+
+ //wenn per roadWalk eine neue Zelle gefunden wurde, kann sie auch noch als Ausbreitungszentrum fungieren. Daher geht von ihr
+ //nochmals ein "Breed" aus.
+
+ //Variablendefinitionen
+ float nbRoadBreed = 0f;
+ int nbRoadBreedNeighbors = 0;
+ nbRoadBreedNeighbors = calculateNeighbors(nbCellNew[0],nbCellNew[1],nbRoadBreed); //Nachbarzellen der neuen Zelle werden gezählt
+ int RNRoadBreed1 = 0;
+ int RNRoadBreed2 = 0;
+ int nbRoadBreedX = 0;
+ int nbRoadBreedY = 0;
+ int anzRoadBreedTreffer = 0;
+
+ if (nbRoadBreedNeighbors >= 2){ //sind mehr als 2 potenzielle Nachbarzellen verfügbar
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNRoadBreed1 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ float RNRoadBreedSlope = 0f;
+ if (RNRoadBreed2 == RNRoadBreed1)
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+ nbRoadBreedX = nbCellNew[0]+NEIGHBOR[cellBreed][0];
+ nbRoadBreedY = nbCellNew[1]+NEIGHBOR[cellBreed][1];
+ if ( nbRoadBreedX < areaMinX || nbRoadBreedY < areaMinY || nbRoadBreedX > areaMaxX || nbRoadBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY) != 0)
+ continue;
+ RNRoadBreedSlope = (float)Math.random(); //Zufallszahl zum Abgleich mit Slope-Koeffizient
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY); //holt sich den Slope-Wert aus dem Slope-Raster
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb); //holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+ double slopeDoubleNb = doubleObjNb.doubleValue(); //konvertiert Double-Objekt in double-Wert
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY); //holt die Werte aus den jeweiligen Nachbarzellen
+ if (breedSample == 0f){ //hat die Nachbarzelle den Wert 0 wird anzBreedTemp hochgezählt
+ anzBreedTemp++;
+ nbPossibleBreedUrban = new int[] {nbRoadBreedX,nbRoadBreedY,anzBreedTemp}; //und Koordinaten dieser Zelle in Array geschrieben
+ if (nbPossibleBreedUrban[2] == RNRoadBreed1 || nbPossibleBreedUrban[2] == RNRoadBreed2 && slopeDoubleNb < RNRoadBreedSlope){ //stimmt der Wert mit einer der beiden Zufallszahlen überein und ist laut Slope-Wert Besiedlung erlaubt...
+ tmpGrid[nbRoadBreedX][nbRoadBreedY] = true; //..wird "true" ins temporäre Raster geschrieben (neue Siedlungszelle erstellt!)
+ anzRoadBreedTreffer++; //Anzahl der durch Breed nach RoadWalk erzeugten Zellen wird hochgezählt
+ // statusOut.println("Road-Breed-Treffer: "+anzRoadBreedTreffer);
+ }
+ }
+ }
+ }
+ } else{ //kommt nach Road-Walk nichts zurück...
+ // statusOut.println("Keine neue Zelle gefunden");
+ }
+ //ist an der Stelle, an der eine neue Zelle entstanden war keine Straße, wird im Folgenden in ihrer Nähe danach gesucht...
+ } else{
+
+ int anzRoadNb = 0;
+
+ //HIER MIT FOR SCHLEIFE RECHTECK WACHSEN LASSEN!!!
+ for (int roadSearch = 0; roadSearch <= rg_value; roadSearch++){ //vergrößere die Nachbarschaft, bis rg_value erreicht ist
+ if (anzRoadNb > 0) //höre auf, sobald Straße in der Nachbarschaft gefunden wurde
+ continue;
+ for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++)
+ for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){
+ //if (gridBounds.contains(nbRoadCellsX, nbRoadCellsY))
+ if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ // if (areaRestr.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY) != 0)
+ // continue;
+ float roadValueNb = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY); //hole Wert aus Straßenraster
+ if (roadValueNb > 0f) //ist der Wert im Straßen-Raster > 0 zähle den Wert anzRoadNb hoch
+ anzRoadNb++;
+
+ //statusOut.println("Strasse in Entfernung 1: "+anzRoadNb+","+nbRoadCellsX+","+nbRoadCellsY);
+ }
+ roadNeighborhoodRange++;
+ RSearchNbRoad = Math.round((float)Math.random()*anzRoadNb);
+ //statusOut.println("--> Zyklus "+roadNeighborhoodRange+"Nachbarn: "+anzRoadNb);
+ //statusOut.println(RSearchNbRoad);
+ int anzTempRoadNb = 0;
+ for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++){
+ for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){
+ // statusOut.println("TEST-ROAD: "+nbRoadCellsX+","+nbRoadCellsY);
+ // if (gridBounds.contains(nbRoadCellsX, nbRoadCellsY))
+ if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ // if (areaRestr.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY) != 0)
+ // continue;
+ float roadValueNbTemp = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY); //hole Wert aus Straßenraster
+ if (roadValueNbTemp > 0f){ //ist der Wert im Straßen-Raster > 0 zähle den Wert anzRoadNbTemp hoch
+ anzTempRoadNb++;
+ tempNbRoadCell = new int[] {nbRoadCellsX,nbRoadCellsY,anzTempRoadNb}; //schreibe die Koordinaten in ein Array
+ if (tempNbRoadCell[2]==RSearchNbRoad){ //Wenn der Wert im Array dem vorher definierten Zufallswert entspricht...
+ //statusOut.println("Treffer: "+tempNbRoadCell[0]+","+tempNbRoadCell[1]+","+tempNbRoadCell[2]);
+ tempRoadCell = tempNbRoadCell; //...wird die temporäre Straßenzelle an diese Position verschoben
+ // statusOut.println("Strasse in Entfernung "+roadSearch+": "+tempRoadCell[0]+","+tempRoadCell[1]+","+tempRoadCell[2]);
+ int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1],disp); //von dort aus wird ein Road-Walk durchgeführt (--> siehe Funktion roadWalk!)
+ if(nbCellNew != null){ //kommt nach roadWalk ein Wert zurück (d.h. wurde potenziell zu besiedelndes Pixel gefunden)...
+ tmpGrid[nbCellNew[0]][nbCellNew[1]] = true; //wird "true" ins temporäre Raster geschrieben (neue Siedlungszelle gefunden!!)
+// statusOut.println(nbCellNew.length);
+// statusOut.println("Neue Zelle: "+nbCellNew[0]+","+nbCellNew[1]);
+// statusOut.println("++++++++++++++++++++++++++++++++++++++++");
+ //Variablendefinitionen
+
+ float nbRoadBreed = 0f;
+ int nbRoadBreedNeighbors = 0;
+ nbRoadBreedNeighbors = calculateNeighbors(nbCellNew[0],nbCellNew[1],nbRoadBreed);
+ int RNRoadBreed1 = 0;
+ int RNRoadBreed2 = 0;
+ int nbRoadBreedX = 0;
+ int nbRoadBreedY = 0;
+ int anzRoadBreedTreffer = 0;
+
+ //wenn per roadWalk eine neue Zelle gefunden wurde, kann sie auch noch als Ausbreitungszentrum fungieren. Daher geht von ihr
+ //nochmals ein "Breed" aus. (GLEICHE FUNKTION WIE OBEN!!)
+
+ if (nbRoadBreedNeighbors >= 2){
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNRoadBreed1 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ float RNRoadBreedSlope = 0f;
+ if (RNRoadBreed2 == RNRoadBreed1)
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+ nbRoadBreedX = nbCellNew[0]+NEIGHBOR[cellBreed][0];
+ nbRoadBreedY = nbCellNew[1]+NEIGHBOR[cellBreed][1];
+ if ( nbRoadBreedX < areaMinX || nbRoadBreedY < areaMinY || nbRoadBreedX > areaMaxX || nbRoadBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY) != 0)
+ continue;
+ RNRoadBreedSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ if (breedSample == 0f){
+ anzBreedTemp++;
+ nbPossibleBreedUrban = new int[] {nbRoadBreedX,nbRoadBreedY,anzBreedTemp};
+ if (nbPossibleBreedUrban[2] == RNRoadBreed1 || nbPossibleBreedUrban[2] == RNRoadBreed2 && slopeDoubleNb < RNRoadBreedSlope){
+ tmpGrid[nbRoadBreedX][nbRoadBreedY] = true;
+ anzRoadBreedTreffer++;
+ //statusOut.println("Road-Breed-Treffer: "+anzRoadBreedTreffer);
+ }
+ }
+ }
+ }
+ } else{ //sind nicht mind. 2 Nachbarzellen gefunden worden...
+ //statusOut.println("Keine neue Zelle gefunden");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ } while (r <= breed);
+
+ // statusOut.println("Spread-Treffer: "+anzSpreadTreffer);
+ // statusOut.println("Dispersion-Treffer: "+anzDispTreffer);
+ // statusOut.println("Breed-Treffer: "+anzBreedTreffer);
+ // statusOut.println("Treffer gesamt: "+anzGesamt);
+
+ // outStep.addGrid();
+
+
+ /**
+ * Hier endet der eigentliche Modellalgorithmus des Urban Growth Modells.
+ * Als nächstes wird das was ins temporäre grid geschrieben wurde ins outputGrid geschrieben.
+ * Mit dem outputGrid wird dann im nächsten Zeitschritt weitergerechnet, bis die maximale Anzahl
+ * an Jahren erreicht ist. Danach wird die nächste Kombination an Koeffizienten gewählt.
+ */
+
+ // TempGrid auf das echte Grid schreiben
+ for (int y = 1; y < outputGrid.getHeight()-1;y++ )
+ for (int x = 1; x < outputGrid.getWidth()-1; x++ ) {
+
+ int X = outputGrid.getMinX() + x;
+ int Y = outputGrid.getMinY() + y;
+
+ boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f; //eine Zelle lebt, wenn sie 1 ist
+ if (tmpGrid[x][y] == false) //wenn im temporären Raster nichts drinsteht...
+ tmpGrid[x][y] = lebt; //wird der Wert aus dem Ausgangsraster übernommen
+
+
+ outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);
+ actUrb = (Float)outputGrid.getRasterSample(x,y);
+ // outStep.getGrid(stepNo-1).setRasterSample(actUrb,x,y);
+ }
+
+ if (!anyBodyAlive) {
+ stepCount = stepNo;
+ //statusOut.println("Lebt keiner mehr... höre hier auf!");
+ }
+
+ //RasterUtil.copyInto(outputGrid, inputGrid);
+ // System.out.println("Finished step " + (stepNo) + " in "
+ // + ((System.currentTimeMillis() - localStartTime)) + " ms\n");
+ localStartTime = System.currentTimeMillis();
+
+ } //HIER ENDET DER ZEITSCHRITT. DIE SCHLEIFE WIRD DURCHLAUFEN, BIS MAX JAHRE ERREICHT SIND.
+
+ /**
+ * +++++ MULTIPLE RESOLUTION VALIDATION ++++++
+ * Sind alle Zeitschritte durchlaufen, wird das Endergebnis validiert.
+ * Als Validierungsmethode wurde die Multiple Resolution Validation ausgewählt (siehe
+ * Costanza(1989), Pontius (2002), Pontius et al. (2005), Lesschen et al. (2005),
+ * Pontius et al. (2008a), Pontius et al. (2008b))
+ * Für das SLEUTH-Modell werden eigentlich eine Reihe an Landschaftsmaßen zur Validierung
+ * verwendet (siehe Clarke et al. (1997), Dietzel et al. (2007)), wie z.B. LeeSallee
+ * oder OSM. Da für die spätere Validierung der Modellierungsergebnisse und zum Vergleich mit
+ * anderen Modelltypen die Multiple Resolution Validation verwendet wird, wird sie auch zur
+ * Bewertung der Kalibrierungsschritte verwendet.
+ */
+
+ //Variablendefinitionen
+ int RoverallSum = 0;
+ int RnumClasses = 0;
+ int SoverallSum = 0;
+ int SnumClasses = 0;
+ int correct = 0;
+ double fractionCorrect = 0f;
+
+
+ long localStartTime = System.currentTimeMillis();
+ neighborhoodRange = (int) Math.sqrt(referenceGrid.getWidth()*referenceGrid.getHeight()); //maximal mögliche Zellengröße
+ //statusOut.println(neighborhoodRange);
+ resultArray = new float[13]; //!!!!!!!!! Ergebnis-Array
+ resultArrayFinal = new float[MonteCarlo-1][10]; //?????????????
+
+ //Für die Ausgangs-Auflösung wird berechnet, wieviel % der Pixel zwischen Modell und Referenz übereinstimmen
+ for (int x = 0; x < referenceGrid.getWidth(); x++)
+ for (int y = 0; y < referenceGrid.getHeight(); y++) {
+ float Rtmp = referenceGrid.getRasterSampleAsFloat(x, y);
+ float Stmp = outputGrid.getRasterSampleAsFloat(x, y);
+ if (!Float.isNaN(Rtmp) && !Float.isNaN(Stmp)){
+ RoverallSum ++;
+ SoverallSum ++;
+ if (Rtmp > RnumClasses)
+ RnumClasses = (int) Rtmp;
+ if (Stmp > SnumClasses)
+ SnumClasses = (int) Stmp;
+ if (Rtmp == Stmp)
+ correct++;
+ }
+ }
+ fractionCorrect = (double) correct / (double) RoverallSum;
+
+ //Anzahl der Pixel pro Klasse
+ for (int i = 1; i <= RnumClasses; i++){
+ int Rj = 0;
+ int Sj = 0;
+ for (int x = 0; x < referenceGrid.getWidth(); x++)
+ for (int y = 0; y < referenceGrid.getHeight(); y++){
+ float Rtmp = referenceGrid.getRasterSampleAsFloat(x, y);
+ float Stmp = outputGrid.getRasterSampleAsFloat(x, y);
+ if (!Float.isNaN(Rtmp))
+ if ((int) Rtmp == i)
+ Rj++;
+ if (!Float.isNaN(Stmp))
+ if ((int) Stmp == i)
+ Sj++;
+ }
+ //statusOut.println("Klasse "+i+": Referenz("+Rj+"), Simulation("+Sj+")");
+ }
+
+ ngrids = 0;
+
+ //Die eigentliche Validierung wird für alle Zellengrößen von 1 (Ausgangsauflösung) bis "neighborhoodRange" durchgeführt
+ for (int r1 = 1; r1 <= neighborhoodRange; r1 = r1+r1){ //für Zellengröße 1 bis zur max. möglichen Zellengröße wird Statistik durchgeführt
+ //statusOut.println(r1);
+ ngrids++;
+ float SumWn = 0f; //Summe der gewichteten Mittelwerte
+ int SumCells = 0; //Summe der Zellen
+ float totalAgreement = 0f; //Endergebnis
+ for (int x = 0; x < referenceGrid.getWidth(); x = x+r1) //für jeden größer werdenden Zellenbereich...
+ for (int y = 0; y < referenceGrid.getHeight(); y = y+r1){ //was folgt passiert innerhalb einer größeren Rasterzelle
+ int nCells = 0; //Anzahl Zellen pro größerer Zelle
+ float SumMinRS = 0f; //Summe der Min-Werte bei Vergleich zweier Raster
+ float Wn = 0; //Gewichtete Zelle
+ for(int x2 = x; x2 < x+r1; x2++) //für jede kleinere Zelle innerhalb der größeren...
+ for(int y2 = y; y2 < y+r1; y2++){
+ if ( x2 < referenceGrid.getMinX() || y2 < referenceGrid.getMinY() || x2 > referenceGrid.getMinX()+referenceGrid.getWidth()-1 || y2 > referenceGrid.getMinY()+referenceGrid.getHeight()-1 ||
+ Float.isNaN(referenceGrid.getRasterSampleAsFloat(x2,y2)))
+ continue;
+ nCells++; //zähle "positive" Zellen
+ }
+ for (int i = 0; i <= RnumClasses; i++){ //für jede Klasse i
+ int Rn = 0; //Anzahl in Referenzkarte
+ int Sn = 0; //Anzahl in Simulationskarte
+ float Rnj = 0f; //Anteil in Referenzkarte
+ float Snj = 0f; //Anteil in Simulationskarte
+ float MinRS = 0f; //Min des Vergleichs zwischen beiden Karten
+ for(int x3 = x; x3 < x+r1; x3++) //für jede kleinere Zelle pro größerer Zelle...
+ for(int y3 = y; y3 < y+r1; y3++){
+ if ( x3 < referenceGrid.getMinX() || y3 < referenceGrid.getMinY() || x3 > referenceGrid.getMinX()+referenceGrid.getWidth()-1 || y3 > referenceGrid.getMinY()+referenceGrid.getHeight()-1 ||
+ Float.isNaN(referenceGrid.getRasterSampleAsFloat(x3,y3)))
+ continue;
+ float Rtmp = referenceGrid.getRasterSampleAsFloat(x3, y3); //hole Wert aus Referenz-Karte und
+ float Stmp = outputGrid.getRasterSampleAsFloat(x3, y3); //Simulationskarte
+ if ((int) Rtmp == i)
+ Rn++; //zähle in Referenzkarte Zellen, die zu Klasse i gehören
+ if ((int) Stmp == i)
+ Sn++; //und in Simulationskarte
+ }
+ if(nCells > 0){ //wenn positive Zellen vorhanden sind...
+ Rnj = (float)Rn / (float)nCells; //berechne Anteile pro größerer Zelle
+ Snj = (float)Sn / (float)nCells;
+ }
+ MinRS = Math.min(Rnj, Snj); //nehme Minimum-Wert des Vergleichs beider Karten
+ SumMinRS += MinRS; //summiere die Minimum-Werte auf
+ // statusOut.println(i+" Min"+MinRS+" Anzahl: "+nCells);
+ }
+
+ Wn = (float)nCells * SumMinRS;
+ // statusOut.println(SumMinRS+", gewichtet: "+Wn);
+ //Erstelle Output-Karten
+ float WnCell = 0f;
+ for(int x4 = x; x4 < x+r1; x4++) //für jede kleinere Zelle pro größerer Zelle...
+ for(int y4 = y; y4 < y+r1; y4++){
+ if ( x4 < referenceGrid.getMinX() || y4 < referenceGrid.getMinY() || x4 > referenceGrid.getMinX()+referenceGrid.getWidth()-1 || y4 > referenceGrid.getMinY()+referenceGrid.getHeight()-1 ||
+ Float.isNaN(referenceGrid.getRasterSampleAsFloat(x4,y4)))
+ continue;
+ WnCell = Wn / (float)nCells; //pro Zelle wird Mittelwert des Vergleichs genommen
+ //actualValidation.setRasterSample( WnCell ,x4 ,y4);
+ }
+
+ SumCells += (float)nCells; //Summiere alle Zellen auf
+ SumWn += Wn; //Summiere die gewichteten Anteile auf
+ } //hier endet die Berechnung innerhalb einer größeren Rasterzelle
+
+
+ //Total Agreement:
+ //statusOut.println(SumWn+" / "+SumCells);
+ totalAgreement = SumWn / (float)SumCells; //Ergebnisformel
+ //statusOut.println(totalAgreement);
+
+ outResults.addValue(totalAgreement);
+ resultArray[ngrids] = totalAgreement;
+
+ // statusOut.println("Gesamt-Pixel: "+RoverallSum);
+ // statusOut.println("Anzahl Klassen: "+RnumClasses);
+ // statusOut.println("Fraction Correct: "+fractionCorrect);
+
+ } //Hier endet die Berechnung pro Auflösung
+
+ // System.out.println("(Slope:"+slope+" Spread:"+spread+" Dispersion:"+disp+" Breed: "+breed+" RoadGravity: "+roadGravity+") "+
+ // resultArray[1]+","+resultArray[2]+","+resultArray[3]+","+resultArray[4]+","+resultArray[5]+","+resultArray[6]+
+ // ","+resultArray[7]+","+resultArray[8]+","+resultArray[9]);
+
+ //Führe jede Position einzeln auf. Das sollte noch automatisiert werden !!!
+ pos1 += resultArray[1];
+ pos2 += resultArray[2];
+ pos3 += resultArray[3];
+ pos4 += resultArray[4];
+ pos5 += resultArray[5];
+ pos6 += resultArray[6];
+ pos7 += resultArray[7];
+ pos8 += resultArray[8];
+ pos9 += resultArray[9];
+ pos10 += resultArray[10];
+ pos11 += resultArray[11];
+ pos12 += resultArray[12];
+ // System.out.print("Finished step " + (stepNo) + " in "
+ // + ((System.currentTimeMillis() - localStartTime)) + " ms");
+ localStartTime = System.currentTimeMillis();
+ // System.out.println(" with sum (local calculated): " + RoverallSum);
+ } //!!!!!!!!!! Hier endet ein Monte-Carlo-Schritt
+
+ System.out.println("-->(Slope:"+slope+" Spread:"+spread+" Dispersion:"+disp+" Breed: "+breed+" RoadGravity: "+roadGravity+") "+
+ pos1/MonteCarlo+","+pos2/MonteCarlo+","+pos3/MonteCarlo+","+pos4/MonteCarlo+","+pos5/MonteCarlo+","+pos6/MonteCarlo+
+ ","+pos7/MonteCarlo+","+pos8/MonteCarlo+","+pos9/MonteCarlo+","+pos10/MonteCarlo+","+pos11/MonteCarlo+","+pos12/MonteCarlo);
+ } //Ende RoadGravity-Koeffizient
+ } //Ende Breed-Koeffizient
+ } //Ende Disp-Koeffizient
+ } //Ende Spread-Koeffizient
+ } //Ende Slope-Koeffizient
+ } //Ende Model-Step
+
+ private int[] roadWalk(int X,int Y,double disp){
+// statusOut.println(X+","+Y);
+ boolean end_of_road;
+ end_of_road = false;
+ int run = 0;
+ int run_value = 0;
+ int[] nbCellNew = null;
+ int[] nbCellTemp = null;
+ while(!end_of_road){
+ end_of_road = true;
+ int nbRoadX = 0;
+ int nbRoadY = 0;
+ int areaMinX = outputGrid.getMinX(); //Dimensionen des Rasters
+ int areaMinY = outputGrid.getMinY();
+ int areaMaxX = outputGrid.getMinX() + outputGrid.getWidth() - 1;
+ int areaMaxY = outputGrid.getMinY() + outputGrid.getHeight() - 1;
+ int roadNb = 0;
+ int roadNbTemp = 0;
+ int RN = 0;
+
+ int[] nbCell = null;
+ for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){
+ nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+ nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+ if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ //if (areaRestr.getRasterSampleAsFloat(nbRoadX,nbRoadY) != 0)
+ // continue;
+ float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);
+ if (roadSample > 0f)
+ roadNb++;
+ }
+ // statusOut.println("Nachbarn von temporaerer Strassenzelle: "+roadNb);
+
+ if (roadNb > 0){
+ RN = 1 + Math.round((float)Math.random()*(roadNb-1));
+
+ for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){
+ nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+ nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+ if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);
+ if (roadSample > 0f){
+ roadNbTemp++;
+ nbCell = new int[] {nbRoadX,nbRoadY,roadNbTemp};
+ if (nbCell[2] == RN){
+// statusOut.println("Nachbarzelle gefunden: "+nbCell[0]+","+nbCell[1]+","+nbCell[2]);
+ end_of_road = false;
+ run++;
+ X = nbRoadX;
+ Y = nbRoadY;
+ float roadSample2 = roadGrid.getRasterSampleAsFloat(X,Y);
+ run_value = (int) (roadSample2 / 100 * disp);
+ // statusOut.println("Run: "+run);
+ // statusOut.println("Run_Value: "+run_value);
+ // statusOut.println(X+","+Y+","+roadSample2);
+ if (run > run_value){
+ end_of_road = true;
+ // statusOut.println("Endzelle erreicht!! Run:"+run+"RunValue: "+run_value);
+ float NbValue = 0f;
+ int Nb = calculateNeighbors(X,Y,NbValue);
+ // statusOut.println("moegliche Nachbarzellen nach RoadWalk: "+Nb);
+ RN = 1 + Math.round((float)Math.random()*(Nb-1));
+ // statusOut.println("Random: "+RN);
+ if (Nb > 0){
+ int nbUrbanizeX = 0;
+ int nbUrbanizeY = 0;
+ int NbTemp = 0;
+ float RNRoadSlope = 0f;
+ // statusOut.println(X+","+Y);
+ for (int urbanizeCells = 0; urbanizeCells < NEIGHBOR.length; urbanizeCells++){
+ nbUrbanizeX = X+NEIGHBOR[urbanizeCells][0];
+ nbUrbanizeY = Y+NEIGHBOR[urbanizeCells][1];
+ if ( nbUrbanizeX < areaMinX || nbUrbanizeY < areaMinY || nbUrbanizeX > areaMaxX || nbUrbanizeY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);
+ RNRoadSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ if (rasterSample == 0f){
+ NbTemp++;
+ nbCellTemp = new int[] {nbUrbanizeX,nbUrbanizeY,NbTemp};
+ if (nbCellTemp[2] == RN && slopeDoubleNb < RNRoadSlope){
+ nbCellNew = new int[] {nbCellTemp[0],nbCellTemp[1],nbCellTemp[2]};
+ }
+ }
+ }
+
+ } else{
+ nbCellNew = null;
+ } break;
+ }
+
+ }
+
+ }
+ }
+
+ }
+ }
+ return nbCellNew;
+ }
+
+ private int calculateNeighbors(int X, int Y, float NbValue){
+ int nbX = 0;
+ int nbY = 0;
+ int areaMinX = outputGrid.getMinX(); //Dimensionen des Rasters
+ int areaMinY = outputGrid.getMinY();
+ int areaMaxX = outputGrid.getMinX() + outputGrid.getWidth() - 1;
+ int areaMaxY = outputGrid.getMinY() + outputGrid.getHeight() - 1;
+ int Nb = 0;
+ for (int nbCells = 0; nbCells < NEIGHBOR.length; nbCells++){
+ nbX = X+NEIGHBOR[nbCells][0];
+ nbY = Y+NEIGHBOR[nbCells][1];
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);
+ if (rasterSample == NbValue)
+ Nb++;
+ }
+ // statusOut.println("..."+Nb+"...");
+ return Nb;
+ }
+
+ protected static boolean checkNoData(int x, int y, WritableGrid grid) {
+ return Float.isNaN(grid.getRasterSampleAsFloat(x,y));
+ }
+}
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationContentManager.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationContentManager.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationContentManager.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,54 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.DefaultModelResource;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+
+public class UrbanGrowthModelCalibrationContentManager extends AbstractModelContentManager {
+
+ public UrbanGrowthModelCalibrationContentManager() {
+ super(25);
+
+ resource[0] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+ resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of MonteCarlo Iterations",ScalarProperty.class,Integer.class,false);
+ resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Input Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[3] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Output Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[4] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Area Restrictions",ScalarProperty.class,WritableGrid.class,false);
+ resource[5] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[6] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[7] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Reference Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[8] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient Start",ScalarProperty.class,Double.class,false);
+ resource[9] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient Step",ScalarProperty.class,Double.class,false);
+ resource[10] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient End",ScalarProperty.class,Double.class,false);
+ resource[11]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient Start",ScalarProperty.class,Double.class,false);
+ resource[12]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient Step",ScalarProperty.class,Double.class,false);
+ resource[13]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient End",ScalarProperty.class,Double.class,false);
+ resource[14]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient Start",ScalarProperty.class,Double.class,false);
+ resource[15]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient Step",ScalarProperty.class,Double.class,false);
+ resource[16]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient End",ScalarProperty.class,Double.class,false);
+ resource[17]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient Start",ScalarProperty.class,Double.class,false);
+ resource[18]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient Step",ScalarProperty.class,Double.class,false);
+ resource[19]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient End",ScalarProperty.class,Double.class,false);
+ resource[20]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient Start",ScalarProperty.class,Double.class,false);
+ resource[21]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient Step",ScalarProperty.class,Double.class,false);
+ resource[22]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient End",ScalarProperty.class,Double.class,false);
+ resource[23]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Slope",ScalarProperty.class,Double.class,false);
+ resource[24]= new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Validation Results",ListProperty.class,Float.class,false);
+ // ===== Ressourcen Bezeichnungen lokalisieren =====
+ resetCaptions(null);
+ }
+
+
+ @Override
+ public void checkAndError() throws XuluDataException {
+ // TODO Auto-generated method stub
+ super.checkAndError();
+ }
+}
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModification.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModification.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModification.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,1290 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import java.awt.Rectangle;
+import java.util.HashMap;
+
+import appl.util.RasterUtil;
+
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ListPropertyWriteAccess;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+
+/**
+ * @see AverageNeighborhoodContentManager
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class UrbanGrowthModelCalibrationSelfModification extends AbstractStepModel {
+
+ private int neighborhoodRange = 0;
+ private float[] resultArray;
+ private float[][] resultArrayFinal;
+ /**
+ * Speichert den ContentManager fuer das Modell.
+ */
+ protected UrbanGrowthModelCalibrationSelfModificationContentManager contManager;
+
+ // ********** Lese/Schreibrechte, die fuer den gesamten ***********
+ // ********** Modellanlauf gehalten werden muessen ***********
+ private PropertyReadAccess RA_steps = null; // Number of steps
+ private PropertyReadAccess RA_MonteCarlo = null; //Number of MonteCarlo Iterations
+ private PropertyReadAccess RA_inputGrid = null; // Input Grid
+ private PropertyWriteAccess WA_outputGrid = null; // Output Grid
+ private PropertyReadAccess RA_areaRestr = null; //Area Restrictions
+ private PropertyReadAccess RA_spreadStart = null; //Spread-Koeffizient
+ private PropertyReadAccess RA_spreadStep = null; //Spread-Koeffizient
+ private PropertyReadAccess RA_spreadEnd = null; //Spread-Koeffizient
+ private PropertyReadAccess RA_dispStart = null; //Dispersions-Koeffizient
+ private PropertyReadAccess RA_dispStep = null; //Dispersions-Koeffizient
+ private PropertyReadAccess RA_dispEnd = null; //Dispersions-Koeffizient
+ private PropertyReadAccess RA_breedStart = null; //Breed-Koeffizient
+ private PropertyReadAccess RA_breedStep = null; //Breed-Koeffizient
+ private PropertyReadAccess RA_breedEnd = null; //Breed-Koeffizient
+ private PropertyReadAccess RA_roadGravityStart = null; //Road-Gravity-Koeffizient
+ private PropertyReadAccess RA_roadGravityStep = null; //Road-Gravity-Koeffizient
+ private PropertyReadAccess RA_roadGravityEnd = null; //Road-Gravity-Koeffizient
+ private PropertyReadAccess RA_slopeStart = null; //Slope-Koeffizient
+ private PropertyReadAccess RA_slopeStep = null; //Slope-Koeffizient
+ private PropertyReadAccess RA_slopeEnd = null; //Slope-Koeffizient
+ private PropertyReadAccess RA_criticalSlope = null; //Critical Slope Value
+ private PropertyReadAccess RA_roadGrid = null; //Road Grid
+ private PropertyReadAccess RA_slopeGrid = null; //Slope Grid
+ private PropertyReadAccess RA_referenceGrid = null; //Observed Validation Grid
+ private ListPropertyWriteAccess WA_outResults = null; //Output Validation Results
+ private PropertyReadAccess RA_roadGravSens = null; //RoadGravity Sensitivity
+ private PropertyReadAccess RA_slopeSens = null; //Slope Sensitivity
+ private PropertyReadAccess RA_criticalLow = null; //Critical Low
+ private PropertyReadAccess RA_criticalHigh = null; //Critical High
+ private PropertyReadAccess RA_Boom = null; //Boom
+ private PropertyReadAccess RA_Bust = null; //Bust
+
+ // **************** Variablen mit denen gearbeitet wird *******************
+ private WritableGrid inputGrid = null; // Input Grid
+ private WritableGrid outputGrid = null; // Output Grid
+ private int steps = 0; // Number of steps
+ private int MonteCarlo = 0; //Number of Monte Carlo Iterations
+ private WritableGrid areaRestr = null; //Area Restrictions
+ protected double spreadStart = 0; //Spread-Koeffizient
+ protected double spreadStep = 0; //Spread-Koeffizient
+ protected double spreadEnd = 0; //Spread-Koeffizient
+ protected double dispStart = 0; //Dispersions-Koeffizient
+ protected double dispStep = 0; //Dispersions-Koeffizient
+ protected double dispEnd = 0; //Dispersions-Koeffizient
+ protected double breedStart = 0; //Breed-Koeffizient
+ protected double breedStep = 0; //Breed-Koeffizient
+ protected double breedEnd = 0; //Breed-Koeffizient
+ protected double roadGravityStart = 0; //Road-Gravity-Koeffizient
+ protected double roadGravityStep = 0; //Road-Gravity-Koeffizient
+ protected double roadGravityEnd = 0; //Road-Gravity-Koeffizient
+ protected double slopeStart = 0; //Slope-Koeffizient
+ protected double slopeStep = 0; //Slope-Koeffizient
+ protected double slopeEnd = 0; //Slope-Koeffizient
+ protected double criticalSlope = 0; //Critical Slope Value
+ private WritableGrid roadGrid = null; //Road Grid
+ private WritableGrid slopeGrid = null; //Slope Grid
+ private WritableGrid referenceGrid = null; //Observed Validation Grid
+ private ListPropertyWriteAccess outResults = null; //Output Validation Results
+ protected double roadGravSens = 0; //RoadGravity Sensitivity
+ protected double slopeSens = 0; //Slope Sensitivity
+ protected double criticalLow = 0; //critical Low
+ protected double criticalHigh = 0; //critical High
+ protected double boom = 0; //Boom
+ protected double bust = 0; //Bust
+
+ private static final int[][] NEIGHBOR = new int[][] {
+ {-1,-1}, {0,-1}, {1,-1},
+ {-1, 0}, {1, 0},
+ {-1, 1}, {0, 1}, {1, 1}
+ };
+
+ protected HashMap<Number,Number> slopeLUT;
+ private int slopeMax = 0;
+ private int totalPixels = 0;
+ private int excldCount = 0;
+
+ /**
+ * Erzeugt eine neue Instanz des Modells.
+ */
+ public UrbanGrowthModelCalibrationSelfModification() {
+ super(new UrbanGrowthModelCalibrationSelfModificationContentManager());
+ this.contManager = (UrbanGrowthModelCalibrationSelfModificationContentManager) super.contManager;
+ }
+
+
+ /**
+ * Initializes the model. Like in the init method of every {@link XuluModel}
+ * the resources are initalized.
+ */
+ public void performModelInit() {
+ if (contManager == null)
+ return;
+ // Zugriffsrechte aus Ressourcen/Propertys holen
+ RA_steps = null;
+ if (contManager.getResource(0).getData() != null)
+ RA_steps = ((ScalarProperty) contManager.getResource(0).getData())
+ .getReadAccess(this);
+ RA_MonteCarlo = null;
+ if (contManager.getResource(1).getData() != null)
+ RA_MonteCarlo = ((ScalarProperty) contManager.getResource(1).getData())
+ .getReadAccess(this);
+ RA_inputGrid = null;
+ if (contManager.getResource(2).getData() != null)
+ RA_inputGrid = ((ScalarProperty) contManager.getResource(2)
+ .getData()).getReadAccess(this);
+ WA_outputGrid = null;
+ if (contManager.getResource(3).getData() != null)
+ WA_outputGrid = ((ScalarProperty) contManager.getResource(3)
+ .getData()).getWriteAccess(this);
+ RA_areaRestr = null;
+ if (contManager.getResource(4).getData() != null)
+ RA_areaRestr = ((ScalarProperty) contManager.getResource(4)
+ .getData()).getReadAccess(this);
+ RA_roadGrid = null;
+ if (contManager.getResource(5).getData() != null)
+ RA_roadGrid = ((ScalarProperty) contManager.getResource(5)
+ .getData()).getReadAccess(this);
+ RA_slopeGrid = null;
+ if (contManager.getResource(6).getData() != null)
+ RA_slopeGrid = ((ScalarProperty) contManager.getResource(6)
+ .getData()).getReadAccess(this);
+ RA_referenceGrid = null;
+ if(contManager.getResource(7).getData() != null)
+ RA_referenceGrid = ((ScalarProperty) contManager.getResource(7)
+ .getData()).getReadAccess(this);
+ RA_spreadStart = null;
+ if (contManager.getResource(8).getData() != null)
+ RA_spreadStart = ((ScalarProperty) contManager.getResource(8).getData())
+ .getReadAccess(this);
+ RA_spreadStep = null;
+ if (contManager.getResource(9).getData() != null)
+ RA_spreadStep = ((ScalarProperty) contManager.getResource(9).getData())
+ .getReadAccess(this);
+ RA_spreadEnd = null;
+ if (contManager.getResource(10).getData() != null)
+ RA_spreadEnd = ((ScalarProperty) contManager.getResource(10).getData())
+ .getReadAccess(this);
+ RA_dispStart = null;
+ if (contManager.getResource(11).getData() != null)
+ RA_dispStart = ((ScalarProperty) contManager.getResource(11).getData())
+ .getReadAccess(this);
+ RA_dispStep = null;
+ if (contManager.getResource(12).getData() != null)
+ RA_dispStep = ((ScalarProperty) contManager.getResource(12).getData())
+ .getReadAccess(this);
+ RA_dispEnd = null;
+ if (contManager.getResource(13).getData() != null)
+ RA_dispEnd = ((ScalarProperty) contManager.getResource(13).getData())
+ .getReadAccess(this);
+ RA_breedStart = null;
+ if (contManager.getResource(14).getData() != null)
+ RA_breedStart = ((ScalarProperty) contManager.getResource(14).getData())
+ .getReadAccess(this);
+ RA_breedStep = null;
+ if (contManager.getResource(15).getData() != null)
+ RA_breedStep = ((ScalarProperty) contManager.getResource(15).getData())
+ .getReadAccess(this);
+ RA_breedEnd = null;
+ if (contManager.getResource(16).getData() != null)
+ RA_breedEnd = ((ScalarProperty) contManager.getResource(16).getData())
+ .getReadAccess(this);
+ RA_roadGravityStart = null;
+ if (contManager.getResource(17).getData() != null)
+ RA_roadGravityStart = ((ScalarProperty) contManager.getResource(17).getData())
+ .getReadAccess(this);
+ RA_roadGravityStep = null;
+ if (contManager.getResource(18).getData() != null)
+ RA_roadGravityStep = ((ScalarProperty) contManager.getResource(18).getData())
+ .getReadAccess(this);
+ RA_roadGravityEnd = null;
+ if (contManager.getResource(19).getData() != null)
+ RA_roadGravityEnd = ((ScalarProperty) contManager.getResource(19).getData())
+ .getReadAccess(this);
+ RA_slopeStart = null;
+ if (contManager.getResource(20).getData() != null)
+ RA_slopeStart = ((ScalarProperty) contManager.getResource(20).getData())
+ .getReadAccess(this);
+ RA_slopeStep = null;
+ if (contManager.getResource(21).getData() != null)
+ RA_slopeStep = ((ScalarProperty) contManager.getResource(21).getData())
+ .getReadAccess(this);
+ RA_slopeEnd = null;
+ if (contManager.getResource(22).getData() != null)
+ RA_slopeEnd = ((ScalarProperty) contManager.getResource(22).getData())
+ .getReadAccess(this);
+ RA_criticalSlope = null;
+ if (contManager.getResource(23).getData() != null)
+ RA_criticalSlope = ((ScalarProperty) contManager.getResource(23).getData())
+ .getReadAccess(this);
+ WA_outResults = null;
+ if (contManager.getResource(24).getData() != null)
+ WA_outResults = ((ListProperty) contManager.getResource(24)
+ .getData()).getWriteAccess(this);
+ RA_roadGravSens = null;
+ if (contManager.getResource(25).getData() != null)
+ RA_roadGravSens = ((ScalarProperty) contManager.getResource(25).getData())
+ .getReadAccess(this);
+ RA_slopeSens = null;
+ if (contManager.getResource(26).getData() != null)
+ RA_slopeSens = ((ScalarProperty) contManager.getResource(26).getData())
+ .getReadAccess(this);
+ RA_criticalLow = null;
+ if (contManager.getResource(27).getData() != null)
+ RA_criticalLow = ((ScalarProperty) contManager.getResource(27).getData())
+ .getReadAccess(this);
+ RA_criticalHigh = null;
+ if (contManager.getResource(28).getData() != null)
+ RA_criticalHigh = ((ScalarProperty) contManager.getResource(28).getData())
+ .getReadAccess(this);
+ RA_Boom = null;
+ if (contManager.getResource(29).getData() != null)
+ RA_Boom = ((ScalarProperty) contManager.getResource(29).getData())
+ .getReadAccess(this);
+ RA_Bust = null;
+ if (contManager.getResource(30).getData() != null)
+ RA_Bust = ((ScalarProperty) contManager.getResource(30).getData())
+ .getReadAccess(this);
+
+ // Variablen belegen mit denen gearbeitet wird
+ steps = RA_steps.getValueAsInt();
+ MonteCarlo = RA_MonteCarlo.getValueAsInt();
+ inputGrid = (WritableGrid) RA_inputGrid.getValue();
+ outputGrid = (WritableGrid) WA_outputGrid.getValue();
+ areaRestr = (WritableGrid) RA_areaRestr.getValue();
+
+ //this.stepCount = steps.getValueAsInt();
+ stepCount = 1;
+ spreadStart = RA_spreadStart.getValueAsDouble();
+ spreadStep = RA_spreadStep.getValueAsDouble();
+ spreadEnd = RA_spreadEnd.getValueAsDouble();
+ dispStart = RA_dispStart.getValueAsDouble();
+ dispStep = RA_dispStep.getValueAsDouble();
+ dispEnd = RA_dispEnd.getValueAsDouble();
+ breedStart = RA_breedStart.getValueAsDouble();
+ breedStep = RA_breedStep.getValueAsDouble();
+ breedEnd = RA_breedEnd.getValueAsDouble();
+ roadGravityStart= RA_roadGravityStart.getValueAsDouble();
+ roadGravityStep = RA_roadGravityStep.getValueAsDouble();
+ roadGravityEnd = RA_roadGravityEnd.getValueAsDouble();
+ slopeStart = RA_slopeStart.getValueAsDouble();
+ slopeStep = RA_slopeStep.getValueAsDouble();
+ slopeEnd = RA_slopeEnd.getValueAsDouble();
+ criticalSlope = RA_criticalSlope.getValueAsDouble();
+ roadGrid = (WritableGrid) RA_roadGrid.getValue();
+ slopeGrid = (WritableGrid) RA_slopeGrid.getValue();
+ referenceGrid = (WritableGrid) RA_referenceGrid.getValue();
+ outResults = WA_outResults;
+ roadGravSens = RA_roadGravSens.getValueAsDouble();
+ slopeSens = RA_slopeSens.getValueAsDouble();
+ criticalLow = RA_criticalLow.getValueAsDouble();
+ criticalHigh = RA_criticalHigh.getValueAsDouble();
+ boom = RA_Boom.getValueAsDouble();
+ bust = RA_Bust.getValueAsDouble();
+
+ int startAnz = 0;
+ for (int i = 0; i < inputGrid.getWidth();i++ ) {
+ for (int ii = 0; ii < inputGrid.getHeight(); ii++ ) {
+ //if (inputGrid.getRasterSampleAsFloat(i,ii) == 1f);
+ float val = inputGrid.getRasterSampleAsFloat(i,ii);
+ if (val == 1.0 ) {
+ val = 1f;
+ startAnz++;
+ }
+ else val = 0f;
+
+ inputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+ outputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+ }
+ }
+
+ for (int x = 0; x < inputGrid.getWidth();x++ )
+ for (int y = 0; y < inputGrid.getHeight(); y++ ) {
+ if ( x < inputGrid.getMinX() || y < inputGrid.getMinY() || x > inputGrid.getMinX()+inputGrid.getWidth()-1 || y > inputGrid.getMinY()+inputGrid.getHeight()-1 ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(x,y)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ totalPixels++;
+ if (areaRestr.getRasterSampleAsFloat(x,y) != 0 && !Float.isNaN(areaRestr.getRasterSampleAsFloat(x,y)))
+ //continue; //wenn in Area Restriction oder wenn schon Siedlung da ist, mach weiter
+ //if (inputGrid.getRasterSampleAsFloat(i,ii) == 1f);
+ excldCount++;
+ }
+
+ }
+
+ /**
+ * like in every model: frees the resources
+ */
+ public void performModelDispose() {
+
+ // Ressourcen wieder freigeben
+ releaseAccess(RA_steps);
+ releaseAccess(RA_MonteCarlo);
+ releaseAccess(RA_inputGrid);
+ releaseAccess(WA_outputGrid);
+ releaseAccess(RA_areaRestr);
+ releaseAccess(RA_spreadStart);
+ releaseAccess(RA_spreadStep);
+ releaseAccess(RA_spreadEnd);
+ releaseAccess(RA_dispStart);
+ releaseAccess(RA_dispStep);
+ releaseAccess(RA_dispEnd);
+ releaseAccess(RA_breedStart);
+ releaseAccess(RA_breedStep);
+ releaseAccess(RA_breedEnd);
+ releaseAccess(RA_roadGravityStart);
+ releaseAccess(RA_roadGravityStep);
+ releaseAccess(RA_roadGravityEnd);
+ releaseAccess(RA_slopeStart);
+ releaseAccess(RA_slopeStep);
+ releaseAccess(RA_slopeEnd);
+ releaseAccess(RA_criticalSlope);
+ releaseAccess(RA_roadGrid);
+ releaseAccess(RA_slopeGrid);
+ releaseAccess(WA_outResults);
+ releaseAccess(RA_roadGravSens);
+ releaseAccess(RA_slopeSens);
+ releaseAccess(RA_criticalLow);
+ releaseAccess(RA_criticalHigh);
+ releaseAccess(RA_Boom);
+ releaseAccess(RA_Bust);
+ }
+
+
+ public void performModelStep(int stepNo) {
+
+ /**
+ * Ermitteln der maximalen Hangneigung
+ */
+ int slopeMax = 0;
+ for (int s = 0; s < inputGrid.getWidth();s++){
+ for(int ss = 0; ss < inputGrid.getHeight();ss++){
+ float slopeVal = slopeGrid.getRasterSampleAsFloat(s,ss);
+ if (slopeVal > slopeMax){
+ slopeMax = (int) slopeVal; //Maximale Hangneigung im Slope-Bild
+ }
+ }
+ }
+
+ /**
+ * Definition von Variablen, die als Output des gesamten Kalibrierungsdurchlaufs benötigt werden
+ */
+ float MCtotalAgreementResult = 0f;
+ int ngrids = 0;
+ double slopeF = 0;
+ double spreadF = 0;
+ double dispF = 0;
+ double breedF = 0;
+ double roadGravityF = 0;
+
+ /**
+ * Start des gesamten Kalibrierungsdurchlaufs:
+ * 1. Für jeden Slope-Wert zwischen Start und End...
+ * 2. Für jeden Spread-Wert zwischen Start und End...
+ * 3. Für jeden Dispersion-Wert zwischen Start und End...
+ * 4. Für jeden Breed-Wert zwischen Start und End...
+ */
+
+ for(int slope = (int)slopeStart;slope <= (int)slopeEnd; slope = slope+(int)slopeStep){
+ for(int spread = (int)spreadStart; spread <= (int)spreadEnd; spread = spread+(int)spreadStep){
+ for(int disp = (int)dispStart; disp <= (int)dispEnd; disp = disp+(int)dispStep){
+ for(int breed = (int)breedStart; breed <= (int)breedEnd+1; breed = breed+(int)breedStep){
+ for(int roadGravity = (int)roadGravityStart; roadGravity <=(int)roadGravityEnd; roadGravity = roadGravity+(int)roadGravityStep){
+
+ /**
+ * An dieser Stelle beginnt der eigentliche Modellalgorithmus des UrbanGrowth-Modells.
+ * Da bei der Kalibrierung das Modell durch jede mögliche Kombination an Werten durchiteriert,
+ * wird der Algorithmus x-mal durchlaufen.
+ * Da häufig Zufallswerte in das Modell eingebaut sind, ist es sinnvoll jeden Iterationsschritt mehrfach durchzuführen
+ * und die Ergebnisse zu mitteln. Dies geschieht "Monte-Carlo"-mal (Wert wird in Modellparametern angegeben).
+ * Das bedeutet, dass der Modellalgorithmus zusätzlich in die folgende for-Schleife eingebunden ist.
+ */
+ float pos1 = 0; //das hier ist nicht optimal gelöst. Für jede Stelle im Result Array eine eigene Variable definiert, die später ausgelesen wird. Habs nur auf die Schnelle nicht besser hinbekommen
+ float pos2 = 0;
+ float pos3 = 0;
+ float pos4 = 0;
+ float pos5 = 0;
+ float pos6 = 0;
+ float pos7 = 0;
+ float pos8 = 0;
+ float pos9 = 0;
+ float pos10 = 0;
+ float pos11 = 0;
+ float pos12 = 0;
+ for(int MC = 1; MC <= MonteCarlo; MC++){ //führe den Modellalgorithmus 1 bis MC-mal durch
+ RasterUtil.copyInto(inputGrid, outputGrid); //starte dabei aber mit dem Eingabebild (das Ausgabebild verändert sich nach jedem Modellschritt!!)
+// statusOut.println("Starting step " + stepNo + "...");
+// statusOut.println(steps);
+
+ //Koeffizienten werden für jeden Iterationsschritt zurückgesetzt. Innerhalb eines MC-Laufs können die Koeffizienten modifiziert werden
+ slopeF = (double)slope; //slopeF erhält am Beginn der Schleife den Wert von slope und kann innerhalb der Schleife modifiziert werden
+ spreadF = (double)spread; //spreadF erhält am Beginn der Schleife den Wert von spread und kann innerhalb der Schleife modifiziert werden
+ dispF = (double) disp; //dispF erhält am Beginn der Schleife den Wert von disp und kann innerhalb der Schleife modifiziert werden
+ breedF = (double)breed; //breedF erhält am Beginn der Schleife den Wert von breed und kann innerhalb der Schleife modifiziert werden
+ roadGravityF = (double) roadGravity; //roadGravityF erhält am Beginn der Schleife den Wert von roadGravity und kann innerhalb der Schleife modifiziert werden
+
+ /**
+ * Der Modelllauf muss so oft wiederholt werden, wie Jahre für den Kalibrierungsmodus angegeben wurden.
+ * Für die anschließende Bewertung der Ergebnisse zählt nur das Bild des Schlussjahres
+ */
+ for(int timeSteps = 1;timeSteps <=steps;timeSteps++){
+ //Dimensionen des Rasters werden definiert
+ int areaMinX = outputGrid.getMinX();
+ int areaMinY = outputGrid.getMinY();
+ int areaMaxX = outputGrid.getMinX() + outputGrid.getWidth() - 1;
+ int areaMaxY = outputGrid.getMinY() + outputGrid.getHeight() - 1;
+ int areaWidth = outputGrid.getWidth();
+ int areaHeight = outputGrid.getHeight();
+
+ //weitere Variablendefinitionen
+ long localStartTime = System.currentTimeMillis();
+ boolean anyBodyAlive = false;
+
+ boolean[][] tmpGrid = new boolean[outputGrid.getWidth()][outputGrid.getHeight()]; //temporäres Raster, in das true und false geschrieben wird, je nachdem ob Siedlung nach Modellschritt vorhanden ist oder nicht
+ Float actUrb = null;
+
+ int nbX = 0; // X-Koordinate einer Nachbarzelle
+ int nbY = 0; // Y-Koordinate einer Nachbarzelle
+ int[] nbCell = null;
+
+ int anzSpreadTreffer = 0;
+ int anzDispTreffer = 0;
+ int anzBreedTreffer = 0;
+ int anzGesamtTreffer = 0;
+ int anzRoadTreffer = 0;
+ double growthRate = 0;
+ int thisYear = 0;
+ int roadCount = 0;
+
+ // Variablen, die für den DISPERSION Bereich benötigt werden
+ double disp_value = Math.round((dispF*0.005)* Math.sqrt(Math.pow(outputGrid.getWidth(), 2)+(Math.pow(outputGrid.getHeight(), 2))));
+ int dispRandX = 0;
+ int dispRandY = 0;
+ float slopeRandDisp = 0;
+
+ // Variablen, die für den ROAD GRAVITY Bereich benötigt werden
+ double max_RG_value = 100.0;
+ double rg_value = Math.round((roadGravityF/max_RG_value)*((areaWidth + areaHeight)/16));
+ double max_search_index = Math.round(4*((int)rg_value*(1+(int)rg_value)));
+// statusOut.println("RG-Value:"+rg_value);
+// statusOut.println("Max-SearchIndex"+max_search_index);
+
+ //Variablendefinitionen bzgl. Slope-Berechnungen
+
+ slopeLUT = new HashMap<Number,Number>(); //Definition eines Lookup-Tables (HashMap --> jeder Indexwert bekommt einen Wert zugewiesen)
+ int MaxSlopeResistance = 100; //Hangneigung kann maximal 100% betragen
+ double exp = 0.0;
+ exp = (slopeF / (MaxSlopeResistance / 2));
+ double[] lookup = new double[slopeMax+1]; //ein Array, das slopeMax+1 Stellen lang ist (+1, da Arrays mit der Zahl 0 beginnen)
+ Number key = 0; //die Zahl key nimmt den Wert des Index für den Lookup-Table an
+
+ //Aufbau des Lookup-Tables
+ for (int i = 0;i <= slopeMax;i++){ //Für jede Hangneigung zwischen 0% und dem maximal im Bild vorhandenen Wert
+ if (i <= criticalSlope){ //der kleiner als criticalSlope ist
+ double val = (criticalSlope - i) / criticalSlope; //berechne den Wert val
+ lookup[i] = 1 - Math.pow(val,exp); //und füge den Wert val hoch exp an der Stelle i in das Array lookup ein
+ key = i; //Index-Wert ist key
+ } else{ //Ist der Wert größer als criticalSlope
+ lookup[i] = 1; //wird der Wert 1 in das Array eingefügt
+ key = i;
+ }
+ slopeLUT.put(key,lookup[i]); //put platziert die Werte key und den entsprechenden Wert aus dem Array lookup in die HashMap-Tabelle
+// statusOut.println(slopeLUT.get(key));
+ }
+
+ /*****************************************************************
+ * DISPERSION and BREED
+ *****************************************************************/
+
+ //Verteile soviel neue Pixel zufällig in geeigneten Bereichen, bis disp_value erreicht ist
+ //-->Beginn einer do-while-Schleife
+ int p = 0;
+ do{
+ dispRandX = Math.round((float) Math.random()*areaWidth); //Zufallsposition in X-Richtung
+ dispRandY = Math.round((float) Math.random()*areaHeight); //Zufallsposition in Y-Richtung
+ if ( dispRandX < areaMinX || dispRandY < areaMinY || dispRandX > areaMaxX || dispRandY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(dispRandX,dispRandY) != 0 || outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY) == 1)
+ continue; //wenn in Area Restriction oder wenn schon Siedlung da ist, mach weiter
+ slopeRandDisp = (float) Math.random(); //Zufallszahl zum Abgleich mit Slope-Koeffizient
+ int getSlope = (int) slopeGrid.getRasterSampleAsFloat(dispRandX,dispRandY); //holt sich den Slope-Wert aus dem Slope-Raster
+ Double doubleObj = (Double)slopeLUT.get(getSlope); //holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+ double slopeDouble = doubleObj.doubleValue(); //konvertiert Double-Objekt in double-Wert
+ // statusOut.println(getSlope+","+slopeDouble+"----Random: "+slopeRandDisp);
+ if(slopeDouble < slopeRandDisp){ //wenn der Slope-Wert kleiner als der Wert der Zufallszahl ist
+ tmpGrid[dispRandX][dispRandY] = true; //wird "true" ins temporäre Raster geschrieben (neue Siedlung entsteht!!)
+ anzDispTreffer++; //Anzahl der Disp-Treffer wird hochgezählt
+
+ //
+ //hier beginnt der BREED Bereich
+ //
+ //Variablendefinitionen
+ float breedRnd = (float) Math.random()*100;
+ int nbBreedX = 0;
+ int nbBreedY = 0;
+ int breedNb = 0;
+ float NbValue = 0f;
+ if (tmpGrid[dispRandX][dispRandY] == true && breedRnd < breedF) //wenn durch DISPERSION neue Zellen entstanden sind UND der Breed-Zufallswert kleiner als der Breed-Wert ist
+ breedNb = calculateNeighbors(dispRandX,dispRandY,NbValue); //werden die Nachbarzellen dieser neuen Zellen gezählt, und zwar alle, die zur weiteren Besiedlung zur Verfügung stehen (--> Funktion calculateNeighbors)
+
+ int RNBreed1 = 0;
+ int RNBreed2 = 0;
+ float RNBreedSlope = 0f;
+
+ if (breedNb >= 2 && tmpGrid[dispRandX][dispRandY] == true){ //sind mehr als 2 Nachbarzellen verfügbar und die Koordinate X/Y true...
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNBreed1 = 1 + Math.round((float)Math.random()*(breedNb-1)); //werden 2 Zufallszahlen zwischen 1 und breedNb erzeugt
+ RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));
+ if (RNBreed2 == RNBreed1) //falls beide Zufallszahlen den gleichen Wert haben sollten, wird die zweite Zahl nochmal erzeugt
+ RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){ //die Nachbarn jeder Zelle müssen nochmal durchgezählt werden, um zu bestimmen, welche per Zufallswert in Siedlung umgewandelt werden soll
+ nbBreedX = dispRandX+NEIGHBOR[cellBreed][0];
+ nbBreedY = dispRandY+NEIGHBOR[cellBreed][1];
+ if ( nbBreedX < areaMinX || nbBreedY < areaMinY || nbBreedX > areaMaxX || nbBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbBreedX,nbBreedY) != 0)
+ continue;
+ RNBreedSlope = (float)Math.random(); //Zufallszahl zum Abgleich mit Slope-Koeffizient
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY); //holt sich den Slope-Wert aus dem Slope-Raster
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb); //holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+ double slopeDoubleNb = doubleObjNb.doubleValue(); //konvertiert Double-Objekt in double-Wert
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY); //holt den Wert aus dem Output-Raster
+ if (breedSample == 0f){ //ist der Wert aus dem Output-Raster 0
+ anzBreedTemp++; //wird die Zahl der zur Verfügung stehenden Zellen hochgezählt
+ nbPossibleBreedUrban = new int[] {nbBreedX,nbBreedY,anzBreedTemp}; //und die Nummer und Koordinaten der jeweiligen Zellen in ein Array geschrieben
+ if (nbPossibleBreedUrban[2] == RNBreed1 || nbPossibleBreedUrban[2] == RNBreed2 && slopeDoubleNb < RNBreedSlope){ //entspricht die Nummer einer der zuvor erstellten Zufallswerte...
+ tmpGrid[nbBreedX][nbBreedY] = true; //wird in das temporäre Raster "true" geschrieben (--> neue Siedlung durch BREED entstanden!!)
+ anzBreedTreffer++; //die Anzahl der BREED-Treffer wird gezählt
+ }
+ }
+ }
+ }
+ } p++; //der Wert p wird hochgezählt, bis der Disp-Wert erreicht ist
+
+ } while (p < disp_value); //while, statt for-Schleife, da Überprüfung erst am Ende vorgenommen werden kann
+ //am Anfang der Schleife ist noch nicht klar, ob alle Pixel verteilt werden können
+ //da ein Teil in Ausschlussflächen etc. landen würde
+ //ENDE DISPERSION UND BREED WACHSTUM
+
+ /*********************************************************************
+ * EDGE
+ *********************************************************************/
+
+ //iterate over all cells
+ for (int x = 0; x < outputGrid.getWidth(); x++)
+ for (int y = 0; y < outputGrid.getHeight(); y++) { //für jede Zelle in x/y-Richtung
+
+ //Dimensionen des Rasters
+ int areaMinXadd = areaMinX + x;
+ int areaMinYadd = areaMinY + y;
+
+ //Variablendefinitionen
+ int anzNachbarn = 0;
+ int noNachbarn = 0;
+
+ for (int nbCellIdx = 0; nbCellIdx < NEIGHBOR.length; nbCellIdx++) { //zählt alle Nachbarn jeder Rasterzelle durch
+ checkBreakingCommands();
+ nbX = x+NEIGHBOR[nbCellIdx][0]; //Nachbarschaft der Zellen
+ nbY = y+NEIGHBOR[nbCellIdx][1];
+ nbCell = new int[] {nbX,nbY}; //jede Nachbarzelle
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);
+ if (rasterSample > 0f) //ist Nachbarzelle urban (1), wird sie als anzNachbarn gezählt
+ anzNachbarn++;
+ if (rasterSample == 0f) //ist sie nicht urban (0), wird sie als noNachbarn gezählt
+ noNachbarn++;
+ }
+
+ boolean lebt = outputGrid.getRasterSampleAsFloat(areaMinXadd , areaMinYadd ) > 0f; //eine Zelle lebt, wenn sie 1 ist
+
+ //hier ist die Abfrage wieviele Nachbarzellen am Leben sind
+ //daraus ergibt sich, ob im tmpGrid die entsprechende Zelle
+ //true oder false ist
+
+ float SpR = (float) Math.random()*100; //eine Zufallszahl zwischen 0 und 1
+ int RN = 0; //hier wird eine Integer-Zufallszahl reingeschrieben
+
+ if (lebt && (anzNachbarn>=2) && (SpR < spreadF) && (noNachbarn >=1)) { //wenn eine Zelle lebt, mindestens 2 lebende Nachbarzellen hat, der Spread-Koeffizient größer als die für die Zelle berechnete Zufallszahl und mindestens einen nicht lebenden Nachbarn hat
+
+ //Variablendefinitionen
+ int anzTemp = 0;
+ int[] nbPossibleUrban = null;
+ RN = 1 + Math.round((float)Math.random()*(noNachbarn-1));
+ float RNEdgeSlope = 0;
+ int nbUrbanX = 0;
+ int nbUrbanY = 0;
+
+ for (int nbCellChange = 0; nbCellChange < NEIGHBOR.length; nbCellChange++){ //dann starte eine Schleife
+ checkBreakingCommands();
+ nbX = x+NEIGHBOR[nbCellChange][0];
+ nbY = y+NEIGHBOR[nbCellChange][1];
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ RNEdgeSlope = (float)Math.random(); //Zufallszahl zum Abgleich mit Slope-Koeffizient
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbX,nbY); //holt sich den Slope-Wert aus dem Slope-Raster
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb); //holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+ double slopeDoubleNb = doubleObjNb.doubleValue(); //konvertiert Double-Objekt in double-Wert
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY); //holt die Werte aus den jeweiligen Nachbarzellen
+ if (rasterSample == 0f){ //wenn der Wert 0 ist
+ anzTemp++; //wird Anzahl der möglichen Zellen erhöht
+ nbPossibleUrban = new int[] {nbX,nbY,anzTemp}; //Koordinaten und Nummern dieser Zellen werden in Array geschrieben
+ int urbanNbTemp = 0;
+ float NbValueEdge = 1f;
+ if (nbPossibleUrban[2] == RN){ //wenn Nummer im "PossibleUrban"-Array der Zufallszahl entspricht, die zwischen 1 und Anzahl der möglichen Zellen liegt...
+ //damit die Städte nicht zu sehr "ausfransen" steht eine Zelle nur zur Umwandlung zur Verfügung, wenn auch sie mind. 2 urbane Nachbarn hat
+ urbanNbTemp = calculateNeighbors(nbX,nbY,NbValueEdge);
+ if (urbanNbTemp >= 2 && tmpGrid[nbX][nbY]==false && slopeDoubleNb < RNEdgeSlope){
+ tmpGrid[nbX][nbY] = true; //wird true ins temporäre Raster geschrieben
+ anzSpreadTreffer++; //und die Anzahl der Spread-Treffer gezählt
+ }
+ }
+ }
+ nbCell = new int[] {nbX,nbY,(int) rasterSample}; //die Nummer und Koordinaten der jeweiligen Zellen wird in ein Array geschrieben
+ }
+ }
+ if (anzNachbarn>0) anyBodyAlive = true;
+ } //ENDE EDGE-WACHSTUM
+
+ /*********************************************************************
+ * ROAD
+ *********************************************************************/
+
+ //Variablendefinitionen
+ int anzGesamt = 0;
+ int[] cellValue = null;
+ int RSearchRoad = 0;
+ int r = 1; //Verteile soviel neue Pixel zufällig in geeigneten Bereichen, bis disp_value erreicht ist
+ //Rectangle gridBounds = new Rectangle(0, 0, outputGrid.getWidth(), outputGrid.getHeight()); //ein Rechteck wird definiert
+
+ //For-Schleife zählt alle als true markierten Zellen im Temp-Raster
+ for (int x = 0; x < outputGrid.getWidth();x++)
+ for(int y = 0; y < outputGrid.getHeight();y++){
+ int X = outputGrid.getMinX() + x;
+ int Y = outputGrid.getMinY() + y;
+ if (tmpGrid[X][Y]==true){
+ anzGesamt++;
+ }
+ }
+
+ //Beginn einer do-while-Schleife
+ do{
+ //Variablendefinitionen
+ RSearchRoad = Math.round((float)Math.random()*anzGesamt); //Zufallszahl zwischen 1 und Anzahl aller bisher neu hinzugekommener Pixel
+ int anzTruePixels = 0;
+ int roadNeighborhoodRange = 0;
+ int RSearchNbRoad = 0;
+ for (int x = 0; x < outputGrid.getWidth();x++){ //gesamtes Raster wird durchsucht
+ for(int y = 0; y < outputGrid.getHeight();y++){
+ int X = outputGrid.getMinX() + x;
+ int Y = outputGrid.getMinY() + y;
+ if (tmpGrid[X][Y]==true){
+ anzTruePixels++; //wird true-Pixel gefunden, wird anzTruePixels hochgezählt
+ cellValue = new int[] {X,Y,anzTruePixels}; //und Koordinaten in Array geschrieben
+ int tempRoadCell[] = null;
+ int tempNbRoadCell[] = null;
+ if (cellValue[2] == RSearchRoad){ //eins der neu entstandenen Pixel wird nach Zufallsprinzip ausgewählt
+ //statusOut.println(cellValue[0]+","+cellValue[1]+","+cellValue[2]);
+ //statusOut.println(r+","+RSearchRoad);
+ r++; //Anzahl der so gefundenen Zellen wird hochgezählt, bis Road-Koeffizient erreicht wird
+ //JETZT NACH STRAßE SUCHEN!!
+ float roadValue = roadGrid.getRasterSampleAsFloat(X,Y); //An Koordinate X/Y wird Wert aus roadGrid geholt
+ // statusOut.println(roadValue);
+ if (roadValue > 0.0){ //wenn Wert > 0 ist...
+ tempRoadCell = new int[] {X,Y}; //wird an Koordinate X/Y eine temporäre Straßenzelle platziert (bzw. Koordinaten in Array geschrieben
+ // statusOut.println("Strasse in Entfernung 0: "+tempRoadCell[0]+","+tempRoadCell[1]);
+ int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1],dispF); //von dieser Koordinate aus wird ein Road-Walk gestartete (siehe Funktion roadWalk!!)
+ if(nbCellNew != null){ //kommt nach roadWalk ein Wert zurück (d.h. wurde potenziell zu besiedelndes Pixel gefunden)...
+ tmpGrid[nbCellNew[0]][nbCellNew[1]] = true; //wird "true" ins temporäre Raster geschrieben (neue Siedlungszelle gefunden!!)
+ // statusOut.println(nbCellNew.length);
+ // statusOut.println("Neue Zelle: "+nbCellNew[0]+","+nbCellNew[1]);
+ // statusOut.println("++++++++++++++++++++++++++++++++++++++++");
+
+ //wenn per roadWalk eine neue Zelle gefunden wurde, kann sie auch noch als Ausbreitungszentrum fungieren. Daher geht von ihr
+ //nochmals ein "Breed" aus.
+
+ //Variablendefinitionen
+ float nbRoadBreed = 0f;
+ int nbRoadBreedNeighbors = 0;
+ nbRoadBreedNeighbors = calculateNeighbors(nbCellNew[0],nbCellNew[1],nbRoadBreed); //Nachbarzellen der neuen Zelle werden gezählt
+ int RNRoadBreed1 = 0;
+ int RNRoadBreed2 = 0;
+ int nbRoadBreedX = 0;
+ int nbRoadBreedY = 0;
+ int anzRoadBreedTreffer = 0;
+
+ if (nbRoadBreedNeighbors >= 2){ //sind mehr als 2 potenzielle Nachbarzellen verfügbar
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNRoadBreed1 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ float RNRoadBreedSlope = 0f;
+ if (RNRoadBreed2 == RNRoadBreed1)
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+ nbRoadBreedX = nbCellNew[0]+NEIGHBOR[cellBreed][0];
+ nbRoadBreedY = nbCellNew[1]+NEIGHBOR[cellBreed][1];
+ if ( nbRoadBreedX < areaMinX || nbRoadBreedY < areaMinY || nbRoadBreedX > areaMaxX || nbRoadBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY) != 0)
+ continue;
+ RNRoadBreedSlope = (float)Math.random(); //Zufallszahl zum Abgleich mit Slope-Koeffizient
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY); //holt sich den Slope-Wert aus dem Slope-Raster
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb); //holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+ double slopeDoubleNb = doubleObjNb.doubleValue(); //konvertiert Double-Objekt in double-Wert
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY); //holt die Werte aus den jeweiligen Nachbarzellen
+ if (breedSample == 0f){ //hat die Nachbarzelle den Wert 0 wird anzBreedTemp hochgezählt
+ anzBreedTemp++;
+ nbPossibleBreedUrban = new int[] {nbRoadBreedX,nbRoadBreedY,anzBreedTemp}; //und Koordinaten dieser Zelle in Array geschrieben
+ if (nbPossibleBreedUrban[2] == RNRoadBreed1 || nbPossibleBreedUrban[2] == RNRoadBreed2 && slopeDoubleNb < RNRoadBreedSlope){ //stimmt der Wert mit einer der beiden Zufallszahlen überein und ist laut Slope-Wert Besiedlung erlaubt...
+ tmpGrid[nbRoadBreedX][nbRoadBreedY] = true; //..wird "true" ins temporäre Raster geschrieben (neue Siedlungszelle erstellt!)
+ anzRoadBreedTreffer++; //Anzahl der durch Breed nach RoadWalk erzeugten Zellen wird hochgezählt
+ anzRoadTreffer++;
+ // statusOut.println("Road-Breed-Treffer: "+anzRoadBreedTreffer);
+ }
+ }
+ }
+ }
+ } else{ //kommt nach Road-Walk nichts zurück...
+ // statusOut.println("Keine neue Zelle gefunden");
+ }
+ //ist an der Stelle, an der eine neue Zelle entstanden war keine Straße, wird im Folgenden in ihrer Nähe danach gesucht...
+ } else{
+
+ int anzRoadNb = 0;
+
+ //HIER MIT FOR SCHLEIFE RECHTECK WACHSEN LASSEN!!!
+ for (int roadSearch = 0; roadSearch <= rg_value; roadSearch++){ //vergrößere die Nachbarschaft, bis rg_value erreicht ist
+ if (anzRoadNb > 0) //höre auf, sobald Straße in der Nachbarschaft gefunden wurde
+ continue;
+ for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++)
+ for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){
+ //if (gridBounds.contains(nbRoadCellsX, nbRoadCellsY))
+ if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ // if (areaRestr.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY) != 0)
+ // continue;
+ float roadValueNb = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY); //hole Wert aus Straßenraster
+ if (roadValueNb > 0f) //ist der Wert im Straßen-Raster > 0 zähle den Wert anzRoadNb hoch
+ anzRoadNb++;
+
+ //statusOut.println("Strasse in Entfernung 1: "+anzRoadNb+","+nbRoadCellsX+","+nbRoadCellsY);
+ }
+ roadNeighborhoodRange++;
+ RSearchNbRoad = Math.round((float)Math.random()*anzRoadNb);
+ //statusOut.println("--> Zyklus "+roadNeighborhoodRange+"Nachbarn: "+anzRoadNb);
+ //statusOut.println(RSearchNbRoad);
+ int anzTempRoadNb = 0;
+ for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++){
+ for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){
+ // statusOut.println("TEST-ROAD: "+nbRoadCellsX+","+nbRoadCellsY);
+ // if (gridBounds.contains(nbRoadCellsX, nbRoadCellsY))
+ if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ // if (areaRestr.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY) != 0)
+ // continue;
+ float roadValueNbTemp = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY); //hole Wert aus Straßenraster
+ if (roadValueNbTemp > 0f){ //ist der Wert im Straßen-Raster > 0 zähle den Wert anzRoadNbTemp hoch
+ anzTempRoadNb++;
+ tempNbRoadCell = new int[] {nbRoadCellsX,nbRoadCellsY,anzTempRoadNb}; //schreibe die Koordinaten in ein Array
+ if (tempNbRoadCell[2]==RSearchNbRoad){ //Wenn der Wert im Array dem vorher definierten Zufallswert entspricht...
+ //statusOut.println("Treffer: "+tempNbRoadCell[0]+","+tempNbRoadCell[1]+","+tempNbRoadCell[2]);
+ tempRoadCell = tempNbRoadCell; //...wird die temporäre Straßenzelle an diese Position verschoben
+ // statusOut.println("Strasse in Entfernung "+roadSearch+": "+tempRoadCell[0]+","+tempRoadCell[1]+","+tempRoadCell[2]);
+ int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1],dispF); //von dort aus wird ein Road-Walk durchgeführt (--> siehe Funktion roadWalk!)
+ if(nbCellNew != null){ //kommt nach roadWalk ein Wert zurück (d.h. wurde potenziell zu besiedelndes Pixel gefunden)...
+ tmpGrid[nbCellNew[0]][nbCellNew[1]] = true; //wird "true" ins temporäre Raster geschrieben (neue Siedlungszelle gefunden!!)
+// statusOut.println(nbCellNew.length);
+// statusOut.println("Neue Zelle: "+nbCellNew[0]+","+nbCellNew[1]);
+// statusOut.println("++++++++++++++++++++++++++++++++++++++++");
+ //Variablendefinitionen
+
+ float nbRoadBreed = 0f;
+ int nbRoadBreedNeighbors = 0;
+ nbRoadBreedNeighbors = calculateNeighbors(nbCellNew[0],nbCellNew[1],nbRoadBreed);
+ int RNRoadBreed1 = 0;
+ int RNRoadBreed2 = 0;
+ int nbRoadBreedX = 0;
+ int nbRoadBreedY = 0;
+ int anzRoadBreedTreffer = 0;
+
+ //wenn per roadWalk eine neue Zelle gefunden wurde, kann sie auch noch als Ausbreitungszentrum fungieren. Daher geht von ihr
+ //nochmals ein "Breed" aus. (GLEICHE FUNKTION WIE OBEN!!)
+
+ if (nbRoadBreedNeighbors >= 2){
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNRoadBreed1 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ float RNRoadBreedSlope = 0f;
+ if (RNRoadBreed2 == RNRoadBreed1)
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+ nbRoadBreedX = nbCellNew[0]+NEIGHBOR[cellBreed][0];
+ nbRoadBreedY = nbCellNew[1]+NEIGHBOR[cellBreed][1];
+ if ( nbRoadBreedX < areaMinX || nbRoadBreedY < areaMinY || nbRoadBreedX > areaMaxX || nbRoadBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY) != 0)
+ continue;
+ RNRoadBreedSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ if (breedSample == 0f){
+ anzBreedTemp++;
+ nbPossibleBreedUrban = new int[] {nbRoadBreedX,nbRoadBreedY,anzBreedTemp};
+ if (nbPossibleBreedUrban[2] == RNRoadBreed1 || nbPossibleBreedUrban[2] == RNRoadBreed2 && slopeDoubleNb < RNRoadBreedSlope){
+ tmpGrid[nbRoadBreedX][nbRoadBreedY] = true;
+ anzRoadBreedTreffer++;
+ anzRoadTreffer++;
+ //statusOut.println("Road-Breed-Treffer: "+anzRoadBreedTreffer);
+ }
+ }
+ }
+ }
+ } else{ //sind nicht mind. 2 Nachbarzellen gefunden worden...
+ //statusOut.println("Keine neue Zelle gefunden");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ } while (r <= breedF);
+
+ // statusOut.println("Spread-Treffer: "+anzSpreadTreffer);
+ // statusOut.println("Dispersion-Treffer: "+anzDispTreffer);
+ // statusOut.println("Breed-Treffer: "+anzBreedTreffer);
+ // statusOut.println("Treffer gesamt: "+anzGesamt);
+ anzGesamtTreffer = anzSpreadTreffer+anzDispTreffer+anzBreedTreffer+anzRoadTreffer;
+ // outStep.addGrid();
+
+
+ /**
+ * Hier endet der eigentliche Modellalgorithmus des Urban Growth Modells.
+ * Als nächstes wird das was ins temporäre grid geschrieben wurde ins outputGrid geschrieben.
+ * Mit dem outputGrid wird dann im nächsten Zeitschritt weitergerechnet, bis die maximale Anzahl
+ * an Jahren erreicht ist. Danach wird die nächste Kombination an Koeffizienten gewählt.
+ */
+
+ // TempGrid auf das echte Grid schreiben
+ for (int y = 1; y < outputGrid.getHeight()-1;y++ )
+ for (int x = 1; x < outputGrid.getWidth()-1; x++ ) {
+
+ int X = outputGrid.getMinX() + x;
+ int Y = outputGrid.getMinY() + y;
+
+ boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f; //eine Zelle lebt, wenn sie 1 ist
+ boolean road = roadGrid.getRasterSampleAsFloat(X, Y) > 0f; //eine Zelle beinhaltet eine Straße...
+ if (tmpGrid[x][y] == false) //wenn im temporären Raster nichts drinsteht...
+ tmpGrid[x][y] = lebt; //wird der Wert aus dem Ausgangsraster übernommen
+ if(lebt == true)
+ thisYear++;
+ if(road == true)
+ roadCount++;
+
+ outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);
+ actUrb = (Float)outputGrid.getRasterSample(x,y);
+ // outStep.getGrid(stepNo-1).setRasterSample(actUrb,x,y);
+ }
+
+ //SELF-MODIFICATION
+ growthRate = ((float)anzGesamtTreffer / (float)thisYear)*100;
+ // statusOut.println("Wachstumsrate: "+growthRate+", Urban: "+anzGesamtTreffer);
+ double percent_urban = (100.0 *(thisYear+roadCount) / (totalPixels-roadCount-excldCount));
+ // statusOut.println("1. Slope-Sensitivity: "+slopeF+", RoadGravity-Sensitivity: "+roadGravityF+", Diffusion-Sensitivity: "+dispF+", Breed-Sensitivity: "+breedF+", Spread-Sensitivity: "+spreadF);
+ //Boom-Year
+ if(growthRate > criticalHigh){
+ slopeF -= (float)percent_urban * (float)slopeSens;
+ if(slopeF <= 0.01)
+ slopeF = 1.0;
+ roadGravityF += (float)percent_urban * roadGravSens;
+ if(roadGravityF > 100.0)
+ roadGravityF = 100.0;
+ if(dispF < 100.0){
+ dispF *= boom;
+ if(dispF > 100.0)
+ dispF = 100.0;
+ breedF *= boom;
+ if(breedF > 100.0)
+ breedF = 100.0;
+ spreadF *= boom;
+ if(spreadF > 100.0)
+ spreadF = 100.0;
+ }
+ }
+ //Bust-Year
+ if(growthRate < criticalLow){
+ slopeF += (float)percent_urban * (float)slopeSens;
+ if(slopeF > MaxSlopeResistance)
+ slopeF = MaxSlopeResistance;
+ roadGravityF -= (float)percent_urban * roadGravSens;
+ if(roadGravityF <= 0.01)
+ roadGravityF = 1.0;
+ if(growthRate < criticalLow && dispF > 0){
+ dispF *= bust;
+ if(dispF <= 0.01)
+ dispF = 1.0;
+ spreadF *= bust;
+ if(spreadF <= 0.01)
+ spreadF = 1.0;
+ breedF *= bust;
+ if(breedF <= 0.01)
+ breedF = 1.0;
+ }
+ }
+ //statusOut.println("thisYear: "+thisYear+", roadCount: "+roadCount+", excldCount: "+excldCount+", percent_urban: "+percent_urban);
+ statusOut.println("Slope-Sensitivity: "+slopeF+", RoadGravity-Sensitivity: "+roadGravityF+", Diffusion-Sensitivity: "+dispF+", Breed-Sensitivity: "+breedF+", Spread-Sensitivity: "+spreadF);
+
+
+ if (!anyBodyAlive) {
+ stepCount = stepNo;
+ //statusOut.println("Lebt keiner mehr... höre hier auf!");
+ }
+
+ //RasterUtil.copyInto(outputGrid, inputGrid);
+ // System.out.println("Finished step " + (stepNo) + " in "
+ // + ((System.currentTimeMillis() - localStartTime)) + " ms\n");
+ localStartTime = System.currentTimeMillis();
+
+ } //HIER ENDET DER ZEITSCHRITT. DIE SCHLEIFE WIRD DURCHLAUFEN, BIS MAX JAHRE ERREICHT SIND.
+
+ /**
+ * +++++ MULTIPLE RESOLUTION VALIDATION ++++++
+ * Sind alle Zeitschritte durchlaufen, wird das Endergebnis validiert.
+ * Als Validierungsmethode wurde die Multiple Resolution Validation ausgewählt (siehe
+ * Costanza(1989), Pontius (2002), Pontius et al. (2005), Lesschen et al. (2005),
+ * Pontius et al. (2008a), Pontius et al. (2008b))
+ * Für das SLEUTH-Modell werden eigentlich eine Reihe an Landschaftsmaßen zur Validierung
+ * verwendet (siehe Clarke et al. (1997), Dietzel et al. (2007)), wie z.B. LeeSallee
+ * oder OSM. Da für die spätere Validierung der Modellierungsergebnisse und zum Vergleich mit
+ * anderen Modelltypen die Multiple Resolution Validation verwendet wird, wird sie auch zur
+ * Bewertung der Kalibrierungsschritte verwendet.
+ */
+
+ //Variablendefinitionen
+ int RoverallSum = 0;
+ int RnumClasses = 0;
+ int SoverallSum = 0;
+ int SnumClasses = 0;
+ int correct = 0;
+ double fractionCorrect = 0f;
+
+
+ long localStartTime = System.currentTimeMillis();
+ neighborhoodRange = (int) Math.sqrt(referenceGrid.getWidth()*referenceGrid.getHeight()); //maximal mögliche Zellengröße
+ //statusOut.println(neighborhoodRange);
+ resultArray = new float[13]; //!!!!!!!!! Ergebnis-Array
+ resultArrayFinal = new float[MonteCarlo-1][13]; //?????????????
+
+ //Für die Ausgangs-Auflösung wird berechnet, wieviel % der Pixel zwischen Modell und Referenz übereinstimmen
+ for (int x = 0; x < referenceGrid.getWidth(); x++)
+ for (int y = 0; y < referenceGrid.getHeight(); y++) {
+ float Rtmp = referenceGrid.getRasterSampleAsFloat(x, y);
+ float Stmp = outputGrid.getRasterSampleAsFloat(x, y);
+ if (!Float.isNaN(Rtmp) && !Float.isNaN(Stmp)){
+ RoverallSum ++;
+ SoverallSum ++;
+ if (Rtmp > RnumClasses)
+ RnumClasses = (int) Rtmp;
+ if (Stmp > SnumClasses)
+ SnumClasses = (int) Stmp;
+ if (Rtmp == Stmp)
+ correct++;
+ }
+ }
+ fractionCorrect = (double) correct / (double) RoverallSum;
+
+ //Anzahl der Pixel pro Klasse
+ for (int i = 1; i <= RnumClasses; i++){
+ int Rj = 0;
+ int Sj = 0;
+ for (int x = 0; x < referenceGrid.getWidth(); x++)
+ for (int y = 0; y < referenceGrid.getHeight(); y++){
+ float Rtmp = referenceGrid.getRasterSampleAsFloat(x, y);
+ float Stmp = outputGrid.getRasterSampleAsFloat(x, y);
+ if (!Float.isNaN(Rtmp))
+ if ((int) Rtmp == i)
+ Rj++;
+ if (!Float.isNaN(Stmp))
+ if ((int) Stmp == i)
+ Sj++;
+ }
+ //statusOut.println("Klasse "+i+": Referenz("+Rj+"), Simulation("+Sj+")");
+ }
+
+ ngrids = 0;
+
+ //Die eigentliche Validierung wird für alle Zellengrößen von 1 (Ausgangsauflösung) bis "neighborhoodRange" durchgeführt
+ for (int r1 = 1; r1 <= neighborhoodRange; r1 = r1+r1){ //für Zellengröße 1 bis zur max. möglichen Zellengröße wird Statistik durchgeführt
+ //statusOut.println(r1);
+ ngrids++;
+ float SumWn = 0f; //Summe der gewichteten Mittelwerte
+ int SumCells = 0; //Summe der Zellen
+ float totalAgreement = 0f; //Endergebnis
+ for (int x = 0; x < referenceGrid.getWidth(); x = x+r1) //für jeden größer werdenden Zellenbereich...
+ for (int y = 0; y < referenceGrid.getHeight(); y = y+r1){ //was folgt passiert innerhalb einer größeren Rasterzelle
+ int nCells = 0; //Anzahl Zellen pro größerer Zelle
+ float SumMinRS = 0f; //Summe der Min-Werte bei Vergleich zweier Raster
+ float Wn = 0; //Gewichtete Zelle
+ for(int x2 = x; x2 < x+r1; x2++) //für jede kleinere Zelle innerhalb der größeren...
+ for(int y2 = y; y2 < y+r1; y2++){
+ if ( x2 < referenceGrid.getMinX() || y2 < referenceGrid.getMinY() || x2 > referenceGrid.getMinX()+referenceGrid.getWidth()-1 || y2 > referenceGrid.getMinY()+referenceGrid.getHeight()-1 ||
+ Float.isNaN(referenceGrid.getRasterSampleAsFloat(x2,y2)))
+ continue;
+ nCells++; //zähle "positive" Zellen
+ }
+ for (int i = 0; i <= RnumClasses; i++){ //für jede Klasse i
+ int Rn = 0; //Anzahl in Referenzkarte
+ int Sn = 0; //Anzahl in Simulationskarte
+ float Rnj = 0f; //Anteil in Referenzkarte
+ float Snj = 0f; //Anteil in Simulationskarte
+ float MinRS = 0f; //Min des Vergleichs zwischen beiden Karten
+ for(int x3 = x; x3 < x+r1; x3++) //für jede kleinere Zelle pro größerer Zelle...
+ for(int y3 = y; y3 < y+r1; y3++){
+ if ( x3 < referenceGrid.getMinX() || y3 < referenceGrid.getMinY() || x3 > referenceGrid.getMinX()+referenceGrid.getWidth()-1 || y3 > referenceGrid.getMinY()+referenceGrid.getHeight()-1 ||
+ Float.isNaN(referenceGrid.getRasterSampleAsFloat(x3,y3)))
+ continue;
+ float Rtmp = referenceGrid.getRasterSampleAsFloat(x3, y3); //hole Wert aus Referenz-Karte und
+ float Stmp = outputGrid.getRasterSampleAsFloat(x3, y3); //Simulationskarte
+ if ((int) Rtmp == i)
+ Rn++; //zähle in Referenzkarte Zellen, die zu Klasse i gehören
+ if ((int) Stmp == i)
+ Sn++; //und in Simulationskarte
+ }
+ if(nCells > 0){ //wenn positive Zellen vorhanden sind...
+ Rnj = (float)Rn / (float)nCells; //berechne Anteile pro größerer Zelle
+ Snj = (float)Sn / (float)nCells;
+ }
+ MinRS = Math.min(Rnj, Snj); //nehme Minimum-Wert des Vergleichs beider Karten
+ SumMinRS += MinRS; //summiere die Minimum-Werte auf
+ // statusOut.println(i+" Min"+MinRS+" Anzahl: "+nCells);
+ }
+
+ Wn = (float)nCells * SumMinRS;
+ // statusOut.println(SumMinRS+", gewichtet: "+Wn);
+ //Erstelle Output-Karten
+ float WnCell = 0f;
+ for(int x4 = x; x4 < x+r1; x4++) //für jede kleinere Zelle pro größerer Zelle...
+ for(int y4 = y; y4 < y+r1; y4++){
+ if ( x4 < referenceGrid.getMinX() || y4 < referenceGrid.getMinY() || x4 > referenceGrid.getMinX()+referenceGrid.getWidth()-1 || y4 > referenceGrid.getMinY()+referenceGrid.getHeight()-1 ||
+ Float.isNaN(referenceGrid.getRasterSampleAsFloat(x4,y4)))
+ continue;
+ WnCell = Wn / (float)nCells; //pro Zelle wird Mittelwert des Vergleichs genommen
+ //actualValidation.setRasterSample( WnCell ,x4 ,y4);
+ }
+
+ SumCells += (float)nCells; //Summiere alle Zellen auf
+ SumWn += Wn; //Summiere die gewichteten Anteile auf
+ } //hier endet die Berechnung innerhalb einer größeren Rasterzelle
+
+
+ //Total Agreement:
+ //statusOut.println(SumWn+" / "+SumCells);
+ totalAgreement = SumWn / (float)SumCells; //Ergebnisformel
+ //statusOut.println(totalAgreement);
+
+ outResults.addValue(totalAgreement);
+ resultArray[ngrids] = totalAgreement;
+
+ // statusOut.println("Gesamt-Pixel: "+RoverallSum);
+ // statusOut.println("Anzahl Klassen: "+RnumClasses);
+ // statusOut.println("Fraction Correct: "+fractionCorrect);
+
+ } //Hier endet die Berechnung pro Auflösung
+
+ // System.out.println("(Slope:"+slope+" Spread:"+spread+" Dispersion:"+disp+" Breed: "+breed+" RoadGravity: "+roadGravity+") "+
+ // resultArray[1]+","+resultArray[2]+","+resultArray[3]+","+resultArray[4]+","+resultArray[5]+","+resultArray[6]+
+ // ","+resultArray[7]+","+resultArray[8]+","+resultArray[9]);
+
+ pos1 += resultArray[1];
+ pos2 += resultArray[2];
+ pos3 += resultArray[3];
+ pos4 += resultArray[4];
+ pos5 += resultArray[5];
+ pos6 += resultArray[6];
+ pos7 += resultArray[7];
+ pos8 += resultArray[8];
+ pos9 += resultArray[9];
+ pos10 += resultArray[10];
+ pos11 += resultArray[11];
+ pos12 += resultArray[12];
+ // System.out.print("Finished step " + (stepNo) + " in "
+ // + ((System.currentTimeMillis() - localStartTime)) + " ms");
+ localStartTime = System.currentTimeMillis();
+ // System.out.println(" with sum (local calculated): " + RoverallSum);
+ } //!!!!!!!!!! Hier endet ein Monte-Carlo-Schritt
+
+ System.out.println("-->(Slope:"+slope+" Spread:"+spread+" Dispersion:"+disp+" Breed: "+breed+" RoadGravity: "+roadGravity+") "+
+ pos1/MonteCarlo+","+pos2/MonteCarlo+","+pos3/MonteCarlo+","+pos4/MonteCarlo+","+pos5/MonteCarlo+","+pos6/MonteCarlo+
+ ","+pos7/MonteCarlo+","+pos8/MonteCarlo+","+pos9/MonteCarlo+","+pos10/MonteCarlo+","+pos11/MonteCarlo+","+pos12/MonteCarlo);
+ } //Ende RoadGravity-Koeffizient
+ } //Ende Breed-Koeffizient
+ } //Ende Disp-Koeffizient
+ } //Ende Spread-Koeffizient
+ } //Ende Slope-Koeffizient
+ } //Ende Model-Step
+
+ private int[] roadWalk(int X,int Y,double dispF){
+// statusOut.println(X+","+Y);
+ boolean end_of_road;
+ end_of_road = false;
+ int run = 0;
+ int run_value = 0;
+ int[] nbCellNew = null;
+ int[] nbCellTemp = null;
+ while(!end_of_road){
+ end_of_road = true;
+ int nbRoadX = 0;
+ int nbRoadY = 0;
+ int areaMinX = outputGrid.getMinX(); //Dimensionen des Rasters
+ int areaMinY = outputGrid.getMinY();
+ int areaMaxX = outputGrid.getMinX() + outputGrid.getWidth() - 1;
+ int areaMaxY = outputGrid.getMinY() + outputGrid.getHeight() - 1;
+ int roadNb = 0;
+ int roadNbTemp = 0;
+ int RN = 0;
+
+ int[] nbCell = null;
+ for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){
+ nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+ nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+ if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ //if (areaRestr.getRasterSampleAsFloat(nbRoadX,nbRoadY) != 0)
+ // continue;
+ float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);
+ if (roadSample > 0f)
+ roadNb++;
+ }
+ // statusOut.println("Nachbarn von temporaerer Strassenzelle: "+roadNb);
+
+ if (roadNb > 0){
+ RN = 1 + Math.round((float)Math.random()*(roadNb-1));
+
+ for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){
+ nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+ nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+ if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);
+ if (roadSample > 0f){
+ roadNbTemp++;
+ nbCell = new int[] {nbRoadX,nbRoadY,roadNbTemp};
+ if (nbCell[2] == RN){
+// statusOut.println("Nachbarzelle gefunden: "+nbCell[0]+","+nbCell[1]+","+nbCell[2]);
+ end_of_road = false;
+ run++;
+ X = nbRoadX;
+ Y = nbRoadY;
+ float roadSample2 = roadGrid.getRasterSampleAsFloat(X,Y);
+ run_value = (int) (roadSample2 / 100 * dispF);
+ // statusOut.println("Run: "+run);
+ // statusOut.println("Run_Value: "+run_value);
+ // statusOut.println(X+","+Y+","+roadSample2);
+ if (run > run_value){
+ end_of_road = true;
+ // statusOut.println("Endzelle erreicht!! Run:"+run+"RunValue: "+run_value);
+ float NbValue = 0f;
+ int Nb = calculateNeighbors(X,Y,NbValue);
+ // statusOut.println("moegliche Nachbarzellen nach RoadWalk: "+Nb);
+ RN = 1 + Math.round((float)Math.random()*(Nb-1));
+ // statusOut.println("Random: "+RN);
+ if (Nb > 0){
+ int nbUrbanizeX = 0;
+ int nbUrbanizeY = 0;
+ int NbTemp = 0;
+ float RNRoadSlope = 0f;
+ // statusOut.println(X+","+Y);
+ for (int urbanizeCells = 0; urbanizeCells < NEIGHBOR.length; urbanizeCells++){
+ nbUrbanizeX = X+NEIGHBOR[urbanizeCells][0];
+ nbUrbanizeY = Y+NEIGHBOR[urbanizeCells][1];
+ if ( nbUrbanizeX < areaMinX || nbUrbanizeY < areaMinY || nbUrbanizeX > areaMaxX || nbUrbanizeY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);
+ RNRoadSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ if (rasterSample == 0f){
+ NbTemp++;
+ nbCellTemp = new int[] {nbUrbanizeX,nbUrbanizeY,NbTemp};
+ if (nbCellTemp[2] == RN && slopeDoubleNb < RNRoadSlope){
+ nbCellNew = new int[] {nbCellTemp[0],nbCellTemp[1],nbCellTemp[2]};
+ }
+ }
+ }
+
+ } else{
+ nbCellNew = null;
+ } break;
+ }
+
+ }
+
+ }
+ }
+
+ }
+ }
+ return nbCellNew;
+ }
+
+ private int calculateNeighbors(int X, int Y, float NbValue){
+ int nbX = 0;
+ int nbY = 0;
+ int areaMinX = outputGrid.getMinX(); //Dimensionen des Rasters
+ int areaMinY = outputGrid.getMinY();
+ int areaMaxX = outputGrid.getMinX() + outputGrid.getWidth() - 1;
+ int areaMaxY = outputGrid.getMinY() + outputGrid.getHeight() - 1;
+ int Nb = 0;
+ for (int nbCells = 0; nbCells < NEIGHBOR.length; nbCells++){
+ nbX = X+NEIGHBOR[nbCells][0];
+ nbY = Y+NEIGHBOR[nbCells][1];
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);
+ if (rasterSample == NbValue)
+ Nb++;
+ }
+ // statusOut.println("..."+Nb+"...");
+ return Nb;
+ }
+
+ protected static boolean checkNoData(int x, int y, WritableGrid grid) {
+ return Float.isNaN(grid.getRasterSampleAsFloat(x,y));
+ }
+}
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModificationContentManager.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModificationContentManager.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModificationContentManager.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,61 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.DefaultModelResource;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+
+public class UrbanGrowthModelCalibrationSelfModificationContentManager extends AbstractModelContentManager {
+
+ public UrbanGrowthModelCalibrationSelfModificationContentManager() {
+ super(31);
+
+ resource[0] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+ resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of MonteCarlo Iterations",ScalarProperty.class,Integer.class,false);
+ resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Input Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[3] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Output Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[4] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Area Restrictions",ScalarProperty.class,WritableGrid.class,false);
+ resource[5] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[6] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[7] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Reference Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[8] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient Start",ScalarProperty.class,Double.class,false);
+ resource[9] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient Step",ScalarProperty.class,Double.class,false);
+ resource[10] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient End",ScalarProperty.class,Double.class,false);
+ resource[11]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient Start",ScalarProperty.class,Double.class,false);
+ resource[12]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient Step",ScalarProperty.class,Double.class,false);
+ resource[13]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient End",ScalarProperty.class,Double.class,false);
+ resource[14]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient Start",ScalarProperty.class,Double.class,false);
+ resource[15]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient Step",ScalarProperty.class,Double.class,false);
+ resource[16]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient End",ScalarProperty.class,Double.class,false);
+ resource[17]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient Start",ScalarProperty.class,Double.class,false);
+ resource[18]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient Step",ScalarProperty.class,Double.class,false);
+ resource[19]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient End",ScalarProperty.class,Double.class,false);
+ resource[20]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient Start",ScalarProperty.class,Double.class,false);
+ resource[21]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient Step",ScalarProperty.class,Double.class,false);
+ resource[22]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient End",ScalarProperty.class,Double.class,false);
+ resource[23]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Slope",ScalarProperty.class,Double.class,false);
+ resource[24]= new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Validation Results",ListProperty.class,Float.class,false);
+ resource[25]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Gravity Sensitivity",ScalarProperty.class,Double.class,false);
+ resource[26]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Sensitivity",ScalarProperty.class,Double.class,false);
+ resource[27]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Low",ScalarProperty.class,Double.class,false);
+ resource[28]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical High",ScalarProperty.class,Double.class,false);
+ resource[29]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Boom",ScalarProperty.class,Double.class,false);
+ resource[30]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Bust",ScalarProperty.class,Double.class,false);
+
+ // ===== Ressourcen Bezeichnungen lokalisieren =====
+ resetCaptions(null);
+ }
+
+
+ @Override
+ public void checkAndError() throws XuluDataException {
+ // TODO Auto-generated method stub
+ super.checkAndError();
+ }
+}
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelContentManager.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelContentManager.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelContentManager.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,44 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.DefaultModelResource;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+
+public class UrbanGrowthModelContentManager extends AbstractModelContentManager {
+
+ public UrbanGrowthModelContentManager() {
+ super(13);
+
+ resource[0] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Input Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Output Grid",ScalarProperty.class,WritableGrid.class,false);
+ // Number of steps
+ resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+ // Spread Coefficient
+ resource[3] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Area Restrictions",ScalarProperty.class,WritableGrid.class,false);
+ resource[4] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient",ScalarProperty.class,Double.class,false);
+ resource[5] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient",ScalarProperty.class,Double.class,false);
+ resource[6] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient",ScalarProperty.class,Double.class,false);
+ resource[7] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient",ScalarProperty.class,Double.class,false);
+ resource[8] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient",ScalarProperty.class,Double.class,false);
+ resource[9] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Slope",ScalarProperty.class,Double.class,false);
+ resource[10]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[11]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[12]= new DefaultModelResource(ModelResource.CATEGORY_OUTPUT,"Step Results",MultiGrid.class,false);
+
+ // ===== Ressourcen Bezeichnungen lokalisieren =====
+ resetCaptions(null);
+ }
+
+
+ @Override
+ public void checkAndError() throws XuluDataException {
+ // TODO Auto-generated method stub
+ super.checkAndError();
+ }
+}
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifying.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifying.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifying.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,951 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import java.awt.Rectangle;
+import java.util.HashMap;
+
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+
+/**
+ * This very simple model looks at every grid cell and takes the average
+ * over a the surrounding cells in a specified neighborhood. It was implemented
+ * as demonstration of the Xulu / V functionality. You can see the parallel version
+ * of this model in {@link AverageNeighborhoodParallelDemoModel} and also a tuned
+ * version using late-merging support in {@link AVNTuned}.
+ * <ol>
+ * <li><b>Input Grid ({@code inputGrid}):</b> A grid with input values </li>
+ * <li><b>Output Grid ({@code outputGrid}):</b> A grid where the output is
+ * stored </li>
+ * <li><b>Number of steps ({@code steps}):</b> the number of steps to
+ * compute. </li>
+ * </ol>
+ *
+ * @see AverageNeighborhoodContentManager
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class UrbanGrowthModelSelfModifying extends AbstractStepModel {
+
+ protected UrbanGrowthModelSelfModifyingContentManager contManager;
+
+ // ********** Lese/Schreibrechte, die fuer den gesamten ***********
+ // ********** Modellanlauf gehalten werden muessen ***********
+ private PropertyReadAccess RA_inputGrid = null; // Input Grid
+ private PropertyWriteAccess WA_outputGrid = null; // Output Grid
+ private PropertyReadAccess RA_steps = null; // Number of steps
+ private PropertyReadAccess RA_areaRestr = null; //Area Restrictions
+ private PropertyReadAccess RA_spread = null; //Spread-Koeffizient
+ private PropertyReadAccess RA_disp = null; //Dispersions-Koeffizient
+ private PropertyReadAccess RA_breed = null; //Breed-Koeffizient
+ private PropertyReadAccess RA_roadGravity = null; //Road-Gravity-Koeffizient
+ private PropertyReadAccess RA_slope = null; //Slope-Koeffizient
+ private PropertyReadAccess RA_criticalSlope = null; //Critical Slope Value
+ private PropertyReadAccess RA_roadGrid = null; //Road Grid
+ private PropertyReadAccess RA_slopeGrid = null; //Slope Grid
+ private PropertyWriteAccess WA_outStep = null; // Step Results
+ private PropertyReadAccess RA_roadGravSens = null; //RoadGravity Sensitivity
+ private PropertyReadAccess RA_slopeSens = null; //Slope Sensitivity
+ private PropertyReadAccess RA_criticalLow = null; //Critical Low
+ private PropertyReadAccess RA_criticalHigh = null; //Critical High
+ private PropertyReadAccess RA_Boom = null; //Boom
+ private PropertyReadAccess RA_Bust = null; //Bust
+
+ // **************** Variablen mit denen gearbeitet wird *******************
+ private WritableGrid inputGrid = null; // Input Grid
+ private WritableGrid outputGrid = null; // Output Grid
+ private PropertyReadAccess steps = null; // Number of steps
+ private WritableGrid areaRestr = null; //Area Restrictions
+ protected double spread = 0; //Spread-Koeffizient
+ protected double disp = 0; //Dispersions-Koeffizient
+ protected double breed = 0; //Breed-Koeffizient
+ protected double roadGravity = 0; //Road-Gravity-Koeffizient
+ protected double slope = 0; //Slope-Koeffizient
+ protected double criticalSlope = 0; //Critical Slope Value
+ private WritableGrid roadGrid = null; //Road Grid
+ private WritableGrid slopeGrid = null; //Slope Grid
+ private MultiGrid outStep = null; //Step Results
+ protected double roadGravSens = 0; //RoadGravity Sensitivity
+ protected double slopeSens = 0; //Slope Sensitivity
+ protected double criticalLow = 0; //critical Low
+ protected double criticalHigh = 0; //critical High
+ protected double boom = 0; //Boom
+ protected double bust = 0; //Bust
+
+ private static final int[][] NEIGHBOR = new int[][] {
+ {-1,-1}, {0,-1}, {1,-1},
+ {-1, 0}, {1, 0},
+ {-1, 1}, {0, 1}, {1, 1}
+ };
+
+ protected HashMap<Number,Number> slopeLUT;
+ private int slopeMax = 0;
+ private int totalPixels = 0;
+ private int excldCount = 0;
+
+ /**
+ * Erzeugt eine neue Instanz des Modells.
+ */
+ public UrbanGrowthModelSelfModifying() {
+ super(new UrbanGrowthModelSelfModifyingContentManager());
+ this.contManager = (UrbanGrowthModelSelfModifyingContentManager) super.contManager;
+ }
+
+
+ /**
+ * Initializes the model. Like in the init method of every {@link XuluModel}
+ * the resources are initalized.
+ */
+ public void performModelInit() {
+ if (contManager == null)
+ return;
+ // Zugriffsrechte aus Ressourcen/Propertys holen
+ RA_inputGrid = null;
+ if (contManager.getResource(0).getData() != null)
+ RA_inputGrid = ((ScalarProperty) contManager.getResource(0)
+ .getData()).getReadAccess(this);
+ WA_outputGrid = null;
+ if (contManager.getResource(1).getData() != null)
+ WA_outputGrid = ((ScalarProperty) contManager.getResource(1)
+ .getData()).getWriteAccess(this);
+ RA_steps = null;
+ if (contManager.getResource(2).getData() != null)
+ RA_steps = ((ScalarProperty) contManager.getResource(2).getData())
+ .getReadAccess(this);
+ RA_areaRestr = null;
+ if (contManager.getResource(3).getData() != null)
+ RA_areaRestr = ((ScalarProperty) contManager.getResource(3)
+ .getData()).getReadAccess(this);
+ RA_spread = null;
+ if (contManager.getResource(4).getData() != null)
+ RA_spread = ((ScalarProperty) contManager.getResource(4).getData())
+ .getReadAccess(this);
+ RA_disp = null;
+ if (contManager.getResource(5).getData() != null)
+ RA_disp = ((ScalarProperty) contManager.getResource(5).getData())
+ .getReadAccess(this);
+ RA_breed = null;
+ if (contManager.getResource(6).getData() != null)
+ RA_breed = ((ScalarProperty) contManager.getResource(6).getData())
+ .getReadAccess(this);
+ RA_roadGravity = null;
+ if (contManager.getResource(7).getData() != null)
+ RA_roadGravity = ((ScalarProperty) contManager.getResource(7).getData())
+ .getReadAccess(this);
+ RA_slope = null;
+ if (contManager.getResource(8).getData() != null)
+ RA_slope = ((ScalarProperty) contManager.getResource(8).getData())
+ .getReadAccess(this);
+ RA_criticalSlope = null;
+ if (contManager.getResource(9).getData() != null)
+ RA_criticalSlope = ((ScalarProperty) contManager.getResource(9).getData())
+ .getReadAccess(this);
+ RA_roadGrid = null;
+ if (contManager.getResource(10).getData() != null)
+ RA_roadGrid = ((ScalarProperty) contManager.getResource(10)
+ .getData()).getReadAccess(this);
+ RA_slopeGrid = null;
+ if (contManager.getResource(11).getData() != null)
+ RA_slopeGrid = ((ScalarProperty) contManager.getResource(11)
+ .getData()).getReadAccess(this);
+ RA_roadGravSens = null;
+ if (contManager.getResource(13).getData() != null)
+ RA_roadGravSens = ((ScalarProperty) contManager.getResource(13).getData())
+ .getReadAccess(this);
+ RA_slopeSens = null;
+ if (contManager.getResource(14).getData() != null)
+ RA_slopeSens = ((ScalarProperty) contManager.getResource(14).getData())
+ .getReadAccess(this);
+ RA_criticalLow = null;
+ if (contManager.getResource(15).getData() != null)
+ RA_criticalLow = ((ScalarProperty) contManager.getResource(15).getData())
+ .getReadAccess(this);
+ RA_criticalHigh = null;
+ if (contManager.getResource(16).getData() != null)
+ RA_criticalHigh = ((ScalarProperty) contManager.getResource(16).getData())
+ .getReadAccess(this);
+ RA_Boom = null;
+ if (contManager.getResource(17).getData() != null)
+ RA_Boom = ((ScalarProperty) contManager.getResource(17).getData())
+ .getReadAccess(this);
+ RA_Bust = null;
+ if (contManager.getResource(18).getData() != null)
+ RA_Bust = ((ScalarProperty) contManager.getResource(18).getData())
+ .getReadAccess(this);
+
+ // Variablen belegen mit denen gearbeitet wird
+ inputGrid = (WritableGrid) RA_inputGrid.getValue();
+ outputGrid = (WritableGrid) WA_outputGrid.getValue();
+ steps = RA_steps;
+ areaRestr = (WritableGrid) RA_areaRestr.getValue();
+
+ this.stepCount = steps.getValueAsInt();
+ // this.spread = RA_spread.getValueAsFloat();
+ spread = RA_spread.getValueAsDouble();
+ disp = RA_disp.getValueAsDouble();
+ breed = RA_breed.getValueAsDouble();
+ roadGravity = RA_roadGravity.getValueAsDouble();
+ slope = RA_slope.getValueAsDouble();
+ criticalSlope = RA_criticalSlope.getValueAsDouble();
+ roadGrid = (WritableGrid) RA_roadGrid.getValue();
+ slopeGrid = (WritableGrid) RA_slopeGrid.getValue();
+ outStep = (MultiGrid)contManager.getResource(12).getData();
+ roadGravSens = RA_roadGravSens.getValueAsDouble();
+ slopeSens = RA_slopeSens.getValueAsDouble();
+ criticalLow = RA_criticalLow.getValueAsDouble();
+ criticalHigh = RA_criticalHigh.getValueAsDouble();
+ boom = RA_Boom.getValueAsDouble();
+ bust = RA_Bust.getValueAsDouble();
+
+ int startAnz = 0;
+ for (int i = 0; i < inputGrid.getWidth();i++ ) {
+ for (int ii = 0; ii < inputGrid.getHeight(); ii++ ) {
+ //if (inputGrid.getRasterSampleAsFloat(i,ii) == 1f);
+ float val = inputGrid.getRasterSampleAsFloat(i,ii);
+ if (val == 1.0 ) {
+ val = 1f;
+ startAnz++;
+ }
+ else val = 0f;
+
+ inputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+ outputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+ }
+ }
+ for (int x = 0; x < inputGrid.getWidth();x++ )
+ for (int y = 0; y < inputGrid.getHeight(); y++ ) {
+ if ( x < inputGrid.getMinX() || y < inputGrid.getMinY() || x > inputGrid.getMinX()+inputGrid.getWidth()-1 || y > inputGrid.getMinY()+inputGrid.getHeight()-1 ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(x,y)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ totalPixels++;
+ if (areaRestr.getRasterSampleAsFloat(x,y) != 0 && !Float.isNaN(areaRestr.getRasterSampleAsFloat(x,y)))
+ //continue; //wenn in Area Restriction oder wenn schon Siedlung da ist, mach weiter
+ //if (inputGrid.getRasterSampleAsFloat(i,ii) == 1f);
+ excldCount++;
+ }
+
+ statusOut.println("Anzahl der startenden Individuen: "+startAnz);
+ statusOut.println(NEIGHBOR.length);
+ statusOut.println("Total: "+totalPixels+", Excluded: "+excldCount);
+
+
+ for (int s = 0; s < inputGrid.getWidth();s++){
+ for(int ss = 0; ss < inputGrid.getHeight();ss++){
+ float slopeVal = slopeGrid.getRasterSampleAsFloat(s,ss);
+ if (slopeVal > slopeMax){
+ slopeMax = (int) slopeVal;
+ }
+ }
+ }
+ statusOut.println("Maximale Hangneigung: "+slopeMax);
+
+ }
+
+ /**
+ * like in every model: frees the resources
+ */
+ public void performModelDispose() {
+
+ // Ressourcen wieder freigeben
+ releaseAccess(RA_inputGrid);
+ releaseAccess(WA_outputGrid);
+ releaseAccess(RA_steps);
+ releaseAccess(RA_areaRestr);
+ releaseAccess(RA_spread);
+ releaseAccess(RA_disp);
+ releaseAccess(RA_breed);
+ releaseAccess(RA_roadGravity);
+ releaseAccess(RA_slope);
+ releaseAccess(RA_criticalSlope);
+ releaseAccess(RA_roadGrid);
+ releaseAccess(RA_slopeGrid);
+ releaseAccess(WA_outStep);
+ releaseAccess(RA_roadGravSens);
+ releaseAccess(RA_slopeSens);
+ releaseAccess(RA_criticalLow);
+ releaseAccess(RA_criticalHigh);
+ releaseAccess(RA_Boom);
+ releaseAccess(RA_Bust);
+ }
+
+ /**
+ * This very simple model looks at every grid cell and takes the average
+ * over a the surrounding cells in a specified neighborhood.
+ *
+ * @param stepNo
+ * zu modellierender Schritt (beginnend bei 1!)
+ */
+ public void performModelStep(int stepNo) {
+
+ statusOut.println("Starting step " + stepNo + "...");
+
+ //Erstellt einen Lookup-Table
+ slopeLUT = new HashMap<Number,Number>();
+
+ int MaxSlopeResistance = 0;
+ double exp = 0.0;
+ MaxSlopeResistance = 100;
+ exp = (slope / (MaxSlopeResistance / 2));
+ double[] lookup = new double[slopeMax+1];
+ Number key = 0;
+
+ for (int i = 0;i <= slopeMax;i++){
+ if (i <= criticalSlope){
+ double val = (criticalSlope - i) / criticalSlope;
+ lookup[i] = 1 - Math.pow(val,exp);
+ key = i;
+ } else{
+ lookup[i] = 1;
+ key = i;
+ }
+ slopeLUT.put(key,lookup[i]);
+ statusOut.println(slopeLUT.get(key));
+ }
+
+ Number number = slopeLUT.get(79);
+// statusOut.println(number);
+
+ int areaMinX = inputGrid.getMinX(); //Dimensionen des Rasters
+ int areaMinY = inputGrid.getMinY();
+ int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+ int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+ int areaWidth = inputGrid.getWidth();
+ int areaHeight = inputGrid.getHeight();
+
+ long localStartTime = System.currentTimeMillis();
+ boolean anyBodyAlive = false;
+
+ boolean[][] tmpGrid = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];
+ Float actUrb = null;
+
+ int nbX = 0; // X-Koordinate einer Nachbarzelle
+ int nbY = 0; // Y-Koordinate einer Nachbarzelle
+ int[] nbCell = null;
+
+ int anzSpreadTreffer = 0;
+ int anzDispTreffer = 0;
+ int anzBreedTreffer = 0;
+ int anzRoadTreffer = 0;
+ int anzGesamtTreffer = 0;
+ double growthRate = 0;
+ int thisYear = 0;
+ int roadCount = 0;
+
+
+ //DISPERSION
+ double disp_value = Math.round((disp*0.005)* Math.sqrt(Math.pow(inputGrid.getWidth(), 2)+(Math.pow(inputGrid.getHeight(), 2))));
+
+ int dispRandX = 0;
+ int dispRandY = 0;
+ float slopeRandDisp = 0;
+
+ //ROAD GRAVITY
+ double max_RG_value = 100.0;
+ double rg_value = Math.round((roadGravity/max_RG_value)*((areaWidth + areaHeight)/16));
+ double max_search_index = Math.round(4*((int)rg_value*(1+(int)rg_value)));
+// statusOut.println("RG-Value:"+rg_value);
+// statusOut.println("Max-SearchIndex"+max_search_index);
+
+
+ /*****************************************************************
+ * DISPERSION and BREED
+ *****************************************************************/
+
+ int p = 0; //Verteile soviel neue Pixel zufällig in geeigneten Bereichen, bis disp_value erreicht ist
+ do{
+ dispRandX = Math.round((float) Math.random()*areaWidth); //Zufallsposition in X-Richtung
+ dispRandY = Math.round((float) Math.random()*areaHeight); //Zufallsposition in Y-Richtung
+ if ( dispRandX < areaMinX || dispRandY < areaMinY || dispRandX > areaMaxX || dispRandY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(dispRandX,dispRandY) != 0 || outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY) == 1)
+ continue; //wenn in Area Restriction oder wenn schon Siedlung da ist, mach weiter
+ slopeRandDisp = (float) Math.random(); //Zufallszahl zum Abgleich mit Slope-Koeffizient
+ int getSlope = (int) slopeGrid.getRasterSampleAsFloat(dispRandX,dispRandY); //holt sich den Slope-Wert aus dem Slope-Raster
+ Double doubleObj = (Double)slopeLUT.get(getSlope); //holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+ double slopeDouble = doubleObj.doubleValue(); //konvertiert Double-Objekt in double-Wert
+// statusOut.println(getSlope+","+slopeDouble+"----Random: "+slopeRandDisp);
+ if(slopeDouble < slopeRandDisp){
+ tmpGrid[dispRandX][dispRandY] = true; //true wird ins temporäre Raster geschrieben
+ anzDispTreffer++;
+ //BREED
+ float breedRnd = (float) Math.random()*100;
+ int nbBreedX = 0;
+ int nbBreedY = 0;
+ int breedNb = 0;
+ float NbValue = 0f;
+ if (tmpGrid[dispRandX][dispRandY] == true && breedRnd < breed)
+ breedNb = calculateNeighbors(dispRandX,dispRandY,NbValue);
+
+ int RNBreed1 = 0;
+ int RNBreed2 = 0;
+ float RNBreedSlope = 0f;
+
+ if (breedNb >= 2 && tmpGrid[dispRandX][dispRandY] == true){
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNBreed1 = 1 + Math.round((float)Math.random()*(breedNb-1));
+ RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));
+ if (RNBreed2 == RNBreed1)
+ RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+ nbBreedX = dispRandX+NEIGHBOR[cellBreed][0];
+ nbBreedY = dispRandY+NEIGHBOR[cellBreed][1];
+ if ( nbBreedX < areaMinX || nbBreedY < areaMinY || nbBreedX > areaMaxX || nbBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbBreedX,nbBreedY) != 0)
+ continue;
+ RNBreedSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY);
+ if (breedSample == 0f){
+ anzBreedTemp++;
+ nbPossibleBreedUrban = new int[] {nbBreedX,nbBreedY,anzBreedTemp};
+ if (nbPossibleBreedUrban[2] == RNBreed1 || nbPossibleBreedUrban[2] == RNBreed2 && slopeDoubleNb < RNBreedSlope){
+ tmpGrid[nbBreedX][nbBreedY] = true;
+ anzBreedTreffer++;
+ }
+ }
+ }
+ }
+ } p++;
+ } while (p < disp_value); //while, statt for-Schleife, da Überprüfung erst am Ende vorgenommen werden kann
+ //am Anfang der Schleife ist noch nicht klar, ob alle Pixel verteilt werden können
+ //da ein Teil in Ausschlussflächen etc. landen würde
+
+ /*********************************************************************
+ * EDGE
+ *********************************************************************/
+
+ //iterate over all cells
+ for (int x = 0; x < inputGrid.getWidth(); x++)
+ for (int y = 0; y < inputGrid.getHeight(); y++) { //für jede Zelle in x/y-Richtung
+
+ int areaMinXadd = areaMinX + x; //Dimensionen des Rasters
+ int areaMinYadd = areaMinY + y;
+
+ int anzNachbarn = 0;
+ int noNachbarn = 0;
+
+
+ for (int nbCellIdx = 0; nbCellIdx < NEIGHBOR.length; nbCellIdx++) {
+ checkBreakingCommands();
+ nbX = x+NEIGHBOR[nbCellIdx][0]; //Nachbarschaft der Zellen
+ nbY = y+NEIGHBOR[nbCellIdx][1];
+ nbCell = new int[] {nbX,nbY}; //jede Nachbarzelle
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);
+ if (rasterSample > 0f) //ist Nachbarzelle urban (1), wird sie gezählt
+ anzNachbarn++;
+ if (rasterSample == 0f)
+ noNachbarn++;
+ }
+
+ boolean lebt = outputGrid.getRasterSampleAsFloat(areaMinXadd , areaMinYadd ) > 0f; //eine Zelle lebt, wenn sie 1 ist
+
+ //hier ist die Abfrage wieviele Nachbarzellen am Leben sind
+ //daraus ergibt sich, ob im tmpGrid die entsprechende Zelle
+ //true oder false ist
+
+ float SpR = (float) Math.random()*100; //eine Zufallszahl zwischen 0 und 1
+ int RN = 0; //hier wird eine Integer-Zufallszahl reingeschrieben
+
+ if (lebt && (anzNachbarn>=2) && (SpR < spread) && (noNachbarn >=1)) { //wenn eine Zelle lebt, mindestens 2 lebende Nachbarzellen hat, der Spread-Koeffizient größer als die für die Zelle berechnete Zufallszahl und mindestens einen nicht lebenden Nachbarn hat
+ int anzTemp = 0;
+ int[] nbPossibleUrban = null;
+ RN = 1 + Math.round((float)Math.random()*(noNachbarn-1));
+ float RNEdgeSlope = 0;
+ int nbUrbanX = 0;
+ int nbUrbanY = 0;
+ for (int nbCellChange = 0; nbCellChange < NEIGHBOR.length; nbCellChange++){ //dann starte eine Schleife
+ checkBreakingCommands();
+ nbX = x+NEIGHBOR[nbCellChange][0];
+ nbY = y+NEIGHBOR[nbCellChange][1];
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ RNEdgeSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbX,nbY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY); //holt die Werte aus den jeweiligen Nachbarzellen
+ if (rasterSample == 0f){ //wenn der Wert 0 ist
+ anzTemp++; //wird Anzahl der möglichen Zellen erhöht
+ nbPossibleUrban = new int[] {nbX,nbY,anzTemp}; //Koordinaten und Nummern dieser Zellen werden in Array geschrieben
+ int urbanNbTemp = 0;
+ float NbValueEdge = 1f;
+ if (nbPossibleUrban[2] == RN){ //wenn Nummer im "PossibleUrban"-Array der Zufallszahl entspricht, die zwischen 1 und Anzahl der möglichen Zellen liegt...
+ //damit die Städte nicht zu sehr "ausfransen" steht eine Zelle nur zur Umwandlung zur Verfügung, wenn auch sie mind. 2 urbane Nachbarn hat
+ urbanNbTemp = calculateNeighbors(nbX,nbY,NbValueEdge);
+ if (urbanNbTemp >= 2 && tmpGrid[nbX][nbY]==false && slopeDoubleNb < RNEdgeSlope){
+ tmpGrid[nbX][nbY] = true; //wird true ins temporäre Raster geschrieben
+ anzSpreadTreffer++;
+ }
+ }
+ }
+ nbCell = new int[] {nbX,nbY,(int) rasterSample};
+ }
+ }
+ if (anzNachbarn>0) anyBodyAlive = true;
+ }
+
+ /*********************************************************************
+ * ROAD
+ *********************************************************************/
+
+ int anzGesamt = 0;
+ int[] cellValue = null;
+
+ //For-Schleife zählt alle als true markierten Zellen im Temp-Raster
+ for (int x = 0; x < inputGrid.getWidth();x++)
+ for(int y = 0; y < inputGrid.getHeight();y++){
+ int X = inputGrid.getMinX() + x;
+ int Y = inputGrid.getMinY() + y;
+ if (tmpGrid[X][Y]==true){
+ anzGesamt++;
+ }
+ }
+
+ int RSearchRoad = 0;
+ int r = 1; //Verteile soviel neue Pixel zufällig in geeigneten Bereichen, bis disp_value erreicht ist
+
+ //Rectangle gridBounds = new Rectangle(0, 0, inputGrid.getWidth(), inputGrid.getHeight()); //ein Rechteck wird definiert
+
+ do{
+ RSearchRoad = Math.round((float)Math.random()*anzGesamt); //Zufallszahl zwischen 1 und Anzahl aller bisher neu hinzugekommener Pixel
+ int anzTruePixels = 0;
+ int roadNeighborhoodRange = 0;
+ int RSearchNbRoad = 0;
+ for (int x = 0; x < inputGrid.getWidth();x++){ //gesamtes Raster wird durchsucht
+ for(int y = 0; y < inputGrid.getHeight();y++){
+ int X = inputGrid.getMinX() + x;
+ int Y = inputGrid.getMinY() + y;
+ if (tmpGrid[X][Y]==true){
+ anzTruePixels++; //wird true-Pixel gefunden, wird anzTruePixels hochgezählt
+ cellValue = new int[] {X,Y,anzTruePixels}; //und Koordinaten in Array geschrieben
+ int tempRoadCell[] = null;
+ int tempNbRoadCell[] = null;
+ if (cellValue[2] == RSearchRoad){
+ //statusOut.println(cellValue[0]+","+cellValue[1]+","+cellValue[2]);
+ //statusOut.println(r+","+RSearchRoad);
+ r++;
+ //JETZT NACH STRAßE SUCHEN!!
+ float roadValue = roadGrid.getRasterSampleAsFloat(X,Y);
+// statusOut.println(roadValue);
+ if (roadValue > 0.0){
+ tempRoadCell = new int[] {X,Y};
+// statusOut.println("Strasse in Entfernung 0: "+tempRoadCell[0]+","+tempRoadCell[1]);
+ //roadWalk(tempRoadCell[0],tempRoadCell[1]);
+ int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1]);
+ if(nbCellNew != null){
+ tmpGrid[nbCellNew[0]][nbCellNew[1]] = true;
+// statusOut.println(nbCellNew.length);
+// statusOut.println("Neue Zelle: "+nbCellNew[0]+","+nbCellNew[1]);
+// statusOut.println("++++++++++++++++++++++++++++++++++++++++");
+ float nbRoadBreed = 0f;
+ int nbRoadBreedNeighbors = 0;
+ nbRoadBreedNeighbors = calculateNeighbors(nbCellNew[0],nbCellNew[1],nbRoadBreed);
+ int RNRoadBreed1 = 0;
+ int RNRoadBreed2 = 0;
+ int nbRoadBreedX = 0;
+ int nbRoadBreedY = 0;
+ int anzRoadBreedTreffer1 = 0;
+
+ if (nbRoadBreedNeighbors >= 2){
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNRoadBreed1 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ float RNRoadBreedSlope = 0f;
+
+ if (RNRoadBreed2 == RNRoadBreed1)
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+ nbRoadBreedX = nbCellNew[0]+NEIGHBOR[cellBreed][0];
+ nbRoadBreedY = nbCellNew[1]+NEIGHBOR[cellBreed][1];
+ if ( nbRoadBreedX < areaMinX || nbRoadBreedY < areaMinY || nbRoadBreedX > areaMaxX || nbRoadBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY) != 0)
+ continue;
+ RNRoadBreedSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ if (breedSample == 0f){
+ anzBreedTemp++;
+ nbPossibleBreedUrban = new int[] {nbRoadBreedX,nbRoadBreedY,anzBreedTemp};
+ if (nbPossibleBreedUrban[2] == RNRoadBreed1 || nbPossibleBreedUrban[2] == RNRoadBreed2 && slopeDoubleNb < RNRoadBreedSlope){
+ tmpGrid[nbRoadBreedX][nbRoadBreedY] = true;
+ anzRoadBreedTreffer1++;
+ anzRoadTreffer++;
+ statusOut.println("Road-Breed-Treffer: "+anzRoadBreedTreffer1);
+ }
+ }
+ }
+
+
+ }
+
+ } else{
+// statusOut.println("Keine neue Zelle gefunden");
+ }
+ } else{
+ int anzRoadNb = 0;
+
+ //HIER MIT FOR SCHLEIFE RECHTECK WACHSEN LASSEN!!!
+ for (int roadSearch = 0; roadSearch <= rg_value; roadSearch++){
+ if (anzRoadNb > 0)
+ continue;
+ for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++){
+ for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){
+ // if (gridBounds.contains(nbRoadCellsX, nbRoadCellsY))
+ if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY) != 0)
+ continue;
+ float roadValueNb = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY);
+ if (roadValueNb > 0f){
+ anzRoadNb++;
+ }
+ //statusOut.println("Strasse in Entfernung 1: "+anzRoadNb+","+nbRoadCellsX+","+nbRoadCellsY);
+ }
+ }
+ roadNeighborhoodRange++;
+ RSearchNbRoad = Math.round((float)Math.random()*anzRoadNb);
+ //statusOut.println("--> Zyklus "+roadNeighborhoodRange+"Nachbarn: "+anzRoadNb);
+ //statusOut.println(RSearchNbRoad);
+ int anzTempRoadNb = 0;
+ for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++){
+ for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){
+// statusOut.println("TEST-ROAD: "+nbRoadCellsX+","+nbRoadCellsY);
+ // if (gridBounds.contains(nbRoadCellsX, nbRoadCellsY))
+ if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY) != 0)
+ continue;
+ float roadValueNbTemp = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY);
+ if (roadValueNbTemp > 0f){
+ anzTempRoadNb++;
+ tempNbRoadCell = new int[] {nbRoadCellsX,nbRoadCellsY,anzTempRoadNb};
+ if (tempNbRoadCell[2]==RSearchNbRoad){
+ //statusOut.println("Treffer: "+tempNbRoadCell[0]+","+tempNbRoadCell[1]+","+tempNbRoadCell[2]);
+ tempRoadCell = tempNbRoadCell;
+// statusOut.println("Strasse in Entfernung "+roadSearch+": "+tempRoadCell[0]+","+tempRoadCell[1]+","+tempRoadCell[2]);
+ //roadWalk(tempRoadCell[0],tempRoadCell[1]);
+ int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1]);
+ if(nbCellNew != null){
+ tmpGrid[nbCellNew[0]][nbCellNew[1]] = true;
+// statusOut.println(nbCellNew.length);
+// statusOut.println("Neue Zelle: "+nbCellNew[0]+","+nbCellNew[1]);
+// statusOut.println("++++++++++++++++++++++++++++++++++++++++");
+
+ float nbRoadBreed = 0f;
+ int nbRoadBreedNeighbors = 0;
+ nbRoadBreedNeighbors = calculateNeighbors(nbCellNew[0],nbCellNew[1],nbRoadBreed);
+ int RNRoadBreed1 = 0;
+ int RNRoadBreed2 = 0;
+ int nbRoadBreedX = 0;
+ int nbRoadBreedY = 0;
+ int anzRoadBreedTreffer2 = 0;
+
+ if (nbRoadBreedNeighbors >= 2){
+ int anzBreedTemp = 0;
+ int[] nbPossibleBreedUrban = null;
+ RNRoadBreed1 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ float RNRoadBreedSlope = 0f;
+ if (RNRoadBreed2 == RNRoadBreed1)
+ RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+ for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+ nbRoadBreedX = nbCellNew[0]+NEIGHBOR[cellBreed][0];
+ nbRoadBreedY = nbCellNew[1]+NEIGHBOR[cellBreed][1];
+ if ( nbRoadBreedX < areaMinX || nbRoadBreedY < areaMinY || nbRoadBreedX > areaMaxX || nbRoadBreedY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY) != 0)
+ continue;
+ RNRoadBreedSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ float breedSample = outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+ if (breedSample == 0f){
+ anzBreedTemp++;
+ nbPossibleBreedUrban = new int[] {nbRoadBreedX,nbRoadBreedY,anzBreedTemp};
+ if (nbPossibleBreedUrban[2] == RNRoadBreed1 || nbPossibleBreedUrban[2] == RNRoadBreed2 && slopeDoubleNb < RNRoadBreedSlope){
+ tmpGrid[nbRoadBreedX][nbRoadBreedY] = true;
+ anzRoadBreedTreffer2++;
+ anzRoadTreffer++;
+ statusOut.println("Road-Breed-Treffer: "+anzRoadBreedTreffer2);
+ }
+ }
+ }
+
+
+ }
+ } else{
+// statusOut.println("Keine neue Zelle gefunden");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ } while (r <= breed);
+
+ statusOut.println("Spread-Treffer: "+anzSpreadTreffer);
+ statusOut.println("Dispersion-Treffer: "+anzDispTreffer);
+ statusOut.println("Breed-Treffer: "+anzBreedTreffer);
+ statusOut.println("Treffer gesamt: "+anzGesamt);
+ statusOut.println("Anzahl Road-Treffer: "+anzRoadTreffer);
+ anzGesamtTreffer = anzSpreadTreffer+anzDispTreffer+anzBreedTreffer+anzRoadTreffer;
+
+ outStep.addGrid();
+
+
+ // TempGrid auf das echte Grid schreiben
+ for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+ for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+
+ int X = inputGrid.getMinX() + x;
+ int Y = inputGrid.getMinY() + y;
+
+
+ boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f; //eine Zelle lebt, wenn sie 1 ist
+ boolean road = roadGrid.getRasterSampleAsFloat(X, Y) > 0f; //eine Zelle beinhaltet eine Straße...
+ if (tmpGrid[x][y] == false) //wenn im temporären Raster nichts drinsteht...
+ tmpGrid[x][y] = lebt; //wird der Wert aus dem Ausgangsraster übernommen
+ if(lebt == true)
+ thisYear++;
+ if(road == true)
+ roadCount++;
+
+ outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);
+ actUrb = (Float)outputGrid.getRasterSample(x,y);
+ outStep.getGrid(stepNo-1).setRasterSample(actUrb,x,y);
+ }
+ }
+
+ //SELF-MODIFICATION
+ growthRate = ((float)anzGesamtTreffer / (float)thisYear)*100;
+ statusOut.println("Wachstumsrate: "+growthRate+", Urban: "+anzGesamtTreffer);
+ double percent_urban = (100.0 *(thisYear+roadCount) / (totalPixels-roadCount-excldCount));
+
+ //Boom-Year
+ if(growthRate > criticalHigh){
+ slope -= (float)percent_urban * (float)slopeSens;
+ if(slope <= 0.01)
+ slope = 1.0;
+ roadGravity += (float)percent_urban * roadGravSens;
+ if(roadGravity > 100.0)
+ roadGravity = 100.0;
+ if(disp < 100.0){
+ disp *= boom;
+ if(disp > 100.0)
+ disp = 100.0;
+ breed *= boom;
+ if(breed > 100.0)
+ breed = 100.0;
+ spread *= boom;
+ if(spread > 100.0)
+ spread = 100.0;
+ }
+ }
+ //Bust-Year
+ if(growthRate < criticalLow){
+ slope += (float)percent_urban * (float)slopeSens;
+ if(slope > MaxSlopeResistance)
+ slope = MaxSlopeResistance;
+ roadGravity -= (float)percent_urban * roadGravSens;
+ if(roadGravity <= 0.01)
+ roadGravity = 1.0;
+ if(growthRate < criticalLow && disp > 0){
+ disp *= bust;
+ if(disp <= 0.01)
+ disp = 1.0;
+ spread *= bust;
+ if(spread <= 0.01)
+ spread = 1.0;
+ breed *= bust;
+ if(breed <= 0.01)
+ breed = 1.0;
+ }
+ }
+ statusOut.println("thisYear: "+thisYear+", roadCount: "+roadCount+", excldCount: "+excldCount+", percent_urban: "+percent_urban);
+ statusOut.println("Slope-Sensitivity: "+slope+", RoadGravity-Sensitivity: "+roadGravity+", Diffusion-Sensitivity: "+disp+", Breed-Sensitivity: "+breed+", Spread-Sensitivity: "+spread);
+
+
+
+ if (!anyBodyAlive) {
+ stepCount = stepNo;
+ statusOut.println("Lebt keiner mehr... höre hier auf!");
+ }
+
+
+ System.out.println("Finished step " + (stepNo) + " in "
+ + ((System.currentTimeMillis() - localStartTime)) + " ms\n");
+ localStartTime = System.currentTimeMillis();
+ }
+
+ private int[] roadWalk(int X,int Y){
+// statusOut.println(X+","+Y);
+ boolean end_of_road;
+ end_of_road = false;
+ int run = 0;
+ int run_value = 0;
+ int[] nbCellNew = null;
+ int[] nbCellTemp = null;
+ while(!end_of_road){
+ end_of_road = true;
+ int nbRoadX = 0;
+ int nbRoadY = 0;
+ int areaMinX = inputGrid.getMinX(); //Dimensionen des Rasters
+ int areaMinY = inputGrid.getMinY();
+ int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+ int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+ int roadNb = 0;
+ int roadNbTemp = 0;
+ int RN = 0;
+
+ int[] nbCell = null;
+ for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){
+ nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+ nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+ if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ //if (areaRestr.getRasterSampleAsFloat(nbRoadX,nbRoadY) != 0)
+ // continue;
+ float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);
+ if (roadSample > 0f)
+ roadNb++;
+ }
+ // statusOut.println("Nachbarn von temporaerer Strassenzelle: "+roadNb);
+
+ if (roadNb > 0){
+ RN = 1 + Math.round((float)Math.random()*(roadNb-1));
+
+ for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){
+ nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+ nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+ if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);
+ if (roadSample > 0f){
+ roadNbTemp++;
+ nbCell = new int[] {nbRoadX,nbRoadY,roadNbTemp};
+ if (nbCell[2] == RN){
+ statusOut.println("Nachbarzelle gefunden: "+nbCell[0]+","+nbCell[1]+","+nbCell[2]);
+ end_of_road = false;
+ run++;
+ X = nbRoadX;
+ Y = nbRoadY;
+ float roadSample2 = roadGrid.getRasterSampleAsFloat(X,Y);
+ run_value = (int) (roadSample2 / 100 * disp);
+ // statusOut.println("Run: "+run);
+ // statusOut.println("Run_Value: "+run_value);
+ // statusOut.println(X+","+Y+","+roadSample2);
+ if (run > run_value){
+ end_of_road = true;
+ // statusOut.println("Endzelle erreicht!! Run:"+run+"RunValue: "+run_value);
+ float NbValue = 0f;
+ int Nb = calculateNeighbors(X,Y,NbValue);
+ // statusOut.println("moegliche Nachbarzellen nach RoadWalk: "+Nb);
+ RN = 1 + Math.round((float)Math.random()*(Nb-1));
+ // statusOut.println("Random: "+RN);
+ if (Nb > 0){
+ int nbUrbanizeX = 0;
+ int nbUrbanizeY = 0;
+ int NbTemp = 0;
+ float RNRoadSlope = 0f;
+ // statusOut.println(X+","+Y);
+ for (int urbanizeCells = 0; urbanizeCells < NEIGHBOR.length; urbanizeCells++){
+ nbUrbanizeX = X+NEIGHBOR[urbanizeCells][0];
+ nbUrbanizeY = Y+NEIGHBOR[urbanizeCells][1];
+ if ( nbUrbanizeX < areaMinX || nbUrbanizeY < areaMinY || nbUrbanizeX > areaMaxX || nbUrbanizeY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);
+ RNRoadSlope = (float)Math.random();
+ int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);
+ Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+ double slopeDoubleNb = doubleObjNb.doubleValue();
+ if (rasterSample == 0f){
+ NbTemp++;
+ nbCellTemp = new int[] {nbUrbanizeX,nbUrbanizeY,NbTemp};
+ if (nbCellTemp[2] == RN && slopeDoubleNb < RNRoadSlope){
+ nbCellNew = new int[] {nbCellTemp[0],nbCellTemp[1],nbCellTemp[2]};
+ }
+ }
+ }
+
+ } else{
+ nbCellNew = null;
+ } break;
+ }
+
+ }
+
+ }
+ }
+
+ }
+ }
+ return nbCellNew;
+ }
+
+ private int calculateNeighbors(int X, int Y, float NbValue){
+ int nbX = 0;
+ int nbY = 0;
+ int areaMinX = inputGrid.getMinX(); //Dimensionen des Rasters
+ int areaMinY = inputGrid.getMinY();
+ int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+ int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+ int Nb = 0;
+ for (int nbCells = 0; nbCells < NEIGHBOR.length; nbCells++){
+ nbX = X+NEIGHBOR[nbCells][0];
+ nbY = Y+NEIGHBOR[nbCells][1];
+ if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+ Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+ continue;
+ if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+ continue;
+ float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);
+ if (rasterSample == NbValue)
+ Nb++;
+ }
+ // statusOut.println("..."+Nb+"...");
+ return Nb;
+ }
+
+ protected static boolean checkNoData(int x, int y, WritableGrid grid) {
+ return Float.isNaN(grid.getRasterSampleAsFloat(x,y));
+ }
+}
Added: trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifyingContentManager.java
===================================================================
--- trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifyingContentManager.java 2009-09-07 12:15:20 UTC (rev 55)
+++ trunk/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifyingContentManager.java 2009-09-10 14:02:19 UTC (rev 56)
@@ -0,0 +1,50 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.DefaultModelResource;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+
+public class UrbanGrowthModelSelfModifyingContentManager extends AbstractModelContentManager {
+
+ public UrbanGrowthModelSelfModifyingContentManager() {
+ super(19);
+
+ resource[0] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Input Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Output Grid",ScalarProperty.class,WritableGrid.class,false);
+ // Number of steps
+ resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+ // Spread Coefficient
+ resource[3] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Area Restrictions",ScalarProperty.class,WritableGrid.class,false);
+ resource[4] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient",ScalarProperty.class,Double.class,false);
+ resource[5] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient",ScalarProperty.class,Double.class,false);
+ resource[6] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient",ScalarProperty.class,Double.class,false);
+ resource[7] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient",ScalarProperty.class,Double.class,false);
+ resource[8] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient",ScalarProperty.class,Double.class,false);
+ resource[9] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Slope",ScalarProperty.class,Double.class,false);
+ resource[10]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[11]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Grid",ScalarProperty.class,WritableGrid.class,false);
+ resource[12]= new DefaultModelResource(ModelResource.CATEGORY_OUTPUT,"Step Results",MultiGrid.class,false);
+ resource[13]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Gravity Sensitivity",ScalarProperty.class,Double.class,false);
+ resource[14]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Sensitivity",ScalarProperty.class,Double.class,false);
+ resource[15]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Low",ScalarProperty.class,Double.class,false);
+ resource[16]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical High",ScalarProperty.class,Double.class,false);
+ resource[17]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Boom",ScalarProperty.class,Double.class,false);
+ resource[18]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Bust",ScalarProperty.class,Double.class,false);
+
+ // ===== Ressourcen Bezeichnungen lokalisieren =====
+ resetCaptions(null);
+ }
+
+
+ @Override
+ public void checkAndError() throws XuluDataException {
+ // TODO Auto-generated method stub
+ super.checkAndError();
+ }
+}
More information about the Xulu-commits
mailing list