Statistics
| Revision:

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

History | View | Annotate | Download (8 KB)

1

    
2

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

    
5
import com.vividsolutions.jts.geom.Coordinate;
6
import com.vividsolutions.jts.geom.Geometry;
7
import com.vividsolutions.jts.geom.GeometryFactory;
8

    
9
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue;
10
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer;
11
import es.unex.sextante.core.GeoAlgorithm;
12
import es.unex.sextante.core.Sextante;
13
import es.unex.sextante.dataObjects.IFeature;
14
import es.unex.sextante.dataObjects.IFeatureIterator;
15
import es.unex.sextante.dataObjects.IRasterLayer;
16
import es.unex.sextante.dataObjects.IVectorLayer;
17
import es.unex.sextante.dataObjects.vectorFilters.BoundingBoxFilter;
18
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
19
import es.unex.sextante.exceptions.RepeatedParameterNameException;
20
import es.unex.sextante.outputs.OutputVectorLayer;
21

    
22

    
23
public class CrossSectionsAlgorithm
24
         extends
25
            GeoAlgorithm {
26

    
27
   public static final String RESULT    = "RESULT";
28
   public static final String NUMPOINTS = "NUMPOINTS";
29
   public static final String WIDTH     = "WIDTH";
30
   public static final String DISTANCE  = "DISTANCE";
31
   public static final String DEM       = "DEM";
32
   public static final String ROUTE     = "ROUTE";
33

    
34
   private IVectorLayer       m_Lines;
35
   private IVectorLayer       m_Result;
36
   private IRasterLayer       m_DEM;
37
   private double             m_dStepX, m_dStepY;
38
   private double             m_dDistance;
39
   private double             m_dInterval;
40
   private double             m_dSectionWidth;
41
   private int                m_iPointsInSection;
42

    
43

    
44
   @Override
45
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
46

    
47
      int i;
48
      int iField;
49
      Class types[];
50
      String sFieldNames[];
51

    
52
      m_Lines = m_Parameters.getParameterValueAsVectorLayer(ROUTE);
53
      if (!m_bIsAutoExtent) {
54
         m_Lines.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
55
      }
56

    
57
      if (m_Lines.getShapesCount() == 0) {
58
         throw new GeoAlgorithmExecutionException("zero shapes in layer");
59
      }
60

    
61
      m_dDistance = m_Parameters.getParameterValueAsDouble(DISTANCE);
62
      m_dSectionWidth = m_Parameters.getParameterValueAsDouble(WIDTH);
63
      m_iPointsInSection = m_Parameters.getParameterValueAsInt(NUMPOINTS);
64
      m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM);
65
      m_DEM.setFullExtent();
66

    
67
      m_dInterval = m_dSectionWidth / m_iPointsInSection;
68

    
69
      sFieldNames = new String[m_iPointsInSection * 2 + 1];
70
      types = new Class[m_iPointsInSection * 2 + 1];
71
      for (i = -m_iPointsInSection, iField = 0; i < m_iPointsInSection + 1; i++, iField++) {
72
         sFieldNames[iField] = Double.toString(m_dInterval * i);
73
         types[iField] = Double.class;
74
      }
75
      sFieldNames[m_iPointsInSection] = "0";
76
      types[m_iPointsInSection] = Double.class;
77

    
78
      m_Result = getNewVectorLayer(RESULT, Sextante.getText("Cross_sections"), IVectorLayer.SHAPE_TYPE_LINE, types, sFieldNames);
79
      final int iCount = m_Lines.getShapesCount();
80
      final IFeatureIterator iter = m_Lines.iterator();
81
      i = 0;
82
      while (iter.hasNext() && setProgress(i, iCount)) {
83
         final IFeature feature = iter.next();
84
         final Geometry geometry = feature.getGeometry();
85
         for (int j = 0; j < geometry.getNumGeometries(); j++) {
86
            final Geometry line = geometry.getGeometryN(j);
87
            processLine(line);
88
         }
89
         i++;
90
      }
91
      iter.close();
92

    
93

    
94
      return !m_Task.isCanceled();
95

    
96
   }
97

    
98

    
99
   @Override
100
   public void defineCharacteristics() {
101

    
102
      setName(Sextante.getText("Cross_sections"));
103
      setGroup(Sextante.getText("Profiles"));
104
      setUserCanDefineAnalysisExtent(true);
105
      try {
106
         m_Parameters.addInputVectorLayer(ROUTE, Sextante.getText("Route"), AdditionalInfoVectorLayer.SHAPE_TYPE_LINE, true);
107
         m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true);
108
         m_Parameters.addNumericalValue(DISTANCE, Sextante.getText("Distance_between_sections"),
109
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE, 100, 0, Double.MAX_VALUE);
110
         m_Parameters.addNumericalValue(WIDTH, Sextante.getText("Section_width__to_each_side"),
111
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE, 10, 0, Double.MAX_VALUE);
112
         m_Parameters.addNumericalValue(NUMPOINTS, Sextante.getText("Number_of_points__on_each_side"),
113
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_INTEGER, 5, 0, Integer.MAX_VALUE);
114
         addOutputVectorLayer(RESULT, Sextante.getText("Cross_sections"), OutputVectorLayer.SHAPE_TYPE_LINE);
115
      }
116
      catch (final RepeatedParameterNameException e) {
117
         Sextante.addErrorToLog(e);
118
      }
119

    
120
   }
121

    
122

    
123
   private void processLine(final Geometry line) {
124

    
125
      int i, j;
126
      int iPoints;
127
      double dX1, dX2, dY1, dY2;
128
      double dAddedPointX = 0, dAddedPointY = 0;
129
      double dDX, dDY;
130
      double dRemainingDistFromLastSegment = 0;
131
      double dDistToNextPoint;
132
      double dDist;
133

    
134
      final Coordinate[] coords = line.getCoordinates();
135
      if (coords.length < 2) {
136
         return;
137
      }
138

    
139
      dX1 = coords[0].x;
140
      dY1 = coords[0].y;
141
      dX2 = coords[1].x;
142
      dY2 = coords[1].y;
143
      dAddedPointX = dX1;
144
      dAddedPointY = dY1;
145
      computeSegmentOrientation(dX1, dY1, dX2, dY2);
146
      addPoint(dX1, dY1);
147
      for (i = 0; i < coords.length - 1; i++) {
148
         dX1 = coords[i].x;
149
         dY1 = coords[i].y;
150
         dX2 = coords[i + 1].x;
151
         dY2 = coords[i + 1].y;
152
         dDX = dX2 - dX1;
153
         dDY = dY2 - dY1;
154
         dDistToNextPoint = Math.sqrt(dDX * dDX + dDY * dDY);
155
         computeSegmentOrientation(dX1, dY1, dX2, dY2);
156
         if (dRemainingDistFromLastSegment + dDistToNextPoint > m_dDistance) {
157
            iPoints = (int) ((dRemainingDistFromLastSegment + dDistToNextPoint) / m_dDistance);
158
            dDist = m_dDistance - dRemainingDistFromLastSegment;
159
            for (j = 0; j < iPoints; j++) {
160
               dDist = m_dDistance - dRemainingDistFromLastSegment;
161
               dDist += j * m_dDistance;
162
               dAddedPointX = dX1 + dDist * dDX / dDistToNextPoint;
163
               dAddedPointY = dY1 + dDist * dDY / dDistToNextPoint;
164
               addPoint(dAddedPointX, dAddedPointY);
165
            }
166
            dDX = dX2 - dAddedPointX;
167
            dDY = dY2 - dAddedPointY;
168
            dRemainingDistFromLastSegment = Math.sqrt(dDX * dDX + dDY * dDY);
169
         }
170
         else {
171
            dRemainingDistFromLastSegment += dDistToNextPoint;
172
         }
173

    
174
      }
175

    
176
   }
177

    
178

    
179
   private void computeSegmentOrientation(final double x,
180
                                          final double y,
181
                                          final double x2,
182
                                          final double y2) {
183

    
184
      double dx, dy;
185
      double dDistance;
186

    
187
      dx = x2 - x;
188
      dy = y2 - y;
189

    
190
      dDistance = Math.sqrt(dx * dx + dy * dy);
191
      m_dStepX = dy / dDistance * m_dInterval;
192
      m_dStepY = -dx / dDistance * m_dInterval;
193

    
194
   }
195

    
196

    
197
   private void addPoint(final double x,
198
                         final double y) {
199

    
200
      int i;
201
      int iField;
202
      double x2, y2;
203
      double dElevation;
204
      final Object value[] = new Object[m_iPointsInSection * 2 + 1];
205

    
206
      final Coordinate[] coords = new Coordinate[2];
207
      coords[0] = new Coordinate(x + m_iPointsInSection * m_dStepX, y + m_iPointsInSection * m_dStepY);
208
      coords[1] = new Coordinate(x - m_iPointsInSection * m_dStepX, y - m_iPointsInSection * m_dStepY);
209

    
210
      for (i = -m_iPointsInSection, iField = 0; i < m_iPointsInSection + 1; i++, iField++) {
211
         x2 = x - i * m_dStepX;
212
         y2 = y - i * m_dStepY;
213
         dElevation = m_DEM.getValueAt(x2, y2);
214
         value[iField] = new Double(dElevation);
215
      }
216

    
217
      final GeometryFactory gf = new GeometryFactory();
218
      m_Result.addFeature(gf.createLineString(coords), value);
219

    
220

    
221
   }
222

    
223
}