Statistics
| Revision:

root / trunk / libraries / libTopology / src / org / gvsig / jts / voronoi / Voronoier.java @ 21244

History | View | Annotate | Download (7.35 KB)

1
/*
2
 * Created on 10-abr-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: 
47
 * $Log: 
48
 */
49
package org.gvsig.jts.voronoi;
50

    
51
import java.util.ArrayList;
52
import java.util.Collection;
53
import java.util.HashMap;
54
import java.util.Iterator;
55
import java.util.List;
56
import java.util.Map;
57

    
58
import org.gvsig.exceptions.BaseException;
59
import org.gvsig.jts.JtsUtil;
60
import org.gvsig.topology.Messages;
61

    
62
import com.iver.cit.gvsig.fmap.core.IFeature;
63
import com.iver.utiles.swing.threads.CancellableProgressTask;
64
import com.vividsolutions.jts.geom.Coordinate;
65
import com.vividsolutions.jts.geom.Envelope;
66
import com.vividsolutions.jts.geom.Geometry;
67
import com.vividsolutions.jts.geom.GeometryFactory;
68
import com.vividsolutions.jts.geom.LinearRing;
69
import com.vividsolutions.jts.operation.polygonize.Polygonizer;
70

    
71
/**
72
 * Computes voronois diagrams from a mess of points.
73
 * 
74
 * 
75
 * @author Alvaro Zabala
76
 * 
77
 */
78
public class Voronoier {
79
        
80
        public interface VoronoiStrategy {
81
                public List<IFeature> createThiessenPolygons(VoronoiAndTinInputLyr inputLyr, boolean onlySelection, CancellableProgressTask progressMonitor) throws BaseException;
82
                public List<IFeature> createThiessenPolygons(VoronoiAndTinInputLyr inputLyr, boolean onlySelection) throws BaseException;
83
                public List<IFeature> createTin(VoronoiAndTinInputLyr inputLyr, boolean onlySelection) throws BaseException;
84
                public List<IFeature> createTin(VoronoiAndTinInputLyr inputLyr, boolean onlySelection, CancellableProgressTask progressMonitor) throws BaseException;
85
        }
86
        
87
        private static final Map<String, VoronoiStrategy> strategies =
88
                new HashMap<String, VoronoiStrategy>();
89
        static{
90
                strategies.put("CHEN", new ChenVoronoiStrategy());
91
                strategies.put("CHEW", new ChewVoronoiStrategy());
92
                strategies.put("DT", new IncrementalTinVoronoiStrategy());
93
        }
94
        
95
        public static List<IFeature> createThiessen(VoronoiAndTinInputLyr inputLyr, boolean onlySelection, String strategyStr, CancellableProgressTask progressMonitor) throws BaseException{
96
                VoronoiStrategy strategy = strategies.get(strategyStr);
97
                return strategy.createThiessenPolygons(inputLyr, onlySelection, progressMonitor);
98
        }
99
        
100
        public static List<IFeature> createThiessen(VoronoiAndTinInputLyr inputLyr, boolean onlySelection, String strategy) throws BaseException{
101
                return createThiessen(inputLyr, onlySelection, strategy, null);
102
        }
103
        
104
        public static List<IFeature> createTIN(VoronoiAndTinInputLyr inputLyr, boolean onlySelection, String strategy) throws BaseException{
105
                return createTIN(inputLyr, onlySelection, strategy, null);
106
        }
107
        
108
        public static List<IFeature> createTIN(VoronoiAndTinInputLyr inputLyr, boolean onlySelection, String strategyStr, CancellableProgressTask progressMonitor) throws BaseException{
109
                VoronoiStrategy strategy = strategies.get(strategyStr);
110
                return strategy.createTin(inputLyr, onlySelection, progressMonitor);
111
        }
112
        
113
        /**
114
         * Returns thiessen polygons associated to a tin
115
         * 
116
         * (tin and thiessen polygons are a dual)
117
         * @param edges
118
         * @param progressMonitor
119
         * @return
120
         */
121
        
122
        //TODO 
123
        /*
124
         * Para facilitar la reusabilidad, pasar un ThiessenVisitor como parametro, y hacerlo 
125
         * void. As? podemos devolver List<Geometry> o List<IGeometry> o List<IFeature>
126
         */
127
        public static List<Geometry> getThiessenPolygons(List<Geometry> edges, 
128
                                                                                CancellableProgressTask progressMonitor){
129
                // -- do union of all edges and use the polygonizer to create polygons
130
                // from it
131
                Geometry lines = null;
132
                Geometry mls = (Geometry) edges.get(0);
133

    
134
                if (progressMonitor != null) {
135
                        progressMonitor.setInitialStep(0);
136
                        int numOfSteps = edges.size();
137
                        progressMonitor.setFinalStep(numOfSteps);
138
                        progressMonitor.setDeterminatedProcess(true);
139
                        progressMonitor.setNote(Messages
140
                                        .getText("topology_clean_of_thiessen_edges"));
141
                        progressMonitor.setStatusMessage(Messages
142
                                        .getText("voronoi_diagram_layer_message"));
143
                        progressMonitor.reportStep();
144
                }
145

    
146
                for (int i = 1; i < edges.size(); i++) {
147
                        Geometry line = (Geometry) edges.get(i);
148
                        mls = mls.union(line);
149
                        if (progressMonitor != null)
150
                                progressMonitor.reportStep();
151
                }
152

    
153
                lines = mls;
154

    
155
        
156
                Polygonizer poly = new Polygonizer();
157
                poly.add(lines);
158
                
159
                Collection polys = poly.getPolygons();
160
                
161
                // -- get final polygons in bounding box (=intersection polygons with
162
                // the bbox)
163
                Envelope envelope = JtsUtil.getBoundingBox(edges);
164
                GeometryFactory gf = JtsUtil.GEOMETRY_FACTORY;
165
                
166
                double xmin = envelope.getMinX();
167
                double ymin = envelope.getMinY();
168
                
169
                double dx = envelope.getWidth();
170
                double dy = envelope.getHeight();
171
                
172
                xmin = xmin - (1.5 * dx);
173
                ymin = ymin - dy;
174
        
175
                Coordinate[] coords = new Coordinate[5];
176
                coords[0] = new Coordinate(xmin + 1 * dx,
177
                                                                        ymin + 0.5 * dy); // lowerleft
178
                
179
                coords[1] = new Coordinate(xmin + 3 * dx,
180
                                                   ymin + 0.5 * dy); // lowerright
181
                
182
                coords[2] = new Coordinate(xmin + 3 * dx,
183
                                                                        ymin + 2.5 * dy); // topright
184
                
185
                coords[3] = new Coordinate(xmin + 1 * dx,
186
                                                                        ymin + 2.5 * dy); // topleft
187
                
188
                // -- to close linestring
189
                coords[4] = new Coordinate(xmin + 1 * dx,
190
                                                                ymin + 0.5 * dy); // lowerleft
191
                LinearRing lr = gf.createLinearRing(coords);
192
                Geometry bbox = gf.createPolygon(lr, null);
193
                
194
                
195

    
196
                if (progressMonitor != null) {
197
                        progressMonitor.setInitialStep(0);
198
                        int numOfSteps = polys.size();
199
                        progressMonitor.setFinalStep(numOfSteps);
200
                        progressMonitor.setDeterminatedProcess(true);
201
                        progressMonitor.setNote(Messages
202
                                        .getText("computing_thiessen_polygons"));
203
                        progressMonitor.setStatusMessage(Messages
204
                                        .getText("voronoi_diagram_layer_message"));
205
                }
206

    
207
                ArrayList<Geometry> finalPolys = new ArrayList<Geometry>();
208
                for (Iterator iter = polys.iterator(); iter.hasNext();) {
209
                        Geometry candPoly = (Geometry) iter.next();
210
                        Geometry intersection = bbox.intersection(candPoly);
211
                        if (progressMonitor != null)
212
                                progressMonitor.reportStep();
213
                        if (intersection != null) {
214
                                if (intersection.getArea() > 0) {
215
                                        finalPolys.add(intersection);
216
                                }
217
                        }
218
                }
219
                if (progressMonitor != null)
220
                        progressMonitor.reportStep();
221
                return finalPolys;
222
        }
223
}