Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGraph / src / org / gvsig / fmap / algorithm / contouring / ContourCalculator.java @ 39203

History | View | Annotate | Download (6.58 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 * 
21
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2008 Software Colaborativo (www.scolab.es)   development
26
 */
27

    
28
package org.gvsig.fmap.algorithm.contouring;
29

    
30
import java.util.ArrayList;
31
import java.util.Collection;
32
import java.util.List;
33

    
34
import org.gvsig.fmap.algorithm.triangulation.TIN;
35
import org.gvsig.fmap.algorithm.triangulation.Triangle;
36

    
37
import com.vividsolutions.jts.geom.Coordinate;
38
import com.vividsolutions.jts.geom.CoordinateList;
39
import com.vividsolutions.jts.geom.GeometryFactory;
40
import com.vividsolutions.jts.geom.LineSegment;
41
import com.vividsolutions.jts.geom.LineString;
42

    
43
public class ContourCalculator {
44
        private TIN tin;
45
        private Coordinate firstPoint;
46
        private Coordinate lastPoint;
47
        LineSegment lastSegment;
48
        private GeometryFactory geomFactory = new GeometryFactory();
49

    
50
        public ContourCalculator(TIN tin) {
51
                this.tin = tin;
52
        }
53

    
54
        public Collection<LineString> getContour(double height) {
55
                CoordinateList gp = null;
56
                ArrayList<LineString> segmentList = new ArrayList<LineString>();
57
                int iTri = 0;
58
                for (Triangle tri : tin.getTriangles()) {
59
                        try {
60
                                if (tri.containsZ(height)) {
61
                                        Coordinate[] segment = tri.getSegmentZ(height);
62
                                        // Checkeamos coordenadas
63
                                        if (segment[0] == segment[1]) {
64
                                                if (tri.containsZ(height - 0.1))
65
                                                {
66
                                                        segment = tri.getSegmentZ(height - 0.1);
67
                                                }
68
                                                else
69
                                                        continue;
70
                                        }
71
                                        LineString lineString = geomFactory.createLineString(segment);
72
                                        segmentList.add(lineString);
73

    
74
//                                        TriEdge edgeIn = tri.getEdgeContainingZ(height);
75
//                                        if (edgeIn != null) {
76
//                                                gp = new CoordinateList();
77
//                                                firstPoint = edgeIn.getPointOnZ(height);
78
//                                                lastPoint = tri.getNextPoint(firstPoint, height);
79
//                                                gp.add(firstPoint, true);
80
//                                                gp.add(lastPoint, false);
81
//                                        }
82
//                                        if (gp.size() > 1) {
83
//                                                LineString lineString = geomFactory.createLineString(gp.toCoordinateArray());
84
//                                                segmentList.add(lineString);
85
//                                        }
86
//                                        else {
87
//                                                System.out.println("stop!!");
88
//                                        }
89
                                }
90
                        } catch (Exception e) {
91
                                // TODO Auto-generated catch block
92
                                System.out.println("ContourCalculator.getContour(): " + e.getMessage());
93
                        }
94
                        iTri++;
95
                }
96
                return segmentList;
97

    
98
        }
99
        
100
        // TODO:
101
        public Collection<LineString> getContour_Complex_BAD(double height) {
102
                CoordinateList gp = null;
103
                for (Triangle tri : tin.getTriangles()) {
104
                        tri.setVisited(false);
105
                }
106
                firstPoint = null;
107
                ArrayList<LineString> contourList = new ArrayList<LineString>();
108
                for (Triangle tri : tin.getTriangles()) {
109
                        if (tri.isVisited() == false) {
110
                                try {
111
                                        if (tri.containsZ(height)) {
112
                                                TriEdge edgeIn = tri.getEdgeContainingZ(height);
113
                                                if (edgeIn != null) {
114
                                                        if (firstPoint == null) { // initialize contour line
115
                                                                gp = new CoordinateList();
116
                                                                firstPoint = edgeIn.getPointOnZ(height);
117
                                                                lastPoint = tri.getNextPoint(firstPoint, height);
118
                                                                lastSegment = new LineSegment(firstPoint, lastPoint);
119
                                                                gp.add(firstPoint, true);
120
                                                                gp.add(lastPoint, false);
121
                                                        }
122
                                                        boolean bExit = false;
123
                                                        do {
124
                                                                Triangle nextTri = findNeighbourg(tri, lastSegment);
125
                                                                if (nextTri != null) {
126
                                                                        Coordinate auxC = new Coordinate(lastPoint);
127
                                                                        lastPoint = nextTri.getNextPoint(lastPoint, height);
128
                                                                        lastSegment = new LineSegment(auxC, lastPoint);
129
                                                                        gp.add(lastPoint, true);
130
                                                                        double dAux = firstPoint.distance(lastPoint);
131
                                                                        if (dAux < 1e-8) {
132
                                                                                gp.closeRing();
133
                                                                                bExit = true;
134
                                                                        }
135
                                                                        nextTri.setVisited(true);
136
                                                                } else
137
                                                                        bExit = true;
138

    
139
                                                        } while (bExit == false);
140
                                                        if (gp.size() > 2) {
141
                                                                LineString lineString = geomFactory.createLineString(gp.toCoordinateArray());
142
                                                                contourList.add(lineString);
143
                                                        }
144
                                                        firstPoint = null;
145
                                                }
146
                                        }
147
                                } catch (Exception e) {
148
                                        // TODO Auto-generated catch block
149
                                        e.printStackTrace();
150
                                }
151
                                tri.setVisited(true);
152
                        }
153
                }
154
                return contourList;
155

    
156
        }
157

    
158
        /**
159
         * Find the triangle side by side with edgeIn 
160
         * Options: 
161
         * 1.- lastPoint on edge, and we exit by other edge.
162
         * 2.- lastPoint on vertex, and we exit by other edge.
163
         * 3.- lastPoint on vertex, and we exit by other vertex.
164
         * 4.- lastPoint on edge, and we exit by a vertex.
165
         * 
166
         * @param tri
167
         * @param lastSegment
168
         * @return
169
         */
170
        private Triangle findNeighbourg(Triangle tri, LineSegment lastSegment) {
171
                // All neighbourgs:
172
                Coordinate lastPoint = lastSegment.p1;
173
                TriEdge s1 = new TriEdge(tri.getV1(), tri.getV2());
174
                TriEdge s2 = new TriEdge(tri.getV2(), tri.getV3());
175
                TriEdge s3 = new TriEdge(tri.getV3(), tri.getV1());
176
                double d1, d2, d3;
177
                d1 = s1.distance(lastPoint);
178
                d2 = s2.distance(lastPoint);
179
                d3 = s3.distance(lastPoint);
180
                ArrayList<Triangle> aux = new ArrayList<Triangle>();
181
                if (d1 < 1E-8) {
182
                        getEdgeNeighbours(s1, aux);
183
                }
184
                else if (d2 < 1E-8) {
185
                        getEdgeNeighbours(s2, aux);
186
                }
187
                else if (d3 < 1E-8) {
188
                        getEdgeNeighbours(s3, aux);
189
                }
190
                
191
                // We choose a point "a little further on lastSegment"
192
                // and try if it is inside neighbourg triangles
193
                Coordinate pointOut = lastSegment.pointAlong(1.001);
194
                for (Triangle theNextTriangle: aux) {
195
                        if (theNextTriangle == tri) continue; // We avoid to test the original triangle.
196
                        if (theNextTriangle.isVisited()) continue;
197
                        if (theNextTriangle.contains(pointOut))
198
                                return theNextTriangle;
199
                }
200
                return null;
201
        }
202
        
203
        private void getEdgeNeighbours(TriEdge s1, ArrayList<Triangle> aux) {
204
                List<Triangle> l1 = tin.getTrianglesRelatedTo(s1.getV1());
205
                List<Triangle> l2 = tin.getTrianglesRelatedTo(s1.getV2());
206
                aux.addAll(l1);
207
                aux.addAll(l2);
208
        }
209

    
210
}