Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / vectorTools / groupNearFeatures / GroupNearFeaturesAlgorithm.java @ 59

History | View | Annotate | Download (5.34 KB)

1

    
2

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

    
5
import java.util.ArrayList;
6
import java.util.HashMap;
7

    
8
import com.vividsolutions.jts.geom.Geometry;
9

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

    
22

    
23
public class GroupNearFeaturesAlgorithm
24
         extends
25
            GeoAlgorithm {
26

    
27
   public static final String LAYER     = "LAYER";
28
   public static final String TOLERANCE = "TOLERANCE";
29
   public static final String RESULT    = "RESULT";
30

    
31

    
32
   @Override
33
   public void defineCharacteristics() {
34

    
35
      setName(Sextante.getText("Group_near_features"));
36
      setGroup(Sextante.getText("Tools_for_vector_layers"));
37
      setUserCanDefineAnalysisExtent(true);
38

    
39
      try {
40
         m_Parameters.addInputVectorLayer(LAYER, Sextante.getText("Layer"), AdditionalInfoVectorLayer.SHAPE_TYPE_ANY, true);
41

    
42
         m_Parameters.addNumericalValue(TOLERANCE, Sextante.getText("Tolerance"),
43
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE, 5.0, 0.0001, Double.MAX_VALUE);
44

    
45
         addOutputVectorLayer(RESULT, Sextante.getText("Result"), OutputVectorLayer.SHAPE_TYPE_UNDEFINED);
46

    
47
      }
48
      catch (final RepeatedParameterNameException e) {
49
         Sextante.addErrorToLog(e);
50
      }
51

    
52
   }
53

    
54

    
55
   @Override
56
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
57

    
58
      final int i = 0;
59
      final IVectorLayer layerIn = m_Parameters.getParameterValueAsVectorLayer(GroupNearFeaturesAlgorithm.LAYER);
60
      final double tolerance = m_Parameters.getParameterValueAsDouble(GroupNearFeaturesAlgorithm.TOLERANCE);
61

    
62
      if (!m_bIsAutoExtent) {
63
         layerIn.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
64
      }
65

    
66
      final Class[] in_ftypes = layerIn.getFieldTypes();
67
      final Class[] out_ftypes = new Class[in_ftypes.length + 1];
68
      System.arraycopy(in_ftypes, 0, out_ftypes, 0, in_ftypes.length);
69
      out_ftypes[out_ftypes.length - 1] = Integer.class;
70

    
71
      final String[] in_fnames = layerIn.getFieldNames();
72
      final String[] out_fnames = new String[in_ftypes.length + 1];
73
      System.arraycopy(in_fnames, 0, out_fnames, 0, in_fnames.length);
74
      out_fnames[out_fnames.length - 1] = "GROUP_ID";
75

    
76
      final IVectorLayer driver = getNewVectorLayer(GroupNearFeaturesAlgorithm.RESULT, Sextante.getText("Grouped_Layer"),
77
               layerIn.getShapeType(), out_ftypes, out_fnames);
78

    
79
      final int iTotal = layerIn.getShapesCount();
80
      int groupID = 0;
81
      final int[] groupedMap = new int[iTotal];
82
      for (int k = 0; k < iTotal; k++) {
83
         groupedMap[k] = -1;
84
      }
85
      //Array of arrays of groups with all geoms of the group
86
      final HashMap groupGeoms = new HashMap();
87

    
88
      final IFeatureIterator iter1 = layerIn.iterator();
89
      final Object[] values = new Object[out_fnames.length];
90
      for (int featCount1 = 0; iter1.hasNext(); featCount1++) {
91
         final IFeature feat1 = iter1.next();
92
         Geometry geom1 = feat1.getGeometry();
93
         if (groupedMap[featCount1] != -1) {
94
            continue;
95
         }
96
         //A new group is created
97
         groupedMap[featCount1] = groupID;
98
         ArrayList geomArray = new ArrayList();
99
         geomArray.add(geom1);
100
         groupGeoms.put(groupID, geomArray);
101
         // Also add this feature on the FeatureCollection
102
         Object[] aux_values = feat1.getRecord().getValues();
103
         System.arraycopy(aux_values, 0, values, 0, aux_values.length);
104
         values[values.length - 1] = groupID;
105
         driver.addFeature(geom1, values);
106

    
107
         IFeatureIterator iter2 = layerIn.iterator();
108
         for (int featCount2 = 0; iter2.hasNext(); featCount2++) {
109
            final IFeature feat2 = iter2.next();
110
            if (groupedMap[featCount2] != -1) {
111
               continue;
112
            }
113
            final Geometry geom2 = feat2.getGeometry();
114
            geomArray = (ArrayList) groupGeoms.get(groupID);
115
            for (int j = 0; j < geomArray.size(); j++) {
116
               geom1 = (Geometry) geomArray.get(j);
117
               final double dist = geom1.distance(geom2);
118
               if (dist < tolerance) {
119
                  groupedMap[featCount2] = groupID;
120
                  geomArray = (ArrayList) groupGeoms.get(groupID);
121
                  geomArray.add(geom2);
122
                  aux_values = feat2.getRecord().getValues();
123
                  System.arraycopy(aux_values, 0, values, 0, aux_values.length);
124
                  values[values.length - 1] = groupID;
125
                  driver.addFeature(geom2, values);
126
                  // It needed to reset the iterator to check if any previous feature belongs to this group
127
                  iter2 = layerIn.iterator();
128
                  featCount2 = -1;
129
                  break;
130
               }
131
            }
132
         }
133
         iter2.close();
134
         groupID++;
135
         setProgress(i, iTotal);
136
      }
137
      iter1.close();
138
      return !m_Task.isCanceled();
139
   }
140
}