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 |
} |