root / branches / v2_0_0_prep / extensions / extRasterTools-SE / src / org / gvsig / rastertools / vectorizacion / process / ContourLinesProcess.java @ 27723
History | View | Annotate | Download (13.8 KB)
1 |
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|
2 |
*
|
3 |
* Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
|
4 |
*
|
5 |
* This program is free software; you can redistribute it and/or
|
6 |
* modify it under the terms of the GNU General Public License
|
7 |
* as published by the Free Software Foundation; either version 2
|
8 |
* of the License, or (at your option) any later version.
|
9 |
*
|
10 |
* This program is distributed in the hope that it will be useful,
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13 |
* GNU General Public License for more details.
|
14 |
*
|
15 |
* You should have received a copy of the GNU General Public License
|
16 |
* along with this program; if not, write to the Free Software
|
17 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
18 |
*/
|
19 |
package org.gvsig.rastertools.vectorizacion.process; |
20 |
|
21 |
import java.io.File; |
22 |
import java.sql.Types; |
23 |
|
24 |
import org.gvsig.fmap.crs.CRSFactory; |
25 |
import org.gvsig.fmap.dal.DALLocator; |
26 |
import org.gvsig.fmap.dal.DataManager; |
27 |
import org.gvsig.fmap.dal.DataTypes; |
28 |
import org.gvsig.fmap.dal.exception.DataException; |
29 |
import org.gvsig.fmap.dal.exception.ValidateDataParametersException; |
30 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
31 |
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor; |
32 |
import org.gvsig.fmap.dal.feature.EditableFeatureType; |
33 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
34 |
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters; |
35 |
import org.gvsig.fmap.dal.feature.impl.DefaultEditableFeatureType; |
36 |
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer; |
37 |
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters; |
38 |
import org.gvsig.fmap.geom.Geometry; |
39 |
import org.gvsig.fmap.geom.GeometryLocator; |
40 |
import org.gvsig.fmap.geom.GeometryManager; |
41 |
import org.gvsig.fmap.geom.Geometry.SUBTYPES; |
42 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
43 |
import org.gvsig.fmap.geom.primitive.GeneralPathX; |
44 |
import org.gvsig.fmap.raster.layers.FLyrRasterSE; |
45 |
import org.gvsig.raster.RasterProcess; |
46 |
import org.gvsig.raster.buffer.RasterBufferInvalidException; |
47 |
import org.gvsig.raster.datastruct.Extent; |
48 |
import org.gvsig.raster.grid.Grid; |
49 |
import org.gvsig.raster.grid.GridException; |
50 |
import org.gvsig.raster.grid.GridExtent; |
51 |
import org.gvsig.raster.process.RasterTask; |
52 |
import org.gvsig.raster.process.RasterTaskQueue; |
53 |
import org.gvsig.raster.util.RasterToolsUtil; |
54 |
|
55 |
/**
|
56 |
* Este proceso vectoriza la capa de entrada que debe estar ya preprocesada.
|
57 |
* 03/07/2008
|
58 |
* @author Victor Olaya (volaya@ya.com)
|
59 |
* @author Nacho Brodin nachobrodin@gmail.com
|
60 |
*/
|
61 |
public class ContourLinesProcess extends RasterProcess { |
62 |
private static final GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
63 |
private FLyrRasterSE lyr = null; |
64 |
private double min = 0; |
65 |
private double max = 0; |
66 |
private double distance = 0; |
67 |
private Extent extent = null; |
68 |
private String fileName = null; |
69 |
|
70 |
private char[][] m_Row = null; |
71 |
private char[][] m_Col = null; |
72 |
private Grid grid = null; |
73 |
private FeatureStore fsWriter = null; |
74 |
private int m_iGeometry = 0; |
75 |
private double percent = 0; |
76 |
|
77 |
private class NextContourInfo { |
78 |
public int iDir; |
79 |
public int x; |
80 |
public int y; |
81 |
public boolean doRow; |
82 |
} |
83 |
|
84 |
/**
|
85 |
* Par?metros obligatorios al proceso:
|
86 |
* <UL>
|
87 |
* <LI></LI>
|
88 |
* <LI>filename: Nombre del fichero de salida</LI>
|
89 |
* <LI></LI>
|
90 |
* <LI></LI>
|
91 |
* <LI></LI>
|
92 |
* <LI></LI>
|
93 |
* </UL>
|
94 |
*/
|
95 |
public void init() { |
96 |
lyr = getLayerParam("layer");
|
97 |
fileName = getStringParam("filename");
|
98 |
min = getDoubleParam("min");
|
99 |
max = getDoubleParam("max");
|
100 |
distance = getDoubleParam("distance");
|
101 |
extent = getExtentParam("extent");
|
102 |
|
103 |
try{
|
104 |
EditableFeatureType featureType = getFeatureType(); |
105 |
|
106 |
EditableFeatureAttributeDescriptor efad=featureType.add("GEOMETRY", DataTypes.GEOMETRY);
|
107 |
efad.setGeometryType(Geometry.TYPES.CURVE); |
108 |
efad.setSRS(CRSFactory.getCRS("EPSG:23030"));
|
109 |
featureType.setDefaultGeometryAttributeName("GEOMETRY");
|
110 |
|
111 |
|
112 |
DataManager datamanager=DALLocator.getDataManager(); |
113 |
FilesystemServerExplorerParameters explorerParams; |
114 |
|
115 |
explorerParams = (FilesystemServerExplorerParameters) datamanager.createServerExplorerParameters(FilesystemServerExplorer.NAME); |
116 |
|
117 |
explorerParams.setRoot(new File(fileName).getParent()); |
118 |
FilesystemServerExplorer explorer=(FilesystemServerExplorer) datamanager.createServerExplorer(explorerParams); |
119 |
NewFeatureStoreParameters newParams = (NewFeatureStoreParameters) explorer.getAddParameters(new File(fileName)); |
120 |
|
121 |
newParams.setDefaultFeatureType(featureType); |
122 |
explorer.add(newParams, true);
|
123 |
DataManager manager = DALLocator.getDataManager(); |
124 |
fsWriter=(FeatureStore)manager.createStore(newParams); |
125 |
if(fileName.endsWith(".dxf")) { |
126 |
} else if(fileName.endsWith(".shp")) { |
127 |
} |
128 |
fsWriter.edit(FeatureStore.MODE_APPEND); |
129 |
} catch (DataException e) {
|
130 |
e.printStackTrace(); |
131 |
} catch (ValidateDataParametersException e) {
|
132 |
// TODO Auto-generated catch block
|
133 |
e.printStackTrace(); |
134 |
} |
135 |
} |
136 |
|
137 |
/**
|
138 |
* Tarea de recorte
|
139 |
*/
|
140 |
public void process() throws InterruptedException { |
141 |
GridExtent ge = null;
|
142 |
insertLineLog("Contour Lines");
|
143 |
if(extent != null) |
144 |
ge = new GridExtent(extent, lyr.getCellSize());
|
145 |
try {
|
146 |
grid = new Grid(lyr.getDataSource(), new int[]{0}, ge); |
147 |
|
148 |
if( min <= max && distance > 0 ) { |
149 |
if( min < grid.getMinValue() )
|
150 |
min += distance * (int)((grid.getMinValue() - min) / distance);
|
151 |
|
152 |
if( max > grid.getMaxValue() )
|
153 |
max = grid.getMaxValue(); |
154 |
|
155 |
createContours(min, max, distance); |
156 |
fsWriter.finishEditing(); |
157 |
} |
158 |
} catch (RasterBufferInvalidException e) {
|
159 |
RasterToolsUtil.messageBoxError("error_loading_grid", this, e); |
160 |
} catch (GridException e) {
|
161 |
RasterToolsUtil.messageBoxError("error_loading_grid", this, e); |
162 |
} catch (DataException e) {
|
163 |
RasterToolsUtil.messageBoxError("", this, e); |
164 |
} catch (CreateGeometryException e) {
|
165 |
RasterToolsUtil.messageBoxError("", this, e); |
166 |
} finally {
|
167 |
if (incrementableTask != null) { |
168 |
incrementableTask.processFinalize(); |
169 |
incrementableTask = null;
|
170 |
} |
171 |
} |
172 |
if(externalActions != null) |
173 |
externalActions.end(fileName); |
174 |
} |
175 |
|
176 |
private void createContours(double dMin, double dMax, double dDistance) throws InterruptedException, GridException, DataException, CreateGeometryException { |
177 |
int x, y;
|
178 |
int i;
|
179 |
int ID;
|
180 |
int iNX,iNY;
|
181 |
double dZ;
|
182 |
double dValue = 0; |
183 |
RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
|
184 |
|
185 |
iNX = grid.getNX(); |
186 |
iNY = grid.getNY(); |
187 |
|
188 |
m_Row = new char[iNY][iNX]; |
189 |
m_Col = new char[iNY][iNX]; |
190 |
|
191 |
if( dDistance <= 0 ) |
192 |
dDistance= 1;
|
193 |
|
194 |
percent = 0;
|
195 |
for(dZ = dMin, ID = 0; dZ <= dMax; dZ += dDistance) { |
196 |
double increment = (25 / (iNY * (((dMax - dMin) / dDistance) + 1))); |
197 |
for(y = 0; y < iNY - 1; y++) { |
198 |
percent += increment; |
199 |
for(x = 0; x < iNX - 1; x++) { |
200 |
dValue = grid.getCellValue(y, x); |
201 |
if( dValue >= dZ ) {
|
202 |
m_Row[y][x] = (char) (grid.getCellValue(y, x + 1) < dZ ? 1 : 0); |
203 |
m_Col[y][x] = (char) (grid.getCellValue(y + 1, x) < dZ ? 1 : 0); |
204 |
} |
205 |
else {
|
206 |
m_Row[y][x] = (char) (grid.getCellValue(y, x + 1) >= dZ ? 1 : 0); |
207 |
m_Col[y][x] = (char) (grid.getCellValue(y + 1, x) >= dZ ? 1 : 0); |
208 |
} |
209 |
} |
210 |
if(task.getEvent() != null) |
211 |
task.manageEvent(task.getEvent()); |
212 |
} |
213 |
|
214 |
increment = (75 / (iNY * (((dMax - dMin) / dDistance) + 1))); |
215 |
for(y = 0; y < iNY - 1; y++) { |
216 |
percent += increment; |
217 |
for(x = 0; x < iNX - 1; x++) { |
218 |
if(m_Row[y][x] != 0) { |
219 |
for(i = 0; i < 2; i++) |
220 |
findContour(x, y, dZ, true, ID++);
|
221 |
m_Row[y][x] = 0;
|
222 |
} |
223 |
|
224 |
if(m_Col[y][x] != 0) { |
225 |
for(i=0; i<2; i++) |
226 |
findContour(x, y, dZ, false, ID++);
|
227 |
m_Col[y][x] = 0;
|
228 |
} |
229 |
} |
230 |
if(task.getEvent() != null) |
231 |
task.manageEvent(task.getEvent()); |
232 |
} |
233 |
} |
234 |
} |
235 |
|
236 |
private void findContour(int x, int y, double z, boolean doRow, int ID) throws GridException, InterruptedException, DataException, CreateGeometryException { |
237 |
boolean doContinue = true; |
238 |
boolean bIsFirstPoint = true; |
239 |
int zx = doRow ? x + 1 : x; |
240 |
int zy = doRow ? y : y + 1; |
241 |
double d = 0; |
242 |
double xPos, yPos;
|
243 |
double xMin = grid.getGridExtent().getMin().getX();
|
244 |
double yMax = grid.getGridExtent().getMax().getY();
|
245 |
Geometry line; |
246 |
Object values[] = new Object[2]; |
247 |
NextContourInfo info = new NextContourInfo();
|
248 |
GeneralPathX genPathX = new GeneralPathX();
|
249 |
|
250 |
info.x = x; |
251 |
info.y = y; |
252 |
info.iDir = 0;
|
253 |
info.doRow = doRow; |
254 |
|
255 |
do{
|
256 |
d = grid.getCellValue(info.y, info.x); |
257 |
d = (d - z) / (d - grid.getCellValue(zy, zx)); |
258 |
|
259 |
xPos = xMin + grid.getCellSize() * (info.x + d * (zx - info.x) + 0.5);
|
260 |
yPos = yMax - grid.getCellSize() * (info.y + d * (zy - info.y) + 0.5);
|
261 |
|
262 |
if (bIsFirstPoint) {
|
263 |
genPathX.moveTo(xPos, yPos); |
264 |
bIsFirstPoint = false;
|
265 |
} else
|
266 |
genPathX.lineTo(xPos, yPos); |
267 |
|
268 |
if( !findNextContour(info) )
|
269 |
doContinue = findNextContour(info); |
270 |
|
271 |
info.iDir = (info.iDir + 5) % 8; |
272 |
|
273 |
if(info.doRow) {
|
274 |
m_Row[info.y][info.x] = 0;
|
275 |
zx = info.x + 1;
|
276 |
zy = info.y; |
277 |
} else {
|
278 |
m_Col[info.y][info.x] = 0;
|
279 |
zx = info.x; |
280 |
zy = info.y + 1;
|
281 |
} |
282 |
|
283 |
} |
284 |
while(doContinue);
|
285 |
|
286 |
values[0] = new Double(ID); |
287 |
values[1] = new Double(z); |
288 |
|
289 |
line = geomManager.createCurve(genPathX, SUBTYPES.GEOM2D); |
290 |
addGeometry(line, values); |
291 |
} |
292 |
|
293 |
private boolean findNextContour(NextContourInfo info) { |
294 |
boolean doContinue;
|
295 |
|
296 |
if(info.doRow)
|
297 |
switch(info.iDir) {
|
298 |
case 0: |
299 |
if(m_Row[info.y + 1][info.x] != 0) { |
300 |
info.y++; |
301 |
info.iDir = 0;
|
302 |
doContinue = true;
|
303 |
break;
|
304 |
} |
305 |
case 1: |
306 |
if(m_Col[info.y][info.x + 1] != 0) { |
307 |
info.x++; |
308 |
info.iDir = 1;
|
309 |
info.doRow = false;
|
310 |
doContinue = true;
|
311 |
break;
|
312 |
} |
313 |
case 2: |
314 |
case 3: |
315 |
if(info.y-1 >= 0) |
316 |
if(m_Col[info.y - 1][info.x + 1] != 0) { |
317 |
info.x++; |
318 |
info.y--; |
319 |
info.doRow = false;
|
320 |
info.iDir = 3;
|
321 |
doContinue = true;
|
322 |
break;
|
323 |
} |
324 |
case 4: |
325 |
if(info.y-1>=0) |
326 |
if(m_Row[info.y - 1][info.x]!= 0) { |
327 |
info.y--; |
328 |
info.iDir = 4;
|
329 |
doContinue = true;
|
330 |
break;
|
331 |
} |
332 |
case 5: |
333 |
if(info.y-1>=0) |
334 |
if(m_Col[info.y - 1][info.x] != 0) { |
335 |
info.y--; |
336 |
info.doRow = false;
|
337 |
info.iDir = 5 ;
|
338 |
doContinue = true;
|
339 |
break;
|
340 |
} |
341 |
case 6: |
342 |
case 7: |
343 |
if(m_Col[info.y][info.x]!= 0) { |
344 |
info.doRow = false;
|
345 |
info.iDir = 7;
|
346 |
doContinue = true;
|
347 |
break;
|
348 |
} |
349 |
default:
|
350 |
info.iDir = 0;
|
351 |
doContinue = false;
|
352 |
} |
353 |
else
|
354 |
switch(info.iDir) {
|
355 |
case 0: |
356 |
case 1: |
357 |
if(m_Row[info.y + 1][info.x] != 0) { |
358 |
info.y++; |
359 |
info.doRow = true;
|
360 |
info.iDir = 1;
|
361 |
doContinue = true;
|
362 |
break;
|
363 |
} |
364 |
case 2: |
365 |
if(m_Col[info.y][info.x + 1] != 0) { |
366 |
info.x++; |
367 |
info.iDir = 2;
|
368 |
doContinue = true;
|
369 |
break;
|
370 |
} |
371 |
case 3: |
372 |
if(m_Row[info.y][info.x] != 0) { |
373 |
info.doRow = true;
|
374 |
info.iDir = 3;
|
375 |
doContinue = true;
|
376 |
break;
|
377 |
} |
378 |
case 4: |
379 |
case 5: |
380 |
if(info.x-1>=0) |
381 |
if(m_Row[info.y][info.x - 1] != 0) { |
382 |
info.x--; |
383 |
info.doRow = true;
|
384 |
info.iDir = 5;
|
385 |
doContinue = true;
|
386 |
break;
|
387 |
} |
388 |
case 6: |
389 |
if(info.x-1>=0) |
390 |
if(m_Col[info.y][info.x - 1] != 0) { |
391 |
info.x--; |
392 |
info.iDir = 6;
|
393 |
doContinue = true;
|
394 |
break;
|
395 |
} |
396 |
case 7: |
397 |
if(info.x-1 >= 0) |
398 |
if(m_Row[info.y + 1][info.x - 1] != 0) { |
399 |
info.x--; |
400 |
info.y++; |
401 |
info.doRow = true;
|
402 |
info.iDir = 7;
|
403 |
doContinue = true;
|
404 |
break;
|
405 |
} |
406 |
default:
|
407 |
info.iDir = 0;
|
408 |
doContinue = false;
|
409 |
} |
410 |
|
411 |
return(doContinue);
|
412 |
} |
413 |
|
414 |
/*
|
415 |
* (non-Javadoc)
|
416 |
* @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
|
417 |
*/
|
418 |
public int getPercent() { |
419 |
return (int)percent; |
420 |
} |
421 |
|
422 |
/*
|
423 |
* (non-Javadoc)
|
424 |
* @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
|
425 |
*/
|
426 |
public String getTitle() { |
427 |
return RasterToolsUtil.getText(this, "vectorization"); |
428 |
} |
429 |
|
430 |
// public void addShape(FShape shape, Value[] value) throws Exception {
|
431 |
// if (shape == null)
|
432 |
// return;
|
433 |
// IGeometry geom = ShapeFactory.createGeometry(shape);
|
434 |
// addGeometry(geom, value);
|
435 |
// }
|
436 |
|
437 |
public void addGeometry(Geometry geom, Object[] value) throws DataException { |
438 |
m_iGeometry++; |
439 |
EditableFeature ef=fsWriter.createNewFeature(); |
440 |
ef.set("ID", value[0]); |
441 |
ef.set("NAME",value[1]); |
442 |
ef.setGeometry("GEOMETRY", geom);
|
443 |
fsWriter.insert(ef); |
444 |
} |
445 |
private EditableFeatureType getFeatureType(){
|
446 |
EditableFeatureType eft=new DefaultEditableFeatureType();
|
447 |
|
448 |
EditableFeatureAttributeDescriptor efad1=eft.add("ID", DataTypes.DOUBLE);
|
449 |
efad1.setPrecision(5);
|
450 |
EditableFeatureAttributeDescriptor efad2=eft.add("NAME", DataTypes.DOUBLE);
|
451 |
efad2.setPrecision(5);
|
452 |
|
453 |
return eft;
|
454 |
} |
455 |
/**
|
456 |
* Returns the length of field
|
457 |
* @param dataType
|
458 |
* @return length of field
|
459 |
*/
|
460 |
public int getDataTypeLength(int dataType) { |
461 |
switch (dataType) {
|
462 |
case Types.NUMERIC: |
463 |
case Types.DOUBLE: |
464 |
case Types.REAL: |
465 |
case Types.FLOAT: |
466 |
case Types.BIGINT: |
467 |
case Types.INTEGER: |
468 |
case Types.DECIMAL: |
469 |
return 20; |
470 |
case Types.CHAR: |
471 |
case Types.VARCHAR: |
472 |
case Types.LONGVARCHAR: |
473 |
return 254; |
474 |
case Types.DATE: |
475 |
return 8; |
476 |
case Types.BOOLEAN: |
477 |
case Types.BIT: |
478 |
return 1; |
479 |
} |
480 |
return 0; |
481 |
} |
482 |
} |