Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / vividsolutions / jts / geomgraph / SnapEdgeIntersectionList.java @ 9178

History | View | Annotate | Download (9.48 KB)

1
/*
2
 * Created on 02-oct-2006
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: SnapEdgeIntersectionList.java 9178 2006-12-04 19:30:23Z azabala $
47
* $Log$
48
* Revision 1.1  2006-12-04 19:30:23  azabala
49
* *** empty log message ***
50
*
51
* Revision 1.1  2006/10/17 18:25:53  azabala
52
* *** empty log message ***
53
*
54
* Revision 1.2  2006/10/09 19:10:56  azabala
55
* First version in CVS
56
*
57
* Revision 1.1  2006/10/05 19:20:57  azabala
58
* first version in cvs
59
*
60
* Revision 1.1  2006/10/02 19:06:39  azabala
61
* *** empty log message ***
62
*
63
*
64
*/
65
package com.vividsolutions.jts.geomgraph;
66

    
67
import java.util.Iterator;
68
import java.util.List;
69
import java.util.TreeMap;
70

    
71
import com.vividsolutions.jts.geom.Coordinate;
72
import com.vividsolutions.jts.geomgraph.DirectedEdgeStar;
73
import com.vividsolutions.jts.geomgraph.Edge;
74
import com.vividsolutions.jts.geomgraph.EdgeEndStar;
75
import com.vividsolutions.jts.geomgraph.EdgeIntersection;
76
import com.vividsolutions.jts.geomgraph.EdgeIntersectionList;
77
import com.vividsolutions.jts.geomgraph.Label;
78
import com.vividsolutions.jts.geomgraph.Node;
79
import com.vividsolutions.jts.geomgraph.NodeFactory;
80

    
81
public class SnapEdgeIntersectionList extends EdgeIntersectionList {
82
                
83
           class SnapEdgeIntersectNode extends Node implements Comparable{
84
                    EdgeIntersection edgeIntersection;
85
                        public SnapEdgeIntersectNode(Coordinate arg0, 
86
                                                                        EdgeEndStar arg1,
87
                                                                        EdgeIntersection edgeIntersection) {
88
                                super(arg0, arg1);
89
                                this.edgeIntersection = edgeIntersection;
90
                        }
91
                        
92
                        //Esto me vale para Nodos a secas, pero para el caso de intersecciones no....
93
                        //porque tienen mas informacion (segmento asociado, etc.)
94
                        //Por ejemplo, primer y ultimo punto de un poligono cerrado no deben ser el 
95
                        //mismo nodo, sino nodos distintos
96
                        
97
                        public boolean equals(Object obj){
98
                                SnapEdgeIntersectNode other = (SnapEdgeIntersectNode) obj;
99
                                return (other.coord.distance(this.coord) 
100
                                                                        <= snapTolerance) &&
101
                                           (other.edgeIntersection.segmentIndex == this.edgeIntersection.segmentIndex) &&
102
                                           ( Math.abs(other.edgeIntersection.dist - this.edgeIntersection.dist) <= snapTolerance);
103
                        }
104
                        public int hashCode() {
105
                          return 1;   //esto no es eficiente 
106
                        }
107
                        
108
                        //Esto es necesario porque a la hora de recorrer
109
                        //las intersecciones de un Edge me interesa
110
                        //que est?n ordenadas en el sentido de los vertices (0,1,2..etc)
111
                        public int compareTo(Object arg0) {
112
                                SnapEdgeIntersectNode other = (SnapEdgeIntersectNode)arg0;
113
                                return this.edgeIntersection.compareTo(other.edgeIntersection);
114
                        }
115
                }//EdgeIntersectionNode
116
                
117
            SnappingNodeMap nodeMap = null;
118
        
119
         // a Map <EdgeIntersection, EdgeIntersection>
120
        //TODO Ver si sustituimos por SnappingNodeMap
121
//          private TreeMap nodeMap = new TreeMap();
122
          SnappingEdge edge;  // the parent edge
123
          
124
          /*
125
           * El codigo de verificacion de snap est? por todas partes.
126
           * Llevar a una clase auxiliar si procede
127
           * */
128
          private double snapTolerance;
129

    
130
          public SnapEdgeIntersectionList(SnappingEdge edge)
131
          {
132
                  super(edge);
133
              this.edge = edge;
134
              this.snapTolerance = edge.getSnapTolerance();
135
              nodeMap = new SnappingNodeMap(new NodeFactory(), snapTolerance){
136
                      public Node addNode(Node n)
137
                      {
138
                            SnapEdgeIntersectNode newNode = (SnapEdgeIntersectNode)n;
139
                        SnapEdgeIntersectNode eNode = (SnapEdgeIntersectNode) 
140
                                super.nodeMap.get(newNode);
141
                        if(eNode != null){
142
                                eNode.mergeLabel(newNode);
143
                                return eNode;
144
                        }else
145
                                super.nodeMap.put(newNode, newNode);
146
                        return newNode;
147
                      }  
148
                      //TODO Esto hay que refinarlo. 
149
                      /*
150
                       * Por un lado quiero la rapidez del HashMap, y la posibilidad
151
                       * de resolver conflictos a partir de equals...
152
                       * 
153
                       * Pero cuando me pidan las intersecciones ordenadas, es 
154
                       * necesario hacerlo seg?n el sentido de los vertices
155
                       * (de mas cercana a mas lejana al vertice 0)
156
                       * 
157
                       * */
158
                      
159
                      public Iterator iterator()
160
                      {
161
                             long t0 = System.currentTimeMillis();
162
                             TreeMap ordered = new TreeMap(nodeMap);
163
                             long t1 = System.currentTimeMillis();
164
//                             System.out.println((t1-t0)+" en crear el Map");
165
                              return ordered.values().iterator();
166
                      }
167
             
168
              };
169
          }
170

    
171
          /**
172
           * Adds an intersection into the list, if it isn't already there.
173
           * The input segmentIndex and dist are expected to be normalized.
174
           * @return the EdgeIntersection found or added
175
           */
176
          public EdgeIntersection add(Coordinate intPt,
177
                                  int segmentIndex, double dist)
178
          {
179
                  EdgeIntersection eiNew = new EdgeIntersection(intPt, 
180
                                                                                            segmentIndex, 
181
                                                                                            dist);
182
                  
183
                  SnapEdgeIntersectNode newNode = new SnapEdgeIntersectNode(intPt,
184
                                 new  DirectedEdgeStar(), eiNew);
185
                  SnapEdgeIntersectNode solution = 
186
                          (SnapEdgeIntersectNode) nodeMap.addNode(newNode);
187
              return solution.edgeIntersection;
188
          }
189

    
190
          /**
191
           * Returns an iterator of {@link EdgeIntersection}s
192
           *
193
           * @return an Iterator of EdgeIntersections
194
           */
195
          public Iterator iterator() { 
196
//                  return nodeMap.values().iterator();
197
                  return nodeMap.iterator();
198
          }
199

    
200
          /**
201
           * Tests if the given point is an edge intersection
202
           *
203
           * @param pt the point to test
204
           * @return true if the point is an intersection
205
           */
206
          public boolean isIntersection(Coordinate pt)
207
          {
208
                  //TODO No seria mejor acudir al NodeMap???
209
            for (Iterator it = iterator(); it.hasNext(); ) {
210
              EdgeIntersection ei = ((SnapEdgeIntersectNode)it.next()).edgeIntersection;
211
              if (ei.coord.distance(pt) <= snapTolerance)
212
               return true;
213
            }
214
            return false;
215
          }
216
          
217
          /**
218
           * Creates new edges for all the edges that the intersections in this
219
           * list split the parent edge into.
220
           * Adds the edges to the input list (this is so a single list
221
           * can be used to accumulate all split edges for a Geometry).
222
           *
223
           * @param edgeList a list of EdgeIntersections
224
           */
225
          public void addSplitEdges(List edgeList)
226
          {
227
            // ensure that the list has entries for the first and last point of the edge
228
            addEndpoints();
229

    
230
            Iterator it = iterator();
231
            // there should always be at least two entries in the list
232
            //es decir, todo Edge tendr? al menos 2 EdgeIntersection...sus nodos
233
            EdgeIntersection eiPrev = ((SnapEdgeIntersectNode) it.next()).edgeIntersection;
234
            
235
            
236
//            UNA DE LAS CLAVES EST? AQUI
237
//            SI TENEMOS COORDENADA-EDGEINTERSECTION-COORDENADA Y EDGEINTERSECTION
238
//            ES UN SNAP DE COORDENADA FINAL, APARECERAN COSAS SPUREAS.
239
            
240
            
241
            
242
            while (it.hasNext()) {
243
              EdgeIntersection ei = ((SnapEdgeIntersectNode)it.next()).edgeIntersection;
244
              Edge newEdge = this.createSplitEdge(eiPrev, ei);
245
              edgeList.add(newEdge);
246

    
247
              eiPrev = ei;
248
            }
249
          }
250
          
251
          public void addEndpoints()
252
          {
253
            int maxSegIndex = edge.getCoordinates().length - 1;
254
            add(edge.getCoordinates()[0], 0, 0.0);
255
            add(edge.getCoordinates()[maxSegIndex], maxSegIndex, 0.0);
256
          }
257

    
258
          /**
259
           * Create a new "split edge" with the section of points between
260
           * (and including) the two intersections.
261
           * The label for the new edge is the same as the label for the parent edge.
262
           */
263
          Edge createSplitEdge(EdgeIntersection ei0, EdgeIntersection ei1)
264
          {
265
//        Debug.print("\ncreateSplitEdge"); Debug.print(ei0); Debug.print(ei1);
266
            int npts = ei1.segmentIndex - ei0.segmentIndex + 2;
267

    
268
            Coordinate lastSegStartPt = this.edge.getCoordinate(ei1.segmentIndex);
269
            // if the last intersection point is not equal to the its segment start pt,
270
            // add it to the points list as well.
271
            
272
            
273
            // (This check is needed because the distance metric is not totally reliable!)
274
            // The check for point equality is 2D only - Z values are ignored
275
           // boolean useIntPt1 = ei1.dist > 0.0 || ! ei1.coord.equals2D(lastSegStartPt);
276
            boolean useIntPt1 = ei1.dist > snapTolerance || ! 
277
                    (ei1.coord.distance(lastSegStartPt) <= snapTolerance);//Con esto se dejaria de usar el segundo punto...pero y el primero??? en el 1er segmento hay que considerarlo
278
            if (! useIntPt1) {
279
              npts--;
280
            }
281
            Coordinate[] pts = new Coordinate[npts];
282
            int ipt = 0;
283
            pts[ipt++] = new Coordinate(ei0.coord);
284
            for (int i = ei0.segmentIndex + 1; i <= ei1.segmentIndex; i++) {
285
              pts[ipt++] = this.edge.getCoordinate(i);
286
            }
287
            if (useIntPt1) pts[ipt] = ei1.coord;
288
            return new SnappingEdge(pts, new Label(this.edge.getLabel()), snapTolerance);
289
          }
290

    
291
}
292