Statistics
| Revision:

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
}