root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / gridTools / clipGrid / ClipGridAlgorithm.java @ 59
History | View | Annotate | Download (7.77 KB)
1 |
package es.unex.sextante.gridTools.clipGrid; |
---|---|
2 |
|
3 |
import java.awt.geom.Rectangle2D; |
4 |
import java.util.Arrays; |
5 |
|
6 |
import com.vividsolutions.jts.geom.Coordinate; |
7 |
import com.vividsolutions.jts.geom.Envelope; |
8 |
import com.vividsolutions.jts.geom.Geometry; |
9 |
|
10 |
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer; |
11 |
import es.unex.sextante.core.AnalysisExtent; |
12 |
import es.unex.sextante.core.GeoAlgorithm; |
13 |
import es.unex.sextante.core.Sextante; |
14 |
import es.unex.sextante.dataObjects.IFeature; |
15 |
import es.unex.sextante.dataObjects.IFeatureIterator; |
16 |
import es.unex.sextante.dataObjects.IRasterLayer; |
17 |
import es.unex.sextante.dataObjects.IVectorLayer; |
18 |
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
19 |
import es.unex.sextante.exceptions.IteratorException; |
20 |
import es.unex.sextante.exceptions.RepeatedParameterNameException; |
21 |
import es.unex.sextante.exceptions.UnsupportedOutputChannelException; |
22 |
|
23 |
public class ClipGridAlgorithm |
24 |
extends
|
25 |
GeoAlgorithm { |
26 |
|
27 |
public static final String INPUT = "INPUT"; |
28 |
public static final String POLYGONS = "POLYGONS"; |
29 |
public static final String RESULT = "RESULT"; |
30 |
|
31 |
private AnalysisExtent m_Extent;
|
32 |
private int m_iMinX, m_iMinY; |
33 |
private IRasterLayer m_Output;
|
34 |
private IRasterLayer m_Raster;
|
35 |
private IVectorLayer m_Polygons;
|
36 |
private int m_iNX; |
37 |
private int m_iNY; |
38 |
|
39 |
|
40 |
@Override
|
41 |
public void defineCharacteristics() { |
42 |
|
43 |
setName(Sextante.getText("Crop_grid_with_polygon_layer"));
|
44 |
setGroup(Sextante.getText("Basic_tools_for_raster_layers"));
|
45 |
setUserCanDefineAnalysisExtent(false);
|
46 |
try {
|
47 |
m_Parameters.addInputRasterLayer(INPUT, Sextante.getText("Layer_to_crop"), true); |
48 |
m_Parameters.addInputVectorLayer(POLYGONS, Sextante.getText("Polygons"), AdditionalInfoVectorLayer.SHAPE_TYPE_POLYGON,
|
49 |
true);
|
50 |
addOutputRasterLayer(RESULT, Sextante.getText("Cropped_layer"));
|
51 |
} |
52 |
catch (final RepeatedParameterNameException e) { |
53 |
Sextante.addErrorToLog(e); |
54 |
} |
55 |
|
56 |
} |
57 |
|
58 |
|
59 |
@Override
|
60 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
61 |
|
62 |
m_Raster = m_Parameters.getParameterValueAsRasterLayer("INPUT");
|
63 |
m_Polygons = m_Parameters.getParameterValueAsVectorLayer("POLYGONS");
|
64 |
|
65 |
clip(); |
66 |
|
67 |
return !m_Task.isCanceled();
|
68 |
|
69 |
} |
70 |
|
71 |
|
72 |
private void clip() throws UnsupportedOutputChannelException, IteratorException { |
73 |
|
74 |
int i;
|
75 |
m_Extent = getAdjustedGridExtent(); |
76 |
|
77 |
if (m_Extent != null) { |
78 |
m_Raster.setWindowExtent(m_Extent); |
79 |
m_Output = getNewRasterLayer(RESULT, Sextante.getText("Result"), m_Raster.getDataType(), m_Extent,
|
80 |
m_Raster.getBandsCount()); |
81 |
m_Output.setNoDataValue(m_Raster.getNoDataValue()); |
82 |
m_Output.assignNoData(); |
83 |
|
84 |
m_iNX = m_Extent.getNX(); |
85 |
m_iNY = m_Extent.getNY(); |
86 |
|
87 |
i = 1;
|
88 |
final IFeatureIterator iter = m_Polygons.iterator();
|
89 |
final int iShapeCount = m_Polygons.getShapesCount(); |
90 |
while (iter.hasNext() && !m_Task.isCanceled()) {
|
91 |
setProgressText(Integer.toString(i) + "/" + Integer.toString(iShapeCount)); |
92 |
final IFeature feature = iter.next();
|
93 |
final Geometry geom = feature.getGeometry();
|
94 |
doPolygon(geom); |
95 |
if (m_Task.isCanceled()) {
|
96 |
return;
|
97 |
} |
98 |
i++; |
99 |
} |
100 |
iter.close(); |
101 |
|
102 |
} |
103 |
|
104 |
} |
105 |
|
106 |
|
107 |
private void doPolygon(final Geometry geom) { |
108 |
|
109 |
for (int i = 0; i < geom.getNumGeometries(); i++) { |
110 |
final Geometry part = geom.getGeometryN(i);
|
111 |
doPolygonPart(part); |
112 |
} |
113 |
|
114 |
} |
115 |
|
116 |
|
117 |
private void doPolygonPart(final Geometry geom) { |
118 |
|
119 |
boolean bFill;
|
120 |
boolean bCrossing[]; |
121 |
int x, y, ix, xStart, xStop, iPoint;
|
122 |
double yPos;
|
123 |
Coordinate pLeft, pRight, pa, pb; |
124 |
final Coordinate p = new Coordinate(); |
125 |
bCrossing = new boolean[m_iNX]; |
126 |
final int iBands = m_Raster.getBandsCount(); |
127 |
|
128 |
final Envelope extent = geom.getEnvelopeInternal();
|
129 |
|
130 |
xStart = (int) ((extent.getMinX() - m_Extent.getXMin()) / m_Extent.getCellSize()) - 1; |
131 |
if (xStart < 0) { |
132 |
xStart = 0;
|
133 |
} |
134 |
|
135 |
xStop = (int) ((extent.getMaxX() - m_Extent.getXMin()) / m_Extent.getCellSize()) + 1; |
136 |
if (xStop >= m_iNX) {
|
137 |
xStop = m_iNX - 1;
|
138 |
} |
139 |
|
140 |
final Coordinate[] points = geom.getCoordinates(); |
141 |
|
142 |
for (y = 0, yPos = m_Extent.getYMax(); (y < m_iNY) && setProgress(y, m_iNY); y++, yPos -= m_Extent.getCellSize()) { |
143 |
if ((yPos >= extent.getMinY()) && (yPos <= extent.getMaxY())) {
|
144 |
Arrays.fill(bCrossing, false); |
145 |
pLeft = new Coordinate(m_Extent.getXMin() - 1.0, yPos); |
146 |
pRight = new Coordinate(m_Extent.getXMax() + 1.0, yPos); |
147 |
|
148 |
pb = points[points.length - 1];
|
149 |
|
150 |
for (iPoint = 0; iPoint < points.length; iPoint++) { |
151 |
pa = pb; |
152 |
pb = points[iPoint]; |
153 |
|
154 |
if ((((pa.y <= yPos) && (yPos < pb.y)) || ((pa.y > yPos) && (yPos >= pb.y)))) {
|
155 |
getCrossing(p, pa, pb, pLeft, pRight); |
156 |
|
157 |
ix = (int) ((p.x - m_Extent.getXMin()) / m_Extent.getCellSize() + 1.0); |
158 |
|
159 |
if (ix < 0) { |
160 |
ix = 0;
|
161 |
} |
162 |
else if (ix >= m_iNX) { |
163 |
ix = m_iNX - 1;
|
164 |
} |
165 |
|
166 |
bCrossing[ix] = !bCrossing[ix]; |
167 |
} |
168 |
} |
169 |
|
170 |
for (x = xStart, bFill = false; x <= xStop; x++) { |
171 |
if (bCrossing[x]) {
|
172 |
bFill = !bFill; |
173 |
} |
174 |
if (bFill) {
|
175 |
for (int i = 0; i < iBands; i++) { |
176 |
final double dValue = m_Raster.getCellValueAsDouble(x, y, i); |
177 |
m_Output.setCellValue(x, y, i, dValue); |
178 |
} |
179 |
} |
180 |
} |
181 |
} |
182 |
} |
183 |
|
184 |
} |
185 |
|
186 |
|
187 |
private boolean getCrossing(final Coordinate crossing, |
188 |
final Coordinate a1,
|
189 |
final Coordinate a2,
|
190 |
final Coordinate b1,
|
191 |
final Coordinate b2) {
|
192 |
|
193 |
double lambda, div, a_dx, a_dy, b_dx, b_dy;
|
194 |
|
195 |
a_dx = a2.x - a1.x; |
196 |
a_dy = a2.y - a1.y; |
197 |
|
198 |
b_dx = b2.x - b1.x; |
199 |
b_dy = b2.y - b1.y; |
200 |
|
201 |
if ((div = a_dx * b_dy - b_dx * a_dy) != 0.0) { |
202 |
lambda = ((b1.x - a1.x) * b_dy - b_dx * (b1.y - a1.y)) / div; |
203 |
|
204 |
crossing.x = a1.x + lambda * a_dx; |
205 |
crossing.y = a1.y + lambda * a_dy; |
206 |
|
207 |
return true; |
208 |
|
209 |
} |
210 |
|
211 |
return false; |
212 |
} |
213 |
|
214 |
|
215 |
private AnalysisExtent getAdjustedGridExtent() {
|
216 |
|
217 |
double iMaxX, iMaxY;
|
218 |
double dMinX, dMinY;
|
219 |
double dMinX2, dMinY2, dMaxX2, dMaxY2;
|
220 |
double dCellSize;
|
221 |
final AnalysisExtent ge = new AnalysisExtent(); |
222 |
|
223 |
final Rectangle2D rect = m_Polygons.getFullExtent(); |
224 |
dMinX = m_Raster.getLayerGridExtent().getXMin(); |
225 |
dMinY = m_Raster.getLayerGridExtent().getYMin(); |
226 |
dCellSize = m_Raster.getLayerGridExtent().getCellSize(); |
227 |
|
228 |
m_iMinX = (int) Math.floor((rect.getMinX() - dMinX) / dCellSize); |
229 |
iMaxX = Math.ceil((rect.getMaxX() - dMinX) / dCellSize);
|
230 |
m_iMinY = (int) Math.floor((rect.getMinY() - dMinY) / dCellSize); |
231 |
iMaxY = Math.ceil((rect.getMaxY() - dMinY) / dCellSize);
|
232 |
|
233 |
dMinX2 = dMinX + m_iMinX * dCellSize; |
234 |
dMinY2 = dMinY + m_iMinY * dCellSize; |
235 |
dMaxX2 = dMinX + iMaxX * dCellSize; |
236 |
dMaxY2 = dMinY + iMaxY * dCellSize; |
237 |
|
238 |
ge.setCellSize(dCellSize); |
239 |
ge.setXRange(dMinX2, dMaxX2, true);
|
240 |
ge.setYRange(dMinY2, dMaxY2, true);
|
241 |
|
242 |
return ge;
|
243 |
|
244 |
} |
245 |
|
246 |
} |