Statistics
| Revision:

root / trunk / libraries / libTopology / src / org / gvsig / jts / RobustLocationIndexedLine.java @ 13591

History | View | Annotate | Download (4.69 KB)

1
/*
2
 * Created on 09-sep-2007
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
*
46
* $Id: RobustLocationIndexedLine.java 13591 2007-09-09 11:44:09Z azabala $
47
* $Log$
48
* Revision 1.1  2007-09-09 11:44:09  azabala
49
* Improvements to JTS (robustness problems)
50
*
51
*
52
*/
53
package org.gvsig.jts;
54

    
55
import com.vividsolutions.jts.geom.Coordinate;
56
import com.vividsolutions.jts.geom.Geometry;
57
import com.vividsolutions.jts.geom.LineSegment;
58
import com.vividsolutions.jts.geom.PrecisionModel;
59
import com.vividsolutions.jts.linearref.LinearIterator;
60
import com.vividsolutions.jts.linearref.LinearLocation;
61
import com.vividsolutions.jts.linearref.LocationIndexedLine;
62

    
63
public class RobustLocationIndexedLine extends LocationIndexedLine {
64

    
65
        
66
        private Geometry linearGeom;
67
        
68
        
69
        public RobustLocationIndexedLine(Geometry arg0) {
70
                super(arg0);
71
                this.linearGeom = arg0;
72
        }
73
        
74
         public LinearLocation indexOf(Coordinate pt)
75
          {
76
            return indexOfFromStart(pt, null);
77
          }
78
         
79
//         These methods are needed because JTS LocationIndexedLine doesnt have an
80
                // indexOfAlter
81
                // method and LocationIndexPoint, which makes all these computations is not
82
                // a public class
83
                // report it to JTS project
84

    
85
                /*
86
                 * M.Davids has said to me that he has added these methods to JTS (1.9
87
                 * version).
88
                 * 
89
                 * TODO REMOVE THESE METHODS WITH JTS 1.9
90
                 */
91

    
92
                public  LinearLocation indexOfAfter(LocationIndexedLine indexedLine, 
93
                                                                                Coordinate inputPt, 
94
                                                                                LinearLocation minIndex) {
95
                        if (minIndex == null)
96
                                return indexedLine.indexOf(inputPt);
97
                        LinearLocation endLoc = LinearLocation.getEndLocation(linearGeom);
98
                        if (endLoc.compareTo(minIndex) <= 0)
99
                                return endLoc;
100

    
101
                        LinearLocation closestAfter = indexOfFromStart(inputPt, minIndex);
102
                        return closestAfter;
103
                }
104

    
105
        
106
        
107
        private LinearLocation indexOfFromStart(Coordinate inputPt, LinearLocation minIndex)
108
          {
109
            double minDistance = Double.MAX_VALUE;
110
            int minComponentIndex = 0;
111
            int minSegmentIndex = 0;
112
            double minFrac = -1.0;
113

    
114
            LineSegment seg = new LineSegment();
115
            for (LinearIterator it = new LinearIterator(linearGeom);
116
                 it.hasNext(); it.next()) {
117
              if (! it.isEndOfLine()) {
118
                seg.p0 = it.getSegmentStart();
119
                seg.p1 = it.getSegmentEnd();
120
                double segDistance = seg.distance(inputPt);
121
                
122
                /*
123
                 * Changes to LocationIndexedLine to avoid robustness problems
124
                 * */
125
                PrecisionModel pm = linearGeom.getPrecisionModel();
126
                segDistance = pm.makePrecise(segDistance);
127
                
128
                double segFrac = segmentFraction(seg, inputPt);
129

    
130
                int candidateComponentIndex = it.getComponentIndex();
131
                int candidateSegmentIndex = it.getVertexIndex();
132
                
133
                
134
                if (segDistance < minDistance) {
135
                  // ensure after minLocation, if any
136
                  if (minIndex == null ||
137
                      minIndex.compareLocationValues(
138
                      candidateComponentIndex, candidateSegmentIndex, segFrac)
139
                      < 0
140
                      ) {
141
                    // otherwise, save this as new minimum
142
                    minComponentIndex = candidateComponentIndex;
143
                    minSegmentIndex = candidateSegmentIndex;
144
                    minFrac = segFrac;
145
                    minDistance = segDistance;
146
                  }
147
                }
148
              }
149
            }
150
            LinearLocation loc = new LinearLocation(minComponentIndex, minSegmentIndex, minFrac);
151
            return loc;
152
          }
153
        
154
        public static double segmentFraction(
155
                      LineSegment seg,
156
                      Coordinate inputPt)
157
                  {
158
                    double segFrac = seg.projectionFactor(inputPt);
159
                    if (segFrac < 0.0)
160
                      segFrac = 0.0;
161
                    else if (segFrac > 1.0)
162
                      segFrac = 1.0;
163
                    return segFrac;
164
                  }
165

    
166
}
167