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