Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / profiles / profile / ProfileAlgorithm.java @ 59

History | View | Annotate | Download (8.16 KB)

1

    
2

    
3
package es.unex.sextante.profiles.profile;
4

    
5
import java.util.ArrayList;
6

    
7
import org.jfree.chart.ChartFactory;
8
import org.jfree.chart.ChartPanel;
9
import org.jfree.chart.JFreeChart;
10
import org.jfree.chart.plot.PlotOrientation;
11
import org.jfree.data.xy.XYSeries;
12
import org.jfree.data.xy.XYSeriesCollection;
13

    
14
import com.vividsolutions.jts.geom.Coordinate;
15
import com.vividsolutions.jts.geom.Geometry;
16
import com.vividsolutions.jts.geom.GeometryFactory;
17
import com.vividsolutions.jts.geom.Point;
18

    
19
import es.unex.sextante.additionalInfo.AdditionalInfoMultipleInput;
20
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer;
21
import es.unex.sextante.core.AnalysisExtent;
22
import es.unex.sextante.core.GeoAlgorithm;
23
import es.unex.sextante.core.Sextante;
24
import es.unex.sextante.dataObjects.IFeatureIterator;
25
import es.unex.sextante.dataObjects.IRasterLayer;
26
import es.unex.sextante.dataObjects.IVectorLayer;
27
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
28
import es.unex.sextante.exceptions.RepeatedParameterNameException;
29
import es.unex.sextante.outputs.OutputVectorLayer;
30

    
31

    
32
public class ProfileAlgorithm
33
         extends
34
            GeoAlgorithm {
35

    
36
   public static final String ROUTE         = "ROUTE";
37
   public static final String DEM           = "DEM";
38
   public static final String LAYERS        = "LAYERS";
39
   public static final String PROFILEPOINTS = "PROFILEPOINTS";
40
   public static final String GRAPH         = "GRAPH";
41
   public static final String INTERPOLATE   = "INTERPOLATE";
42

    
43
   private IVectorLayer       m_Profile;
44
   private IRasterLayer       m_DEM;
45
   private IRasterLayer       m_Layer[];
46
   private double             m_dDist       = 0, m_dHorzDist = 0;
47
   private double             m_dLastX, m_dLastY, m_dLastZ;
48
   private int                m_iPoints     = 0;
49
   private XYSeries           serie;
50

    
51

    
52
   @Override
53
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
54

    
55
      int i;
56
      Class types[];
57
      String sFieldNames[];
58
      final XYSeriesCollection dataset = new XYSeriesCollection();
59
      serie = new XYSeries(Sextante.getText("Profile"));
60
      dataset.addSeries(serie);
61

    
62
      boolean bInterpolate = m_Parameters.getParameterValueAsBoolean(INTERPOLATE);
63

    
64
      final IVectorLayer lines = m_Parameters.getParameterValueAsVectorLayer(ROUTE);
65

    
66
      if (lines.getShapesCount() == 0) {
67
         throw new GeoAlgorithmExecutionException(Sextante.getText("Zero_lines_in_layer"));
68
      }
69

    
70
      final ArrayList layers = m_Parameters.getParameterValueAsArrayList(LAYERS);
71
      m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM);
72
      m_DEM.setFullExtent();
73
      if (!bInterpolate) {
74
         m_DEM.setInterpolationMethod(IRasterLayer.INTERPOLATION_NearestNeighbour);
75
      }
76
      final AnalysisExtent extent = m_DEM.getWindowGridExtent();
77

    
78
      m_Layer = new IRasterLayer[layers.size()];
79
      for (i = 0; i < layers.size(); i++) {
80
         m_Layer[i] = (IRasterLayer) layers.get(i);
81
         m_Layer[i].setWindowExtent(extent);
82
         if (!bInterpolate) {
83
            m_Layer[i].setInterpolationMethod(IRasterLayer.INTERPOLATION_NearestNeighbour);
84
         }
85
      }
86

    
87
      sFieldNames = new String[layers.size() + 5];
88
      sFieldNames[0] = "X";
89
      sFieldNames[1] = "Y";
90
      sFieldNames[2] = "Z";
91
      sFieldNames[3] = Sextante.getText("ProjDist");
92
      sFieldNames[4] = Sextante.getText("RealDist");
93
      for (i = 0; i < layers.size(); i++) {
94
         sFieldNames[i + 5] = m_Layer[i].getName();
95
      }
96

    
97
      types = new Class[layers.size() + 5];
98
      for (i = 0; i < types.length; i++) {
99
         types[i] = Double.class;
100
      }
101

    
102
      m_Profile = getNewVectorLayer(PROFILEPOINTS, Sextante.getText("Profile_[points]"), IVectorLayer.SHAPE_TYPE_POINT, types,
103
               sFieldNames);
104

    
105
      final IFeatureIterator iterator = lines.iterator();
106
      final Geometry line = iterator.next().getGeometry().getGeometryN(0);
107
      processLine(line);
108
      iterator.close();
109

    
110
      final JFreeChart chart = ChartFactory.createXYLineChart(null, null, null, dataset, PlotOrientation.VERTICAL, false, true,
111
               true);
112

    
113
      final ChartPanel jPanelChart = new ChartPanel(chart);
114
      jPanelChart.setPreferredSize(new java.awt.Dimension(500, 300));
115
      jPanelChart.setPreferredSize(new java.awt.Dimension(500, 300));
116
      jPanelChart.setBorder(javax.swing.BorderFactory.createLineBorder(java.awt.Color.gray, 1));
117

    
118
      addOutputChart(GRAPH, Sextante.getText("Profile"), jPanelChart);
119

    
120
      return true;
121
   }
122

    
123

    
124
   @Override
125
   public void defineCharacteristics() {
126

    
127
      setName(Sextante.getText("Profile"));
128
      setGroup(Sextante.getText("Profiles"));
129
      setUserCanDefineAnalysisExtent(false);
130
      try {
131
         m_Parameters.addInputVectorLayer(ROUTE, Sextante.getText("Profile_route"), AdditionalInfoVectorLayer.SHAPE_TYPE_LINE,
132
                  true);
133
         m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true);
134
         m_Parameters.addMultipleInput(LAYERS, Sextante.getText("Additional_layers"),
135
                  AdditionalInfoMultipleInput.DATA_TYPE_RASTER, false);
136
         m_Parameters.addBoolean(INTERPOLATE, Sextante.getText("Use_interpolation"), false);
137
         addOutputVectorLayer(PROFILEPOINTS, Sextante.getText("Profile_[points]"), OutputVectorLayer.SHAPE_TYPE_POINT);
138
         addOutputChart(GRAPH, Sextante.getText("Profile"));
139
      }
140
      catch (final RepeatedParameterNameException e) {
141
         Sextante.addErrorToLog(e);
142
      }
143

    
144
   }
145

    
146

    
147
   private void processLine(final Geometry line) {
148

    
149
      double x, y, x2, y2;
150
      final Coordinate[] coords = line.getCoordinates();
151

    
152
      for (int i = 0; (i < coords.length - 1) && setProgress(i, coords.length - 1); i++) {
153
         x = coords[i].x;
154
         y = coords[i].y;
155
         x2 = coords[i + 1].x;
156
         y2 = coords[i + 1].y;
157
         processSegment(x, y, x2, y2);
158
      }
159

    
160
   }
161

    
162

    
163
   private void processSegment(double x,
164
                               double y,
165
                               final double x2,
166
                               final double y2) {
167

    
168
      double dx, dy, d, n;
169

    
170
      dx = Math.abs(x2 - x);
171
      dy = Math.abs(y2 - y);
172

    
173
      if ((dx > 0.0) || (dy > 0.0)) {
174
         if (dx > dy) {
175
            dx /= m_DEM.getWindowCellSize();
176
            n = dx;
177
            dy /= dx;
178
            dx = m_DEM.getWindowCellSize();
179
         }
180
         else {
181
            dy /= m_DEM.getWindowCellSize();
182
            n = dy;
183
            dx /= dy;
184
            dy = m_DEM.getWindowCellSize();
185
         }
186

    
187
         if (x2 < x) {
188
            dx = -dx;
189
         }
190

    
191
         if (y2 < y) {
192
            dy = -dy;
193
         }
194

    
195
         for (d = 0.0; d <= n; d++, x += dx, y += dy) {
196
            addPoint(x, y);
197
         }
198
      }
199

    
200
   }
201

    
202

    
203
   private void addPoint(final double x,
204
                         final double y) {
205

    
206
      int i;
207
      double z;
208
      double dDX, dDY, dDZ;
209
      double dValue;
210
      final Object values[] = new Object[m_Layer.length + 5];
211

    
212
      z = m_DEM.getValueAt(x, y);
213

    
214
      if (m_iPoints == 0) {
215
         m_dDist = 0.0;
216
         m_dHorzDist = 0.0;
217
      }
218
      else {
219
         dDX = x - m_dLastX;
220
         dDY = y - m_dLastY;
221
         if (m_DEM.isNoDataValue(z) || m_DEM.isNoDataValue(m_dLastZ)) {
222
            dDZ = 0.0;
223
         }
224
         else {
225
            dDZ = z - m_dLastZ;
226
         }
227
         m_dDist += Math.sqrt(dDX * dDX + dDY * dDY);
228
         m_dHorzDist += Math.sqrt(dDX * dDX + dDY * dDY + dDZ * dDZ);
229
      }
230

    
231
      m_dLastX = x;
232
      m_dLastY = y;
233
      m_dLastZ = z;
234
      m_iPoints++;
235

    
236
      final Point geometry = new GeometryFactory().createPoint(new Coordinate(x, y));
237
      values[0] = new Double(x);
238
      values[1] = new Double(y);
239
      values[2] = new Double(z);
240
      values[3] = new Double(m_dDist);
241
      values[4] = new Double(m_dHorzDist);
242
      for (i = 0; i < m_Layer.length; i++) {
243
         dValue = m_Layer[i].getValueAt(x, y);
244
         values[i + 5] = new Double(dValue);
245
      }
246
      if (!m_DEM.isNoDataValue(z)) {
247
         serie.add(m_dDist, z);
248
      }
249
      m_Profile.addFeature(geometry, values);
250

    
251
   }
252

    
253
}