1 |
mojays |
2 |
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 |
mojays |
114 |
import de.appl.util.RasterMetaData; |
10 |
|
|
import de.schmitzm.geotools.data.WritableGrid; |
11 |
mojays |
2 |
|
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 |
|
|
} |