Statistics
| Revision:

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

History | View | Annotate | Download (10.1 KB)

1

    
2

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

    
5
import java.awt.geom.Point2D;
6
import java.util.ArrayList;
7

    
8
import com.vividsolutions.jts.geom.Coordinate;
9
import com.vividsolutions.jts.geom.Envelope;
10
import com.vividsolutions.jts.geom.Geometry;
11
import com.vividsolutions.jts.geom.GeometryFactory;
12

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

    
27

    
28
public class FitNPointsInPolygonAlgorithm
29
         extends
30
            GeoAlgorithm {
31

    
32
   private static final int   MAX_REP                           = 50;
33

    
34
   public static final String POLYGONS                          = "POLYGONS";
35
   public static final String NPOINTS                           = "NPOINTS";
36
   public static final String NPOINTS_METHOD                    = "NPOINTS_METHOD";
37
   public static final String METHOD                            = "METHOD";
38
   public static final String RESULT                            = "RESULT";
39
   public static final String FIELD                             = "FIELD";
40

    
41
   public static final int    NPOINTS_FIXED                     = 0;
42
   public static final int    NPOINTS_FROM_FIELD                = 1;
43

    
44
   public static final int    METHOD_REGULARLY_SPACED           = 0;
45
   public static final int    METHOD_RANDOMLY                   = 1;
46
   public static final int    METHOD_REGULARLY_SPACED_ALTERNATE = 2;
47

    
48

    
49
   @Override
50
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
51

    
52
      int iPointsIn = 0;
53
      int iRep = 0;
54
      int i = 0, j;
55
      double x, y;
56
      double dArea;
57
      double dDist;
58
      double dDistInf, dDistSup;
59
      final String[] sFields = { "X", "Y" };
60
      final Class[] types = { Double.class, Double.class };
61
      final ArrayList points = new ArrayList();
62
      final ArrayList allPoints = new ArrayList();
63
      Envelope extent;
64
      final Coordinate coord = new Coordinate();
65
      final Object[] values = new Object[2];
66

    
67
      final IVectorLayer polygons = m_Parameters.getParameterValueAsVectorLayer(POLYGONS);
68
      int iPoints = m_Parameters.getParameterValueAsInt(NPOINTS);
69
      final int iMethod = m_Parameters.getParameterValueAsInt(METHOD);
70
      final int iField = m_Parameters.getParameterValueAsInt(FIELD);
71
      final int iNPointsMethod = m_Parameters.getParameterValueAsInt(NPOINTS_METHOD);
72

    
73
      if (!m_bIsAutoExtent) {
74
         polygons.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
75
      }
76

    
77
      final GeometryFactory gf = new GeometryFactory();
78
      final int iShapeCount = polygons.getShapesCount();
79
      final IFeatureIterator iter = polygons.iterator();
80
      while (iter.hasNext() && !m_Task.isCanceled()) {
81
         setProgressText(Integer.toString(i) + "/" + Integer.toString(iShapeCount));
82
         final IFeature feature = iter.next();
83
         final Geometry geometry = feature.getGeometry();
84
         if (iNPointsMethod == NPOINTS_FROM_FIELD) {
85
            try {
86
               iPoints = Integer.parseInt(feature.getRecord().getValue(iField).toString());
87
            }
88
            catch (final Exception e) {
89
               iPoints = 0;
90
            }
91
         }
92
         extent = geometry.getEnvelopeInternal();
93
         if (iMethod == METHOD_REGULARLY_SPACED) {
94
            iRep = 0;
95
            dArea = geometry.getArea();
96
            dDist = Math.sqrt(dArea / iPoints);
97
            dDistInf = Math.sqrt(dArea / (iPoints + 2));
98
            dDistSup = Math.sqrt(dArea / (iPoints - Math.min(2, iPoints - 1)));
99
            if (dDist > 0) {
100
               do {
101
                  points.clear();
102
                  iPointsIn = 0;
103
                  iRep++;
104
                  for (x = extent.getMinX(); x < extent.getMaxX(); x = x + dDist) {
105
                     for (y = extent.getMinY(); y < extent.getMaxY(); y = y + dDist) {
106
                        coord.x = x;
107
                        coord.y = y;
108
                        if (geometry.contains(gf.createPoint(coord))) {
109
                           points.add(new Point2D.Double(x, y));
110
                           iPointsIn++;
111
                           setProgress(iPointsIn, iPoints);
112
                        }
113
                     }
114
                  }
115
                  if (iPointsIn > iPoints) {
116
                     dDistInf = dDist;
117
                     dDist = (dDistInf + dDistSup) / 2.;
118
                  }
119
                  else if (iPointsIn < iPoints) {
120
                     dDistSup = dDist;
121
                     dDist = (dDistInf + dDistSup) / 2.;
122
                  }
123
               }
124
               while ((iPointsIn != iPoints) && (iRep < MAX_REP) && !m_Task.isCanceled());
125
               for (j = 0; j < points.size(); j++) {
126
                  allPoints.add(new Point2D.Double(((Point2D) points.get(j)).getX(), ((Point2D) points.get(j)).getY()));
127
               }
128
            }
129
         }
130
         else if (iMethod == METHOD_RANDOMLY) {
131
            iPointsIn = 0;
132
            do {
133
               x = Math.random() * extent.getWidth() + extent.getMinX();
134
               y = Math.random() * extent.getHeight() + extent.getMinY();
135
               coord.x = x;
136
               coord.y = y;
137
               if (geometry.contains(gf.createPoint(coord))) {
138
                  allPoints.add(new Point2D.Double(x, y));
139
                  iPointsIn++;
140
               }
141
            }
142
            while ((iPointsIn != iPoints) && setProgress(iPointsIn, iPoints));
143
         }
144
         else if (iMethod == METHOD_REGULARLY_SPACED_ALTERNATE) {
145
            iRep = 0;
146
            dArea = geometry.getArea();
147
            dDist = Math.sqrt(dArea / iPoints);
148
            dDistInf = Math.sqrt(dArea / (iPoints + 2));
149
            dDistSup = Math.sqrt(dArea / (iPoints - Math.min(2, iPoints - 1)));
150
            if (dDist > 0) {
151
               do {
152
                  points.clear();
153
                  iPointsIn = 0;
154
                  iRep++;
155
                  for (x = extent.getMinX(); x < extent.getMaxX(); x = x + dDist) {
156
                     boolean bDisplace = false;
157
                     for (y = extent.getMinY(); y < extent.getMaxY(); y = y + dDist) {
158
                        coord.x = x;
159
                        coord.y = y;
160
                        if (bDisplace) {
161
                           coord.x = coord.x + dDist / 2;
162
                        }
163
                        bDisplace = !bDisplace;
164
                        if (geometry.contains(gf.createPoint(coord))) {
165
                           points.add(new Point2D.Double(coord.x, coord.y));
166
                           iPointsIn++;
167
                           setProgress(iPointsIn, iPoints);
168
                        }
169
                     }
170
                  }
171
                  if (iPointsIn > iPoints) {
172
                     dDistInf = dDist;
173
                     dDist = (dDistInf + dDistSup) / 2.;
174
                  }
175
                  else if (iPointsIn < iPoints) {
176
                     dDistSup = dDist;
177
                     dDist = (dDistInf + dDistSup) / 2.;
178
                  }
179
               }
180
               while ((iPointsIn != iPoints) && (iRep < MAX_REP) && !m_Task.isCanceled());
181
               for (j = 0; j < points.size(); j++) {
182
                  allPoints.add(new Point2D.Double(((Point2D) points.get(j)).getX(), ((Point2D) points.get(j)).getY()));
183
               }
184
            }
185
         }
186
         i++;
187
      }
188

    
189
      if (allPoints.size() != 0) {
190
         final IVectorLayer outputLayer = getNewVectorLayer(RESULT, Sextante.getText("Points"), IVectorLayer.SHAPE_TYPE_POINT,
191
                  types, sFields);
192

    
193
         for (i = 0; i < allPoints.size(); i++) {
194
            x = ((Point2D) allPoints.get(i)).getX();
195
            y = ((Point2D) allPoints.get(i)).getY();
196
            values[0] = new Double(x);
197
            values[1] = new Double(y);
198
            final Geometry pt = gf.createPoint(new Coordinate(x, y));
199
            outputLayer.addFeature(pt, values);
200
         }
201
      }
202

    
203
      return !m_Task.isCanceled();
204
   }
205

    
206

    
207
   @Override
208
   public void defineCharacteristics() {
209

    
210
      final String[] sOptions = { Sextante.getText("Regular_grid"), Sextante.getText("Random"),
211
               Sextante.getText("Regular_grid_alternate") };
212

    
213
      final String[] sOptionsNPoints = { Sextante.getText("Fixed_number"), Sextante.getText("Take_from_table_field") };
214

    
215
      setName(Sextante.getText("Adjust_n_point_to_polygon"));
216
      setGroup(Sextante.getText("Tools_for_polygon_layers"));
217
      setUserCanDefineAnalysisExtent(true);
218

    
219
      try {
220
         m_Parameters.addInputVectorLayer(POLYGONS, Sextante.getText("Polygons"), AdditionalInfoVectorLayer.SHAPE_TYPE_POLYGON,
221
                  true);
222
         m_Parameters.addTableField(FIELD, Sextante.getText("Field_for_number_of_points"), POLYGONS);
223
         m_Parameters.addNumericalValue(NPOINTS, Sextante.getText("Number_of_points"),
224
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_INTEGER, 10, 1, Integer.MAX_VALUE);
225
         m_Parameters.addSelection(METHOD, Sextante.getText("Method"), sOptions);
226
         m_Parameters.addSelection(NPOINTS_METHOD, Sextante.getText("Number_of_points"), sOptionsNPoints);
227
         addOutputVectorLayer(RESULT, Sextante.getText("Points"), OutputVectorLayer.SHAPE_TYPE_POINT);
228
      }
229
      catch (final RepeatedParameterNameException e) {
230
         Sextante.addErrorToLog(e);
231
      }
232
      catch (final UndefinedParentParameterNameException e) {
233
         e.printStackTrace();
234
      }
235
      catch (final OptionalParentParameterException e) {
236
         e.printStackTrace();
237
      }
238

    
239
   }
240

    
241
}