Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / gridTools / locateExtremeValues / LocateExtremeValuesAlgorithm.java @ 59

History | View | Annotate | Download (7.89 KB)

1

    
2

    
3
package es.unex.sextante.gridTools.locateExtremeValues;
4

    
5
import java.awt.geom.Point2D;
6
import java.util.Arrays;
7

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

    
16
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer;
17
import es.unex.sextante.core.AnalysisExtent;
18
import es.unex.sextante.core.GeoAlgorithm;
19
import es.unex.sextante.core.Sextante;
20
import es.unex.sextante.dataObjects.IFeature;
21
import es.unex.sextante.dataObjects.IFeatureIterator;
22
import es.unex.sextante.dataObjects.IRasterLayer;
23
import es.unex.sextante.dataObjects.IVectorLayer;
24
import es.unex.sextante.dataObjects.vectorFilters.BoundingBoxFilter;
25
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
26
import es.unex.sextante.exceptions.RepeatedParameterNameException;
27
import es.unex.sextante.outputs.OutputVectorLayer;
28

    
29

    
30
public class LocateExtremeValuesAlgorithm
31
         extends
32
            GeoAlgorithm {
33

    
34
   public static final String RESULT             = "RESULT";
35
   public static final String GRID               = "GRID";
36
   public static final String POLYGONS           = "POLYGONS";
37
   public static final String EXTREME_VALUE_TYPE = "EXTREME_VALUE_TYPE";
38

    
39
   private int                m_iNX, m_iNY;
40
   private IVectorLayer       m_Layer;
41
   private AnalysisExtent     m_Extent;
42
   private IRasterLayer       m_Window;
43
   private Coordinate         m_Coordinate;
44
   private double             m_dExtremeValue;
45
   private IVectorLayer       m_Output;
46

    
47

    
48
   @Override
49
   public void defineCharacteristics() {
50

    
51
      setName(Sextante.getText("Locate_max_values"));
52
      setGroup(Sextante.getText("Basic_tools_for_raster_layers"));
53
      setUserCanDefineAnalysisExtent(true);
54

    
55
      try {
56
         m_Parameters.addInputVectorLayer(POLYGONS, Sextante.getText("Polygons"), AdditionalInfoVectorLayer.SHAPE_TYPE_POLYGON,
57
                  true);
58
         m_Parameters.addInputRasterLayer(GRID, Sextante.getText("Grid"), true);
59
         addOutputVectorLayer(RESULT, Sextante.getText("Max_values"), OutputVectorLayer.SHAPE_TYPE_POINT);
60
      }
61
      catch (final RepeatedParameterNameException e) {
62
         Sextante.addErrorToLog(e);
63
      }
64

    
65
   }
66

    
67

    
68
   @Override
69
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
70

    
71
      int i = 0;
72
      int iShapeCount;
73
      final GeometryFactory gf = new GeometryFactory();
74

    
75
      m_Coordinate = new Coordinate();
76
      m_Layer = m_Parameters.getParameterValueAsVectorLayer(POLYGONS);
77
      m_Window = m_Parameters.getParameterValueAsRasterLayer(GRID);
78

    
79
      final String[] sNames = { m_Window.getName() };
80
      final Class[] types = { Double.class };
81

    
82
      m_Output = getNewVectorLayer(RESULT, Sextante.getText("Result"), IVectorLayer.SHAPE_TYPE_POINT, types, sNames);
83

    
84
      if (!m_bIsAutoExtent) {
85
         m_Layer.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
86
      }
87
      iShapeCount = m_Layer.getShapesCount();
88

    
89
      m_Window.setFullExtent();
90
      m_Extent = m_Window.getWindowGridExtent();
91
      final Coordinate[] coords = new Coordinate[5];
92
      coords[0] = new Coordinate(m_Extent.getXMin(), m_Extent.getYMin());
93
      coords[1] = new Coordinate(m_Extent.getXMin(), m_Extent.getYMax());
94
      coords[2] = new Coordinate(m_Extent.getYMax(), m_Extent.getYMax());
95
      coords[3] = new Coordinate(m_Extent.getXMax(), m_Extent.getYMin());
96
      coords[4] = new Coordinate(m_Extent.getXMin(), m_Extent.getYMin());
97

    
98
      final LinearRing ring = gf.createLinearRing(coords);
99
      final Polygon extent = gf.createPolygon(ring, null);
100
      m_iNX = m_Window.getNX();
101
      m_iNY = m_Window.getNY();
102
      final IFeatureIterator iter = m_Layer.iterator();
103
      i = 0;
104
      while (iter.hasNext() && setProgress(i, iShapeCount)) {
105
         final IFeature feature = iter.next();
106
         final Geometry geom = feature.getGeometry();
107
         if (geom.intersects(extent)) {
108
            m_dExtremeValue = Double.NEGATIVE_INFINITY;
109
            doPolygon(geom);
110
            final Point pt = gf.createPoint(new Coordinate(m_Coordinate.x, m_Coordinate.y));
111
            m_Output.addFeature(pt, new Object[] { new Double(m_dExtremeValue) });
112
         }
113
         i++;
114
      }
115
      iter.close();
116

    
117
      return !m_Task.isCanceled();
118

    
119
   }
120

    
121

    
122
   private void doPolygon(final Geometry geom) {
123

    
124
      for (int i = 0; i < geom.getNumGeometries(); i++) {
125
         final Geometry part = geom.getGeometryN(i);
126
         doPolygonPart(part);
127
      }
128

    
129

    
130
   }
131

    
132

    
133
   private void doPolygonPart(final Geometry geom) {
134

    
135
      boolean bFill;
136
      boolean bCrossing[];
137
      int x, y, ix, xStart, xStop, iPoint;
138
      double yPos;
139
      double dValue;
140
      Coordinate pLeft, pRight, pa, pb;
141
      final Coordinate p = new Coordinate();
142
      bCrossing = new boolean[m_iNX];
143

    
144
      final Envelope extent = geom.getEnvelopeInternal();
145

    
146
      xStart = (int) ((extent.getMinX() - m_Extent.getXMin()) / m_Extent.getCellSize()) - 1;
147
      if (xStart < 0) {
148
         xStart = 0;
149
      }
150

    
151
      xStop = (int) ((extent.getMaxX() - m_Extent.getXMin()) / m_Extent.getCellSize()) + 1;
152
      if (xStop >= m_iNX) {
153
         xStop = m_iNX - 1;
154
      }
155

    
156
      final Coordinate[] points = geom.getCoordinates();
157

    
158
      for (y = 0, yPos = m_Extent.getYMax(); y < m_iNY; y++, yPos -= m_Extent.getCellSize()) {
159
         if ((yPos >= extent.getMinY()) && (yPos <= extent.getMaxY())) {
160
            Arrays.fill(bCrossing, false);
161
            pLeft = new Coordinate(m_Extent.getXMin() - 1.0, yPos);
162
            pRight = new Coordinate(m_Extent.getXMax() + 1.0, yPos);
163

    
164
            pb = points[points.length - 1];
165

    
166
            for (iPoint = 0; iPoint < points.length; iPoint++) {
167
               pa = pb;
168
               pb = points[iPoint];
169

    
170
               if ((((pa.y <= yPos) && (yPos < pb.y)) || ((pa.y > yPos) && (yPos >= pb.y)))) {
171
                  getCrossing(p, pa, pb, pLeft, pRight);
172

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

    
175
                  if (ix < 0) {
176
                     ix = 0;
177
                  }
178
                  else if (ix >= m_iNX) {
179
                     ix = m_iNX - 1;
180
                  }
181

    
182
                  bCrossing[ix] = !bCrossing[ix];
183
               }
184
            }
185

    
186
            for (x = xStart, bFill = false; x <= xStop; x++) {
187
               if (bCrossing[x]) {
188
                  bFill = !bFill;
189
               }
190
               if (bFill) {
191
                  dValue = m_Window.getCellValueAsDouble(x, y);
192
                  if (!m_Window.isNoDataValue(dValue)) {
193
                     if (dValue > m_dExtremeValue) {
194
                        m_dExtremeValue = dValue;
195
                        final Point2D coord = m_Extent.getWorldCoordsFromGridCoords(x, y);
196
                        m_Coordinate.x = coord.getX();
197
                        m_Coordinate.y = coord.getY();
198
                     }
199
                  }
200
               }
201
            }
202
         }
203
      }
204

    
205
   }
206

    
207

    
208
   private boolean getCrossing(final Coordinate crossing,
209
                               final Coordinate a1,
210
                               final Coordinate a2,
211
                               final Coordinate b1,
212
                               final Coordinate b2) {
213

    
214
      double lambda, div, a_dx, a_dy, b_dx, b_dy;
215

    
216
      a_dx = a2.x - a1.x;
217
      a_dy = a2.y - a1.y;
218

    
219
      b_dx = b2.x - b1.x;
220
      b_dy = b2.y - b1.y;
221

    
222
      if ((div = a_dx * b_dy - b_dx * a_dy) != 0.0) {
223
         lambda = ((b1.x - a1.x) * b_dy - b_dx * (b1.y - a1.y)) / div;
224

    
225
         crossing.x = a1.x + lambda * a_dx;
226
         crossing.y = a1.y + lambda * a_dy;
227

    
228
         return true;
229

    
230
      }
231

    
232
      return false;
233
   }
234

    
235
}