Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / vectorTools / generateRoutes / GenerateRoutesAlgorithm.java @ 59

History | View | Annotate | Download (8.06 KB)

1
package es.unex.sextante.vectorTools.generateRoutes;
2

    
3
import java.util.ArrayList;
4
import java.util.Collections;
5

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

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

    
21
public class GenerateRoutesAlgorithm
22
         extends
23
            GeoAlgorithm {
24

    
25
   public static final String ROUTE        = "ROUTE";
26
   public static final String NROUTES      = "NROUTES";
27
   public static final String METHOD       = "METHOD";
28
   public static final String SINUOSITY    = "SINUOSITY";
29
   public static final String USESINUOSITY = "USESINUOSITY";
30
   public static final String RESULT       = "RESULT";
31

    
32
   private IVectorLayer       m_Routes;
33
   private ArrayList          m_X;
34
   private ArrayList          m_Y;
35
   private int                m_iNewRoutes;
36
   private double             m_dInitX;
37
   private double             m_dInitY;
38
   private double             m_dSinuosity;
39
   private double             m_dFinalX;
40
   private double             m_dFinalY;
41

    
42

    
43
   @Override
44
   public void defineCharacteristics() {
45

    
46
      setName(Sextante.getText("Generate_alternative_routes"));
47
      setGroup(Sextante.getText("Cost_distances_and_routes"));
48
      setUserCanDefineAnalysisExtent(false);
49

    
50
      try {
51
         m_Parameters.addInputVectorLayer(ROUTE, Sextante.getText("Original_route"), AdditionalInfoVectorLayer.SHAPE_TYPE_LINE,
52
                  true);
53
         m_Parameters.addNumericalValue(NROUTES, Sextante.getText("Number_of_new_routes"),
54
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_INTEGER, 10, 1, Integer.MAX_VALUE);
55
         m_Parameters.addSelection(METHOD, Sextante.getText("Method"), new String[] {
56
                  Sextante.getText("Constrained_brownian_motion"), Sextante.getText("Recombination") });
57
         m_Parameters.addNumericalValue(SINUOSITY, Sextante.getText("Sinuosity"),
58
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE, 1.3, 1, 10.);
59
         m_Parameters.addBoolean(USESINUOSITY, Sextante.getText("Use_base_route_sinuosity"), false);
60
         addOutputVectorLayer(RESULT, Sextante.getText("Routes"), OutputVectorLayer.SHAPE_TYPE_LINE);
61
      }
62
      catch (final RepeatedParameterNameException e) {
63
         Sextante.addErrorToLog(e);
64
      }
65

    
66
   }
67

    
68

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

    
72
      double x, y;
73
      double dDifX, dDifY;
74
      double dRouteDist = 0, dStraightDist;
75

    
76
      final IVectorLayer lines = m_Parameters.getParameterValueAsVectorLayer(ROUTE);
77
      m_iNewRoutes = m_Parameters.getParameterValueAsInt(NROUTES);
78
      final int iMethod = m_Parameters.getParameterValueAsInt(METHOD);
79
      final boolean bUseRouteSinuosity = m_Parameters.getParameterValueAsBoolean(USESINUOSITY);
80
      m_dSinuosity = m_Parameters.getParameterValueAsDouble(SINUOSITY);
81

    
82
      final int iShapeCount = lines.getShapesCount();
83

    
84
      if (iShapeCount == 0) {
85
         throw new GeoAlgorithmExecutionException("zero lines in layer");
86
      }
87

    
88
      m_Routes = getNewVectorLayer(RESULT, Sextante.getText("Alternative_routes"), IVectorLayer.SHAPE_TYPE_LINE,
89
               new Class[] { Integer.class }, new String[] { "ID" });
90

    
91
      final IFeatureIterator iter = lines.iterator();
92
      final IFeature feature = iter.next();
93
      final Geometry geom = feature.getGeometry();
94
      final Geometry line = geom.getGeometryN(0);
95
      final Coordinate[] coords = line.getCoordinates();
96

    
97
      m_X = new ArrayList();
98
      m_Y = new ArrayList();
99

    
100
      m_dInitX = x = coords[0].x;
101
      m_dInitY = y = coords[0].y;
102

    
103
      for (int i = 1; i < coords.length; i++) {
104
         dDifX = coords[i].x - x;
105
         dDifY = coords[i].y - y;
106
         dRouteDist += Math.sqrt(dDifX * dDifX + dDifY * dDifY);
107
         m_X.add(new Double(dDifX));
108
         m_Y.add(new Double(dDifY));
109
         x = coords[i].x;
110
         y = coords[i].y;
111
      }
112

    
113
      m_dFinalX = x;
114
      m_dFinalY = y;
115

    
116
      dStraightDist = Math.sqrt(Math.pow(m_dFinalX - m_dInitX, 2) + Math.pow(m_dFinalY - m_dInitY, 2));
117
      if (bUseRouteSinuosity) {
118
         m_dSinuosity = dRouteDist / dStraightDist;
119
      }
120

    
121
      if (iMethod == 0) {
122
         generateRoutesBrownian();
123
      }
124
      else {
125
         generateRoutesRecombine();
126
      }
127

    
128
      return !m_Task.isCanceled();
129

    
130
   }
131

    
132

    
133
   private void generateRoutesRecombine() {
134

    
135
      final Object value[] = new Object[1];
136
      double dLastX, dLastY;
137
      double dX, dY;
138

    
139
      for (int i = 0; (i < m_iNewRoutes) && setProgress(i, m_iNewRoutes); i++) {
140
         Collections.shuffle(m_X);
141
         Collections.shuffle(m_Y);
142
         final Coordinate coords[] = new Coordinate[m_X.size() + 1];
143
         dLastX = m_dInitX;
144
         dLastY = m_dInitY;
145
         coords[0] = new Coordinate(m_dInitX, m_dInitY);
146
         for (int j = 0; j < m_X.size(); j++) {
147
            dX = dLastX + ((Double) m_X.get(j)).doubleValue();
148
            dY = dLastY + ((Double) m_Y.get(j)).doubleValue();
149
            coords[j + 1] = new Coordinate(dX, dY);
150
            dLastX = dX;
151
            dLastY = dY;
152
         }
153
         value[0] = new Integer(i);
154
         final GeometryFactory gf = new GeometryFactory();
155
         final Geometry geom = gf.createLineString(coords);
156
         m_Routes.addFeature(geom, value);
157
      }
158

    
159
   }
160

    
161

    
162
   private void generateRoutesBrownian() {
163

    
164
      int i;
165
      int iIter;
166
      final int SEGMENTS = 50;
167
      double dMaxDist, dMaxSegmentDist;
168
      double dPreviousDist = 0;
169
      double dDist;
170
      double dAngle;
171
      double dX, dY;
172
      double dLastX, dLastY;
173
      final double dTotalXDif = m_dFinalX - m_dInitX;
174
      final double dTotalYDif = m_dFinalY - m_dInitY;
175
      final double dTotalDist = Math.sqrt(dTotalXDif * dTotalXDif + dTotalYDif * dTotalYDif) * m_dSinuosity;
176
      final Object value[] = new Object[1];
177

    
178
      for (int iRoute = 0; (iRoute < m_iNewRoutes) && setProgress(iRoute, m_iNewRoutes); iRoute++) {
179
         final Coordinate coords[] = new Coordinate[SEGMENTS + 1];
180
         coords[0] = new Coordinate(m_dInitX, m_dInitY);
181
         dLastX = m_dInitX;
182
         dLastY = m_dInitY;
183
         dPreviousDist = 0;
184

    
185
         for (i = 1; i < SEGMENTS; i++) {
186
            dMaxDist = (dTotalDist - dPreviousDist);
187
            dMaxSegmentDist = dMaxDist / (SEGMENTS - i);
188
            dMaxDist /= (m_dSinuosity);
189
            iIter = 0;
190
            do {
191
               dDist = Math.random() * dMaxSegmentDist;
192
               dAngle = Math.random() * Math.PI * 2;
193
               dX = dLastX + dDist * Math.cos(dAngle);
194
               dY = dLastY + dDist * Math.sin(dAngle);
195
               dDist = Math.sqrt(Math.pow(m_dFinalX - dX, 2) + Math.pow(m_dFinalY - dY, 2));
196
               iIter++;
197
            }
198
            while ((dDist > dMaxDist) && (iIter < 1000));
199
            if (iIter == 1000) {
200
               dX = dLastX + (m_dFinalX - dLastX) * (dMaxSegmentDist / dMaxDist);
201
               dY = dLastY + (m_dFinalY - dLastY) * (dMaxSegmentDist / dMaxDist);
202
            }
203
            dPreviousDist += Math.sqrt(Math.pow(dLastX - dX, 2) + Math.pow(dLastY - dY, 2));
204
            coords[i] = new Coordinate(dX, dY);
205
            dLastX = dX;
206
            dLastY = dY;
207
         }
208
         coords[i] = new Coordinate(m_dFinalX, m_dFinalY);
209
         value[0] = new Integer(iRoute);
210
         final GeometryFactory gf = new GeometryFactory();
211
         final Geometry geom = gf.createLineString(coords);
212
         m_Routes.addFeature(geom, value);
213
      }
214
   }
215

    
216

    
217
}