Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / extRasterTools-SE / src / org / gvsig / rastertools / vectorizacion / process / PotraceProcess.java @ 28155

History | View | Annotate | Download (10.4 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.awt.geom.AffineTransform;
22
import java.awt.geom.Point2D;
23
import java.io.File;
24
import java.sql.Types;
25

    
26
import org.gvsig.fmap.crs.CRSFactory;
27
import org.gvsig.fmap.dal.DALLocator;
28
import org.gvsig.fmap.dal.DataManager;
29
import org.gvsig.fmap.dal.DataTypes;
30
import org.gvsig.fmap.dal.exception.DataException;
31
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
32
import org.gvsig.fmap.dal.feature.EditableFeature;
33
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
34
import org.gvsig.fmap.dal.feature.EditableFeatureType;
35
import org.gvsig.fmap.dal.feature.FeatureStore;
36
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
37
import org.gvsig.fmap.dal.feature.impl.DefaultEditableFeatureType;
38
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
39
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
40
import org.gvsig.fmap.geom.Geometry;
41
import org.gvsig.fmap.geom.GeometryLocator;
42
import org.gvsig.fmap.geom.GeometryManager;
43
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
44
import org.gvsig.fmap.geom.exception.CreateGeometryException;
45
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
46
import org.gvsig.raster.RasterProcess;
47
import org.gvsig.raster.dataset.io.RasterDriverException;
48
import org.gvsig.raster.process.RasterTask;
49
import org.gvsig.raster.process.RasterTaskQueue;
50
import org.gvsig.raster.util.RasterToolsUtil;
51
import org.gvsig.raster.vectorization.VectorizationBinding;
52
import org.gvsig.rastertools.vectorizacion.fmap.BezierPathX;
53
/**
54
 * Este proceso vectoriza la capa de entrada que debe estar ya preprocesada.
55
 * Usa la libreria de potrace por debajo.
56
 *
57
 * @version 15/09/2008
58
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
59
 */
60
public class PotraceProcess extends RasterProcess {
61
        private static final GeometryManager        geomManager                   = GeometryLocator.getGeometryManager();
62
        private double                                               percent               = 0;
63
        private FLyrRasterSE                                         lyr                   = null;
64
        private String                                               fileName              = null;
65
        private FeatureStore                                         fsWriter              = null;
66
        private Object[]                                             values                = null;
67
        private int                                                  m_iGeometry           = 0;
68

    
69
        // Default Values
70
        private int                                                  bezierPoints          = 7;
71
        private int                                                  policy                = VectorizationBinding.POLICY_MINORITY;
72
        private int                                                  despeckle             = 0;
73
        private double                                               cornerThreshold       = 1.0;
74
        private double                                      optimizationTolerance = 0.2;
75
        private int                                                 outputQuantization    = 10;
76
        private boolean                                              curveOptimization     = true;
77

    
78

    
79
        /*
80
         * (non-Javadoc)
81
         * @see org.gvsig.raster.RasterProcess#init()
82
         */
83
        public void init() {
84
                lyr = getLayerParam("layer");
85
                fileName = getStringParam("filename");
86
                policy = getIntParam("policy");
87
                bezierPoints = getIntParam("points");
88
                despeckle = getIntParam("despeckle");
89
                cornerThreshold = getDoubleParam("cornerThreshold");
90
                optimizationTolerance = getDoubleParam("optimizationTolerance");
91
                outputQuantization = getIntParam("outputQuantization");
92
                curveOptimization = getBooleanParam("curveoptimization");
93
        }
94

    
95
        /*
96
         * (non-Javadoc)
97
         * @see org.gvsig.raster.RasterProcess#process()
98
         */
99
        public void process() throws InterruptedException {
100
                try {
101
                        insertLineLog("Potrace");
102
                        generatePotrace();
103
                } catch (DataException e) {
104
                        RasterToolsUtil.messageBoxError("error_loading_store", this, e);
105
                } catch (CreateGeometryException e) {
106
                        RasterToolsUtil.messageBoxError("error_closing_grid", this, e);
107
                } catch (RasterDriverException e) {
108
                        RasterToolsUtil.messageBoxError("error_closing_grid", this, e);
109
                } catch (ValidateDataParametersException e) {
110
                        RasterToolsUtil.messageBoxError("error_loading_store", this, e);
111
                } catch (NullPointerException e) {
112
                        e.printStackTrace();
113
                } finally {
114
                        if (incrementableTask != null) {
115
                                incrementableTask.processFinalize();
116
                                incrementableTask = null;
117
                        }
118
                }
119
                if (externalActions != null)
120
                        externalActions.end(fileName);
121
        }
122

    
123
        /**
124
         * Genera la capa vectorial a partir del raster de entrada
125
         * 
126
         * @param lyr
127
         * @param fileOut
128
         * @param bezierPoints
129
         * @throws CreateGeometryException
130
         * @throws ValidateDataParametersException
131
         * @throws Exception
132
         */
133
        public void generatePotrace() throws InterruptedException,
134
                        RasterDriverException, DataException, CreateGeometryException,
135
                        ValidateDataParametersException {
136
                VectorizationBinding binding = new VectorizationBinding(lyr.getBufferFactory());
137
                binding.setPolicy(policy);
138
                binding.setDespeckle(despeckle);
139
                binding.setCornerThreshold(cornerThreshold);
140
                binding.setOptimizationTolerance(optimizationTolerance);
141
                binding.setOutputQuantization(outputQuantization);
142
                binding.setEnabledCurveOptimization(curveOptimization);
143

    
144
                // binding.setCornerThreshold(-1);
145
                double geometrias[] = binding.VectorizeBuffer();
146

    
147
                String sFields[] = new String[2];
148
                sFields[0] = "ID";
149
                sFields[1] = fileName + "";
150
                
151
                EditableFeatureType featureType = getFeatureType(fileName);
152

    
153
                EditableFeatureAttributeDescriptor efad = featureType.add("GEOMETRY", DataTypes.GEOMETRY);
154
                efad.setGeometryType(Geometry.TYPES.CURVE);
155
                efad.setSRS(CRSFactory.getCRS("EPSG:23030"));
156
                featureType.setDefaultGeometryAttributeName("GEOMETRY");
157

    
158
                DataManager datamanager = DALLocator.getDataManager();
159
                FilesystemServerExplorerParameters explorerParams;
160

    
161
                explorerParams = (FilesystemServerExplorerParameters) datamanager.createServerExplorerParameters(FilesystemServerExplorer.NAME);
162

    
163
                explorerParams.setRoot(new File(fileName).getParent());
164
                FilesystemServerExplorer explorer = (FilesystemServerExplorer) datamanager.createServerExplorer(explorerParams);
165
                NewFeatureStoreParameters newParams = (NewFeatureStoreParameters) explorer.getAddParameters(new File(fileName));
166

    
167
                newParams.setDefaultFeatureType(featureType);
168
                newParams.setDynValue("srs", CRSFactory.getCRS("EPSG:23030"));
169
                explorer.add(newParams, true);
170
                DataManager manager = DALLocator.getDataManager();
171
                ////////////////////////
172
                fsWriter = (FeatureStore)manager.createStore(newParams);
173
                fsWriter.edit(FeatureStore.MODE_APPEND);
174

    
175
                values = new Object[2];
176
                values[0] = new Double(0);
177
                values[1] = new Double(0);
178

    
179
                showPotrace(geometrias, bezierPoints);
180

    
181
                fsWriter.finishEditing();
182
        }
183

    
184
        public void addGeometry(Geometry geom, Object[] value) throws DataException {
185
                m_iGeometry++;
186
                EditableFeature ef = fsWriter.createNewFeature();
187
                ef.set("ID", value[0]);
188
                ef.set("NAME", value[1]);
189
                ef.setGeometry("GEOMETRY", geom);
190
                fsWriter.insert(ef);
191
        }
192

    
193
        private Point2D getTransformPixel(double x, double y) {
194
                AffineTransform at = lyr.getAffineTransform();
195
                Point2D ptSrc = new Point2D.Double(x, lyr.getPxHeight() - y);
196
                at.transform(ptSrc, ptSrc);
197
                return ptSrc;
198
        }
199

    
200
        private void showPotrace(double[] potraceX, int trozos) throws DataException, CreateGeometryException, InterruptedException {
201
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
202
                BezierPathX pathX = new BezierPathX(trozos);
203
                int ID = 0;
204
                double dZ;
205
                
206
                double increment = (100 / (double)potraceX.length);
207
                int cont = 1;
208
                while (true) {
209
                        if ((cont >= potraceX.length) || (cont >= potraceX[0]))
210
                                return;
211
                        switch ((int) potraceX[cont]) {
212
                                case 0: // MoveTo
213
                                        pathX.moveTo(getTransformPixel(potraceX[cont + 1], potraceX[cont + 2]));
214
                                        cont += 3;
215
                                        percent += (increment * 3);
216
                                        break;
217
                                case 1: // LineTo
218
                                        pathX.lineTo(getTransformPixel(potraceX[cont + 1], potraceX[cont + 2]));
219
                                        cont += 3;
220
                                        percent += (increment * 3);
221
                                        break;
222
                                case 2: // CurveTo
223
                                        pathX.curveTo(getTransformPixel(potraceX[cont + 1], potraceX[cont + 2]), getTransformPixel(potraceX[cont + 3], potraceX[cont + 4]), getTransformPixel(potraceX[cont + 5], potraceX[cont + 6]));
224
                                        cont += 7;
225
                                        percent += (increment * 7);
226
                                        break;
227
                                case 3: // closePath
228
                                        Geometry line =  geomManager.createCurve(pathX, SUBTYPES.GEOM2D);
229
                                        ID ++;
230
                                        values[0] = new Double(ID);
231
                                        addGeometry(line, values);
232
                                        pathX = new BezierPathX(trozos);
233
                                        cont ++;
234
                                        percent += increment;
235
                                        break;
236
                        }
237
                        if(task.getEvent() != null)
238
                                task.manageEvent(task.getEvent());
239
                }
240
        }
241
        private EditableFeatureType getFeatureType(String fileName){
242
                EditableFeatureType eft=new DefaultEditableFeatureType();
243

    
244
                EditableFeatureAttributeDescriptor efad1 = eft.add("ID", DataTypes.DOUBLE);
245
                efad1.setPrecision(5);
246
                EditableFeatureAttributeDescriptor efad2 = eft.add("NAME", DataTypes.DOUBLE);
247
                efad2.setPrecision(5);
248

    
249
                return eft;
250
        }
251
        /*
252
         * (non-Javadoc)
253
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
254
         */
255
        public int getPercent() {
256
                return (int) percent;
257
        }
258

    
259
        /*
260
         * (non-Javadoc)
261
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
262
         */
263
        public String getTitle() {
264
                return RasterToolsUtil.getText(this, "vectorization");
265
        }
266

    
267
        /**
268
         * Returns the length of field
269
         * @param dataType
270
         * @return length of field
271
         */
272
        public int getDataTypeLength(int dataType) {
273
                switch (dataType) {
274
                case Types.NUMERIC:
275
                case Types.DOUBLE:
276
                case Types.REAL:
277
                case Types.FLOAT:
278
                case Types.BIGINT:
279
                case Types.INTEGER:
280
                case Types.DECIMAL:
281
                        return 20;
282
                case Types.CHAR:
283
                case Types.VARCHAR:
284
                case Types.LONGVARCHAR:
285
                        return 254;
286
                case Types.DATE:
287
                        return 8;
288
                case Types.BOOLEAN:
289
                case Types.BIT:
290
                        return 1;
291
                }
292
                return 0;
293
        }
294
}