Statistics
| Revision:

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

History | View | Annotate | Download (5.57 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 org.gvsig.tools.exception.BaseException;
11

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

    
24

    
25
public class GroupNearFeaturesAlgorithm
26
         extends
27
            GeoAlgorithm {
28

    
29
   public static final String LAYER     = "LAYER";
30
   public static final String TOLERANCE = "TOLERANCE";
31
   public static final String RESULT    = "RESULT";
32

    
33

    
34
   @Override
35
   public void defineCharacteristics() {
36

    
37
      setName(Sextante.getText("Group_near_features"));
38
      setGroup(Sextante.getText("Tools_for_vector_layers"));
39
      setUserCanDefineAnalysisExtent(true);
40

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

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

    
47
         addOutputVectorLayer(RESULT, Sextante.getText("Result"), OutputVectorLayer.SHAPE_TYPE_UNDEFINED);
48

    
49
      }
50
      catch (final RepeatedParameterNameException e) {
51
         Sextante.addErrorToLog(e);
52
      }
53

    
54
   }
55

    
56

    
57
   @Override
58
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
59

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

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

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

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

    
78
      int subtype;
79
    try {
80
        subtype = layerIn.getSubType();
81
    } catch (BaseException e) {
82
        subtype = org.gvsig.fmap.geom.Geometry.SUBTYPES.UNKNOWN;
83
    }
84

    
85
      final IVectorLayer driver = getNewVectorLayer(GroupNearFeaturesAlgorithm.RESULT, Sextante.getText("Grouped_Layer"),
86
               layerIn.getShapeType(), out_ftypes, out_fnames, subtype);
87

    
88
      final int iTotal = layerIn.getShapesCount();
89
      int groupID = 0;
90
      final int[] groupedMap = new int[iTotal];
91
      for (int k = 0; k < iTotal; k++) {
92
         groupedMap[k] = -1;
93
      }
94
      //Array of arrays of groups with all geoms of the group
95
      final HashMap groupGeoms = new HashMap();
96

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

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