Revision 23307

View differences:

trunk/extensions/extRasterTools-SE/src/org/gvsig/rastertools/vectorizacion/fmap/BezierPathX.java
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.fmap;
20

  
21
import java.awt.geom.Point2D;
22

  
23
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
24
/**
25
 * Reimplementacion del GeneralPathX para que acepte curvas de Bezier
26
 * 
27
 * @version 28/08/2008
28
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
29
 */
30
public class BezierPathX extends GeneralPathX {
31
	private static final long serialVersionUID = -77239133302246295L;
32
	private Point2D lastPoint      = new Point2D.Double(0, 0);
33
	private int     numberOfPoints = 1;
34

  
35
	/**
36
	 * Crea un GeneralPathX definiendo cuantos cortes tendr? en las curvas de
37
	 * Bezier. Cuanto mayor sea el numero de puntos, mejor definido estar?
38
	 * @param numberOfPoints
39
	 */
40
	public BezierPathX(int numberOfPoints) {
41
		this.numberOfPoints = numberOfPoints;
42
	}
43

  
44
	/**
45
	 * Devuelve el punto de la curva de Bezier para el intervalo t
46
	 * @param cp
47
	 * @param t
48
	 * @return
49
	 */
50
	private Point2D pointOnCubicBezier(Point2D[] cp, double t) {
51
		double ax, bx, cx;
52
		double ay, by, cy;
53
		double tSquared, tCubed;
54
		Point2D result = new Point2D.Double();
55

  
56
		/* c?lculo de los coeficientes polinomiales */
57

  
58
		cx = 3.0 * (cp[1].getX() - cp[0].getX());
59
		bx = 3.0 * (cp[2].getX() - cp[1].getX()) - cx;
60
		ax = cp[3].getX() - cp[0].getX() - cx - bx;
61

  
62
		cy = 3.0 * (cp[1].getY() - cp[0].getY());
63
		by = 3.0 * (cp[2].getY() - cp[1].getY()) - cy;
64
		ay = cp[3].getY() - cp[0].getY() - cy - by;
65

  
66
		/* calculate the curve point at parameter value t */
67

  
68
		tSquared = t * t;
69
		tCubed = tSquared * t;
70

  
71
		result.setLocation((ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].getX(), (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].getY());
72

  
73
		return result;
74
	}
75

  
76
	/*
77
	 * (non-Javadoc)
78
	 * @see com.iver.cit.gvsig.fmap.core.GeneralPathX#curveTo(double, double, double, double, double, double)
79
	 */
80
	public synchronized void curveTo(double x1, double y1, double x2, double y2, double x3, double y3) {
81
		Point2D points[] = new Point2D[4];
82
		points[0] = new Point2D.Double(lastPoint.getX(), lastPoint.getY());
83
		points[1] = new Point2D.Double(x1, y1);
84
		points[2] = new Point2D.Double(x2, y2);
85
		points[3] = new Point2D.Double(x3, y3);
86

  
87
		double dt = 1.0 / (numberOfPoints - 1);
88

  
89
		Point2D aux;
90
		for (int i = 0; i < numberOfPoints; i++) {
91
			aux = pointOnCubicBezier(points, i * dt);
92
			lineTo(aux.getX(), aux.getY());
93
		}
94
	}
95

  
96
	/*
97
	 * (non-Javadoc)
98
	 * @see com.iver.cit.gvsig.fmap.core.GeneralPathX#lineTo(double, double)
99
	 */
100
	public synchronized void lineTo(double x, double y) {
101
		super.lineTo(x, y);
102
		lastPoint.setLocation(x, y);
103
	}
104

  
105
	/*
106
	 * (non-Javadoc)
107
	 * @see com.iver.cit.gvsig.fmap.core.GeneralPathX#moveTo(double, double)
108
	 */
109
	public synchronized void moveTo(double x, double y) {
110
		super.moveTo(x, y);
111
		lastPoint.setLocation(x, y);
112
	}
113
}
0 114

  
trunk/extensions/extRasterTools-SE/src-test/org/gvsig/rastertools/vectorization/TestRasterPotrace.java
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.vectorization;
20

  
21
import java.io.File;
22
import java.sql.Types;
23
import java.text.DecimalFormat;
24
import java.text.NumberFormat;
25

  
26
import org.cresques.cts.ProjectionPool;
27
import org.gvsig.raster.dataset.NotSupportedExtensionException;
28
import org.gvsig.raster.dataset.io.RasterDriverException;
29
import org.gvsig.raster.vectorization.VectorizationBinding;
30
import org.gvsig.rastertools.vectorizacion.fmap.BezierPathX;
31

  
32
import com.hardcode.gdbms.driver.exceptions.InitializeWriterException;
33
import com.hardcode.gdbms.engine.values.Value;
34
import com.hardcode.gdbms.engine.values.ValueFactory;
35
import com.iver.cit.gvsig.exceptions.visitors.StartWriterVisitorException;
36
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
37
import com.iver.cit.gvsig.fmap.core.FPolyline2D;
38
import com.iver.cit.gvsig.fmap.core.FShape;
39
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
40
import com.iver.cit.gvsig.fmap.core.IGeometry;
41
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
42
import com.iver.cit.gvsig.fmap.drivers.DXFLayerDefinition;
43
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
44
import com.iver.cit.gvsig.fmap.drivers.LayerDefinition;
45
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
46
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited;
47
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
48
import com.iver.cit.gvsig.fmap.edition.IWriter;
49
import com.iver.cit.gvsig.fmap.edition.writers.dxf.DxfFieldsMapping;
50
import com.iver.cit.gvsig.fmap.edition.writers.dxf.DxfWriter;
51
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
52
/**
53
* 
54
* @version 05/08/2008
55
* @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
56
*/
57
public class TestRasterPotrace {
58
	private String        baseDir     = "./test-images/";
59
	private String        fileName    = "wheel";
60
//	private String        fileName    = "letters";
61
//	private String        fileName    = "potrace";
62

  
63
	private String        fileIn      = baseDir + fileName + ".bmp";
64
//	private String        fileIn      = baseDir + "NewLayer_6.tif";
65
	
66
	private String        fileOutBase = "/tmp/" + fileName;
67

  
68
	private Value         values[];
69
	private FPolyline2D   line        = null;
70
	private GeneralPathX  pathX       = null;
71
	private IWriter       writer;
72
	private int           m_iGeometry = 0;
73
	
74
	public void generatePotrace(String fileIn, String fileOutBase, int trozos) {
75
		NumberFormat formatter = new DecimalFormat("000");
76
		String s = formatter.format(trozos);
77

  
78
		String fileOutShape = fileOutBase + s + ".shp";
79
		String fieldName = fileName + s;
80
		try {
81
			VectorizationBinding binding = new VectorizationBinding(fileIn);
82
			binding.setCornerThreshold(-1);
83
			double geometrias[] = binding.VectorizeBuffer();
84

  
85
			String sFields[] = new String[2];
86
			sFields[0] = "ID";
87
			sFields[1] = fieldName + "";
88

  
89
			LayerDefinition tableDef = null;
90
			if(fileOutShape.endsWith(".dxf")) {
91
				writer = new DxfWriter();
92
				((DxfWriter)writer).setFile(new File(fileOutShape));
93
				ProjectionPool pool = new ProjectionPool();
94
				((DxfWriter)writer).setProjection(pool.get("EPSG:23030"));
95
				tableDef = new DXFLayerDefinition();
96

  
97
				DxfFieldsMapping fieldsMapping = new DxfFieldsMapping();
98
				((DxfWriter)writer).setFieldMapping(fieldsMapping);
99
			}
100
			if(fileOutShape.endsWith(".shp")) {
101
				writer = new ShpWriter();
102
				((ShpWriter)writer).setFile(new File(fileOutShape));
103
				tableDef = new SHPLayerDefinition();
104
			}
105
			tableDef.setShapeType(FShape.LINE);
106

  
107
			int types[] = {Types.DOUBLE, Types.DOUBLE};
108
			FieldDescription[] fields = new FieldDescription[sFields.length];
109
			for (int i = 0; i < fields.length; i++) {
110
				fields[i] = new FieldDescription();
111
				fields[i].setFieldName(sFields[i]);
112
				fields[i].setFieldType(types[i]);
113
				fields[i].setFieldLength(getDataTypeLength(types[i]));
114
				fields[i].setFieldDecimalCount(5);
115
			}
116
			tableDef.setFieldsDesc(fields);
117
			tableDef.setName(fileOutShape);
118

  
119
			try {
120
				writer.initialize(tableDef);
121
				writer.preProcess();
122
			} catch (InitializeWriterException e) {
123
				e.printStackTrace();
124
			} catch (StartWriterVisitorException e) {
125
				e.printStackTrace();
126
			}
127
			
128
			values = new Value[2];
129
			values[0] = ValueFactory.createValue(0);
130
			values[1] = ValueFactory.createValue(0);
131

  
132
			showPotrace(geometrias, trozos);
133
			
134
			writer.postProcess();
135
		} catch (NotSupportedExtensionException e) {
136
			e.printStackTrace();
137
		} catch (RasterDriverException e) {
138
			e.printStackTrace();
139
		} catch (InterruptedException e) {
140
			e.printStackTrace();
141
		} catch (Exception e) {
142
			e.printStackTrace();
143
		}
144
	}
145
	
146
	public TestRasterPotrace() {
147
		for (int i = 2; i <= 15; i++) {
148
			generatePotrace(fileIn, fileOutBase, i);
149
		}
150
		generatePotrace(fileIn, fileOutBase, 100);
151
	}
152

  
153
	public void addShape(FShape shape, Value[] value)  throws Exception {
154
		if (shape == null) 
155
			return;
156
		IGeometry geom = ShapeFactory.createGeometry(shape);
157
		addGeometry(geom, value);
158
	}
159

  
160
	public void addGeometry(IGeometry geom, Value[] value) throws Exception {
161
		DefaultFeature feat = new DefaultFeature(geom, value, Integer.toString(m_iGeometry));
162
		IRowEdited editFeat = new DefaultRowEdited(feat, IRowEdited.STATUS_MODIFIED, m_iGeometry);
163
		m_iGeometry++;
164
		writer.process(editFeat);
165
	}
166
	
167
	private void showPotrace(double[] potraceX, int trozos) throws Exception {
168
		pathX = new BezierPathX(trozos);
169

  
170
		int cont = 1;
171
		while (true) {
172
			if ((cont >= potraceX.length) || (cont >= potraceX[0]))
173
				return;
174
			switch ((int) potraceX[cont]) {
175
				case 0: // MoveTo
176
					pathX.moveTo(potraceX[cont + 1], potraceX[cont + 2]);
177
					cont += 3;
178
					break;
179
				case 1: // LineTo
180
					pathX.lineTo(potraceX[cont + 1], potraceX[cont + 2]);
181
					cont += 3;
182
					break;
183
				case 2: // CurveTo
184
					pathX.curveTo(potraceX[cont + 1], potraceX[cont + 2], potraceX[cont + 3], potraceX[cont + 4], potraceX[cont + 5], potraceX[cont + 6]);
185
					cont += 7;
186
					break;
187
				case 3: // closePath
188
					line =  new FPolyline2D(pathX);
189
					addShape(line, values);
190
					pathX = new BezierPathX(trozos);
191
					cont ++;
192
					break;
193
			}
194
		}
195
		
196
	}
197
	
198
	/**
199
	 * Returns the length of field
200
	 * @param dataType
201
	 * @return length of field
202
	 */
203
	public int getDataTypeLength(int dataType) {
204
		switch (dataType) {
205
		case Types.NUMERIC:
206
		case Types.DOUBLE:
207
		case Types.REAL:
208
		case Types.FLOAT:
209
		case Types.BIGINT:
210
		case Types.INTEGER:
211
		case Types.DECIMAL:
212
			return 20;
213
		case Types.CHAR:
214
		case Types.VARCHAR:
215
		case Types.LONGVARCHAR:
216
			return 254;
217
		case Types.DATE:
218
			return 8;
219
		case Types.BOOLEAN:
220
		case Types.BIT:
221
			return 1;
222
		}
223
		return 0;
224
	}
225

  
226
	public static void main(String[] args){
227
		new TestRasterPotrace();
228
	}
229
}
0 230

  

Also available in: Unified diff