Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / topology / geomgraph / SnappingNodeMap.java @ 7591

History | View | Annotate | Download (3.68 KB)

1
/*
2
 * Created on 11-sep-2006 by azabala
3
 *
4
 */
5
package com.iver.cit.gvsig.fmap.topology.geomgraph;
6

    
7
import java.util.ArrayList;
8
import java.util.Collection;
9
import java.util.Collections;
10
import java.util.Comparator;
11
import java.util.Iterator;
12
import java.util.List;
13

    
14
import com.vividsolutions.jts.geom.Coordinate;
15
import com.vividsolutions.jts.geom.Envelope;
16
import com.vividsolutions.jts.geom.Location;
17
import com.vividsolutions.jts.geomgraph.EdgeEnd;
18
import com.vividsolutions.jts.geomgraph.Node;
19
import com.vividsolutions.jts.geomgraph.NodeFactory;
20
import com.vividsolutions.jts.geomgraph.NodeMap;
21
import com.vividsolutions.jts.index.quadtree.Quadtree;
22

    
23
/**
24
 * Repository of nodes of a PlanarGraph that applies a snap 
25
 * tolerance.
26
 * 
27
 * If we ask for a node, and it founds a node in the tolerance distance
28
 * it returns the found node.
29
 * 
30
 * 
31
 * 
32
 * @author alzabord
33
 */
34
public class SnappingNodeMap extends NodeMap {
35

    
36
        
37
        private Quadtree spatialIndex;
38
        private double snapTolerance;
39
        private NodeFactory nodeFact;
40
        
41
        
42
        public SnappingNodeMap(NodeFactory arg0, double snapTolerance) {
43
                super(arg0);
44
                this.snapTolerance = snapTolerance;
45
                spatialIndex = new Quadtree();
46
        }
47
        
48
        class MinDistCoordComparator implements Comparator{
49
                Coordinate coord;
50
                
51
                 MinDistCoordComparator(Coordinate coord){
52
                        this.coord = coord;
53
                }
54
                
55
                
56
                public int compare(Object arg0, Object arg1) {
57
                        Coordinate c1 = (Coordinate) arg0;
58
                        Coordinate c2 = (Coordinate) arg1;
59
                        
60
                        double d1 = c1.distance(coord);
61
                        double d2 = c2.distance(coord);
62
                        
63
                        if (d1 < d2) return 1;
64
                        if (d1 > d2) return -1;
65
                        else return 0;
66
                }
67
        }
68
        
69
        
70
        private Envelope getQueryRect(Coordinate coord){
71
                double xmin = coord.x - snapTolerance;
72
                  double ymin = coord.x + snapTolerance;
73
                  double xmax = coord.y - snapTolerance;
74
                  double ymax = coord.y + snapTolerance;
75
                  Envelope queryRect = new Envelope(xmin, xmax, ymin, ymax);
76
                  return queryRect;
77
        }
78
        
79
         
80
        
81
          public Node addNode(final Coordinate coord)
82
          {
83
                  Envelope queryRect = getQueryRect(coord);
84
                  List nodes = spatialIndex.query(getQueryRect(coord));
85
                  Collections.sort(nodes, new MinDistCoordComparator(coord));          
86
                  Node candidate = (Node) nodes.get(0);
87
                  if(candidate == null)
88
                  {
89
              candidate = nodeFact.createNode(coord);
90
              this.spatialIndex.insert(queryRect, candidate);
91
            }
92
                  return candidate;  
93
          }
94
          
95
          
96
//FIXME: REVISAR SI HABR?A QUE HACER UN MERGE LABEL ARRIBA O AQU?
97
          public Node addNode(Node n)
98
          {
99
                  
100
            Node node = addNode(n.getCoordinate());
101
            node.mergeLabel(n);
102
            return node;
103
          }
104

    
105
          
106
          
107
          /**
108
           * Adds a node for the start point of this EdgeEnd
109
           * (if one does not already exist in this map).
110
           * Adds the EdgeEnd to the (possibly new) node.
111
           */
112
          public void add(EdgeEnd e)
113
          {
114
            Coordinate p = e.getCoordinate();
115
            Node n = addNode(p);
116
            n.add(e);
117
          }
118
          
119
          
120
          
121
          /**
122
           * @return the node if found; null otherwise
123
           */
124
          public Node find(Coordinate coord)  { 
125
                Envelope queryRect = getQueryRect(coord);
126
                  List nodes = spatialIndex.query(getQueryRect(coord));
127
                  Collections.sort(nodes, new MinDistCoordComparator(coord));          
128
                  Node candidate = (Node) nodes.get(0);
129
                  return candidate;  
130
          }
131

    
132
          
133
          
134
          public Iterator iterator()
135
          {
136
            return spatialIndex.queryAll().iterator();
137
          }
138
          
139
          
140
          public Collection values()
141
          {
142
            return spatialIndex.queryAll();
143
          }
144
          
145

    
146
          
147
          public Collection getBoundaryNodes(int geomIndex)
148
          {
149
            Collection bdyNodes = new ArrayList();
150
            for (Iterator i = iterator(); i.hasNext(); ) {
151
              Node node = (Node) i.next();
152
              if (node.getLabel().getLocation(geomIndex) == Location.BOUNDARY)
153
                bdyNodes.add(node);
154
            }
155
            return bdyNodes;
156
          }
157
          
158

    
159
          
160
        
161

    
162
}