Revision 41160 trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.impl/src/main/java/org/gvsig/fmap/geom/primitive/impl/Surface2D.java

View differences:

Surface2D.java
24 24
package org.gvsig.fmap.geom.primitive.impl;
25 25

  
26 26
import java.awt.geom.Rectangle2D;
27
import java.util.ArrayList;
28
import java.util.List;
27 29

  
30
import com.vividsolutions.jts.geom.GeometryFactory;
31
import com.vividsolutions.jts.geom.LineString;
32
import com.vividsolutions.jts.geom.LinearRing;
33
import com.vividsolutions.jts.geom.MultiPolygon;
34
import com.vividsolutions.jts.geom.Polygon;
35
import com.vividsolutions.jts.geom.PrecisionModel;
36
import com.vividsolutions.jts.geom.TopologyException;
37
import com.vividsolutions.jts.precision.GeometryPrecisionReducer;
38

  
28 39
import org.cresques.cts.IProjection;
29 40

  
30 41
import org.gvsig.fmap.geom.Geometry;
42
import org.gvsig.fmap.geom.exception.CreateGeometryException;
43
import org.gvsig.fmap.geom.operation.GeometryOperationException;
44
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
31 45
import org.gvsig.fmap.geom.primitive.FShape;
32 46
import org.gvsig.fmap.geom.primitive.GeneralPathX;
33 47
import org.gvsig.fmap.geom.primitive.Surface;
34 48
import org.gvsig.fmap.geom.primitive.SurfaceAppearance;
35 49
import org.gvsig.fmap.geom.type.GeometryType;
50
import org.gvsig.fmap.geom.util.Converter;
36 51

  
37 52
/**
38 53
 * Pol�gono 2D.
......
97 112
		// TODO Auto-generated method stub
98 113
		
99 114
	}
115
	
116
    public Geometry union(Geometry other)
117
        throws GeometryOperationNotSupportedException,
118
        GeometryOperationException {
119

  
120
        com.vividsolutions.jts.geom.Geometry this_jts, other_jts, union_jts;
121
        Geometry resp = null;
122

  
123
        try {
124
            this_jts = getJTS();
125
            other_jts = Converter.geometryToJts(other);
126
            union_jts = this_jts.union(other_jts);
127
            if (union_jts instanceof Polygon) {
128
                double tole = union_jts.getArea();
129
                tole = tole * 1e-12;
130
                union_jts = removeInvalidHoles((Polygon) union_jts, tole);
131
            } else {
132
                if (union_jts instanceof MultiPolygon) {
133
                    double tole = union_jts.getArea();
134
                    tole = tole * 1e-12;
135
                    union_jts =
136
                        removeInvalidHoles((MultiPolygon) union_jts, tole);
137
                }
138
            }
139
            resp = Converter.jtsToGeometry(union_jts);
140
            return resp;
141
        } catch (CreateGeometryException e) {
142
            throw new GeometryOperationException(e);
143
        } catch (TopologyException e) {
144
            /*
145
             * If JTS throws this, we'll try to simplify them
146
             */
147
            try {
148
                this_jts = getJTS();
149
                other_jts = Converter.geometryToJts(other);
150

  
151
                PrecisionModel pm = new PrecisionModel(1000000);
152
                GeometryPrecisionReducer gpr = new GeometryPrecisionReducer(pm);
153
                this_jts = gpr.reduce(this_jts);
154
                other_jts = gpr.reduce(other_jts);
155
                union_jts = this_jts.union(other_jts);
156

  
157
                if (union_jts instanceof Polygon) {
158
                    double tole = union_jts.getArea();
159
                    tole = tole * 1e-12;
160
                    union_jts = removeInvalidHoles((Polygon) union_jts, tole);
161
                } else {
162
                    if (union_jts instanceof MultiPolygon) {
163
                        double tole = union_jts.getArea();
164
                        tole = tole * 1e-12;
165
                        union_jts =
166
                            removeInvalidHoles((MultiPolygon) union_jts, tole);
167
                    }
168
                }
169

  
170
                resp = Converter.jtsToGeometry(union_jts);
171
                return resp;
172
            } catch (Exception exc) {
173
                throw new GeometryOperationException(exc);
174
            }
175
        }
176
    }
177
    
178
    
179
    private com.vividsolutions.jts.geom.Geometry getJTS() {
180
        return Converter.geometryToJts(this);
181
    }
182
    
183
    private MultiPolygon removeInvalidHoles(MultiPolygon mpo, double tol) {
184

  
185
        GeometryFactory gf = new GeometryFactory(mpo.getPrecisionModel());
186
        
187
        int npo = mpo.getNumGeometries();
188
        Polygon[] pos = new Polygon[npo];
189
        for (int i=0; i<npo; i++) {
190
            pos[i] = removeInvalidHoles((Polygon) mpo.getGeometryN(i), tol);
191
        }
192
        return gf.createMultiPolygon(pos);
193
    }
194
    
195
    private Polygon removeInvalidHoles(Polygon po, double tol) {
196
        
197
        GeometryFactory gf = new GeometryFactory(po.getPrecisionModel());
198
        
199
        int nholes = po.getNumInteriorRing();
200
        List validholes = new ArrayList();
201
        for (int i=0; i<nholes; i++) {
202
            LineString ls = po.getInteriorRingN(i);
203
            LinearRing lr = toLinearRing(ls, gf);
204
            if (getLinearRingArea(lr, gf) > tol) {
205
                validholes.add(lr);
206
            }
207
            
208
        }
209
        
210
        if (validholes.size() < nholes) {
211
            
212
            LinearRing[] holes = (LinearRing[]) validholes.toArray(new LinearRing[0]);
213
            return gf.createPolygon(
214
                toLinearRing(po.getExteriorRing(), gf), holes);
215
        } else {
216
            return po;
217
        }
218
        
219
    }
220

  
221
    private double getLinearRingArea(LinearRing lr, GeometryFactory gf) {
222
        Polygon po = gf.createPolygon(lr);
223
        double resp = po.getArea(); 
224
        return resp;
225
    }
226

  
227
    private LinearRing toLinearRing(LineString ls, GeometryFactory gf) {
228
        return gf.createLinearRing(ls.getCoordinateSequence());
229
    }
230
    
231
    
232
    
233
	
100 234
}

Also available in: Unified diff