Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extRasterTools-SE / src / org / gvsig / rastertools / vectorizacion / process / PotraceProcess.java @ 31410

History | View | Annotate | Download (9.96 KB)

1 23467 bsanchez
/* 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.awt.geom.AffineTransform;
22
import java.awt.geom.Point2D;
23
import java.io.File;
24
import java.sql.Types;
25
26
import org.cresques.cts.ProjectionPool;
27
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
28
import org.gvsig.raster.RasterProcess;
29 27442 nbrodin
import org.gvsig.raster.dataset.io.RasterDriverException;
30
import org.gvsig.raster.process.RasterTask;
31
import org.gvsig.raster.process.RasterTaskQueue;
32 23467 bsanchez
import org.gvsig.raster.util.RasterToolsUtil;
33
import org.gvsig.raster.vectorization.VectorizationBinding;
34
import org.gvsig.rastertools.vectorizacion.fmap.BezierPathX;
35
36 27442 nbrodin
import com.hardcode.gdbms.driver.exceptions.InitializeWriterException;
37 23467 bsanchez
import com.hardcode.gdbms.engine.values.Value;
38
import com.hardcode.gdbms.engine.values.ValueFactory;
39 27442 nbrodin
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
40 23467 bsanchez
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
41
import com.iver.cit.gvsig.fmap.core.FPolyline2D;
42
import com.iver.cit.gvsig.fmap.core.FShape;
43
import com.iver.cit.gvsig.fmap.core.IGeometry;
44
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
45
import com.iver.cit.gvsig.fmap.drivers.DXFLayerDefinition;
46
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
47
import com.iver.cit.gvsig.fmap.drivers.LayerDefinition;
48
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
49
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited;
50
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
51
import com.iver.cit.gvsig.fmap.edition.IWriter;
52
import com.iver.cit.gvsig.fmap.edition.writers.dxf.DxfFieldsMapping;
53
import com.iver.cit.gvsig.fmap.edition.writers.dxf.DxfWriter;
54
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
55
/**
56
 * Este proceso vectoriza la capa de entrada que debe estar ya preprocesada.
57
 * Usa la libreria de potrace por debajo.
58
 *
59
 * @version 15/09/2008
60
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
61
 */
62
public class PotraceProcess extends RasterProcess {
63 23667 bsanchez
        private double       percent               = 0;
64
        private FLyrRasterSE lyr                   = null;
65
        private String       fileName              = null;
66
        private IWriter      writer                = null;
67
        private Value        values[]              = null;
68
        private int          m_iGeometry           = 0;
69 23467 bsanchez
70 23667 bsanchez
        // Default Values
71
        private int          bezierPoints          = 7;
72
        private int          policy                = VectorizationBinding.POLICY_MINORITY;
73
        private int          despeckle             = 0;
74
        private double       cornerThreshold       = 1.0;
75
        private double       optimizationTolerance = 0.2;
76
        private int          outputQuantization    = 10;
77
        private boolean      curveOptimization     = true;
78
79
80 23467 bsanchez
        /*
81
         * (non-Javadoc)
82
         * @see org.gvsig.raster.RasterProcess#init()
83
         */
84
        public void init() {
85
                lyr = getLayerParam("layer");
86
                fileName = getStringParam("filename");
87 23520 bsanchez
                policy = getIntParam("policy");
88 23521 bsanchez
                bezierPoints = getIntParam("points");
89 23667 bsanchez
                despeckle = getIntParam("despeckle");
90
                cornerThreshold = getDoubleParam("cornerThreshold");
91
                optimizationTolerance = getDoubleParam("optimizationTolerance");
92
                outputQuantization = getIntParam("outputQuantization");
93
                curveOptimization = getBooleanParam("curveoptimization");
94 23467 bsanchez
        }
95
96
        /*
97
         * (non-Javadoc)
98
         * @see org.gvsig.raster.RasterProcess#process()
99
         */
100
        public void process() throws InterruptedException {
101
                try {
102 27442 nbrodin
                        insertLineLog("Potrace");
103 23467 bsanchez
                        generatePotrace();
104 27442 nbrodin
                } catch (VisitorException e) {
105 23467 bsanchez
                        RasterToolsUtil.messageBoxError("error_closing_grid", this, e);
106 27442 nbrodin
                } catch (InitializeWriterException e) {
107
                        RasterToolsUtil.messageBoxError("error_closing_grid", this, e);
108
                } catch (RasterDriverException e) {
109
                        RasterToolsUtil.messageBoxError("error_closing_grid", this, e);
110 23467 bsanchez
                } finally {
111 27442 nbrodin
                        if (incrementableTask != null) {
112
                                incrementableTask.processFinalize();
113
                                incrementableTask = null;
114
                        }
115 23467 bsanchez
                }
116 27442 nbrodin
                if (externalActions != null)
117
                        externalActions.end(fileName);
118 23467 bsanchez
        }
119
120
        /**
121
         * Genera la capa vectorial a partir del raster de entrada
122
         *
123
         * @param lyr
124
         * @param fileOut
125 23521 bsanchez
         * @param bezierPoints
126 27442 nbrodin
         * @throws RasterDriverException
127
         * @throws InterruptedException
128
         * @throws VisitorException
129
         * @throws InitializeWriterException
130 23467 bsanchez
         * @throws Exception
131
         */
132 27442 nbrodin
        public void generatePotrace() throws InterruptedException, RasterDriverException, VisitorException, InitializeWriterException {
133 23467 bsanchez
                VectorizationBinding binding = new VectorizationBinding(lyr.getBufferFactory());
134 23520 bsanchez
                binding.setPolicy(policy);
135 23667 bsanchez
                binding.setDespeckle(despeckle);
136
                binding.setCornerThreshold(cornerThreshold);
137
                binding.setOptimizationTolerance(optimizationTolerance);
138
                binding.setOutputQuantization(outputQuantization);
139
                binding.setEnabledCurveOptimization(curveOptimization);
140
141 23467 bsanchez
                // binding.setCornerThreshold(-1);
142
                double geometrias[] = binding.VectorizeBuffer();
143
144
                String sFields[] = new String[2];
145
                sFields[0] = "ID";
146
                sFields[1] = fileName + "";
147
148
                LayerDefinition tableDef = null;
149
                if (fileName.endsWith(".dxf")) {
150
                        writer = new DxfWriter();
151
                        ((DxfWriter) writer).setFile(new File(fileName));
152
                        ProjectionPool pool = new ProjectionPool();
153
                        ((DxfWriter) writer).setProjection(pool.get("EPSG:23030"));
154
                        tableDef = new DXFLayerDefinition();
155
156
                        DxfFieldsMapping fieldsMapping = new DxfFieldsMapping();
157
                        ((DxfWriter) writer).setFieldMapping(fieldsMapping);
158
                }
159
                if (fileName.endsWith(".shp")) {
160
                        writer = new ShpWriter();
161
                        ((ShpWriter) writer).setFile(new File(fileName));
162
                        tableDef = new SHPLayerDefinition();
163
                }
164
                tableDef.setShapeType(FShape.LINE);
165
166
                int types[] = { Types.DOUBLE, Types.DOUBLE };
167
                FieldDescription[] fields = new FieldDescription[sFields.length];
168
                for (int i = 0; i < fields.length; i++) {
169
                        fields[i] = new FieldDescription();
170
                        fields[i].setFieldName(sFields[i]);
171
                        fields[i].setFieldType(types[i]);
172
                        fields[i].setFieldLength(getDataTypeLength(types[i]));
173
                        fields[i].setFieldDecimalCount(5);
174
                }
175
                tableDef.setFieldsDesc(fields);
176
                tableDef.setName(fileName);
177
178
                writer.initialize(tableDef);
179
                writer.preProcess();
180
181
                values = new Value[2];
182
                values[0] = ValueFactory.createValue(0);
183
                values[1] = ValueFactory.createValue(0);
184
185 23521 bsanchez
                showPotrace(geometrias, bezierPoints);
186 23467 bsanchez
187
                writer.postProcess();
188
        }
189
190 27442 nbrodin
        public void addShape(FShape shape, Value[] value) throws VisitorException {
191 23467 bsanchez
                if (shape == null)
192
                        return;
193
                IGeometry geom = ShapeFactory.createGeometry(shape);
194
                addGeometry(geom, value);
195
        }
196
197 27442 nbrodin
        public void addGeometry(IGeometry geom, Value[] value) throws VisitorException {
198 23467 bsanchez
                DefaultFeature feat = new DefaultFeature(geom, value, Integer.toString(m_iGeometry));
199
                IRowEdited editFeat = new DefaultRowEdited(feat, IRowEdited.STATUS_MODIFIED, m_iGeometry);
200
                m_iGeometry++;
201
                writer.process(editFeat);
202
        }
203
204
        private Point2D getTransformPixel(double x, double y) {
205
                AffineTransform at = lyr.getAffineTransform();
206
                Point2D ptSrc = new Point2D.Double(x, lyr.getPxHeight() - y);
207
                at.transform(ptSrc, ptSrc);
208
                return ptSrc;
209
        }
210
211 27442 nbrodin
        private void showPotrace(double[] potraceX, int trozos) throws InterruptedException, VisitorException {
212
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
213 23467 bsanchez
                BezierPathX pathX = new BezierPathX(trozos);
214
215 27442 nbrodin
                double increment = (100 / (double)potraceX.length);
216 23467 bsanchez
                int cont = 1;
217
                while (true) {
218
                        if ((cont >= potraceX.length) || (cont >= potraceX[0]))
219
                                return;
220
                        switch ((int) potraceX[cont]) {
221
                                case 0: // MoveTo
222
                                        pathX.moveTo(getTransformPixel(potraceX[cont + 1], potraceX[cont + 2]));
223
                                        cont += 3;
224 27442 nbrodin
                                        percent += (increment * 3);
225 23467 bsanchez
                                        break;
226
                                case 1: // LineTo
227
                                        pathX.lineTo(getTransformPixel(potraceX[cont + 1], potraceX[cont + 2]));
228
                                        cont += 3;
229 27442 nbrodin
                                        percent += (increment * 3);
230 23467 bsanchez
                                        break;
231
                                case 2: // CurveTo
232
                                        pathX.curveTo(getTransformPixel(potraceX[cont + 1], potraceX[cont + 2]), getTransformPixel(potraceX[cont + 3], potraceX[cont + 4]), getTransformPixel(potraceX[cont + 5], potraceX[cont + 6]));
233
                                        cont += 7;
234 27442 nbrodin
                                        percent += (increment * 7);
235 23467 bsanchez
                                        break;
236
                                case 3: // closePath
237
                                        FPolyline2D line =  new FPolyline2D(pathX);
238
                                        addShape(line, values);
239
                                        pathX = new BezierPathX(trozos);
240
                                        cont ++;
241 27442 nbrodin
                                        percent += increment;
242 23467 bsanchez
                                        break;
243
                        }
244 27442 nbrodin
                        if(task.getEvent() != null)
245
                                task.manageEvent(task.getEvent());
246 23467 bsanchez
                }
247
        }
248
249
        /*
250
         * (non-Javadoc)
251
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
252
         */
253
        public int getPercent() {
254
                return (int) percent;
255
        }
256
257
        /*
258
         * (non-Javadoc)
259
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
260
         */
261
        public String getTitle() {
262
                return RasterToolsUtil.getText(this, "vectorization");
263
        }
264
265
        /**
266
         * Returns the length of field
267
         * @param dataType
268
         * @return length of field
269
         */
270
        public int getDataTypeLength(int dataType) {
271
                switch (dataType) {
272
                case Types.NUMERIC:
273
                case Types.DOUBLE:
274
                case Types.REAL:
275
                case Types.FLOAT:
276
                case Types.BIGINT:
277
                case Types.INTEGER:
278
                case Types.DECIMAL:
279
                        return 20;
280
                case Types.CHAR:
281
                case Types.VARCHAR:
282
                case Types.LONGVARCHAR:
283
                        return 254;
284
                case Types.DATE:
285
                        return 8;
286
                case Types.BOOLEAN:
287
                case Types.BIT:
288
                        return 1;
289
                }
290
                return 0;
291
        }
292
}