gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster_dataaccess_refactoring / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / store / FramedBufferResampling.java @ 2236
History | View | Annotate | Download (6.8 KB)
1 |
package org.gvsig.raster.impl.store; |
---|---|
2 |
|
3 |
import java.awt.Rectangle; |
4 |
|
5 |
import org.gvsig.fmap.dal.coverage.RasterLocator; |
6 |
import org.gvsig.fmap.dal.coverage.dataset.Buffer; |
7 |
import org.gvsig.fmap.dal.coverage.datastruct.Extent; |
8 |
import org.gvsig.fmap.dal.coverage.datastruct.NoData; |
9 |
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException; |
10 |
import org.gvsig.fmap.dal.coverage.exception.QueryException; |
11 |
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException; |
12 |
import org.gvsig.fmap.dal.coverage.store.RasterDataStore; |
13 |
import org.gvsig.raster.impl.DefaultRasterManager; |
14 |
import org.gvsig.raster.impl.buffer.DefaultRasterQuery; |
15 |
import org.gvsig.raster.impl.provider.AbstractRasterProvider; |
16 |
import org.gvsig.raster.impl.provider.RasterProvider; |
17 |
|
18 |
/**
|
19 |
* The requests to a <code>RasterDataStore</code> adjust the bounding box and the size in pixels
|
20 |
* to the source limits. The user can need a buffer that exceeds the raster dimension.
|
21 |
* In this case, the area that is out of the raster limits should be set to nodata values or
|
22 |
* transparent in RGB cases.
|
23 |
*
|
24 |
* @author Nacho Brodin (nachobrodin@gmail.com)
|
25 |
*/
|
26 |
public class FramedBufferResampling { |
27 |
private DefaultRasterQuery query = null; |
28 |
private DefaultRasterQuery originalQuery = null; |
29 |
private RasterDataStore store = null; |
30 |
protected byte byteNoData = (byte)0x00; |
31 |
protected short shortNoData = Short.MIN_VALUE; |
32 |
protected int intNoData = Integer.MIN_VALUE; |
33 |
protected float floatNoData = -99999; |
34 |
protected double doubleNoData = -99999; |
35 |
|
36 |
public FramedBufferResampling(DefaultRasterQuery q, RasterDataStore store) {
|
37 |
this.query = q;
|
38 |
this.store = store;
|
39 |
this.originalQuery = (DefaultRasterQuery)query.clone();
|
40 |
setNoDataValue(store.getNoDataValue()); |
41 |
} |
42 |
|
43 |
public Buffer query(RasterProvider provider) throws QueryException, ProcessInterruptedException { |
44 |
adjustQueryToTheStore(); |
45 |
query.calculateParameters(store); |
46 |
originalQuery.calculateParameters(store); |
47 |
Buffer bufResult = null; |
48 |
try {
|
49 |
Buffer buf = ((AbstractRasterProvider)provider).getDataSet(query);
|
50 |
bufResult = buildBuffer(buf.getBandCount(), originalQuery.getAdjustedBufWidth(), originalQuery.getAdjustedBufHeight()); |
51 |
RasterLocator.getManager().getRasterUtils().copyToBuffer( |
52 |
bufResult, |
53 |
originalQuery.getAdjustedRequestBoundingBox(), |
54 |
buf, |
55 |
query.getAdjustedRequestBoundingBox(), |
56 |
1,
|
57 |
store.getColorInterpretation().hasAlphaBand()); |
58 |
buf.dispose(); |
59 |
} catch (RasterDriverException e) {
|
60 |
throw new QueryException("Error getting data", e); |
61 |
} |
62 |
return bufResult;
|
63 |
} |
64 |
|
65 |
/**
|
66 |
* Sets the nodata value
|
67 |
* @param noData
|
68 |
*/
|
69 |
private void setNoDataValue(NoData noData) { |
70 |
if(noData == null) |
71 |
return;
|
72 |
switch (store.getDataType()[0]) { |
73 |
case Buffer.TYPE_BYTE: |
74 |
byteNoData = noData.getValue().byteValue(); |
75 |
break;
|
76 |
case Buffer.TYPE_SHORT: |
77 |
shortNoData = noData.getValue().shortValue(); |
78 |
break;
|
79 |
case Buffer.TYPE_INT: |
80 |
intNoData = noData.getValue().intValue(); |
81 |
break;
|
82 |
case Buffer.TYPE_FLOAT: |
83 |
floatNoData = noData.getValue().floatValue(); |
84 |
break;
|
85 |
case Buffer.TYPE_DOUBLE: |
86 |
doubleNoData = ((NoData)noData).getValue().doubleValue(); |
87 |
break;
|
88 |
} |
89 |
} |
90 |
|
91 |
/**
|
92 |
* Builds a buffer using the specified number of bands and initialize it
|
93 |
* @param nbands
|
94 |
* @return
|
95 |
*/
|
96 |
private Buffer buildBuffer(int nbands, int w, int h) { |
97 |
Buffer bufResult = DefaultRasterManager.getInstance().createBuffer(store.getDataType()[0], w, h, nbands, true); |
98 |
for (int i = 0; i < bufResult.getBandCount(); i++) { |
99 |
clearMaskBuffer(bufResult, i); |
100 |
} |
101 |
return bufResult;
|
102 |
} |
103 |
|
104 |
/**
|
105 |
* Sets a band to NODATA value
|
106 |
* @param bufResult
|
107 |
* @param tileExtent
|
108 |
* @param buf
|
109 |
* @param ex
|
110 |
* @param pixelSize
|
111 |
*/
|
112 |
protected void clearMaskBuffer(Buffer buf, int nBand) { |
113 |
if(buf.getDataType() == Buffer.TYPE_BYTE) { |
114 |
for (int i = 0; i < buf.getHeight(); i++) { |
115 |
for (int j = 0; j < buf.getWidth(); j++) { |
116 |
buf.setElem(i, j, nBand, byteNoData); |
117 |
} |
118 |
} |
119 |
return;
|
120 |
} |
121 |
if(buf.getDataType() == Buffer.TYPE_SHORT) { |
122 |
for (int i = 0; i < buf.getHeight(); i++) { |
123 |
for (int j = 0; j < buf.getWidth(); j++) { |
124 |
buf.setElem(i, j, nBand, shortNoData); |
125 |
} |
126 |
} |
127 |
return;
|
128 |
} |
129 |
if(buf.getDataType() == Buffer.TYPE_INT) { |
130 |
for (int i = 0; i < buf.getHeight(); i++) { |
131 |
for (int j = 0; j < buf.getWidth(); j++) { |
132 |
buf.setElem(i, j, nBand, intNoData); |
133 |
} |
134 |
} |
135 |
return;
|
136 |
} |
137 |
if(buf.getDataType() == Buffer.TYPE_FLOAT) { |
138 |
for (int i = 0; i < buf.getHeight(); i++) { |
139 |
for (int j = 0; j < buf.getWidth(); j++) { |
140 |
buf.setElem(i, j, nBand, floatNoData); |
141 |
} |
142 |
} |
143 |
return;
|
144 |
} |
145 |
if(buf.getDataType() == Buffer.TYPE_DOUBLE) { |
146 |
for (int i = 0; i < buf.getHeight(); i++) { |
147 |
for (int j = 0; j < buf.getWidth(); j++) { |
148 |
buf.setElem(i, j, nBand, doubleNoData); |
149 |
} |
150 |
} |
151 |
return;
|
152 |
} |
153 |
} |
154 |
|
155 |
private double round(double value) { |
156 |
double a = (value - (int)value); |
157 |
return (a > 0.95 || a < 0.05) ? Math.round(value) : value; |
158 |
} |
159 |
|
160 |
private void adjustQueryToTheStore() { |
161 |
if(query.getType() == DefaultRasterQuery.TYPE_WCOORDS_SHIFT) {
|
162 |
Extent e = query.getAdjustedRequestBoundingBox().intersection(store.getExtent()); |
163 |
int w = (int)Math.ceil(round((query.getBufWidth() * e.width()) / query.getAdjustedRequestBoundingBox().width())); |
164 |
int h = (int)Math.ceil(round((query.getBufHeight() * e.height()) / query.getAdjustedRequestBoundingBox().height())); |
165 |
query.setAdjustedRequestBoundingBox(e); |
166 |
query.setBufWidth(w); |
167 |
query.setBufHeight(h); |
168 |
} |
169 |
|
170 |
if(query.getType() == DefaultRasterQuery.TYPE_PX_SHIFT) {
|
171 |
Rectangle r = adjustRectangleToStoreSize(query.getRequestPxWindow());
|
172 |
query.setRequestPixelWindow(r); |
173 |
} |
174 |
|
175 |
if(query.getType() == DefaultRasterQuery.TYPE_PX_RESCALED_SHIFT) {
|
176 |
Rectangle r = adjustRectangleToStoreSize(query.getRequestPxWindow());
|
177 |
query.setRequestPixelWindow(r); |
178 |
int w = (int)r.getWidth() - (int)originalQuery.getRequestPxWindow().getWidth(); |
179 |
int h = (int)r.getHeight() - (int)originalQuery.getRequestPxWindow().getHeight(); |
180 |
query.setBufWidth(query.getBufWidth() - w); |
181 |
query.setBufHeight(query.getBufHeight() - h); |
182 |
} |
183 |
} |
184 |
|
185 |
/**
|
186 |
* Adjusts the limits of the rectangle to the store limits
|
187 |
* @param r
|
188 |
* @return
|
189 |
*/
|
190 |
private Rectangle adjustRectangleToStoreSize(Rectangle r) { |
191 |
Rectangle newRect = (Rectangle)r.clone(); |
192 |
if(r.getX() < 0) |
193 |
newRect.setBounds(0, (int)r.getY(), (int)(r.getWidth() + r.getX()), (int)r.getHeight()); |
194 |
if(r.getY() < 0) |
195 |
newRect.setBounds((int)r.getX(), 0, (int)r.getWidth(), (int)(r.getHeight() + r.getY())); |
196 |
if(newRect.getWidth() > store.getWidth())
|
197 |
newRect.setSize((int)store.getWidth(), (int)r.getHeight()); |
198 |
if(newRect.getHeight() > store.getHeight())
|
199 |
newRect.setSize((int)r.getWidth(), (int)store.getHeight()); |
200 |
return newRect;
|
201 |
} |
202 |
} |