Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / rasterize / rasterizeVectorLayerForMask / RasterizeVectorLayerForMaskAlgorithm.java @ 59

History | View | Annotate | Download (10.3 KB)

1

    
2

    
3
package es.unex.sextante.rasterize.rasterizeVectorLayerForMask;
4

    
5
import java.util.Arrays;
6

    
7
import com.vividsolutions.jts.geom.Coordinate;
8
import com.vividsolutions.jts.geom.Envelope;
9
import com.vividsolutions.jts.geom.Geometry;
10
import com.vividsolutions.jts.geom.GeometryFactory;
11
import com.vividsolutions.jts.geom.LinearRing;
12
import com.vividsolutions.jts.geom.Polygon;
13

    
14
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer;
15
import es.unex.sextante.core.AnalysisExtent;
16
import es.unex.sextante.core.GeoAlgorithm;
17
import es.unex.sextante.core.Sextante;
18
import es.unex.sextante.dataObjects.IFeature;
19
import es.unex.sextante.dataObjects.IFeatureIterator;
20
import es.unex.sextante.dataObjects.IRasterLayer;
21
import es.unex.sextante.dataObjects.IRecord;
22
import es.unex.sextante.dataObjects.IVectorLayer;
23
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
24
import es.unex.sextante.exceptions.RepeatedParameterNameException;
25
import es.unex.sextante.rasterWrappers.GridCell;
26

    
27

    
28
public class RasterizeVectorLayerForMaskAlgorithm
29
         extends
30
            GeoAlgorithm {
31

    
32
   private double             NO_DATA;
33

    
34
   public static final String LAYER  = "LAYER";
35
   public static final String FIELD  = "FIELD";
36
   public static final String RESULT = "RESULT";
37

    
38
   private int                m_iNX, m_iNY;
39
   private IVectorLayer       m_Layer;
40
   private IRasterLayer       m_Result;
41
   private AnalysisExtent     m_Extent;
42

    
43

    
44
   @Override
45
   public void defineCharacteristics() {
46

    
47
      setName(Sextante.getText("Rasterize_vector_layer_for_mask"));
48
      setGroup(Sextante.getText("Rasterization_and_interpolation"));
49
      setUserCanDefineAnalysisExtent(true);
50

    
51
      try {
52
         m_Parameters.addInputVectorLayer(LAYER, Sextante.getText("Vector_layer"), AdditionalInfoVectorLayer.SHAPE_TYPE_ANY, true);
53
         addOutputRasterLayer(RESULT, Sextante.getText("Result"));
54
      }
55
      catch (final RepeatedParameterNameException e) {
56
         Sextante.addErrorToLog(e);
57
      }
58

    
59
   }
60

    
61

    
62
   @Override
63
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
64

    
65
      int i;
66
      int iType;
67
      int iShapeCount;
68

    
69
      NO_DATA = 0;
70

    
71
      m_Layer = m_Parameters.getParameterValueAsVectorLayer(LAYER);
72

    
73
      m_Result = getNewRasterLayer(RESULT, m_Layer.getName() + Sextante.getText("[rasterizedo]"),
74
               IRasterLayer.RASTER_DATA_TYPE_DOUBLE);
75
      m_Result.setNoDataValue(NO_DATA);
76
      m_Result.assignNoData();
77

    
78
      m_Extent = m_Result.getWindowGridExtent();
79

    
80
      m_iNX = m_Extent.getNX();
81
      m_iNY = m_Extent.getNY();
82

    
83
      final Coordinate[] coords = new Coordinate[5];
84
      coords[0] = new Coordinate(m_Extent.getXMin(), m_Extent.getYMin());
85
      coords[1] = new Coordinate(m_Extent.getXMin(), m_Extent.getYMax());
86
      coords[2] = new Coordinate(m_Extent.getXMax(), m_Extent.getYMax());
87
      coords[3] = new Coordinate(m_Extent.getXMax(), m_Extent.getYMin());
88
      coords[4] = new Coordinate(m_Extent.getXMin(), m_Extent.getYMin());
89
      final GeometryFactory gf = new GeometryFactory();
90
      final LinearRing ring = gf.createLinearRing(coords);
91
      final Polygon extent = gf.createPolygon(ring, null);
92

    
93
      i = 0;
94
      iType = m_Layer.getShapeType();
95
      iShapeCount = m_Layer.getShapesCount();
96
      final IFeatureIterator iter = m_Layer.iterator();
97
      while (iter.hasNext() && setProgress(i, iShapeCount)) {
98
         final IFeature feature = iter.next();
99
         final IRecord record = feature.getRecord();
100

    
101
         final Geometry geometry = feature.getGeometry();
102

    
103
         if (geometry.intersects(extent)) {
104
            switch (iType) {
105
               case IVectorLayer.SHAPE_TYPE_POINT:
106
                  doPoint(geometry, 1);
107
                  break;
108
               case IVectorLayer.SHAPE_TYPE_LINE:
109
                  doLine(geometry, 1);
110
                  break;
111
               case IVectorLayer.SHAPE_TYPE_POLYGON:
112
                  doPolygon(geometry, 1);
113
                  break;
114
            }
115
         }
116
         i++;
117
      }
118
      iter.close();
119

    
120
      return !m_Task.isCanceled();
121

    
122

    
123
   }
124

    
125

    
126
   private void doPolygon(final Geometry geom,
127
                          final double dValue) {
128

    
129
      final GeometryFactory gf = new GeometryFactory();
130
      for (int i = 0; i < geom.getNumGeometries(); i++) {
131
         final Polygon poly = (Polygon) geom.getGeometryN(i);
132
         LinearRing lr = gf.createLinearRing(poly.getExteriorRing().getCoordinates());
133
         Polygon part = gf.createPolygon(lr, null);
134
         doPolygonPart(part, dValue, false);
135
         for (int j = 0; j < poly.getNumInteriorRing(); j++) {
136
            lr = gf.createLinearRing(poly.getInteriorRingN(j).getCoordinates());
137
            part = gf.createPolygon(lr, null);
138
            doPolygonPart(part, dValue, true);
139
         }
140
      }
141

    
142
   }
143

    
144

    
145
   private void doPolygonPart(final Polygon geom,
146
                              final double dValue,
147
                              final boolean bIsHole) {
148

    
149
      boolean bFill;
150
      boolean bCrossing[];
151
      int x, y, ix, xStart, xStop, iPoint;
152
      double yPos;;
153
      Coordinate pLeft, pRight, pa, pb;
154
      final Coordinate p = new Coordinate();
155
      bCrossing = new boolean[m_iNX];
156

    
157
      final Envelope extent = geom.getEnvelopeInternal();
158

    
159
      xStart = (int) ((extent.getMinX() - m_Extent.getXMin()) / m_Extent.getCellSize()) - 1;
160
      if (xStart < 0) {
161
         xStart = 0;
162
      }
163

    
164
      xStop = (int) ((extent.getMaxX() - m_Extent.getXMin()) / m_Extent.getCellSize()) + 1;
165
      if (xStop >= m_iNX) {
166
         xStop = m_iNX - 1;
167
      }
168

    
169
      final Coordinate[] points = geom.getCoordinates();
170

    
171
      for (y = 0, yPos = m_Extent.getYMax(); y < m_iNY; y++, yPos -= m_Extent.getCellSize()) {
172
         if ((yPos >= extent.getMinY()) && (yPos <= extent.getMaxY())) {
173
            Arrays.fill(bCrossing, false);
174
            pLeft = new Coordinate(m_Extent.getXMin() - 1.0, yPos);
175
            pRight = new Coordinate(m_Extent.getXMax() + 1.0, yPos);
176

    
177
            pb = points[points.length - 1];
178

    
179
            for (iPoint = 0; iPoint < points.length; iPoint++) {
180
               pa = pb;
181
               pb = points[iPoint];
182

    
183
               if ((((pa.y <= yPos) && (yPos < pb.y)) || ((pa.y > yPos) && (yPos >= pb.y)))) {
184
                  getCrossing(p, pa, pb, pLeft, pRight);
185

    
186
                  ix = (int) ((p.x - m_Extent.getXMin()) / m_Extent.getCellSize() + 1.0);
187

    
188
                  if (ix < 0) {
189
                     ix = 0;
190
                  }
191
                  else if (ix >= m_iNX) {
192
                     ix = m_iNX - 1;
193
                  }
194

    
195
                  bCrossing[ix] = !bCrossing[ix];
196
               }
197
            }
198

    
199
            for (x = xStart, bFill = false; x <= xStop; x++) {
200
               if (bCrossing[x]) {
201
                  bFill = !bFill;
202
               }
203
               if (bFill) {
204
                  final double dPrevValue = m_Result.getCellValueAsDouble(x, y);
205
                  if (bIsHole) {
206
                     if (dPrevValue == dValue) {
207
                        m_Result.setNoData(x, y);
208
                     }
209
                  }
210
                  else {
211
                     if (dPrevValue == NO_DATA) {
212
                        m_Result.setCellValue(x, y, dValue);
213
                     }
214
                  }
215
               }
216
            }
217
         }
218
      }
219

    
220
   }
221

    
222

    
223
   private void doLine(final Geometry geom,
224
                       final double dValue) {
225

    
226
      for (int i = 0; i < geom.getNumGeometries(); i++) {
227
         final Geometry part = geom.getGeometryN(i);
228
         doLineString(part, dValue);
229
      }
230

    
231
   }
232

    
233

    
234
   private void doLineString(final Geometry geom,
235
                             final double dValue) {
236

    
237
      int i;
238
      double x, y, x2, y2;
239
      final Coordinate[] coords = geom.getCoordinates();
240
      for (i = 0; i < coords.length - 1; i++) {
241
         x = coords[i].x;
242
         y = coords[i].y;
243
         x2 = coords[i + 1].x;
244
         y2 = coords[i + 1].y;
245
         writeSegment(x, y, x2, y2, dValue);
246
      }
247

    
248
   }
249

    
250

    
251
   private void writeSegment(double x,
252
                             double y,
253
                             final double x2,
254
                             final double y2,
255
                             final double dValue) {
256

    
257
      double dx, dy, d, n;
258
      GridCell cell;
259

    
260
      dx = Math.abs(x2 - x);
261
      dy = Math.abs(y2 - y);
262

    
263
      if ((dx > 0.0) || (dy > 0.0)) {
264
         if (dx > dy) {
265
            dx /= m_Result.getWindowCellSize();
266
            n = dx;
267
            dy /= dx;
268
            dx = m_Result.getWindowCellSize();
269
         }
270
         else {
271
            dy /= m_Result.getWindowCellSize();
272
            n = dy;
273
            dx /= dy;
274
            dy = m_Result.getWindowCellSize();
275
         }
276

    
277
         if (x2 < x) {
278
            dx = -dx;
279
         }
280

    
281
         if (y2 < y) {
282
            dy = -dy;
283
         }
284

    
285
         for (d = 0.0; d <= n; d++, x += dx, y += dy) {
286
            if (m_Extent.contains(x, y)) {
287
               cell = m_Extent.getGridCoordsFromWorldCoords(x, y);
288
               //System.out.println(cell.getX() + " " + cell.getY());
289
               m_Result.setCellValue(cell.getX(), cell.getY(), dValue);
290
            }
291
         }
292
      }
293

    
294
   }
295

    
296

    
297
   private void doPoint(final Geometry geometry,
298
                        final double dValue) {
299

    
300
      final Coordinate coord = geometry.getCoordinate();
301
      final GridCell cell = m_Extent.getGridCoordsFromWorldCoords(coord.x, coord.y);
302
      m_Result.setCellValue(cell.getX(), cell.getY(), dValue);
303

    
304
   }
305

    
306

    
307
   private boolean getCrossing(final Coordinate crossing,
308
                               final Coordinate a1,
309
                               final Coordinate a2,
310
                               final Coordinate b1,
311
                               final Coordinate b2) {
312

    
313
      double lambda, div, a_dx, a_dy, b_dx, b_dy;
314

    
315
      a_dx = a2.x - a1.x;
316
      a_dy = a2.y - a1.y;
317

    
318
      b_dx = b2.x - b1.x;
319
      b_dy = b2.y - b1.y;
320

    
321
      if ((div = a_dx * b_dy - b_dx * a_dy) != 0.0) {
322
         lambda = ((b1.x - a1.x) * b_dy - b_dx * (b1.y - a1.y)) / div;
323

    
324
         crossing.x = a1.x + lambda * a_dx;
325
         crossing.y = a1.y + lambda * a_dy;
326

    
327
         return true;
328

    
329
      }
330

    
331
      return false;
332
   }
333

    
334
}