Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / vectorTools / union / UnionAlgorithm.java @ 87

History | View | Annotate | Download (9.12 KB)

1

    
2

    
3
package es.unex.sextante.vectorTools.union;
4

    
5
import com.vividsolutions.jts.geom.Geometry;
6
import com.vividsolutions.jts.geom.GeometryCollection;
7
import com.vividsolutions.jts.geom.GeometryFactory;
8

    
9
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer;
10
import es.unex.sextante.core.GeoAlgorithm;
11
import es.unex.sextante.core.Sextante;
12
import es.unex.sextante.dataObjects.IFeature;
13
import es.unex.sextante.dataObjects.IFeatureIterator;
14
import es.unex.sextante.dataObjects.IVectorLayer;
15
import es.unex.sextante.dataObjects.vectorFilters.BoundingBoxFilter;
16
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
17
import es.unex.sextante.exceptions.IteratorException;
18
import es.unex.sextante.exceptions.RepeatedParameterNameException;
19
import es.unex.sextante.outputs.OutputVectorLayer;
20

    
21

    
22
public class UnionAlgorithm
23
         extends
24
            GeoAlgorithm {
25

    
26
   public static final String LAYER1 = "LAYER1";
27
   public static final String LAYER2 = "LAYER2";
28
   public static final String RESULT = "RESULT";
29

    
30
   private Geometry           m_ClipGeometry;
31

    
32

    
33
   @Override
34
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
35

    
36
      final IVectorLayer layer1 = m_Parameters.getParameterValueAsVectorLayer(LAYER1);
37
      final IVectorLayer layer2 = m_Parameters.getParameterValueAsVectorLayer(LAYER2);
38

    
39
      if (!m_bIsAutoExtent) {
40
         layer1.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
41
         layer2.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
42
      }
43

    
44
      final Class[] fieldTypes = new Class[layer1.getFieldCount() + layer2.getFieldCount()];
45
      final String[] sFieldNames = new String[fieldTypes.length];
46

    
47
      for (int i = 0; i < layer1.getFieldCount(); i++) {
48
         fieldTypes[i] = layer1.getFieldType(i);
49
         sFieldNames[i] = layer1.getFieldName(i);
50
      }
51
      for (int i = 0; i < layer2.getFieldCount(); i++) {
52
         fieldTypes[i + layer1.getFieldCount()] = layer2.getFieldType(i);
53
         sFieldNames[i + layer1.getFieldCount()] = layer2.getFieldName(i);
54
      }
55

    
56
      final IVectorLayer intersection = getTempVectorLayer(IVectorLayer.SHAPE_TYPE_POLYGON, fieldTypes, sFieldNames);
57

    
58
      final IVectorLayer output = getNewVectorLayer(RESULT, Sextante.getText("Union"), IVectorLayer.SHAPE_TYPE_POLYGON,
59
               fieldTypes, sFieldNames);
60

    
61
      //first we do an intersection
62

    
63
      setProgressText(Sextante.getText("Intersection") + "(1/4)");
64
      IFeatureIterator iter = layer1.iterator();
65

    
66
      int i = 0;
67
      int iShapeCount = layer1.getShapesCount();
68
      while (iter.hasNext() && setProgress(i, iShapeCount)) {
69
         final IFeature feature = iter.next();
70
         final Object[] values = feature.getRecord().getValues();
71
         final Geometry g = feature.getGeometry();
72
         final IFeatureIterator iter2 = layer2.iterator();
73
         while (iter2.hasNext()) {
74
            final IFeature feature2 = iter2.next();
75
            final Geometry g2 = feature2.getGeometry();
76
            if (g2.intersects(g)) {
77
               final Object[] values2 = feature2.getRecord().getValues();
78
               final Geometry inter = g.intersection(g2);
79
               final Object[] resultValues = new Object[values.length + values2.length];
80
               System.arraycopy(values, 0, resultValues, 0, values.length);
81
               System.arraycopy(values2, 0, resultValues, values.length, values2.length);
82
               intersection.addFeature(inter, resultValues);
83
            }
84
         }
85
         iter2.close();
86
         i++;
87
      }
88
      iter.close();
89

    
90

    
91
      if (m_Task.isCanceled()) {
92
         return false;
93
      }
94

    
95
      //copy the resulting features to the final layer
96
      setProgressText(Sextante.getText("Copying_entities") + "(2/4)");
97
      intersection.close();
98
      try {
99
         intersection.postProcess();
100
      }
101
      catch (final Exception e) {
102
         throw new GeoAlgorithmExecutionException(e.getMessage());
103
      }
104
      intersection.open();
105
      iter = intersection.iterator();
106

    
107
      i = 0;
108
      iShapeCount = intersection.getShapesCount();
109
      while (iter.hasNext() && setProgress(i, iShapeCount)) {
110
         final IFeature feature = iter.next();
111
         output.addFeature(feature);
112
      }
113
      iter.close();
114

    
115
      //Now we calculate difference between layer 1 and intersection
116
      //and add the resulting entities to the final layer
117
      m_ClipGeometry = computeJtsClippingPoly(intersection);
118
      setProgressText(Sextante.getText("Copying_entities") + "(3/4)");
119
      iter = layer1.iterator();
120
      i = 0;
121
      iShapeCount = layer1.getShapesCount();
122
      while (iter.hasNext() && setProgress(i, iShapeCount)) {
123
         final IFeature feature = iter.next();
124
         final Geometry g = difference(feature.getGeometry());
125
         if (g != null) {
126
            final Object[] values = feature.getRecord().getValues();
127
            final Object[] resultValues = new Object[output.getFieldCount()];
128
            System.arraycopy(values, 0, resultValues, 0, values.length);
129
            output.addFeature(g, resultValues);
130
         }
131
         i++;
132
      }
133
      iter.close();
134

    
135
      if (m_Task.isCanceled()) {
136
         return false;
137
      }
138

    
139
      //And now the same difference but with layer2
140
      setProgressText(Sextante.getText("Copying_entities") + "(4/4)");
141
      iter = layer2.iterator();
142
      i = 0;
143
      iShapeCount = layer1.getShapesCount();
144
      while (iter.hasNext() && setProgress(i, iShapeCount)) {
145
         final IFeature feature = iter.next();
146
         final Geometry g = difference(feature.getGeometry());
147
         if (g != null) {
148
            final Object[] values = feature.getRecord().getValues();
149
            final Object[] resultValues = new Object[output.getFieldCount()];
150
            System.arraycopy(values, 0, resultValues, layer1.getFieldCount(), values.length);
151
            output.addFeature(g, resultValues);
152
         }
153
         i++;
154
      }
155
      iter.close();
156

    
157
      intersection.close();
158

    
159
      return !m_Task.isCanceled();
160

    
161
   }
162

    
163

    
164
   public Geometry difference(final Geometry g) throws GeoAlgorithmExecutionException {
165

    
166
      if (g == null) {
167
         return null;
168
      }
169

    
170
      final Geometry env = g.getEnvelope();
171
      if (env == null || m_ClipGeometry == null) {
172
         return null;
173
      }
174
      if (!env.intersects(m_ClipGeometry.getEnvelope())) {
175
         return null;
176
      }
177
      if (g.intersects(m_ClipGeometry)) {
178
         try {
179
            final Geometry newGeom = g.difference(m_ClipGeometry);
180
            return newGeom;
181
         }
182
         catch (final com.vividsolutions.jts.geom.TopologyException e) {
183
            if (!g.isValid()) {
184
               throw new GeoAlgorithmExecutionException("Wrong input geometry");
185
            }
186
            if (!m_ClipGeometry.isValid()) {
187
               throw new GeoAlgorithmExecutionException("Wrong clipping geometry");
188
            }
189
         }
190
      }
191
      return null;
192
   }
193

    
194

    
195
   private Geometry computeJtsClippingPoly(final IVectorLayer layer) throws IteratorException {
196

    
197
      Geometry currentGeometry;
198
      Geometry geometry = null;
199
      final GeometryFactory geomFact = new GeometryFactory();
200

    
201
      final IFeatureIterator iter = layer.iterator();
202
      while (iter.hasNext()) {
203
         final IFeature feature = iter.next();
204
         currentGeometry = feature.getGeometry();
205
         if (geometry == null) {
206
            geometry = currentGeometry;
207
         }
208
         else {
209
            final Geometry[] geoms = new Geometry[2];
210
            geoms[0] = geometry;
211
            geoms[1] = currentGeometry;
212
            final GeometryCollection gc = geomFact.createGeometryCollection(geoms);
213
            geometry = gc.buffer(0d);
214
         }
215
      }
216
      iter.close();
217

    
218
      return geometry;
219

    
220
   }
221

    
222

    
223
   @Override
224
   public void defineCharacteristics() {
225

    
226
      setName(Sextante.getText("Union"));
227
      setGroup(Sextante.getText("Tools_for_polygon_layers"));
228
      setUserCanDefineAnalysisExtent(true);
229

    
230
      try {
231
         m_Parameters.addInputVectorLayer(LAYER1, Sextante.getText("Layer_1"), AdditionalInfoVectorLayer.SHAPE_TYPE_POLYGON, true);
232
         m_Parameters.addInputVectorLayer(LAYER2, Sextante.getText("Layer_2"), AdditionalInfoVectorLayer.SHAPE_TYPE_POLYGON, true);
233
         addOutputVectorLayer(RESULT, Sextante.getText("Capa_union"), OutputVectorLayer.SHAPE_TYPE_POLYGON);
234
      }
235
      catch (final RepeatedParameterNameException e) {
236
         Sextante.addErrorToLog(e);
237
      }
238

    
239
   }
240

    
241

    
242
   public Geometry clipGeometry(final Geometry g) throws GeoAlgorithmExecutionException {
243

    
244
      if (g == null) {
245
         return null;
246
      }
247

    
248
      final Geometry env = g.getEnvelope();
249
      if (env == null) {
250
         return null;
251
      }
252
      if (!env.intersects(m_ClipGeometry.getEnvelope())) {
253
         return null;
254
      }
255
      if (g.intersects(m_ClipGeometry)) {
256
         try {
257
            final Geometry newGeom = g.symDifference(m_ClipGeometry);
258
            return newGeom;
259
         }
260
         catch (final com.vividsolutions.jts.geom.TopologyException e) {
261
            if (!g.isValid()) {
262
               throw new GeoAlgorithmExecutionException("Wrong input geometry");
263
            }
264
            if (!m_ClipGeometry.isValid()) {
265
               throw new GeoAlgorithmExecutionException("Wrong clipping geometry");
266
            }
267
         }
268
      }
269
      return null;
270
   }
271

    
272
}