Revision 21382

View differences:

branches/v2_0_0_prep/libraries/libFMap_geometries/src-test/org/gvsig/fmap/geom/GeometryManagerTest.java
9 9
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
10 10
import org.gvsig.fmap.geom.operation.GeometryOperationException;
11 11
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
12
import org.gvsig.fmap.geom.operation.ensureOrientation.EnsureOrientation;
13
import org.gvsig.fmap.geom.operation.flip.Flip;
14
import org.gvsig.fmap.geom.operation.isCCW.IsCCW;
12 15
import org.gvsig.fmap.geom.operation.tojts.ToJTS;
13 16
import org.gvsig.fmap.geom.operation.towkb.ToWKB;
17
import org.gvsig.fmap.geom.primitive.Curve;
14 18
import org.gvsig.fmap.geom.primitive.Curve2D;
15 19
import org.gvsig.fmap.geom.primitive.Point;
16 20
import org.gvsig.fmap.geom.primitive.Point2D;
......
21 25
public class GeometryManagerTest extends TestCase {
22 26

  
23 27
	private static Logger logger = Logger.getLogger("org.gvsig");
24

  
28
	
25 29
	static {
26

  
27 30
		logger.addAppender(new ConsoleAppender(new SimpleLayout()));
28

  
29 31
	}
30

  
32
	
31 33
	private GeometryManager manager;
32 34
	private GeometryFactory factory;
33

  
35
	
34 36
	protected void setUp() throws Exception {
35 37
		super.setUp();
36 38

  
......
42 44

  
43 45
		logger.debug("--------- testRegister() START ----------");
44 46

  
45
		GeometryType geomType1 = manager.registerGeometryType(Point2D.class);
46
		GeometryType geomType2 = manager.registerGeometryType(Curve2D.class);
47
		GeometryType geomType1 = manager.getGeometryType(Point2D.class);//)registerGeometryType(Point2D.class);
48
		GeometryType geomType2 = manager.getGeometryType(Curve2D.class);//registerGeometryType(Curve2D.class);
47 49

  
48
		int op = manager.registerGeometryOperation("toJTS", new ToJTS(),
49
				geomType1);
50
		logger.debug("op=" + op);
50
		int op1 = manager.registerGeometryOperation("toJTS", new ToJTS(),geomType1);
51
		logger.debug("op1=" + op1);
51 52

  
52 53
		int op2 = -1;
53 54
		try {
54
			op2 = manager.registerGeometryOperation("toJTS", ToJTS.class,
55
					geomType1);
55
			op2 = manager.registerGeometryOperation("toJTS", ToJTS.class,geomType1);
56 56
			logger.debug("op2=" + op2);
57 57
		} catch (Exception e) {
58 58
			logger.error("Error registrando operaci?n: ", e);
59 59
		}
60 60

  
61
		int op3 = manager.registerGeometryOperation("toWKB", new ToWKB(),
62
				geomType1);
63

  
64
		int op4 = manager.registerGeometryOperation("toWKB", new ToWKB(),
65
				geomType2);
66

  
61
		int op3 = manager.registerGeometryOperation("toWKB", new ToWKB(),geomType1);
62
		int op4 = manager.registerGeometryOperation("toWKB", new ToWKB(),geomType2);
63
		
67 64
		logger.debug("op3=" + op3);
68 65

  
69
		assertTrue("FALLO: op != op2", op == op2);
70
		assertTrue("FALLO: op == op3", op != op3);
71
		assertFalse("FALLO: op4 == op", op4 == op);
66
		assertTrue("FALLO: op1 != op2", op1 == op2);
67
		assertTrue("FALLO: op1 == op3", op1 != op3);
68
		assertFalse("FALLO: op4 == op", op4 == op1);
72 69

  
73 70
		Point p = (Point) factory.createPoint2D(1, 2);
74

  
71
		
75 72
		GeometryOperationContext ctx = new GeometryOperationContext();
76 73
		ctx.setAttribute("dummy", "DummyValue");
77

  
74
		
78 75
		try {
79 76
			p.invokeOperation(ToWKB.CODE, ctx);
80 77
			p.invokeOperation(ToJTS.CODE, ctx);
78
			p.invokeOperation(Flip.CODE, ctx);
81 79
		} catch (Exception e) {
82 80
			logger.error("Error, ", e);
83 81
		}
84 82

  
85 83
		// Registramos una factory
86

  
87 84
		manager.registerGeometryFactory(new MyFactory());
88 85
		MyFactory fact = (MyFactory) manager.getGeometryFactory();
89 86
		Solid sol = fact.createTorus3D(0, 1);
......
92 89
		manager.registerGeometryFactory(factory);
93 90
		logger.debug("--------- testRegister() END ----------");
94 91
	}
92
	
93
	public void testGeneralPathXOperations(){
94
		logger.debug("--------- Test GeneralPathX Operation START ----------");
95
		
96
		//Registering the operation Flip() to all the geometries...
97
		manager.registerGeometryOperation("flip", new Flip());
95 98

  
99
		//Registering the operation ensureOrientation() to all the geometries...
100
		manager.registerGeometryOperation("ensureOrientation", new EnsureOrientation());
101

  
102
		//Registering the operation isCCW() to all the geometries...
103
		manager.registerGeometryOperation("isCCW", new IsCCW());
104
		
105
		//Building the Points for a curve...
106
		java.awt.geom.Point2D p1 = new java.awt.geom.Point2D.Double(1,2);
107
		java.awt.geom.Point2D p2 = new java.awt.geom.Point2D.Double(2,1);
108
		java.awt.geom.Point2D p3 = new java.awt.geom.Point2D.Double(3,3);
109
		
110
		//Build a curve to get the operation invoked with the registered operation.
111
		Geometry curve = (Curve) factory.createArc(p1, p2, p3);
112
		
113

  
114
		try {
115
			curve.invokeOperation(Flip.CODE, null);
116
		} catch (GeometryOperationNotSupportedException e) {
117
			logger.error("Operation doesn't be registered for this geometry. \n", e);
118
		} catch (GeometryOperationException e) {
119
			logger.error("An error produced while the Operation was running. \n", e);
120
		}
121
		GeometryOperationContext ctx = new GeometryOperationContext();
122
		ctx.setAttribute("bCCW",new Boolean(true));		
123
		Boolean aux1 = null;
124
		try {
125
			aux1 = (Boolean) curve.invokeOperation(EnsureOrientation.CODE, ctx);
126
		} catch (GeometryOperationNotSupportedException e) {
127
			logger.error("Operation doesn't be registered for this geometry. \n", e);
128
		} catch (GeometryOperationException e) {
129
			// TODO Auto-generated catch block
130
			logger.error("An error produced while the Operation was running. \n", e);
131
		}
132
		//True si es exterior, le ha dado la vuelta.
133
		assertTrue(aux1.booleanValue());
134
		
135
		Boolean aux2 = null;
136
		try {
137
			aux2 = (Boolean) curve.invokeOperation(IsCCW.CODE, null);
138
		} catch (GeometryOperationNotSupportedException e) {
139
			logger.error("Operation doesn't be registered for this geometry. \n", e);
140
		} catch (GeometryOperationException e) {
141
			// TODO Auto-generated catch block
142
			logger.error("An error produced while the Operation was running. \n", e);
143
		}
144
		//True si es CCW.
145
		assertTrue(aux2.booleanValue());
146
		
147
		logger.debug("--------- Test GeneralPathX Operation END ----------");
148
	}
149
	
96 150
	public void testInvoke() {
97 151
		int size = 1000000;
98 152

  
99 153
		// Fill the operation context with required params
100 154
		GeometryOperationContext ctx = new GeometryOperationContext();
101

  
155
		GeometryOperationContext var = new GeometryOperationContext();
156
		var.setAttribute("bCCW",new Boolean(true));	
157
		
102 158
		logger.debug("ToJTS.-");
103 159
		indirectInvoke(ToJTS.CODE, ctx, size);
104 160
		directInvoke(ToJTS.CODE, ctx, size);
105 161
		logger.debug("ToWKB.-");
106 162
		indirectInvoke(ToWKB.CODE, ctx, size);
107 163
		directInvoke(ToWKB.CODE, ctx, size);
164
		logger.debug("Flip.-");
165
		indirectInvoke(Flip.CODE, ctx, size);
166
		directInvoke(Flip.CODE, ctx, size);
167
		logger.debug("EnsureOrientation.-");
168
		//indirectInvoke(EnsureOrientation.CODE, var, size);
169
		directInvoke(EnsureOrientation.CODE, var, size);
170
		logger.debug("isCCW.-");
171
		//indirectInvoke(IsCCW.CODE, ctx, size);
172
		directInvoke(IsCCW.CODE, ctx, size);
108 173

  
109 174
	}
110 175

  
......
123 188

  
124 189
		GeometryOperation geomOp = null;
125 190
		try {
126
			geomOp = manager.getGeometryOperation(Point2D.class, ToJTS.CODE);
191
			geomOp = manager.getGeometryOperation(Point.class, ToJTS.CODE);
127 192
		} catch (GeometryTypeNotSupportedException gtnse) {
128 193
			logger.error("Error:", gtnse);
129 194
		} catch (GeometryOperationNotSupportedException gonse) {
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/primitive/Solid2DZ.java
184 184
	public int getType() {
185 185
		return CODE;
186 186
	}
187

  
188
	public GeneralPathX getGeneralPath() {
189
		// TODO Auto-generated method stub
190
		return null;
191
	}
187 192
	
188 193
}
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/primitive/GeneralPathXIterator.java
111 111
     * @return true if there are more points to read
112 112
     */
113 113
    public boolean isDone() {
114
        return (typeIdx >= path.numTypes);
114
        return (typeIdx >= path.getNumTypes());
115 115
    }
116 116

  
117 117
    /**
......
120 120
     * more points in that direction.
121 121
     */
122 122
    public void next() {
123
	int type = path.pointTypes[typeIdx++];
123
	int type = path.getPointTypes()[typeIdx++];
124 124
	pointIdx += curvesize[type];
125 125
    }
126 126

  
......
143 143
     * @see PathIterator#SEG_CLOSE
144 144
     */
145 145
    public int currentSegment(float[] coords) {
146
	int type = path.pointTypes[typeIdx];
146
	int type = path.getPointTypes()[typeIdx];
147 147
	int numCoords = curvesize[type];
148 148
	if (numCoords > 0 && affine != null) {
149
	    affine.transform(path.pointCoords, pointIdx,
149
	    affine.transform(path.getPointCoords(), pointIdx,
150 150
			     coords, 0,
151 151
			     numCoords / 2);
152 152
	} else {
153 153
	    for (int i=0; i < numCoords; i++) {
154
			coords[i] = (float) path.pointCoords[pointIdx + i];
154
			coords[i] = (float) path.getPointCoords()[pointIdx + i];
155 155
		    }
156 156

  
157 157
	}
......
177 177
     * @see PathIterator#SEG_CLOSE
178 178
     */
179 179
    public int currentSegment(double[] coords) {
180
	int type = path.pointTypes[typeIdx];
180
	int type = path.getPointTypes()[typeIdx];
181 181
	int numCoords = curvesize[type];
182 182
	if (numCoords > 0 && affine != null) {
183
	    affine.transform(path.pointCoords, pointIdx,
183
	    affine.transform(path.getPointCoords(), pointIdx,
184 184
			     coords, 0,
185 185
			     numCoords / 2);
186 186
	} else {
187
	    System.arraycopy(path.pointCoords, pointIdx, coords, 0, numCoords);
187
	    System.arraycopy(path.getPointCoords(), pointIdx, coords, 0, numCoords);
188 188
	}
189 189
        return type;
190 190
    }
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/primitive/Curve2D.java
53 53

  
54 54
	private static final long serialVersionUID = 1L;
55 55

  
56
	private GeneralPathX generalpathx=null;
57
	
56 58
	private static GeometryType geomType = GeometryManager.getInstance()
57 59
			.registerGeometryType(Curve2D.class);
58 60

  
......
60 62
	
61 63
	public Curve2D(String id, IProjection projection, GeneralPathX gpx) {
62 64
		super(id, projection, gpx);
65
		generalpathx=gpx;
63 66
	}
64 67

  
65 68
	public Curve2D(GeneralPathX gpx) {
66 69
		this(null, null, gpx);
70
		generalpathx=gpx;
67 71
	}
68 72

  
69 73
	/*
......
95 99
	public int getType() {
96 100
		return CODE;
97 101
	}
102

  
103
	public GeneralPathX getGeneralPath() {
104
		// TODO Auto-generated method stub
105
		return generalpathx;
106
	}
98 107
	
99 108
}
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/primitive/Ellipse2D.java
204 204
		 * @return DOCUMENT ME!
205 205
		 */
206 206
		public void move(double x, double y) {
207
			for (int i = 0; i < gp.numCoords / 2; i++) {
208
				gp.pointCoords[i * 2] += x;
209
				gp.pointCoords[i * 2 + 1] += y;
207
			for (int i = 0; i < gp.getNumCoords() / 2; i++) {
208
				gp.getPointCoords()[i * 2] += x;
209
				gp.getPointCoords()[i * 2 + 1] += y;
210 210
			}
211 211
			init = new Point2D.Double(init.getX() + x, init.getY() + y);
212 212
			end = new Point2D.Double(end.getX() + x, end.getY() + y);
......
251 251
		 * @return DOCUMENT ME!
252 252
		 */
253 253
		public void move(double x, double y) {
254
			for (int i = 0; i < gp.numCoords / 2; i++) {
255
				gp.pointCoords[i * 2] += x;
256
				gp.pointCoords[i * 2 + 1] += y;
254
			for (int i = 0; i < gp.getNumCoords() / 2; i++) {
255
				gp.getPointCoords()[i * 2] += x;
256
				gp.getPointCoords()[i * 2 + 1] += y;
257 257
			}
258 258
		}
259 259

  
......
265 265
					(init.getY() + end.getY()) / 2);
266 266
			double dx = x - center.getX();
267 267
			double dy = y - center.getY();
268
			for (int i = 0; i < gp.numCoords / 2; i++) {
269
				gp.pointCoords[i * 2] += dx;
270
				gp.pointCoords[i * 2 + 1] += dy;
268
			for (int i = 0; i < gp.getNumCoords() / 2; i++) {
269
				gp.getPointCoords()[i * 2] += dx;
270
				gp.getPointCoords()[i * 2 + 1] += dy;
271 271
			}
272 272
			init = new Point2D.Double(init.getX() + dx, init.getY() + dy);
273 273
			end = new Point2D.Double(end.getX() + dx, end.getY() + dy);
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/primitive/NullGeometry.java
218 218
	public int getType() {
219 219
		return CODE;
220 220
	}
221

  
222
	public GeneralPathX getGeneralPath() {
223
		// TODO Auto-generated method stub
224
		return null;
225
	}
221 226
	
222 227
}
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/primitive/Circle2D.java
193 193
		 */
194 194
		public void move(double x, double y) {
195 195
			center = new Point2D.Double(center.getX() + x, center.getY() + y);
196
			for (int i = 0; i < gp.numCoords / 2; i++) {
197
				gp.pointCoords[i * 2] += x;
198
				gp.pointCoords[i * 2 + 1] += y;
196
			for (int i = 0; i < gp.getNumCoords() / 2; i++) {
197
				gp.getPointCoords()[i * 2] += x;
198
				gp.getPointCoords()[i * 2 + 1] += y;
199 199
			}
200 200
		}
201 201

  
......
239 239
		 * @return DOCUMENT ME!
240 240
		 */
241 241
		public void move(double x, double y) {
242
			for (int i = 0; i < gp.numCoords / 2; i++) {
243
				gp.pointCoords[i * 2] += x;
244
				gp.pointCoords[i * 2 + 1] += y;
242
			for (int i = 0; i < gp.getNumCoords() / 2; i++) {
243
				gp.getPointCoords()[i * 2] += x;
244
				gp.getPointCoords()[i * 2 + 1] += y;
245 245
			}
246 246
		}
247 247

  
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/primitive/OrientablePrimitive2D.java
338 338
		 * @return DOCUMENT ME!
339 339
		 */
340 340
		public void move(double x, double y) {
341
			gp.pointCoords[index*2]+=x;
342
			gp.pointCoords[index*2+1]+=y;
341
			gp.getPointCoords()[index*2]+=x;
342
			gp.getPointCoords()[index*2+1]+=y;
343 343
		}
344 344

  
345 345
		/**
346 346
		 * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
347 347
		 */
348 348
		public void set(double x, double y) {
349
			gp.pointCoords[index*2]=x;
350
			gp.pointCoords[index*2+1]=y;
349
			gp.getPointCoords()[index*2]=x;
350
			gp.getPointCoords()[index*2+1]=y;
351 351
		}
352 352
	}
353 353
	/**
......
376 376
		 * @return DOCUMENT ME!
377 377
		 */
378 378
		public void move(double x, double y) {
379
			gp.pointCoords[index*2]+=x;
380
			gp.pointCoords[index*2+1]+=y;
379
			gp.getPointCoords()[index*2]+=x;
380
			gp.getPointCoords()[index*2+1]+=y;
381 381
		}
382 382

  
383 383
		/**
384 384
		 * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
385 385
		 */
386 386
		public void set(double x, double y) {
387
			gp.pointCoords[index*2]=x;
388
			gp.pointCoords[index*2+1]=y;
387
			gp.getPointCoords()[index*2]=x;
388
			gp.getPointCoords()[index*2+1]=y;
389 389
		}
390 390
	}
391 391
	
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/primitive/Surface2D.java
54 54
public class Surface2D extends OrientableSurface2D implements Surface {
55 55

  
56 56
	private static final long serialVersionUID = 1L;
57

  
57
   
58
	private GeneralPathX generalpathx;
59
	
58 60
	private static GeometryType geomType = GeometryManager.getInstance()
59 61
			.registerGeometryType(Surface2D.class);
60 62
	
......
68 70
	 */
69 71
	public Surface2D(String id, IProjection projection, GeneralPathX gpx) {
70 72
		super(id, projection, gpx);
73
		generalpathx=gpx;
71 74
	}
72 75

  
73 76
	public Surface2D(GeneralPathX gpx) {
74 77
		this(null, null, gpx);
78
		generalpathx=gpx;
75 79
	}
76 80

  
77 81
	/**
......
105 109
	
106 110
	public int getType() {
107 111
		return CODE;
112
	}
113

  
114
	public GeneralPathX getGeneralPath() {
115
		// TODO Auto-generated method stub
116
		return generalpathx;
108 117
	}	
109 118
}
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/primitive/Point2D.java
340 340
	public GeometryType getGeometryType() {
341 341
		return geomType;
342 342
	}
343

  
344
	public GeneralPathX getGeneralPath() {
345
		// TODO Auto-generated method stub
346
		return null;
347
	}
343 348
}
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/primitive/GeneralPathX.java
59 59
import java.awt.geom.Point2D;
60 60
import java.awt.geom.Rectangle2D;
61 61
import java.io.Serializable;
62
import java.util.ArrayList;
63 62

  
64 63
import org.cresques.cts.ICoordTrans;
65 64
import org.gvsig.fmap.geom.util.Converter;
......
67 66
import sun.awt.geom.Crossings;
68 67
import sun.awt.geom.Curve;
69 68

  
70
import com.vividsolutions.jts.algorithm.CGAlgorithms;
71
import com.vividsolutions.jts.geom.Coordinate;
72
import com.vividsolutions.jts.geom.CoordinateList;
73
import com.vividsolutions.jts.geom.CoordinateSequences;
74
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;
75

  
76 69
/**
77 70
 * The <code>GeneralPathX</code> class represents a geometric path
78 71
 * constructed from straight lines, and quadratic and cubic
......
117 110

  
118 111
    // For code simplicity, copy these constants to our namespace
119 112
    // and cast them to byte constants for easy storage.
120
    private static final byte SEG_MOVETO  = (byte) PathIterator.SEG_MOVETO;
121
    private static final byte SEG_LINETO  = (byte) PathIterator.SEG_LINETO;
122
    private static final byte SEG_QUADTO  = (byte) PathIterator.SEG_QUADTO;
123
    private static final byte SEG_CUBICTO = (byte) PathIterator.SEG_CUBICTO;
124
    private static final byte SEG_CLOSE   = (byte) PathIterator.SEG_CLOSE;
113
    public static final byte SEG_MOVETO  = (byte) PathIterator.SEG_MOVETO;
114
    public static final byte SEG_LINETO  = (byte) PathIterator.SEG_LINETO;
115
    public static final byte SEG_QUADTO  = (byte) PathIterator.SEG_QUADTO;
116
    public static final byte SEG_CUBICTO = (byte) PathIterator.SEG_CUBICTO;
117
    public static final byte SEG_CLOSE   = (byte) PathIterator.SEG_CLOSE;
125 118

  
126
    byte[] pointTypes;
127
    double[] pointCoords;
128
    int numTypes;
129
    int numCoords;
119
    private byte[] pointTypes;
120
    private double[] pointCoords;
121
    private int numTypes;
122
    private int numCoords;
130 123
    int windingRule;
131 124

  
132 125
    static final int INIT_SIZE = 20;
133 126
    static final int EXPAND_MAX = 500;
134 127

  
135
    private static final int curvesize[] = {2, 2, 4, 6, 0};
128
    public static final int curvesize[] = {2, 2, 4, 6, 0};
136 129

  
137 130
    /**
138 131
     * Constructs a new <code>GeneralPathX</code> object.
......
191 184
     */
192 185
    GeneralPathX(int rule, int initialTypes, int initialCoords) {
193 186
	setWindingRule(rule);
194
	pointTypes = new byte[initialTypes];
195
	pointCoords = new double[initialCoords * 2];
187
	setPointTypes(new byte[initialTypes]);
188
	setPointCoords(new double[initialCoords * 2]);
196 189
    }
197 190

  
198 191
    /**
......
211 204
    }
212 205

  
213 206
    private void needRoom(int newTypes, int newCoords, boolean needMove) {
214
	if (needMove && numTypes == 0) {
207
	if (needMove && getNumTypes() == 0) {
215 208
	    throw new IllegalPathStateException("missing initial moveto "+
216 209
						"in path definition");
217 210
	}
218
	int size = pointCoords.length;
219
	if (numCoords + newCoords > size) {
211
	int size = getPointCoords().length;
212
	if (getNumCoords() + newCoords > size) {
220 213
	    int grow = size;
221 214
	    if (grow > EXPAND_MAX * 2) {
222 215
		grow = EXPAND_MAX * 2;
......
225 218
		grow = newCoords;
226 219
	    }
227 220
	    double[] arr = new double[size + grow];
228
	    System.arraycopy(pointCoords, 0, arr, 0, numCoords);
229
	    pointCoords = arr;
221
	    System.arraycopy(getPointCoords(), 0, arr, 0, getNumCoords());
222
	    setPointCoords(arr);
230 223
	}
231
	size = pointTypes.length;
232
	if (numTypes + newTypes > size) {
224
	size = getPointTypes().length;
225
	if (getNumTypes() + newTypes > size) {
233 226
	    int grow = size;
234 227
	    if (grow > EXPAND_MAX) {
235 228
		grow = EXPAND_MAX;
......
238 231
		grow = newTypes;
239 232
	    }
240 233
	    byte[] arr = new byte[size + grow];
241
	    System.arraycopy(pointTypes, 0, arr, 0, numTypes);
242
	    pointTypes = arr;
234
	    System.arraycopy(getPointTypes(), 0, arr, 0, getNumTypes());
235
	    setPointTypes(arr);
243 236
	}
244 237
    }
245 238

  
......
249 242
     * @param x,&nbsp;y the specified coordinates
250 243
     */
251 244
    public synchronized void moveTo(double x, double y) {
252
	if (numTypes > 0 && pointTypes[numTypes - 1] == SEG_MOVETO) {
253
	    pointCoords[numCoords - 2] = x;
254
	    pointCoords[numCoords - 1] = y;
245
	if (getNumTypes() > 0 && getPointTypes()[getNumTypes() - 1] == SEG_MOVETO) {
246
	    getPointCoords()[getNumCoords() - 2] = x;
247
	    getPointCoords()[getNumCoords() - 1] = y;
255 248
	} else {
256 249
	    needRoom(1, 2, false);
257
	    pointTypes[numTypes++] = SEG_MOVETO;
258
	    pointCoords[numCoords++] = x;
259
	    pointCoords[numCoords++] = y;
250
	    getPointTypes()[numTypes++] = SEG_MOVETO;
251
	    getPointCoords()[numCoords++] = x;
252
	    getPointCoords()[numCoords++] = y;
260 253
	}
261 254
    }
262 255

  
......
267 260
     */
268 261
    public synchronized void lineTo(double x, double y) {
269 262
	needRoom(1, 2, true);
270
	pointTypes[numTypes++] = SEG_LINETO;
271
	pointCoords[numCoords++] = x;
272
	pointCoords[numCoords++] = y;
263
	getPointTypes()[numTypes++] = SEG_LINETO;
264
	getPointCoords()[numCoords++] = x;
265
	getPointCoords()[numCoords++] = y;
273 266
    }
274 267

  
275 268
    /**
......
284 277
     */
285 278
    public synchronized void quadTo(double x1, double y1, double x2, double y2) {
286 279
	needRoom(1, 4, true);
287
	pointTypes[numTypes++] = SEG_QUADTO;
288
	pointCoords[numCoords++] = x1;
289
	pointCoords[numCoords++] = y1;
290
	pointCoords[numCoords++] = x2;
291
	pointCoords[numCoords++] = y2;
280
	getPointTypes()[numTypes++] = SEG_QUADTO;
281
	getPointCoords()[numCoords++] = x1;
282
	getPointCoords()[numCoords++] = y1;
283
	getPointCoords()[numCoords++] = x2;
284
	getPointCoords()[numCoords++] = y2;
292 285
    }
293 286

  
294 287
    /**
......
307 300
    		double x2, double y2,
308 301
    		double x3, double y3) {
309 302
	needRoom(1, 6, true);
310
	pointTypes[numTypes++] = SEG_CUBICTO;
311
	pointCoords[numCoords++] = x1;
312
	pointCoords[numCoords++] = y1;
313
	pointCoords[numCoords++] = x2;
314
	pointCoords[numCoords++] = y2;
315
	pointCoords[numCoords++] = x3;
316
	pointCoords[numCoords++] = y3;
303
	getPointTypes()[numTypes++] = SEG_CUBICTO;
304
	getPointCoords()[numCoords++] = x1;
305
	getPointCoords()[numCoords++] = y1;
306
	getPointCoords()[numCoords++] = x2;
307
	getPointCoords()[numCoords++] = y2;
308
	getPointCoords()[numCoords++] = x3;
309
	getPointCoords()[numCoords++] = y3;
317 310
    }
318 311

  
319 312
    /**
......
322 315
     * closed then this method has no effect.
323 316
     */
324 317
    public synchronized void closePath() {
325
	if (numTypes == 0 || pointTypes[numTypes - 1] != SEG_CLOSE) {
318
	if (getNumTypes() == 0 || getPointTypes()[getNumTypes() - 1] != SEG_CLOSE) {
326 319
	    needRoom(1, 0, true);
327
	    pointTypes[numTypes++] = SEG_CLOSE;
320
	    getPointTypes()[numTypes++] = SEG_CLOSE;
328 321
	}
329 322
    }
330 323

  
......
439 432
	while (!pi.isDone()) {
440 433
	    switch (pi.currentSegment(coords)) {
441 434
	    case SEG_MOVETO:
442
		if (!connect || numTypes < 1 || numCoords < 2) {
435
		if (!connect || getNumTypes() < 1 || getNumCoords() < 2) {
443 436
		    moveTo(coords[0], coords[1]);
444 437
		    break;
445 438
		}
446
		if (pointTypes[numTypes - 1] != SEG_CLOSE &&
447
		    pointCoords[numCoords - 2] == coords[0] &&
448
		    pointCoords[numCoords - 1] == coords[1])
439
		if (getPointTypes()[getNumTypes() - 1] != SEG_CLOSE &&
440
		    getPointCoords()[getNumCoords() - 2] == coords[0] &&
441
		    getPointCoords()[getNumCoords() - 1] == coords[1])
449 442
		{
450 443
		    // Collapse out initial moveto/lineto
451 444
		    break;
......
512 505
     * in the path.
513 506
     */
514 507
    public synchronized Point2D getCurrentPoint() {
515
	if (numTypes < 1 || numCoords < 2) {
508
	if (getNumTypes() < 1 || getNumCoords() < 2) {
516 509
	    return null;
517 510
	}
518
	int index = numCoords;
519
	if (pointTypes[numTypes - 1] == SEG_CLOSE) {
511
	int index = getNumCoords();
512
	if (getPointTypes()[getNumTypes() - 1] == SEG_CLOSE) {
520 513
	loop:
521
	    for (int i = numTypes - 2; i > 0; i--) {
522
		switch (pointTypes[i]) {
514
	    for (int i = getNumTypes() - 2; i > 0; i--) {
515
		switch (getPointTypes()[i]) {
523 516
		case SEG_MOVETO:
524 517
		    break loop;
525 518
		case SEG_LINETO:
......
536 529
		}
537 530
	    }
538 531
	}
539
	return new Point2D.Double(pointCoords[index - 2],
540
				 pointCoords[index - 1]);
532
	return new Point2D.Double(getPointCoords()[index - 2],
533
				 getPointCoords()[index - 1]);
541 534
    }
542 535

  
543 536
    /**
......
546 539
     * forgotten.
547 540
     */
548 541
    public synchronized void reset() {
549
	numTypes = numCoords = 0;
542
	setNumTypes(setNumCoords(0));
550 543
    }
551 544

  
552 545
    /**
......
557 550
     * @param at the <code>AffineTransform</code> used to transform the area
558 551
     */
559 552
    public void transform(AffineTransform at) {
560
	at.transform(pointCoords, 0, pointCoords, 0, numCoords / 2);
553
	at.transform(getPointCoords(), 0, getPointCoords(), 0, getNumCoords() / 2);
561 554
    }
562 555

  
563 556
    public void reProject(ICoordTrans ct)
564 557
    {
565 558
    	Point2D pt = new Point2D.Double();
566
    	for (int i = 0; i < numCoords; i+=2)
559
    	for (int i = 0; i < getNumCoords(); i+=2)
567 560
    	{
568
    		pt.setLocation(pointCoords[i], pointCoords[i+1]);
561
    		pt.setLocation(getPointCoords()[i], getPointCoords()[i+1]);
569 562
    		pt = ct.convert(pt,null);
570
    		pointCoords[i] = pt.getX();
571
    		pointCoords[i+1] = pt.getY();
563
    		getPointCoords()[i] = pt.getX();
564
    		getPointCoords()[i+1] = pt.getY();
572 565
    	}
573 566

  
574 567
    }
......
605 598
     */
606 599
    public synchronized Rectangle2D getBounds2D() {
607 600
	double x1, y1, x2, y2;
608
	int i = numCoords;
601
	int i = getNumCoords();
609 602
	if (i > 0) {
610
	    y1 = y2 = pointCoords[--i];
611
	    x1 = x2 = pointCoords[--i];
603
	    y1 = y2 = getPointCoords()[--i];
604
	    x1 = x2 = getPointCoords()[--i];
612 605
	    while (i > 0) {
613
		double y = pointCoords[--i];
614
		double x = pointCoords[--i];
606
		double y = getPointCoords()[--i];
607
		double x = getPointCoords()[--i];
615 608
		if (x < x1) x1 = x;
616 609
		if (y < y1) y1 = y;
617 610
		if (x > x2) x2 = x;
......
631 624
     * <code>Shape</code>; <code>false</code> otherwise
632 625
     */
633 626
    public boolean contains(double x, double y) {
634
	if (numTypes < 2) {
627
	if (getNumTypes() < 2) {
635 628
	    return false;
636 629
	}
637 630
//	int cross = sun.awt.geom.Curve.pointCrossingsForPath(getPathIterator(null), x, y);
......
757 750
    public Object clone() {
758 751
	try {
759 752
	    GeneralPathX copy = (GeneralPathX) super.clone();
760
	    copy.pointTypes = (byte[]) pointTypes.clone();
761
	    copy.pointCoords = (double[]) pointCoords.clone();
753
	    copy.setPointTypes((byte[]) getPointTypes().clone());
754
	    copy.setPointCoords((double[]) getPointCoords().clone());
762 755
	    return copy;
763 756
	} catch (CloneNotSupportedException e) {
764 757
	    // this shouldn't happen, since we are Cloneable
......
775 768
    // used to construct from native
776 769

  
777 770
	this.windingRule = windingRule;
778
	this.pointTypes = pointTypes;
779
	this.numTypes = numTypes;
780
	this.pointCoords = pointCoords;
781
	this.numCoords = numCoords;
771
	this.setPointTypes(pointTypes);
772
	this.setNumTypes(numTypes);
773
	this.setPointCoords(pointCoords);
774
	this.setNumCoords(numCoords);
782 775
    }
783 776

  
784
    /**
785
     * Convertimos el path a puntos y luego le damos la vuelta.
786
     */
787
    public void flip()
788
	{
789
		PathIterator theIterator = getPathIterator(null, Converter.FLATNESS); //polyLine.getPathIterator(null, flatness);
790
		double[] theData = new double[6];
791
        //Coordinate first = null;
792
        CoordinateList coordList = new CoordinateList();
793
        Coordinate c1;
794
        GeneralPathX newGp = new GeneralPathX();
795
        ArrayList listOfParts = new ArrayList();
796
		while (!theIterator.isDone()) {
797
			//while not done
798
			int type = theIterator.currentSegment(theData);
799
        	switch (type)
800
        	{
801
        	case SEG_MOVETO:
802
        		coordList = new CoordinateList();
803
        		listOfParts.add(coordList);
804
        		c1= new Coordinate(theData[0], theData[1]);
805
        		coordList.add(c1, true);
806
        		break;
807
        	case SEG_LINETO:
808
        		c1= new Coordinate(theData[0], theData[1]);
809
        		coordList.add(c1, true);
810
        		break;
777
	public void setNumTypes(int numTypes) {
778
		this.numTypes = numTypes;
779
	}
811 780

  
812
        	case SEG_CLOSE:
813
        		coordList.add(coordList.getCoordinate(0));
814
        		break;
781
	public int getNumTypes() {
782
		return numTypes;
783
	}
815 784

  
816
        	}
817
        	theIterator.next();
818
		}
785
	public int setNumCoords(int numCoords) {
786
		return this.numCoords = numCoords;
787
	}
819 788

  
820
		for (int i=listOfParts.size()-1; i>=0; i--)
821
		{
822
			coordList = (CoordinateList) listOfParts.get(i);
823
			Coordinate[] coords = coordList.toCoordinateArray();
824
			CoordinateArraySequence seq = new CoordinateArraySequence(coords);
825
			CoordinateSequences.reverse(seq);
826
			coords = seq.toCoordinateArray();
827
			newGp.moveTo(coords[0].x, coords[0].y);
828
			for (int j=1; j < coords.length; j++)
829
			{
830
				newGp.lineTo(coords[j].x, coords[j].y);
831
			}
832
		}
833
		reset();
834
		append(newGp, false);
789
	public int getNumCoords() {
790
		return numCoords;
835 791
	}
836 792

  
837
	/**
838
	 * Use this function to ensure you get real polygons or holes
839
	 * En JTS, con bCCW = false obtienes un pol�gono exterior.
840
	 * Nota: Solo se le da la vuelta (si es que lo necesita) al
841
	 * pol�gono exterior. El resto, por ahora, no se tocan.
842
	 * Si se necesita tenerlos en cuenta, habr�a que mirar
843
	 * si est�n dentro del otro, y entonces revisar que tiene
844
	 * un CCW contrario al exterior.
845
	 * @param bCCW true if you want the GeneralPath in CCW order
846
	 * @return true si se le ha dado la vuelta. (true if flipped)
847
	 * TODO: TERMINAR ESTO!! NO EST� COMPLETO!! NO sirve para multipoligonos
848
	 */
849
	public boolean ensureOrientation(boolean bCCW) {
850
        byte[] pointTypesAux = new byte[numTypes+1];
851
        double[] pointCoordsAux = new double[numCoords+2];
852
        int i;
853
        int pointIdx = 0;
793
	public void setPointTypes(byte[] pointTypes) {
794
		this.pointTypes = pointTypes;
795
	}
854 796

  
855
        Coordinate c1, c2, c3;
856
        CoordinateList coordList = new CoordinateList();
857
        CoordinateList firstList = new CoordinateList();
858
        boolean bFirstList = true;
859
        Coordinate cInicio = null;
797
	public byte[] getPointTypes() {
798
		return pointTypes;
799
	}
860 800

  
861
        for (i=0; i< numTypes; i++)
862
        {
863
        	int type = pointTypes[i];
801
	public void setPointCoords(double[] pointCoords) {
802
		this.pointCoords = pointCoords;
803
	}
864 804

  
865
        	switch (type)
866
        	{
867
        	case SEG_MOVETO:
868
        		c1= new Coordinate(pointCoords[pointIdx], pointCoords[pointIdx+1]);
869
        		cInicio = c1;
870
        		coordList.add(c1, true);
871
        		if (i>0) bFirstList = false;
872
        		if (bFirstList)
873
        		{
874
        			firstList.add(c1,true);
875
        		}
876
        		break;
877
        	case SEG_LINETO:
878
        		c1= new Coordinate(pointCoords[pointIdx], pointCoords[pointIdx+1]);
879
        		coordList.add(c1, true);
880
        		if (bFirstList)
881
        		{
882
        			firstList.add(c1,true);
883
        		}
884
        		break;
885
        	case SEG_QUADTO:
886
        		c1= new Coordinate(pointCoords[pointIdx], pointCoords[pointIdx+1]);
887
        		coordList.add(c1, true);
888
        		c2= new Coordinate(pointCoords[pointIdx+2], pointCoords[pointIdx+3]);
889
        		coordList.add(c2, true);
890
        		if (bFirstList)
891
        		{
892
        			firstList.add(c1,true);
893
        			firstList.add(c2,true);
894
        		}
895

  
896
        		break;
897
        	case SEG_CUBICTO:
898
        		c1= new Coordinate(pointCoords[pointIdx], pointCoords[pointIdx+1]);
899
        		coordList.add(c1, true);
900
        		c2= new Coordinate(pointCoords[pointIdx+2], pointCoords[pointIdx+3]);
901
        		coordList.add(c2, true);
902
        		c3= new Coordinate(pointCoords[pointIdx+4], pointCoords[pointIdx+5]);
903
        		coordList.add(c3, true);
904
        		if (bFirstList)
905
        		{
906
        			firstList.add(c1,true);
907
        			firstList.add(c2,true);
908
        			firstList.add(c3,true);
909
        		}
910

  
911
        		break;
912
        	case SEG_CLOSE:
913
        		coordList.add(cInicio, true);
914
        		if (bFirstList)
915
        		{
916
        			firstList.add(cInicio,true);
917
        		}
918
        		break;
919

  
920
        	}
921
        	pointIdx += curvesize[type];
922
        }
923
		// Guardamos el path dandole la vuelta
924
		Coordinate[] coords = coordList.toCoordinateArray();
925
		boolean bFlipped = false;
926
		if (CGAlgorithms.isCCW(coords) != bCCW) // Le damos la vuelta
927
		{
928
			CoordinateArraySequence seq = new CoordinateArraySequence(coords);
929
			CoordinateSequences.reverse(seq);
930
			coords = seq.toCoordinateArray();
931

  
932

  
933
			// En el primer punto metemos un moveto
934
			pointCoordsAux[0] = coords[0].x;
935
			pointCoordsAux[1] = coords[0].y;
936
			pointTypesAux[0] = SEG_MOVETO;
937
			int idx = 2;
938
			i=0;
939
			int j=1;
940
			for (int k=0; k < coords.length; k++)
941
			{
942
				pointCoordsAux[idx++] = coords[k].x;
943
				pointCoordsAux[idx++] = coords[k].y;
944
	        	int type = pointTypes[i++];
945
	        	pointIdx += curvesize[type];
946
	        	switch (type)
947
	        	{
948
	        	case SEG_MOVETO:
949
	        		pointTypesAux[j] = SEG_LINETO;
950
	        		break;
951
	        	case SEG_LINETO:
952
	        		pointTypesAux[j] = SEG_LINETO;
953
	        		break;
954
	        	case SEG_QUADTO:
955
	        		pointTypesAux[j] = SEG_QUADTO;
956
	        		break;
957
	        	case SEG_CUBICTO:
958
	        		pointTypesAux[j] = SEG_CUBICTO;
959
	        		break;
960
	        	case SEG_CLOSE:
961
	        		// TODO: IMPLEMENTAR ESTO!!!
962
	        		break;
963

  
964
	        	}
965
	        	j++;
966

  
967
			}
968

  
969
	        pointTypes = pointTypesAux;
970
	        pointCoords = pointCoordsAux;
971
	        numCoords= numCoords+2;
972
	        numTypes++;
973
	        bFlipped  = true;
974

  
975
		}
976
		return bFlipped;
805
	public double[] getPointCoords() {
806
		return pointCoords;
977 807
	}
978 808

  
979
    /**
980
     * Check if the first part is CCW.
981
     * @return
982
     */
983
    public boolean isCCW()
984
    {
985
        //int i;
986

  
987
		PathIterator theIterator = getPathIterator(null, Converter.FLATNESS); //polyLine.getPathIterator(null, flatness);
988
		double[] theData = new double[6];
989
        Coordinate first = null;
990
        CoordinateList coordList = new CoordinateList();
991
        Coordinate c1;
992
        boolean bFirst = true;
993
		while (!theIterator.isDone()) {
994
			//while not done
995
			int type = theIterator.currentSegment(theData);
996
        	switch (type)
997
        	{
998
        	case SEG_MOVETO:
999
        		c1= new Coordinate(theData[0], theData[1]);
1000
        		if (bFirst == false) // Ya tenemos la primera parte.
1001
        			break;
1002
        		if (bFirst)
1003
        		{
1004
        			bFirst=false;
1005
        			first = c1;
1006
        		}
1007
        		coordList.add(c1, true);
1008
        		break;
1009
        	case SEG_LINETO:
1010
        		c1= new Coordinate(theData[0], theData[1]);
1011
        		coordList.add(c1, true);
1012
        		break;
1013

  
1014
        	}
1015
        	theIterator.next();
1016
		}
1017
		coordList.add(first, true);
1018
        return CGAlgorithms.isCCW(coordList.toCoordinateArray());
1019

  
1020
    }
1021

  
1022 809
}
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/Geometry.java
53 53
import org.gvsig.fmap.geom.operation.GeometryOperationException;
54 54
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
55 55
import org.gvsig.fmap.geom.primitive.FShape;
56
import org.gvsig.fmap.geom.primitive.GeneralPathX;
56 57
import org.gvsig.fmap.geom.type.GeometryType;
57 58

  
58 59
/**
......
250 251
	 */
251 252
	public GeometryType getGeometryType();
252 253
	
254
	/**
255
	 * Get GeneralPathIterator, to do registered operations to it:
256
	 */
257
	public GeneralPathX getGeneralPath();
253 258
}
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/operation/flip/Flip.java
1
package org.gvsig.fmap.geom.operation.flip;
2

  
3
import java.awt.geom.PathIterator;
4
import java.util.ArrayList;
5

  
6
import com.vividsolutions.jts.geom.Coordinate;
7
import com.vividsolutions.jts.geom.CoordinateList;
8
import com.vividsolutions.jts.geom.CoordinateSequences;
9
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;
10

  
11
import org.gvsig.fmap.geom.Geometry;
12
import org.gvsig.fmap.geom.GeometryManager;
13
import org.gvsig.fmap.geom.operation.GeometryOperation;
14
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
15
import org.gvsig.fmap.geom.operation.GeometryOperationException;
16
import org.gvsig.fmap.geom.primitive.GeneralPathX;
17
import org.gvsig.fmap.geom.util.Converter;
18

  
19
/**
20
 * This class converts the path into points, then flip it down. 
21
 * 
22
 * @author Carlos S?nchez Peri??n <a href = "mailto:csanchez@prodevelop.es"> e-mail </a>
23
 */
24
public class Flip extends GeometryOperation{
25
   
26
	private GeneralPathX generalPathX = null;
27
    
28
	public static final int CODE = GeometryManager.getInstance().registerGeometryOperation("flip", new Flip());
29
	
30
	public int getOperationIndex() {
31
		return CODE;
32
	}
33
	
34
    public Object invoke(Geometry geom, GeometryOperationContext ctx) throws GeometryOperationException {
35
    	generalPathX = geom.getGeneralPath();
36
		if(generalPathX == null){
37
			//if there isn't path the operation hasn't sense.
38
			return null;
39
    	}
40
		PathIterator theIterator = geom.getPathIterator(null, Converter.FLATNESS); //polyLine.getPathIterator(null, flatness);
41
    	double[] theData = new double[6];
42
    	//Coordinate first = null;
43
    	CoordinateList coordList = new CoordinateList();
44
    	Coordinate c1;
45
    	GeneralPathX newGp = new GeneralPathX();
46
    	ArrayList listOfParts = new ArrayList();
47
    	while (!theIterator.isDone()) {
48
    		//while not done
49
    		int type = theIterator.currentSegment(theData);
50
    		switch (type)
51
    		{
52
    		case (byte) PathIterator.SEG_MOVETO:
53
    			coordList = new CoordinateList();
54
    			listOfParts.add(coordList);
55
    			c1= new Coordinate(theData[0], theData[1]);
56
    			coordList.add(c1, true);
57
    			break;
58
    	    case (byte) PathIterator.SEG_LINETO:
59
    			c1= new Coordinate(theData[0], theData[1]);
60
    			coordList.add(c1, true);
61
    			break;
62
    		case (byte) PathIterator.SEG_CLOSE:
63
    			coordList.add(coordList.getCoordinate(0));
64
    			break;
65
    		}
66
    		theIterator.next();
67
    	}
68
    		
69
    	for (int i=listOfParts.size()-1; i>=0; i--)
70
    	{
71
    		coordList = (CoordinateList) listOfParts.get(i);
72
    		Coordinate[] coords = coordList.toCoordinateArray();
73
    		CoordinateArraySequence seq = new CoordinateArraySequence(coords);
74
    		CoordinateSequences.reverse(seq);
75
    		coords = seq.toCoordinateArray();
76
    		newGp.moveTo(coords[0].x, coords[0].y);
77
    		for (int j=1; j < coords.length; j++)
78
    		{
79
    			newGp.lineTo(coords[j].x, coords[j].y);
80
    		}
81
    	}
82
    	generalPathX.reset();
83
    	generalPathX.append(newGp, false);	
84
    	
85
		return null;		
86
	}
87
}
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/operation/ensureOrientation/EnsureOrientation.java
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

  
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2008 PRODEVELOP S.L. Main Development
26
*/
27
 
28
package org.gvsig.fmap.geom.operation.ensureOrientation;
29

  
30
import org.gvsig.fmap.geom.Geometry;
31
import org.gvsig.fmap.geom.GeometryManager;
32
import org.gvsig.fmap.geom.operation.GeometryOperation;
33
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
34
import org.gvsig.fmap.geom.operation.GeometryOperationException;
35
import org.gvsig.fmap.geom.primitive.GeneralPathX;
36

  
37
import com.vividsolutions.jts.algorithm.CGAlgorithms;
38
import com.vividsolutions.jts.geom.Coordinate;
39
import com.vividsolutions.jts.geom.CoordinateList;
40
import com.vividsolutions.jts.geom.CoordinateSequences;
41
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;
42

  
43
/**
44
 * Use this function class to ensure you get real polygons or holes
45
 * En JTS, con bCCW = false obtienes un poligono exterior.
46
 * Nota: Solo se le da la vuelta (si es que lo necesita) al
47
 * poligono exterior. El resto, por ahora, no se tocan.
48
 * Si se necesita tenerlos en cuenta, habr?a que mirar
49
 * si est?n dentro del otro, y entonces revisar que tiene
50
 * un CCW contrario al exterior.
51
 * @param bCCW true if you want the GeneralPath in CCW order
52
 * @return true si se le ha dado la vuelta. (true if flipped)
53
 * TODO: TERMINAR ESTO!! NO EST? COMPLETO!! NO sirve para multipoligonos
54
 */
55
/**
56
 * @author Carlos S?nchez Peri??n <a href = "mailto:csanchez@prodevelop.es"> e-mail </a>
57
 */
58
public class EnsureOrientation extends GeometryOperation{
59

  
60
	private GeneralPathX generalPathX = null;
61
	
62
	private Boolean bCCW;
63
	
64
	public static final int CODE = GeometryManager.getInstance().registerGeometryOperation("ensureOrientation", new EnsureOrientation());
65
	
66
	public int getOperationIndex() {
67
		return CODE;
68
	}
69

  
70
	public Object invoke(Geometry geom, GeometryOperationContext ctx)throws GeometryOperationException {
71
		bCCW = (Boolean) ctx.getAttribute("bCCW");
72
		if (bCCW==null)
73
			throw new GeometryOperationException(new Exception("The function Parameter hasn't been passed or is null."));
74
		
75
		generalPathX = geom.getGeneralPath();
76
		if (generalPathX==null){
77
			//if there isn't path the operation hasn't sense.
78
			return null;
79
		}
80
		
81
        byte[] pointTypesAux = new byte[generalPathX.getNumTypes()+1];
82
        double[] pointCoordsAux = new double[generalPathX.getNumCoords()+2];
83
        int i;
84
        int pointIdx = 0;
85

  
86
        Coordinate c1, c2, c3;
87
        CoordinateList coordList = new CoordinateList();
88
        CoordinateList firstList = new CoordinateList();
89
        boolean bFirstList = true;
90
        Coordinate cInicio = null;
91

  
92
        for (i=0; i< generalPathX.getNumTypes(); i++)
93
        {
94
        	int type = generalPathX.getPointTypes()[i];
95

  
96
        	switch (type)
97
        	{
98
        	case GeneralPathX.SEG_MOVETO:
99
        		c1= new Coordinate(generalPathX.getPointCoords()[pointIdx], generalPathX.getPointCoords()[pointIdx+1]);
100
        		cInicio = c1;
101
        		coordList.add(c1, true);
102
        		if (i>0) bFirstList = false;
103
        		if (bFirstList)
104
        		{
105
        			firstList.add(c1,true);
106
        		}
107
        		break;
108
        	case GeneralPathX.SEG_LINETO:
109
        		c1= new Coordinate(generalPathX.getPointCoords()[pointIdx], generalPathX.getPointCoords()[pointIdx+1]);
110
        		coordList.add(c1, true);
111
        		if (bFirstList)
112
        		{
113
        			firstList.add(c1,true);
114
        		}
115
        		break;
116
        	case GeneralPathX.SEG_QUADTO:
117
        		c1= new Coordinate(generalPathX.getPointCoords()[pointIdx], generalPathX.getPointCoords()[pointIdx+1]);
118
        		coordList.add(c1, true);
119
        		c2= new Coordinate(generalPathX.getPointCoords()[pointIdx+2],generalPathX.getPointCoords()[pointIdx+3]);
120
        		coordList.add(c2, true);
121
        		if (bFirstList)
122
        		{
123
        			firstList.add(c1,true);
124
        			firstList.add(c2,true);
125
        		}
126

  
127
        		break;
128
        	case GeneralPathX.SEG_CUBICTO:
129
        		c1= new Coordinate(generalPathX.getPointCoords()[pointIdx], generalPathX.getPointCoords()[pointIdx+1]);
130
        		coordList.add(c1, true);
131
        		c2= new Coordinate(generalPathX.getPointCoords()[pointIdx+2],generalPathX.getPointCoords()[pointIdx+3]);
132
        		coordList.add(c2, true);
133
        		c3= new Coordinate(generalPathX.getPointCoords()[pointIdx+4],generalPathX.getPointCoords()[pointIdx+5]);
134
        		coordList.add(c3, true);
135
        		if (bFirstList)
136
        		{
137
        			firstList.add(c1,true);
138
        			firstList.add(c2,true);
139
        			firstList.add(c3,true);
140
        		}
141

  
142
        		break;
143
        	case GeneralPathX.SEG_CLOSE:
144
        		coordList.add(cInicio, true);
145
        		if (bFirstList)
146
        		{
147
        			firstList.add(cInicio,true);
148
        		}
149
        		break;
150

  
151
        	}
152
        	pointIdx += GeneralPathX.curvesize[type];
153
        }
154
		// Guardamos el path dandole la vuelta
155
		Coordinate[] coords = coordList.toCoordinateArray();
156
		boolean bFlipped = false;
157
		if (CGAlgorithms.isCCW(coords) != bCCW.booleanValue()) // Le damos la vuelta
158
		{
159
			CoordinateArraySequence seq = new CoordinateArraySequence(coords);
160
			CoordinateSequences.reverse(seq);
161
			coords = seq.toCoordinateArray();
162

  
163

  
164
			// En el primer punto metemos un moveto
165
			pointCoordsAux[0] = coords[0].x;
166
			pointCoordsAux[1] = coords[0].y;
167
			pointTypesAux[0] = GeneralPathX.SEG_MOVETO;
168
			int idx = 2;
169
			i=0;
170
			int j=1;
171
			for (int k=0; k < coords.length; k++)
172
			{
173
				pointCoordsAux[idx++] = coords[k].x;
174
				pointCoordsAux[idx++] = coords[k].y;
175
	        	int type = generalPathX.getPointTypes()[i++];
176
	        	pointIdx += GeneralPathX.curvesize[type];
177
	        	switch (type)
178
	        	{
179
	        	case GeneralPathX.SEG_MOVETO:
180
	        		pointTypesAux[j] = GeneralPathX.SEG_LINETO;
181
	        		break;
182
	        	case GeneralPathX.SEG_LINETO:
183
	        		pointTypesAux[j] = GeneralPathX.SEG_LINETO;
184
	        		break;
185
	        	case GeneralPathX.SEG_QUADTO:
186
	        		pointTypesAux[j] = GeneralPathX.SEG_QUADTO;
187
	        		break;
188
	        	case GeneralPathX.SEG_CUBICTO:
189
	        		pointTypesAux[j] = GeneralPathX.SEG_CUBICTO;
190
	        		break;
191
	        	case GeneralPathX.SEG_CLOSE:
192
	        		// TODO: IMPLEMENTAR ESTO!!!
193
	        		break;
194

  
195
	        	}
196
	        	j++;
197

  
198
			}
199
			generalPathX.setPointTypes(pointTypesAux);
200
			generalPathX.setPointCoords(pointCoordsAux);
201
	        generalPathX.setNumCoords(generalPathX.getNumCoords()+2);
202
	        generalPathX.setNumTypes(generalPathX.getNumTypes()+1);
203
	        bFlipped  = true;
204
		}
205
		return new Boolean((boolean) bFlipped);
206
	}
207

  
208
}
branches/v2_0_0_prep/libraries/libFMap_geometries/src/org/gvsig/fmap/geom/operation/isCCW/IsCCW.java
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

  
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2008 PRODEVELOP S.L. Main Development
26
*/
27
 
28
/**
29
 * 
30
 */
31
package org.gvsig.fmap.geom.operation.isCCW;
32

  
33
import java.awt.geom.PathIterator;
34

  
35
import org.gvsig.fmap.geom.Geometry;
36
import org.gvsig.fmap.geom.GeometryManager;
37
import org.gvsig.fmap.geom.operation.GeometryOperation;
38
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
39
import org.gvsig.fmap.geom.operation.GeometryOperationException;
40
import org.gvsig.fmap.geom.primitive.GeneralPathX;
41
import org.gvsig.fmap.geom.util.Converter;
42

  
43
import com.vividsolutions.jts.algorithm.CGAlgorithms;
44
import com.vividsolutions.jts.geom.Coordinate;
45
import com.vividsolutions.jts.geom.CoordinateList;
46

  
47
/**
48
 * This class checks if the first part from the General Path of a complex geometry is CCW.
49
 * @return Boolean <code>true<code> if is CCW
50
 * @author Carlos S?nchez Peri??n <a href = "mailto:csanchez@prodevelop.es"> e-mail </a>
51
 */
52
public class IsCCW extends GeometryOperation{
53

  
54
	private GeneralPathX generalPathX = null;
55
	
56
	public static final int CODE = GeometryManager.getInstance().registerGeometryOperation("isCCW", new IsCCW());
57
	
58
	public int getOperationIndex() {
59
		return CODE;
60
	}
61

  
62
	public Object invoke(Geometry geom, GeometryOperationContext ctx) throws GeometryOperationException {
63
		generalPathX = geom.getGeneralPath();
64
		if(generalPathX == null){
65
			//if there isn't path the operation hasn't sense.
66
			return null;
67
    	}
68
		PathIterator theIterator = generalPathX.getPathIterator(null, Converter.FLATNESS); //polyLine.getPathIterator(null, flatness);
69
		double[] theData = new double[6];
70
        Coordinate first = null;
71
        CoordinateList coordList = new CoordinateList();
72
        Coordinate c1;
73
        boolean bFirst = true;
74
		while (!theIterator.isDone()) {
75
			//while not done
76
			int type = theIterator.currentSegment(theData);
77
        	switch (type)
78
        	{
79
        	case GeneralPathX.SEG_MOVETO:
80
        		c1= new Coordinate(theData[0], theData[1]);
81
        		if (bFirst == false) // Ya tenemos la primera parte.
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff