Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / vividsolutions / jts / geomgraph / SnapEdgeIntersectionList.java @ 10627

History | View | Annotate | Download (9.13 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 10627 2007-03-06 17:10:21Z caballero $
47
* $Log$
48
* Revision 1.2  2007-03-06 17:08:55  caballero
49
* Exceptions
50
*
51
* Revision 1.1  2006/12/04 19:30:23  azabala
52
* *** empty log message ***
53
*
54
* Revision 1.1  2006/10/17 18:25:53  azabala
55
* *** empty log message ***
56
*
57
* Revision 1.2  2006/10/09 19:10:56  azabala
58
* First version in CVS
59
*
60
* Revision 1.1  2006/10/05 19:20:57  azabala
61
* first version in cvs
62
*
63
* Revision 1.1  2006/10/02 19:06:39  azabala
64
* *** empty log message ***
65
*
66
*
67
*/
68
package com.vividsolutions.jts.geomgraph;
69

    
70
import java.util.Iterator;
71
import java.util.List;
72
import java.util.TreeMap;
73

    
74
import com.vividsolutions.jts.geom.Coordinate;
75

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

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

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

    
185
          /**
186
           * Returns an iterator of {@link EdgeIntersection}s
187
           *
188
           * @return an Iterator of EdgeIntersections
189
           */
190
          public Iterator iterator() { 
191
//                  return nodeMap.values().iterator();
192
                  return nodeMap.iterator();
193
          }
194

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

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

    
242
              eiPrev = ei;
243
            }
244
          }
245
          
246
          public void addEndpoints()
247
          {
248
            int maxSegIndex = edge.getCoordinates().length - 1;
249
            add(edge.getCoordinates()[0], 0, 0.0);
250
            add(edge.getCoordinates()[maxSegIndex], maxSegIndex, 0.0);
251
          }
252

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

    
263
            Coordinate lastSegStartPt = this.edge.getCoordinate(ei1.segmentIndex);
264
            // if the last intersection point is not equal to the its segment start pt,
265
            // add it to the points list as well.
266
            
267
            
268
            // (This check is needed because the distance metric is not totally reliable!)
269
            // The check for point equality is 2D only - Z values are ignored
270
           // boolean useIntPt1 = ei1.dist > 0.0 || ! ei1.coord.equals2D(lastSegStartPt);
271
            boolean useIntPt1 = ei1.dist > snapTolerance || ! 
272
                    (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
273
            if (! useIntPt1) {
274
              npts--;
275
            }
276
            Coordinate[] pts = new Coordinate[npts];
277
            int ipt = 0;
278
            pts[ipt++] = new Coordinate(ei0.coord);
279
            for (int i = ei0.segmentIndex + 1; i <= ei1.segmentIndex; i++) {
280
              pts[ipt++] = this.edge.getCoordinate(i);
281
            }
282
            if (useIntPt1) pts[ipt] = ei1.coord;
283
            return new SnappingEdge(pts, new Label(this.edge.getLabel()), snapTolerance);
284
          }
285

    
286
}
287