Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / tin / linearIsolinesFromTin / LinearContourLines.java @ 59

History | View | Annotate | Download (11.4 KB)

1
/**
2
 *    @author              Josef Bezdek, ZCU Plzen
3
 *          @version             1.0
4
 *    @since                 JDK1.5
5
 */
6

    
7
package es.unex.sextante.tin.linearIsolinesFromTin;
8

    
9
import java.util.ArrayList;
10
import java.util.Iterator;
11
import java.util.LinkedList;
12
import java.util.TreeMap;
13

    
14
import com.vividsolutions.jts.geom.Coordinate;
15

    
16
public class LinearContourLines {
17

    
18
   ArrayList finalIsolines = null;
19
   double    elevatedStep;
20
   double    clusterTol;
21
   double    minIso;
22
   double    maxIso;
23
   int       numberOfIsolines;
24
   TreeMap   treeIndex;
25

    
26

    
27
   /******************************************************************************************************************************
28
    * Constructor
29
    * 
30
    * @param equidistance -
31
    *                equidistance between isolines
32
    * @param clusterTol -
33
    *                minimum diference in X,Y coordinates between points where the points are indetical
34
    */
35
   public LinearContourLines(final double equiDistance,
36
                             double clusterTol) {
37
      elevatedStep = equiDistance;
38
      int coeficient = 1;
39
      while (clusterTol < 1) {
40
         coeficient *= 10;
41
         clusterTol *= 10;
42
         //System.out.println(clusterTol);
43
      }
44
      this.clusterTol = coeficient * 10;
45
      finalIsolines = new ArrayList();
46
      treeIndex = new TreeMap<Integer, BinaryTree>();
47
   }
48

    
49

    
50
   /******************************************************************************************************************************
51
    * Private function which generetes izolines from triangle with defined elevated Step
52
    * 
53
    * @param T -
54
    *                triangle
55
    */
56
   private void trianglesIsoLines(final Coordinate[] triangle) {
57
      Double minZ = new Double(0);
58
      Double maxZ = new Double(0);
59
      Coordinate startIZO = null;
60
      Coordinate stopIZO = null;
61
      double elev = Double.NEGATIVE_INFINITY;
62

    
63
      //TEST OF SINGULAR POINTS
64
      if (triangle[0].z / elevatedStep == (int) (triangle[0].z / elevatedStep)) {
65
         triangle[0].z = triangle[0].z + elevatedStep * 0.01;//Float.MIN_VALUE;
66
      }
67
      if (triangle[1].z / elevatedStep == (int) (triangle[1].z / elevatedStep)) {
68
         triangle[1].z = triangle[1].z + elevatedStep * 0.01;//Float.MIN_VALUE;
69
      }
70
      if (triangle[2].z / elevatedStep == (int) (triangle[2].z / elevatedStep)) {
71
         triangle[2].z = triangle[2].z + elevatedStep * 0.01;//Float.MIN_VALUE;
72
      }
73

    
74
      minZ = triangle[0].z;
75
      maxZ = triangle[0].z;
76
      if (minZ > triangle[1].z) {
77
         minZ = triangle[1].z;
78
      }
79
      if (minZ > triangle[2].z) {
80
         minZ = triangle[2].z;
81
      }
82
      if (maxZ < triangle[1].z) {
83
         maxZ = triangle[1].z;
84
      }
85
      if (maxZ < triangle[2].z) {
86
         maxZ = triangle[2].z;
87
      }
88
      if (minZ >= 0) {
89
         elev = ((int) (minZ / elevatedStep + 1)) * elevatedStep;
90
      }
91
      else {
92
         elev = ((int) (minZ / elevatedStep)) * elevatedStep;
93
      }
94

    
95
      if (elev <= minZ) {
96
         elev += elevatedStep;
97
      }
98

    
99
      while (elev < maxZ) {
100
         if (((triangle[0].z < elev) & (triangle[1].z > elev)) || ((triangle[0].z > elev) & (triangle[1].z < elev))) {
101
            startIZO = solveLinearInterpolation(triangle[0], triangle[1], elev);
102
         }
103
         if (((triangle[0].z < elev) & (triangle[2].z > elev)) || ((triangle[0].z > elev) & (triangle[2].z < elev))) {
104
            if (startIZO == null) {
105
               startIZO = solveLinearInterpolation(triangle[0], triangle[2], elev);
106
            }
107
            else {
108
               stopIZO = solveLinearInterpolation(triangle[0], triangle[2], elev);
109
            }
110
         }
111
         if (((triangle[1].z < elev) & (triangle[2].z > elev)) || ((triangle[1].z > elev) & (triangle[2].z < elev))) {
112
            if (startIZO == null) {
113
               startIZO = solveLinearInterpolation(triangle[1], triangle[2], elev);
114
            }
115
            if (stopIZO == null) {
116
               stopIZO = solveLinearInterpolation(triangle[1], triangle[2], elev);
117
            }
118
         }
119

    
120
         startIZO.x = Math.round(startIZO.x * clusterTol) / clusterTol;
121
         startIZO.y = Math.round(startIZO.y * clusterTol) / clusterTol;
122
         stopIZO.x = Math.round(stopIZO.x * clusterTol) / clusterTol;
123
         stopIZO.y = Math.round(stopIZO.y * clusterTol) / clusterTol;
124

    
125
         if (!startIZO.equals2D(stopIZO)) {
126
            sortIsolines(startIZO, stopIZO, elev); //
127
         }
128

    
129
         startIZO = null;
130
         stopIZO = null;
131
         elev += elevatedStep;
132

    
133
      }
134

    
135
   }
136

    
137

    
138
   /******************************************************************************************************************************
139
    * Private function which computes point on line, (Linear interpolation)
140
    * 
141
    * @param A -
142
    *                start point of line
143
    * @param B -
144
    *                end point of line
145
    * @param elev -
146
    *                defined elevation
147
    * @return - coordinate of point with definied elevation
148
    */
149
   private Coordinate solveLinearInterpolation(final Coordinate A,
150
                                               final Coordinate B,
151
                                               final double elev) {
152
      final double koef;
153
      double rate;
154
      if (B.z > A.z) {
155
         rate = (elev - A.z) / (B.z - A.z);
156
         return new Coordinate((A.x + (B.x - A.x) * rate), (A.y + (B.y - A.y) * rate), elev);
157
      }
158
      else {
159
         rate = (elev - B.z) / (A.z - B.z);
160
         return new Coordinate((B.x + (A.x - B.x) * rate), (B.y + (A.y - B.y) * rate), elev);
161
      }
162
   }
163

    
164

    
165
   /******************************************************************************************************************************
166
    * The method for counting isolines from TIN
167
    * 
168
    * @param triangles -
169
    *                array of vertexes of triangles
170
    */
171
   public void countIsolines(final Coordinate[][] triangles) {
172
      for (int i = 0; i < triangles.length; i++) {
173
         trianglesIsoLines(triangles[i]);
174
         triangles[i] = null;
175
      }
176
   }
177

    
178

    
179
   /******************************************************************************************************************************
180
    * The method gets list of isolines
181
    * 
182
    * @return ArrayList of isolines
183
    */
184
   public ArrayList getIsolines() {
185
      return finalIsolines;
186
   }
187

    
188

    
189
   /******************************************************************************************************************************
190
    * The method sorts segment of isoline to LineString
191
    * 
192
    * @param coordA -
193
    *                start vertex of isoline's segment
194
    * @param coordB -
195
    *                stop vertex of isoline's segment
196
    * @param elevation -
197
    *                elevation of isoline's segment
198
    */
199
   private void sortIsolines(final Coordinate coordA,
200
                             final Coordinate coordB,
201
                             final double elevation) {
202
      DVertex izoA = null;
203
      DVertex izoB = null;
204
      int indexA = 0;
205
      int indexB = 0;
206
      BinaryTree tree = null;
207

    
208
      final int elevIndex = new Double((elevation - minIso) / elevatedStep).intValue();
209

    
210
      if (treeIndex.containsKey(elevIndex)) {
211
         tree = (BinaryTree) treeIndex.get(elevIndex);
212
      }
213
      else {
214
         tree = new BinaryTree();
215
         treeIndex.put(elevIndex, tree);
216
      }
217

    
218
      izoA = (DVertex) tree.search(coordA);
219
      izoB = (DVertex) tree.search(coordB);
220

    
221
      if (izoA != null) {
222
         indexA = 1;
223
      }
224
      if (izoB != null) {
225
         indexB = 2;
226
      }
227

    
228
      switch (indexA + indexB) {
229
         case 0: {
230
            final LinkedList izoList = new LinkedList();
231
            izoList.add(coordA);
232
            izoList.add(coordB);
233

    
234
            tree.insert(coordA, new Integer(finalIsolines.size()));
235
            tree.insert(coordB, new Integer(finalIsolines.size()));
236
            finalIsolines.add(finalIsolines.size(), izoList);
237
            break;
238
         }
239
         case 1: {
240
            final LinkedList izoList = (LinkedList) finalIsolines.get(izoA.data);
241
            if (izoList == null) {
242
               break;
243
            }
244
            tree.remove(coordA);
245
            if (((Coordinate) izoList.getFirst()).equals2D(coordA)) {
246
               izoList.addFirst(coordB);
247
               tree.insert(coordB, izoA.data);
248
            }
249
            else {
250

    
251
               izoList.addLast(coordB);
252
               tree.insert(coordB, izoA.data);
253
            }
254
            break;
255
         }
256
         case 2: {
257
            final LinkedList izoList = (LinkedList) finalIsolines.get(izoB.data);
258
            if (izoList == null) {
259
               break;
260
            }
261
            tree.remove(coordB);
262
            if (((Coordinate) izoList.getFirst()).equals2D(coordB)) {
263
               izoList.addFirst(coordA);
264
               tree.insert(coordA, izoB.data);
265

    
266
            }
267
            else {
268
               izoList.addLast(coordA);
269
               tree.insert(coordA, izoB.data);
270
            }
271
            break;
272
         }
273
         case 3: {
274
            final LinkedList izoList = (LinkedList) finalIsolines.get(izoA.data);
275
            if (izoList == null) {
276
               break;
277
            }
278
            if ((izoA.data.intValue() == izoB.data.intValue())) {
279
               tree.remove(coordA);
280
               tree.remove(coordB);
281
               if (((Coordinate) izoList.getFirst()).equals2D(coordA)) {
282
                  izoList.addLast(coordA);
283
               }
284
               else {
285
                  izoList.addFirst(coordA);
286
               }
287
            }
288
            else {
289
               final LinkedList izoListB = (LinkedList) finalIsolines.get(izoB.data);
290
               if (izoListB == null) {
291
                  break;
292
               }
293
               if (((Coordinate) izoList.getFirst()).equals2D(coordA)) {
294
                  if (((Coordinate) izoListB.getFirst()).equals2D(coordB)) {
295
                     final Iterator iterIzoB = izoListB.iterator();
296
                     while (iterIzoB.hasNext()) {
297
                        izoList.addFirst(iterIzoB.next());
298
                     }
299
                  }
300
                  else {
301
                     final Iterator iterIzoB = izoListB.descendingIterator();
302
                     while (iterIzoB.hasNext()) {
303
                        izoList.addFirst(iterIzoB.next());
304
                     }
305
                  }
306
               }
307
               else {
308
                  if (((Coordinate) izoListB.getFirst()).equals2D(coordB)) {
309
                     final Iterator iterIzoB = izoListB.iterator();
310
                     while (iterIzoB.hasNext()) {
311
                        izoList.addLast(iterIzoB.next());
312
                     }
313
                  }
314
                  else {
315
                     final Iterator iterIzoB = izoListB.descendingIterator();
316
                     while (iterIzoB.hasNext()) {
317
                        izoList.addLast(iterIzoB.next());
318
                     }
319
                  }
320

    
321
               }
322
               finalIsolines.set(izoB.data, null);
323
               ((DVertex) tree.search((Coordinate) izoList.getLast())).data = izoA.data;
324
               ((DVertex) tree.search((Coordinate) izoList.getFirst())).data = izoA.data;
325

    
326
            }
327
            tree.remove(coordA);
328
            tree.remove(coordB);
329

    
330
         }
331
      }
332

    
333
   }
334

    
335
}