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