Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / process / vector / PotraceVectorization.java @ 2443

History | View | Annotate | Download (9.43 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.impl.process.vector;
23

    
24
import java.util.ArrayList;
25
import java.util.List;
26

    
27
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
28
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
29
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
30
import org.gvsig.fmap.dal.coverage.exception.QueryException;
31
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
32
import org.gvsig.fmap.dal.coverage.process.vector.Vectorization;
33
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
34
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
35
import org.gvsig.fmap.dal.exception.InitializeException;
36
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
37
import org.gvsig.jpotrace.Potrace;
38
import org.gvsig.jpotrace.PotraceException;
39
import org.gvsig.raster.impl.DefaultRasterManager;
40
import org.gvsig.raster.impl.store.QueryableRaster;
41
/**
42
 * La clase VectorizationBinding se usa para poder vectorizar una capa raster.<p>
43
 * 
44
 * La entrada es una capa raster, ya sea en un fichero, BufferFactory o un
45
 * RasterDataset.<p>
46
 * 
47
 * El uso de comunicacion con la libreria jpotrace es como funciona el comando
48
 * potrace, de hecho, se pueden a?adir mas opciones si potrace los admite por
49
 * linea de comandos.<p>
50
 * 
51
 * Una vez creada una instancia a VectorizationBinding. Se definen todos los
52
 * parametros deseables o en caso de no definirlos se usaran los valores por
53
 * defecto y se invoca al metodo VectorizeBuffer()<p>
54
 * 
55
 * Este ultimo metodo, devuelve un array de doubles indicando si lo que se ha
56
 * devuelto son operaciones tipicas de shapes... MoveTo, LineTo, CurveTo, etc...<p>
57
 * 
58
 * En la primera posicion se devuelve el tama?o del array.<p>
59
 * 
60
 * 03/09/2008
61
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
62
 */
63
public class PotraceVectorization implements Vectorization {
64
        private Buffer          buffer                = null;
65
        private Double          cornerThreshold       = null;
66
        private Integer         despeckle             = null;
67
        private Integer         policy                = null;
68
        private Double          optimizationTolerance = null;
69
        private boolean         curveOptimization     = true;
70
        private Integer         outputQuantization    = null;
71
        private RasterQuery     query                 = null;
72

    
73
        /**
74
         * Construye un VectorizationBinding a partir de la ruta de un Raster
75
         * @param file
76
         * @throws NotSupportedExtensionException
77
         * @throws RasterDriverException
78
         * @throws ProcessInterruptedException
79
         */
80
        public PotraceVectorization(String file) throws QueryException, NotSupportedExtensionException, RasterDriverException, ProcessInterruptedException {
81
                this.setFile(file);
82
        }
83

    
84
        /**
85
         * Construye un VectorizationBinding a partir de un RasterDataset
86
         * @param dataset
87
         * @throws RasterDriverException 
88
         * @throws ProcessInterruptedException 
89
         * @throws ProcessInterruptedException
90
         * @throws RasterDriverException
91
         */
92
        public PotraceVectorization(QueryableRaster dataset) throws ProcessInterruptedException, QueryException {
93
                setDataSource((RasterDataStore)dataset);
94
        }
95

    
96
        /**
97
         * Construye un VectorizationBinding a partir de un BufferFactory
98
         * @param bufferFactory
99
         * @throws RasterDriverException 
100
         * @throws ProcessInterruptedException 
101
         * @throws ProcessInterruptedException
102
         * @throws RasterDriverException
103
         */
104
        public PotraceVectorization(RasterDataStore dataSource) throws ProcessInterruptedException, QueryException {
105
                setDataSource(dataSource);
106
        }
107
        
108
        /**
109
         * Se especifica el fichero del raster
110
         * @param file
111
         * @throws NotSupportedExtensionException
112
         * @throws RasterDriverException
113
         * @throws ProcessInterruptedException
114
         */
115
        private void setFile(String file) throws QueryException, NotSupportedExtensionException, RasterDriverException, ProcessInterruptedException {
116
                RasterDataStore ds = null;
117
                try {
118
                        ds = DefaultRasterManager.getInstance().getProviderServices().open(file);
119
                } catch (InitializeException e) {
120
                        throw new RasterDriverException("Error opening file", e);
121
                } catch (ProviderNotRegisteredException e) {
122
                        throw new RasterDriverException("Error opening file", e);
123
                }
124
                setDataSource(ds);
125
        }
126

    
127
        /**
128
         * Se especifica el BufferFactory
129
         * @param bufferFactory
130
         * @throws ProcessInterruptedException
131
         * @throws RasterDriverException
132
         */
133
        private void setDataSource(RasterDataStore dataSource) throws ProcessInterruptedException, QueryException {
134
                query.setAllDrawableBands();
135
                query.setAreaOfInterest();
136
                setRasterBuffer(dataSource.query(query));
137
        }
138

    
139
        /**
140
         * Se establece el RasterBuffer
141
         * @param buffer
142
         */
143
        private void setRasterBuffer(Buffer buffer) {
144
                this.buffer = buffer;
145
        }
146

    
147
        /**
148
         * Pone a 1 la posici?n del bit pasado por parametro en el value. Operaci?n binaria OR
149
         * @param value
150
         * @param pos
151
         * @return
152
         */
153
        private int enableBit(int value, int pos) {
154
                value = (value | ((int)1 << pos));
155
                return value;
156
        }
157
        
158
        /**
159
         * Set the corner threshold parameter (default 1)
160
         * @param value
161
         */
162
        public void setCornerThreshold(double value) {
163
                cornerThreshold = new Double(value);
164
        }
165

    
166
        /**
167
         * Quantize output to 1/unit pixels (default 10)
168
         * @param value
169
         */
170
        public void setOutputQuantization(int value) {
171
                outputQuantization = new Integer(value);
172
        }
173

    
174
        /**
175
         * Suppress speckles of up to this size (default 2)
176
         * @param value
177
         */
178
        public void setDespeckle(int value) {
179
                despeckle = new Integer(value);
180
        }
181

    
182
        /**
183
         * Set how to resolve ambiguities in path decomposition<p>
184
         * 
185
         * Use:<br><b>
186
         *          POLICY_BLACK<br>
187
         *   POLICY_LEFT<br>
188
         *   POLICY_MAJORITY<br>
189
         *   POLICY_MINORITY<br>
190
         *   POLICY_RANDOM<br>
191
         *   POLICY_RIGHT<br>
192
         *   POLICY_WHITE</b>
193
         *  
194
         * @param value
195
         */
196
        public void setPolicy(int value) {
197
                policy = new Integer(value);
198
        }
199
        
200
        /**
201
         * Set the curve optimization tolerance (default 0.2)
202
         * @param value
203
         */
204
        public void setOptimizationTolerance(double value) {
205
                optimizationTolerance = new Double(value);
206
        }
207

    
208
        /**
209
         * Return if the curve optimization is enabled or disabled
210
         * @param value
211
         */
212
        public boolean isEnabledCurveOptimization() {
213
                return curveOptimization;
214
        }
215

    
216
        /**
217
         * Enable/Disable the curve optimization (default enabled)
218
         * @param value
219
         */
220
        public void setEnabledCurveOptimization(boolean value) {
221
                curveOptimization = value;
222
        }
223
        
224
        /**
225
         * Devuelve los parametros en formato de array (Similar a como los recibe el
226
         * main de un fichero en c) indicando la llamada entera al comando potrace.
227
         * @return
228
         */
229
        private String[] getParams() {
230
                List<String> params = new ArrayList<String>();
231
                params.add("./potrace");
232

    
233
                if (cornerThreshold != null) {
234
                        params.add("-a");
235
                        params.add(cornerThreshold.toString());
236
                }
237

    
238
                if (despeckle != null) {
239
                        params.add("-t");
240
                        params.add(despeckle.toString());
241
                }
242
                
243
                if (outputQuantization != null) {
244
                        params.add("-u");
245
                        params.add(outputQuantization.toString());
246
                }
247
                
248
                if (policy != null) {
249
                        String param = null;
250
                        switch (policy.intValue()) {
251
                                case POLICY_BLACK:
252
                                        param = "black";
253
                                        break;
254
                                case POLICY_WHITE:
255
                                        param = "white";
256
                                        break;
257
                                case POLICY_LEFT:
258
                                        param = "left";
259
                                        break;
260
                                case POLICY_RIGHT:
261
                                        param = "right";
262
                                        break;
263
                                case POLICY_MINORITY:
264
                                        param = "minority";
265
                                        break;
266
                                case POLICY_MAJORITY:
267
                                        param = "majority";
268
                                        break;
269
                                case POLICY_RANDOM:
270
                                        param = "random";
271
                                        break;
272
                        }
273
                        if (param != null) {
274
                                params.add("-z");
275
                                params.add(param);
276
                        }
277
                }
278
                
279
                if (optimizationTolerance != null) {
280
                        // Curve optimization tolerance
281
                        params.add("-O");
282
                        params.add(optimizationTolerance.toString());
283
                }
284
                
285
                if (!curveOptimization) {
286
                        // turn off curve optimization
287
                        params.add("-n"); 
288
                }
289

    
290
                String[] strings = new String[params.size()];
291
                for (int i = 0; i < strings.length; i++) {
292
                        strings[i] = (String) params.get(i);
293
                }
294

    
295
                return strings;
296
        }
297

    
298
        /**
299
         * Hace el proeso de Vectorizacion de un Raster
300
         * @return
301
         * @throws PotraceException
302
         */
303
        public double[] VectorizeBuffer() {
304
                int dy = (buffer.getWidth() + 32 - 1) / 32;
305

    
306
                int[] bufferBits = new int[buffer.getHeight() * dy];
307

    
308
                for (int i = 0; i < bufferBits.length; i++)
309
                        bufferBits[i] = 0;
310
                
311
                int bit = 0;
312
                int pos = 0;
313
                for (int i = 0; i < buffer.getHeight(); i++) {
314
                        pos = (buffer.getHeight() - i - 1) * dy;
315
                        bit = 0;
316
                        for (int j = 0; j < buffer.getWidth(); j++) {
317
                                byte data = buffer.getElemByte(i, j, 0);
318

    
319
                                if (data == 0) {
320
                                        bufferBits[pos] = enableBit(bufferBits[pos], 31 - bit);
321
                                }
322

    
323
                                bit++;
324
                                if (bit >= 32) {
325
                                        bit = 0;
326
                                        pos++;
327
                                }
328
                        }
329
                }
330

    
331
                try {
332
                        return Potrace.vectorizeBufferRaster(bufferBits, buffer.getWidth(), buffer.getHeight(), getParams());
333
                } catch (PotraceException e) {
334
                }
335
                return null;
336
        }
337
}