1 |
package appl.parallel.util; |
2 |
|
3 |
import java.awt.Rectangle; |
4 |
import java.awt.image.DataBuffer; |
5 |
|
6 |
import appl.parallel.data.WritableGridArrayPartition; |
7 |
import appl.parallel.spmd.split.SplittableResource; |
8 |
import appl.parallel.spmd.split.WritableGridPartition; |
9 |
import de.appl.util.RasterMetaData; |
10 |
import de.schmitzm.geotools.data.WritableGrid; |
11 |
|
12 |
/** |
13 |
* See method description for details. |
14 |
* |
15 |
* @author Dominik Appl |
16 |
*/ |
17 |
public class PartitionUtil { |
18 |
|
19 |
/** |
20 |
* Returns partition of a {@link WritableGrid} as a {@link WritableGridArray}. |
21 |
* Notice, that the minX and minY values are ignored and will be set to 0 |
22 |
* (see {@link WritableGrid} for more information about minX and minY). If |
23 |
* the given {@link WritableGrid} is not an instance of |
24 |
* {@link WritableGridPartition} it is assumed that the topLeft corner of |
25 |
* the source grid is (0,0) (like in standard image processing).<br> |
26 |
* If the partition is a {@link WritableGridPartition} it is assumed that |
27 |
* the the bounds of the two Partition refer to the same coordinate system. |
28 |
* Real coordinates are supposed to reference the South(!)-West Corner. |
29 |
* |
30 |
* @param sourceGrid |
31 |
* the grid to be partitioned |
32 |
* @param partitionBounds |
33 |
* the rectangle describing the partition |
34 |
* @param rootID |
35 |
* the id to identify the root partition |
36 |
* @return the new partition including the given corners |
37 |
* @see SplittableResource#getRootID() |
38 |
*/ |
39 |
public static WritableGridPartition getPartitialGrid2D(WritableGrid sourceGrid, |
40 |
Rectangle partitionBounds, int rootID) { |
41 |
|
42 |
// (int) partitionBounds.getX(), |
43 |
// (int) partitionBounds.getY(), |
44 |
// (int) (partitionBounds.getX() + partitionBounds.getWidth() - 1), |
45 |
// (int) (partitionBounds.getY() + partitionBounds.getHeight() - 1)); |
46 |
|
47 |
// get Metadata of the big Grid |
48 |
RasterMetaData bigMeta = new RasterMetaData(sourceGrid); |
49 |
|
50 |
//create MetaData for the new partitial Grid |
51 |
//Height an width of the partitial Grid |
52 |
int pHeight = (int) partitionBounds.getHeight(); |
53 |
int pWidth = (int)partitionBounds.getWidth(); |
54 |
|
55 |
//real coordinates of the partitial Grid (which are referenced by the SW Corner) |
56 |
double pX = partitionBounds.getX() * bigMeta.getCellWidth() + bigMeta.getX(); |
57 |
double pY = (partitionBounds.getY() + partitionBounds.getHeight() - 1) * bigMeta.getCellHeight() + bigMeta.getY(); |
58 |
double pRealWidth = pWidth * bigMeta.getCellWidth(); |
59 |
double pRealHeight = pHeight * bigMeta.getCellHeight(); |
60 |
|
61 |
//the MetaData of the new Grid |
62 |
RasterMetaData pMetaData = new RasterMetaData(bigMeta.getDataType(), |
63 |
pWidth, pHeight, 0, 0, pX, pY, pRealWidth, pRealHeight, bigMeta.getCoordinateReferenceSystem()); |
64 |
|
65 |
//create empty return Grid |
66 |
WritableGridPartition pGrid; |
67 |
switch(bigMeta.getDataType()){ |
68 |
case DataBuffer.TYPE_INT: |
69 |
pGrid = new WritableGridArrayPartition.Integer(pMetaData,rootID,partitionBounds); |
70 |
break; |
71 |
case DataBuffer.TYPE_DOUBLE: |
72 |
pGrid = new WritableGridArrayPartition.Double(pMetaData,rootID,partitionBounds); |
73 |
break; |
74 |
default: |
75 |
pGrid = new WritableGridArrayPartition.Float(pMetaData,rootID,partitionBounds); |
76 |
} |
77 |
|
78 |
//if the sourceGrid is a partition itself then we do not want to to start reading from (0,0) |
79 |
//but shifted relative to the global coordinate system. So we calculate now the start values: |
80 |
|
81 |
//for standard WritableGrids these are simply the bounds of the new partition... |
82 |
int startX = (int) partitionBounds.getX(); |
83 |
int startY = (int) partitionBounds.getY(); |
84 |
|
85 |
// ...but for partitions these values are shifted: |
86 |
if(sourceGrid instanceof WritableGridPartition){ |
87 |
Rectangle srcBounds = ((WritableGridPartition) sourceGrid).getPartitionBounds(); |
88 |
startX -= srcBounds.getX(); |
89 |
startY -= srcBounds.getY(); |
90 |
} |
91 |
//read the data into the raster from left to right and downwards |
92 |
int x=0,y=0; |
93 |
try{ |
94 |
for (y = 0; y < pHeight; y++) |
95 |
for (x = 0; x < pWidth; x++) |
96 |
pGrid.setRasterSample( |
97 |
sourceGrid.getRasterSample(startX + x, startY + y), |
98 |
x, |
99 |
y); |
100 |
}catch (Exception e) { |
101 |
System.out.println("stop"); |
102 |
} |
103 |
return pGrid; |
104 |
} |
105 |
|
106 |
/** |
107 |
* Overwrites the data at the location specified by the {@link Rectangle} with |
108 |
* the given partition-data. If the given baseGrid is NOT an instance |
109 |
* of {@link WritableGridPartition} it is assumed that its the topLeft corner (0,0). |
110 |
* If it IS a {@link WritableGridPartition} it is assumed that the the |
111 |
* bounds of the two Partition refer to the same coordinate system and the partition |
112 |
* is inserted at the correct absolut position. |
113 |
* |
114 |
* @param baseGrid the grid in which the data is inserted |
115 |
* @param gridPartition the grid to be inserted |
116 |
* @param partitionBounds the excact location in coordinates of the baseGrid |
117 |
*/ |
118 |
public static void setPartition(WritableGrid baseGrid, WritableGrid gridPartition, Rectangle partitionBounds) { |
119 |
//Check if partition and the rectangle fit |
120 |
if((gridPartition.getWidth()!=partitionBounds.getWidth()) || |
121 |
(gridPartition.getHeight()!=partitionBounds.getHeight())) |
122 |
throw new UnsupportedOperationException("The partition width/height does not match the rectangle width/height"); |
123 |
|
124 |
//if the baseeGrid is a partition itself then we do not want to to start writing from (0,0) |
125 |
//but shifted relative to the global coordinate system. So we calculate now the start values: |
126 |
|
127 |
//for standard WritableGrids these are simply the bounds of the new partition... |
128 |
int startX = (int) partitionBounds.getX(); |
129 |
int startY = (int) partitionBounds.getY(); |
130 |
|
131 |
// ...but for partitions these values are shifted: |
132 |
if(baseGrid instanceof WritableGridPartition){ |
133 |
Rectangle targetBounds = ((WritableGridPartition) baseGrid).getPartitionBounds(); |
134 |
startX -= targetBounds.getX(); |
135 |
startY -= targetBounds.getY(); |
136 |
} |
137 |
//check if the partition fits in |
138 |
// if(((partitionBounds.getX()+partitionBounds.getWidth()-1)>baseGrid.getWidth() || |
139 |
// (partitionBounds.getY()+partitionBounds.getHeight()-1)>baseGrid.getHeight())) |
140 |
// System.out.println("X"); |
141 |
//throw new UnsupportedOperationException("The partition does not fit in the Grid!"); |
142 |
//write the partition into the Grid |
143 |
|
144 |
for(int y = 0; y < partitionBounds.getHeight();y++) |
145 |
for(int x = 0; x < partitionBounds.getWidth(); x++) |
146 |
baseGrid.setRasterSample( |
147 |
gridPartition.getRasterSample(x,y), |
148 |
x + startX, |
149 |
y + startY); |
150 |
|
151 |
} |
152 |
|
153 |
} |