root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / rasterize / rasterizeVectorLayerForMask / RasterizeVectorLayerForMaskAlgorithm.java @ 59
History | View | Annotate | Download (10.3 KB)
1 |
|
---|---|
2 |
|
3 |
package es.unex.sextante.rasterize.rasterizeVectorLayerForMask; |
4 |
|
5 |
import java.util.Arrays; |
6 |
|
7 |
import com.vividsolutions.jts.geom.Coordinate; |
8 |
import com.vividsolutions.jts.geom.Envelope; |
9 |
import com.vividsolutions.jts.geom.Geometry; |
10 |
import com.vividsolutions.jts.geom.GeometryFactory; |
11 |
import com.vividsolutions.jts.geom.LinearRing; |
12 |
import com.vividsolutions.jts.geom.Polygon; |
13 |
|
14 |
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer; |
15 |
import es.unex.sextante.core.AnalysisExtent; |
16 |
import es.unex.sextante.core.GeoAlgorithm; |
17 |
import es.unex.sextante.core.Sextante; |
18 |
import es.unex.sextante.dataObjects.IFeature; |
19 |
import es.unex.sextante.dataObjects.IFeatureIterator; |
20 |
import es.unex.sextante.dataObjects.IRasterLayer; |
21 |
import es.unex.sextante.dataObjects.IRecord; |
22 |
import es.unex.sextante.dataObjects.IVectorLayer; |
23 |
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
24 |
import es.unex.sextante.exceptions.RepeatedParameterNameException; |
25 |
import es.unex.sextante.rasterWrappers.GridCell; |
26 |
|
27 |
|
28 |
public class RasterizeVectorLayerForMaskAlgorithm |
29 |
extends
|
30 |
GeoAlgorithm { |
31 |
|
32 |
private double NO_DATA; |
33 |
|
34 |
public static final String LAYER = "LAYER"; |
35 |
public static final String FIELD = "FIELD"; |
36 |
public static final String RESULT = "RESULT"; |
37 |
|
38 |
private int m_iNX, m_iNY; |
39 |
private IVectorLayer m_Layer;
|
40 |
private IRasterLayer m_Result;
|
41 |
private AnalysisExtent m_Extent;
|
42 |
|
43 |
|
44 |
@Override
|
45 |
public void defineCharacteristics() { |
46 |
|
47 |
setName(Sextante.getText("Rasterize_vector_layer_for_mask"));
|
48 |
setGroup(Sextante.getText("Rasterization_and_interpolation"));
|
49 |
setUserCanDefineAnalysisExtent(true);
|
50 |
|
51 |
try {
|
52 |
m_Parameters.addInputVectorLayer(LAYER, Sextante.getText("Vector_layer"), AdditionalInfoVectorLayer.SHAPE_TYPE_ANY, true); |
53 |
addOutputRasterLayer(RESULT, Sextante.getText("Result"));
|
54 |
} |
55 |
catch (final RepeatedParameterNameException e) { |
56 |
Sextante.addErrorToLog(e); |
57 |
} |
58 |
|
59 |
} |
60 |
|
61 |
|
62 |
@Override
|
63 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
64 |
|
65 |
int i;
|
66 |
int iType;
|
67 |
int iShapeCount;
|
68 |
|
69 |
NO_DATA = 0;
|
70 |
|
71 |
m_Layer = m_Parameters.getParameterValueAsVectorLayer(LAYER); |
72 |
|
73 |
m_Result = getNewRasterLayer(RESULT, m_Layer.getName() + Sextante.getText("[rasterizedo]"),
|
74 |
IRasterLayer.RASTER_DATA_TYPE_DOUBLE); |
75 |
m_Result.setNoDataValue(NO_DATA); |
76 |
m_Result.assignNoData(); |
77 |
|
78 |
m_Extent = m_Result.getWindowGridExtent(); |
79 |
|
80 |
m_iNX = m_Extent.getNX(); |
81 |
m_iNY = m_Extent.getNY(); |
82 |
|
83 |
final Coordinate[] coords = new Coordinate[5]; |
84 |
coords[0] = new Coordinate(m_Extent.getXMin(), m_Extent.getYMin()); |
85 |
coords[1] = new Coordinate(m_Extent.getXMin(), m_Extent.getYMax()); |
86 |
coords[2] = new Coordinate(m_Extent.getXMax(), m_Extent.getYMax()); |
87 |
coords[3] = new Coordinate(m_Extent.getXMax(), m_Extent.getYMin()); |
88 |
coords[4] = new Coordinate(m_Extent.getXMin(), m_Extent.getYMin()); |
89 |
final GeometryFactory gf = new GeometryFactory(); |
90 |
final LinearRing ring = gf.createLinearRing(coords);
|
91 |
final Polygon extent = gf.createPolygon(ring, null); |
92 |
|
93 |
i = 0;
|
94 |
iType = m_Layer.getShapeType(); |
95 |
iShapeCount = m_Layer.getShapesCount(); |
96 |
final IFeatureIterator iter = m_Layer.iterator();
|
97 |
while (iter.hasNext() && setProgress(i, iShapeCount)) {
|
98 |
final IFeature feature = iter.next();
|
99 |
final IRecord record = feature.getRecord();
|
100 |
|
101 |
final Geometry geometry = feature.getGeometry();
|
102 |
|
103 |
if (geometry.intersects(extent)) {
|
104 |
switch (iType) {
|
105 |
case IVectorLayer.SHAPE_TYPE_POINT:
|
106 |
doPoint(geometry, 1);
|
107 |
break;
|
108 |
case IVectorLayer.SHAPE_TYPE_LINE:
|
109 |
doLine(geometry, 1);
|
110 |
break;
|
111 |
case IVectorLayer.SHAPE_TYPE_POLYGON:
|
112 |
doPolygon(geometry, 1);
|
113 |
break;
|
114 |
} |
115 |
} |
116 |
i++; |
117 |
} |
118 |
iter.close(); |
119 |
|
120 |
return !m_Task.isCanceled();
|
121 |
|
122 |
|
123 |
} |
124 |
|
125 |
|
126 |
private void doPolygon(final Geometry geom, |
127 |
final double dValue) { |
128 |
|
129 |
final GeometryFactory gf = new GeometryFactory(); |
130 |
for (int i = 0; i < geom.getNumGeometries(); i++) { |
131 |
final Polygon poly = (Polygon) geom.getGeometryN(i); |
132 |
LinearRing lr = gf.createLinearRing(poly.getExteriorRing().getCoordinates()); |
133 |
Polygon part = gf.createPolygon(lr, null); |
134 |
doPolygonPart(part, dValue, false);
|
135 |
for (int j = 0; j < poly.getNumInteriorRing(); j++) { |
136 |
lr = gf.createLinearRing(poly.getInteriorRingN(j).getCoordinates()); |
137 |
part = gf.createPolygon(lr, null);
|
138 |
doPolygonPart(part, dValue, true);
|
139 |
} |
140 |
} |
141 |
|
142 |
} |
143 |
|
144 |
|
145 |
private void doPolygonPart(final Polygon geom, |
146 |
final double dValue, |
147 |
final boolean bIsHole) { |
148 |
|
149 |
boolean bFill;
|
150 |
boolean bCrossing[]; |
151 |
int x, y, ix, xStart, xStop, iPoint;
|
152 |
double yPos;;
|
153 |
Coordinate pLeft, pRight, pa, pb; |
154 |
final Coordinate p = new Coordinate(); |
155 |
bCrossing = new boolean[m_iNX]; |
156 |
|
157 |
final Envelope extent = geom.getEnvelopeInternal();
|
158 |
|
159 |
xStart = (int) ((extent.getMinX() - m_Extent.getXMin()) / m_Extent.getCellSize()) - 1; |
160 |
if (xStart < 0) { |
161 |
xStart = 0;
|
162 |
} |
163 |
|
164 |
xStop = (int) ((extent.getMaxX() - m_Extent.getXMin()) / m_Extent.getCellSize()) + 1; |
165 |
if (xStop >= m_iNX) {
|
166 |
xStop = m_iNX - 1;
|
167 |
} |
168 |
|
169 |
final Coordinate[] points = geom.getCoordinates(); |
170 |
|
171 |
for (y = 0, yPos = m_Extent.getYMax(); y < m_iNY; y++, yPos -= m_Extent.getCellSize()) { |
172 |
if ((yPos >= extent.getMinY()) && (yPos <= extent.getMaxY())) {
|
173 |
Arrays.fill(bCrossing, false); |
174 |
pLeft = new Coordinate(m_Extent.getXMin() - 1.0, yPos); |
175 |
pRight = new Coordinate(m_Extent.getXMax() + 1.0, yPos); |
176 |
|
177 |
pb = points[points.length - 1];
|
178 |
|
179 |
for (iPoint = 0; iPoint < points.length; iPoint++) { |
180 |
pa = pb; |
181 |
pb = points[iPoint]; |
182 |
|
183 |
if ((((pa.y <= yPos) && (yPos < pb.y)) || ((pa.y > yPos) && (yPos >= pb.y)))) {
|
184 |
getCrossing(p, pa, pb, pLeft, pRight); |
185 |
|
186 |
ix = (int) ((p.x - m_Extent.getXMin()) / m_Extent.getCellSize() + 1.0); |
187 |
|
188 |
if (ix < 0) { |
189 |
ix = 0;
|
190 |
} |
191 |
else if (ix >= m_iNX) { |
192 |
ix = m_iNX - 1;
|
193 |
} |
194 |
|
195 |
bCrossing[ix] = !bCrossing[ix]; |
196 |
} |
197 |
} |
198 |
|
199 |
for (x = xStart, bFill = false; x <= xStop; x++) { |
200 |
if (bCrossing[x]) {
|
201 |
bFill = !bFill; |
202 |
} |
203 |
if (bFill) {
|
204 |
final double dPrevValue = m_Result.getCellValueAsDouble(x, y); |
205 |
if (bIsHole) {
|
206 |
if (dPrevValue == dValue) {
|
207 |
m_Result.setNoData(x, y); |
208 |
} |
209 |
} |
210 |
else {
|
211 |
if (dPrevValue == NO_DATA) {
|
212 |
m_Result.setCellValue(x, y, dValue); |
213 |
} |
214 |
} |
215 |
} |
216 |
} |
217 |
} |
218 |
} |
219 |
|
220 |
} |
221 |
|
222 |
|
223 |
private void doLine(final Geometry geom, |
224 |
final double dValue) { |
225 |
|
226 |
for (int i = 0; i < geom.getNumGeometries(); i++) { |
227 |
final Geometry part = geom.getGeometryN(i);
|
228 |
doLineString(part, dValue); |
229 |
} |
230 |
|
231 |
} |
232 |
|
233 |
|
234 |
private void doLineString(final Geometry geom, |
235 |
final double dValue) { |
236 |
|
237 |
int i;
|
238 |
double x, y, x2, y2;
|
239 |
final Coordinate[] coords = geom.getCoordinates(); |
240 |
for (i = 0; i < coords.length - 1; i++) { |
241 |
x = coords[i].x; |
242 |
y = coords[i].y; |
243 |
x2 = coords[i + 1].x;
|
244 |
y2 = coords[i + 1].y;
|
245 |
writeSegment(x, y, x2, y2, dValue); |
246 |
} |
247 |
|
248 |
} |
249 |
|
250 |
|
251 |
private void writeSegment(double x, |
252 |
double y,
|
253 |
final double x2, |
254 |
final double y2, |
255 |
final double dValue) { |
256 |
|
257 |
double dx, dy, d, n;
|
258 |
GridCell cell; |
259 |
|
260 |
dx = Math.abs(x2 - x);
|
261 |
dy = Math.abs(y2 - y);
|
262 |
|
263 |
if ((dx > 0.0) || (dy > 0.0)) { |
264 |
if (dx > dy) {
|
265 |
dx /= m_Result.getWindowCellSize(); |
266 |
n = dx; |
267 |
dy /= dx; |
268 |
dx = m_Result.getWindowCellSize(); |
269 |
} |
270 |
else {
|
271 |
dy /= m_Result.getWindowCellSize(); |
272 |
n = dy; |
273 |
dx /= dy; |
274 |
dy = m_Result.getWindowCellSize(); |
275 |
} |
276 |
|
277 |
if (x2 < x) {
|
278 |
dx = -dx; |
279 |
} |
280 |
|
281 |
if (y2 < y) {
|
282 |
dy = -dy; |
283 |
} |
284 |
|
285 |
for (d = 0.0; d <= n; d++, x += dx, y += dy) { |
286 |
if (m_Extent.contains(x, y)) {
|
287 |
cell = m_Extent.getGridCoordsFromWorldCoords(x, y); |
288 |
//System.out.println(cell.getX() + " " + cell.getY());
|
289 |
m_Result.setCellValue(cell.getX(), cell.getY(), dValue); |
290 |
} |
291 |
} |
292 |
} |
293 |
|
294 |
} |
295 |
|
296 |
|
297 |
private void doPoint(final Geometry geometry, |
298 |
final double dValue) { |
299 |
|
300 |
final Coordinate coord = geometry.getCoordinate();
|
301 |
final GridCell cell = m_Extent.getGridCoordsFromWorldCoords(coord.x, coord.y);
|
302 |
m_Result.setCellValue(cell.getX(), cell.getY(), dValue); |
303 |
|
304 |
} |
305 |
|
306 |
|
307 |
private boolean getCrossing(final Coordinate crossing, |
308 |
final Coordinate a1,
|
309 |
final Coordinate a2,
|
310 |
final Coordinate b1,
|
311 |
final Coordinate b2) {
|
312 |
|
313 |
double lambda, div, a_dx, a_dy, b_dx, b_dy;
|
314 |
|
315 |
a_dx = a2.x - a1.x; |
316 |
a_dy = a2.y - a1.y; |
317 |
|
318 |
b_dx = b2.x - b1.x; |
319 |
b_dy = b2.y - b1.y; |
320 |
|
321 |
if ((div = a_dx * b_dy - b_dx * a_dy) != 0.0) { |
322 |
lambda = ((b1.x - a1.x) * b_dy - b_dx * (b1.y - a1.y)) / div; |
323 |
|
324 |
crossing.x = a1.x + lambda * a_dx; |
325 |
crossing.y = a1.y + lambda * a_dy; |
326 |
|
327 |
return true; |
328 |
|
329 |
} |
330 |
|
331 |
return false; |
332 |
} |
333 |
|
334 |
} |