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 |
} |