Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGeoProcessing / src / com / iver / cit / gvsig / geoprocess / impl / dissolve / fmap / AdjacencyDissolveVisitor.java @ 10626

History | View | Annotate | Download (7.06 KB)

1
/*
2
 * Created on 09-may-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: AdjacencyDissolveVisitor.java 10626 2007-03-06 16:55:54Z caballero $
47
 * $Log$
48
 * Revision 1.3  2007-03-06 16:47:58  caballero
49
 * Exceptions
50
 *
51
 * Revision 1.2  2006/07/21 11:06:06  azabala
52
 * fixed bug 604: empty dist field in buffered dissolved features
53
 *
54
 * Revision 1.1  2006/06/20 18:20:45  azabala
55
 * first version in cvs
56
 *
57
 * Revision 1.1  2006/05/24 21:11:14  azabala
58
 * primera version en cvs despues de refactoring orientado a crear un framework extensible de geoprocessing
59
 *
60
 *
61
 */
62
package com.iver.cit.gvsig.geoprocess.impl.dissolve.fmap;
63

    
64
import java.awt.geom.Rectangle2D;
65
import java.util.ArrayList;
66
import java.util.List;
67
import java.util.Stack;
68

    
69
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
70
import com.hardcode.gdbms.engine.data.driver.DriverException;
71
import com.hardcode.gdbms.engine.values.DoubleValue;
72
import com.hardcode.gdbms.engine.values.Value;
73
import com.hardcode.gdbms.engine.values.ValueFactory;
74
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
75
import com.iver.cit.gvsig.exceptions.visitors.ProcessVisitorException;
76
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
77
import com.iver.cit.gvsig.fmap.core.IGeometry;
78
import com.iver.cit.gvsig.geoprocess.core.fmap.FeatureProcessor;
79
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes;
80
import com.vividsolutions.jts.geom.Geometry;
81

    
82
/**
83
 * <p>
84
 * This Visitor generates a dissolve of input layer based in adjacency criteria:
85
 * it dissolves two polygons, if and only if they are adjacent.
86
 * </p>
87
 * TODO: To dissolve buffers from radial rings create a DissolveVisitor
88
 * to compare FROM-TO Fields.
89
 *
90
 * @author azabala
91
 *
92
 */
93
public class AdjacencyDissolveVisitor extends DissolveVisitor {
94

    
95
        /**
96
         * Reference to the buffer distance of the visited buffered feature.
97
         */
98
        private DoubleValue currentBufferDistance = null;
99

    
100
        public AdjacencyDissolveVisitor(String dissolveField,
101
                        FeatureProcessor processor) {
102
                super(dissolveField, processor);
103
        }
104

    
105
        protected boolean verifyIfDissolve(DissolvedFeature f1, DissolvedFeature f2) {
106
                Geometry geo1 = f1.getJtsGeometry();
107
                Geometry geo2 = f2.getJtsGeometry();
108
                return geo1.intersects(geo2);
109
        }
110

    
111
        /**
112
         * Creates a new IFeature with util info for dissolve geoprocess
113
         * (it ignore non numerical values, etc)
114
         *
115
         * @param g
116
         * @param index
117
         * @return
118
         * @throws DriverException
119
         */
120
        protected DissolvedFeature createFeature(IGeometry g, int index) {
121
                DissolvedFeature solution = new DissolvedFeature(g, null, index);
122
                return solution;
123
        }
124

    
125
        /**
126
         * We overwrite this method because we are not interested in save sumarization
127
         * function values with dissolved features.
128
         * Instead, we want to add buffer distance like an attribute of them.
129
         */
130
        public void visit(IGeometry g, int index) throws VisitorException, ProcessVisitorException {
131
                if(g == null)
132
                        return;
133
                if(g.getGeometryType() != XTypes.POLYGON &&
134
                                g.getGeometryType() != XTypes.MULTI)
135
                        return;
136
                if (!dissolvedGeometries.get(index)) {
137
                        try {
138
                                int fieldIndex = recordset.getFieldIndexByName("DIST");
139
                                currentBufferDistance = (DoubleValue) recordset.getFieldValue(index, fieldIndex);
140
                                // if we havent dissolved this feature
141
                                Stack toDissol = new Stack();// stack for adjacent features
142
                                DissolvedFeature feature = createFeature(g, index);
143
                                toDissol.push(feature);
144
                                ArrayList geometries = new ArrayList();
145
                                Value[] values = dissolveGeometries(toDissol, geometries);
146
                                Geometry geometry = union(geometries);
147
                                Value[] valuesWithFID = new Value[values.length + 1];
148
                                System.arraycopy(values, 0, valuesWithFID, 1, values.length);
149
                                valuesWithFID[0] = ValueFactory.createValue(fid);
150
                                DissolvedFeature dissolved = new DissolvedFeature(null,valuesWithFID, fid/*index*/);
151
                                dissolved.setJtsGeometry(geometry);
152
                                this.featureProcessor.processFeature(dissolved);
153
                                fid++;
154
                                resetFunctions();
155
                        } catch (ReadDriverException e) {
156
                                throw new ProcessVisitorException(recordset.getName(),e,
157
                                        "Error al procesar las geometrias a fusionar durante dissolve");
158
                        } catch (ExpansionFileReadException e) {
159
                                throw new ProcessVisitorException(recordset.getName(),e,
160
                                "Error al procesar las geometrias a fusionar durante dissolve");
161
                        } catch (VisitorException e) {
162
                                throw new ProcessVisitorException(recordset.getName(),e,
163
                                "Error al procesar las geometrias a fusionar durante dissolve");
164
                        }
165
                }// if
166
        }
167

    
168
        /**
169
         * We overwrite this method to ignore sumarization values and to
170
         * add buffer distance to the attributes of the result features.
171
         * @throws VisitorException
172
         * @throws ExpansionFileReadException
173
         * @throws ReadDriverException
174
         */
175
        protected Value[] dissolveGeometries(Stack toDissol,
176
                        List geometries) throws
177
                        ReadDriverException, ExpansionFileReadException, VisitorException {
178

    
179
                IndividualGeometryDissolveVisitor visitor = null;
180
                DissolvedFeature feature = null;
181
                while (toDissol.size() != 0) {
182
                        feature = (DissolvedFeature) toDissol.pop();
183
                        // flags this idx (to not to process in future)
184
                        dissolvedGeometries.set(feature.getIndex());
185
                        if (visitor == null) {
186
                                visitor = new IndividualGeometryDissolveVisitor(feature,
187
                                                dissolvedGeometries, toDissol,
188
                                                numericField_sumarizeFunction);
189
                                visitor.setDissolveField(this.dissolveField);
190
                        } else {
191
                                visitor.setProcessedFeature(feature);
192
                        }
193
                        Rectangle2D bounds = feature.getGeometry().getBounds2D();
194
                        double xmin = bounds.getMinX();
195
                        double ymin = bounds.getMinY();
196
                        double xmax = bounds.getMaxX();
197
                        double ymax = bounds.getMaxY();
198
                        double magnify = 15d;
199
                        Rectangle2D query = new Rectangle2D.Double(xmin - magnify, ymin
200
                                        - magnify, (xmax - xmin) + magnify, (ymax - ymin) + magnify);
201

    
202
                        strategy.process(visitor, query);
203
                        //al final de toda la pila de llamadas recursivas,
204
                        //geometries tendr? todas las geometrias que debemos dissolver
205
                        geometries.add(feature.getJtsGeometry());
206
                }// while
207
                Value[] values = new Value[1];
208
                values[0] = currentBufferDistance;
209
                return values;
210
        }
211

    
212

    
213

    
214

    
215

    
216
}