svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.impl / src / main / java / org / gvsig / fmap / geom / util / Converter.java @ 40559
History | View | Annotate | Download (53.9 KB)
1 | 40559 | jjdelcerro | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | 40435 | jjdelcerro | *
|
4 | 40559 | jjdelcerro | * Copyright (C) 2007-2013 gvSIG Association.
|
5 | 40435 | jjdelcerro | *
|
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 | 40559 | jjdelcerro | * as published by the Free Software Foundation; either version 3
|
9 | 40435 | jjdelcerro | * 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 | 40559 | jjdelcerro | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
19 | * MA 02110-1301, USA.
|
||
20 | 40435 | jjdelcerro | *
|
21 | 40559 | jjdelcerro | * For any additional information, do not hesitate to contact us
|
22 | * at info AT gvsig.com, or visit our website www.gvsig.com.
|
||
23 | 40435 | jjdelcerro | */
|
24 | package org.gvsig.fmap.geom.util; |
||
25 | |||
26 | import java.awt.Shape; |
||
27 | import java.awt.geom.AffineTransform; |
||
28 | import java.awt.geom.Area; |
||
29 | import java.awt.geom.NoninvertibleTransformException; |
||
30 | import java.awt.geom.PathIterator; |
||
31 | import java.awt.geom.Rectangle2D; |
||
32 | import java.lang.reflect.Array; |
||
33 | import java.util.ArrayList; |
||
34 | import java.util.List; |
||
35 | |||
36 | import org.gvsig.fmap.geom.Geometry; |
||
37 | import org.gvsig.fmap.geom.GeometryLocator; |
||
38 | import org.gvsig.fmap.geom.GeometryManager; |
||
39 | import org.gvsig.fmap.geom.Geometry.SUBTYPES; |
||
40 | import org.gvsig.fmap.geom.Geometry.TYPES; |
||
41 | import org.gvsig.fmap.geom.aggregate.MultiCurve; |
||
42 | import org.gvsig.fmap.geom.aggregate.MultiPoint; |
||
43 | import org.gvsig.fmap.geom.aggregate.MultiPrimitive; |
||
44 | import org.gvsig.fmap.geom.aggregate.MultiSurface; |
||
45 | import org.gvsig.fmap.geom.exception.CreateGeometryException; |
||
46 | import org.gvsig.fmap.geom.primitive.Curve; |
||
47 | import org.gvsig.fmap.geom.primitive.GeneralPathX; |
||
48 | import org.gvsig.fmap.geom.primitive.Primitive; |
||
49 | import org.gvsig.fmap.geom.primitive.Surface; |
||
50 | import org.slf4j.Logger; |
||
51 | import org.slf4j.LoggerFactory; |
||
52 | |||
53 | import com.vividsolutions.jts.algorithm.CGAlgorithms; |
||
54 | import com.vividsolutions.jts.algorithm.RobustCGAlgorithms; |
||
55 | import com.vividsolutions.jts.geom.Coordinate; |
||
56 | import com.vividsolutions.jts.geom.CoordinateArrays; |
||
57 | import com.vividsolutions.jts.geom.Envelope; |
||
58 | import com.vividsolutions.jts.geom.GeometryCollection; |
||
59 | import com.vividsolutions.jts.geom.LineString; |
||
60 | import com.vividsolutions.jts.geom.LinearRing; |
||
61 | import com.vividsolutions.jts.geom.MultiLineString; |
||
62 | import com.vividsolutions.jts.geom.MultiPolygon; |
||
63 | import com.vividsolutions.jts.geom.Point; |
||
64 | import com.vividsolutions.jts.geom.Polygon; |
||
65 | |||
66 | /**
|
||
67 | * Clase con varios metodos estaticos utilizados para pasar de java2d a jts
|
||
68 | * y viceversa.
|
||
69 | *
|
||
70 | * @author fjp
|
||
71 | * @deprecated to be removed or moved from API to implementation in gvSIG 2.1.0
|
||
72 | */
|
||
73 | public class Converter { |
||
74 | private static final GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
||
75 | private static final Logger logger = LoggerFactory.getLogger(Converter.class); |
||
76 | public final static com.vividsolutions.jts.geom.GeometryFactory geomFactory = new com.vividsolutions.jts.geom.GeometryFactory(); |
||
77 | public static CGAlgorithms cga = new RobustCGAlgorithms(); |
||
78 | |||
79 | private static GeometryManager manager = GeometryLocator.getGeometryManager(); |
||
80 | |||
81 | //returns true if testPoint is a point in the pointList list.
|
||
82 | static boolean pointInList(Coordinate testPoint, Coordinate[] pointList) { |
||
83 | int t;
|
||
84 | int numpoints;
|
||
85 | Coordinate p; |
||
86 | |||
87 | numpoints = Array.getLength(pointList);
|
||
88 | |||
89 | for (t = 0; t < numpoints; t++) { |
||
90 | p = pointList[t]; |
||
91 | |||
92 | if ((testPoint.x == p.x) && (testPoint.y == p.y) &&
|
||
93 | ((testPoint.z == p.z) || (!(testPoint.z == testPoint.z))) //nan test; x!=x iff x is nan
|
||
94 | ) { |
||
95 | return true; |
||
96 | } |
||
97 | } |
||
98 | |||
99 | return false; |
||
100 | } |
||
101 | |||
102 | /**
|
||
103 | * Receives a JTS Geometry and returns a DAL Geometry
|
||
104 | * @param jtsGeometry jts Geometry
|
||
105 | * @return IGeometry of FMap
|
||
106 | * @author azabala
|
||
107 | * @throws CreateGeometryException
|
||
108 | */
|
||
109 | public static Geometry jtsToGeometry(com.vividsolutions.jts.geom.Geometry geo) throws CreateGeometryException{ |
||
110 | Geometry shpNew = null;
|
||
111 | |||
112 | try {
|
||
113 | if (geo instanceof Point) { |
||
114 | shpNew = geomManager.createPoint(((Point) geo).getX(),((Point) geo).getY(), SUBTYPES.GEOM2D); |
||
115 | } |
||
116 | |||
117 | if (geo.isEmpty()) {
|
||
118 | shpNew = null;
|
||
119 | } |
||
120 | |||
121 | try{
|
||
122 | if (geo instanceof com.vividsolutions.jts.geom.MultiPoint) { |
||
123 | shpNew = geomManager.create(TYPES.MULTIPOINT, SUBTYPES.GEOM2D); |
||
124 | for (int i = 0; i < geo.getNumGeometries(); i++) { |
||
125 | Point point = (Point) geo.getGeometryN(i); |
||
126 | ((MultiPoint)shpNew).addPoint((org.gvsig.fmap.geom.primitive.Point) jtsToGeometry(point)); |
||
127 | } |
||
128 | |||
129 | } |
||
130 | |||
131 | if (geo instanceof Polygon) { |
||
132 | shpNew = geomManager.createSurface(toShape((Polygon) geo), SUBTYPES.GEOM2D);
|
||
133 | } |
||
134 | |||
135 | if (geo instanceof MultiPolygon) { |
||
136 | /*
|
||
137 | * A loop is not needed here because manager
|
||
138 | * correctly creates and appends a primitive (surface)
|
||
139 | * each time there is a move_to in the GeneralPathX
|
||
140 | */
|
||
141 | shpNew = geomManager.createMultiSurface(toShape((MultiPolygon) geo), SUBTYPES.GEOM2D); |
||
142 | } |
||
143 | |||
144 | if (geo instanceof LineString) { |
||
145 | shpNew = geomManager.createCurve(toShape((LineString) geo), SUBTYPES.GEOM2D); |
||
146 | } |
||
147 | |||
148 | if (geo instanceof MultiLineString) { |
||
149 | shpNew = geomManager.create(TYPES.MULTICURVE, SUBTYPES.GEOM2D); |
||
150 | for (int i = 0; i < ((MultiLineString)geo).getNumGeometries(); i++) { |
||
151 | com.vividsolutions.jts.geom.Geometry g = ((MultiLineString)geo).getGeometryN(i); |
||
152 | Curve c = geomManager.createCurve(toShape((LineString) g), SUBTYPES.GEOM2D); |
||
153 | ((MultiCurve)shpNew).addCurve(c); |
||
154 | } |
||
155 | } |
||
156 | }catch(CreateGeometryException e){
|
||
157 | logger.error("Error creating a geometry", e);
|
||
158 | } |
||
159 | |||
160 | return shpNew;
|
||
161 | } catch (NoninvertibleTransformException e) { |
||
162 | e.printStackTrace(); |
||
163 | } |
||
164 | |||
165 | return null; |
||
166 | } |
||
167 | |||
168 | /**
|
||
169 | * Convierte un MultiPoint2D a un MultiPoint de JTS
|
||
170 | * @param geom
|
||
171 | * @return
|
||
172 | */
|
||
173 | public static com.vividsolutions.jts.geom.Geometry geometryToJts(MultiPoint geom) { |
||
174 | Coordinate[] theGeoms = new Coordinate[geom.getPrimitivesNumber()]; |
||
175 | for (int i = 0; i < theGeoms.length; i++) { |
||
176 | java.awt.geom.Point2D p = geom.getPrimitiveAt(i) |
||
177 | .getHandlers(Geometry.SELECTHANDLER)[0].getPoint();
|
||
178 | Coordinate c = new Coordinate(p.getX(), p.getY());
|
||
179 | theGeoms[i] = c; |
||
180 | } |
||
181 | com.vividsolutions.jts.geom.MultiPoint geomCol = |
||
182 | new com.vividsolutions.jts.geom.GeometryFactory().createMultiPoint(theGeoms);
|
||
183 | return geomCol;
|
||
184 | } |
||
185 | |||
186 | /**
|
||
187 | * Convierte una MultiCurve2D en una MultiLineString de JTS
|
||
188 | * @param geom
|
||
189 | * @return
|
||
190 | */
|
||
191 | public static com.vividsolutions.jts.geom.Geometry geometryToJts(MultiCurve geom) { |
||
192 | LineString[] lines = new LineString[geom.getPrimitivesNumber()]; |
||
193 | for (int i = 0; i < lines.length; i++) { |
||
194 | lines[i] = (LineString) geometryToJts((geom.getPrimitiveAt(i))); |
||
195 | } |
||
196 | return new com.vividsolutions.jts.geom.GeometryFactory().createMultiLineString(lines); |
||
197 | } |
||
198 | |||
199 | public static com.vividsolutions.jts.geom.Geometry multiCurveToJts(MultiCurve geom, int srid) { |
||
200 | LineString[] lines = new LineString[geom.getPrimitivesNumber()]; |
||
201 | for (int i = 0; i < lines.length; i++){ |
||
202 | lines[i] = (LineString) curveToJts((geom.getPrimitiveAt(i)), srid); |
||
203 | } |
||
204 | return new com.vividsolutions.jts.geom.GeometryFactory().createMultiLineString(lines); |
||
205 | } |
||
206 | |||
207 | /**
|
||
208 | * Convierte una MultiSurface2D en un MultiPolygon de JTS
|
||
209 | * @return
|
||
210 | */
|
||
211 | public static com.vividsolutions.jts.geom.Geometry geometryToJts(MultiSurface geom) { |
||
212 | Polygon[] polygons = new Polygon[geom.getPrimitivesNumber()]; |
||
213 | for (int i = 0; i < polygons.length; i++){ |
||
214 | polygons[i] = (Polygon) geometryToJts((geom.getPrimitiveAt(i)));
|
||
215 | } |
||
216 | return new com.vividsolutions.jts.geom.GeometryFactory().createMultiPolygon(polygons); |
||
217 | } |
||
218 | |||
219 | /**
|
||
220 | * Convierte una BaseMultiPrimitive en una GeometryCollection de JTS
|
||
221 | * @return
|
||
222 | */
|
||
223 | public com.vividsolutions.jts.geom.Geometry geometryToJts(MultiPrimitive geom) {
|
||
224 | com.vividsolutions.jts.geom.Geometry[] geometriesAux = new LineString[geom.getPrimitivesNumber()]; |
||
225 | for (int i = 0; i < geometriesAux.length; i++) { |
||
226 | geometriesAux[i] = geometryToJts((geom.getPrimitiveAt(i))); |
||
227 | } |
||
228 | return new com.vividsolutions.jts.geom.GeometryFactory().createGeometryCollection(geometriesAux); |
||
229 | } |
||
230 | |||
231 | public static com.vividsolutions.jts.geom.Geometry geometryToJtsWithSRID(Geometry geom, int srid) { |
||
232 | return geometryToJts(geom, geom.getType(), srid);
|
||
233 | } |
||
234 | |||
235 | public static com.vividsolutions.jts.geom.Geometry geometryToJtsWithSRIDForcingType(Geometry geom, int srid, int type) { |
||
236 | return geometryToJts(geom, type, srid);
|
||
237 | } |
||
238 | |||
239 | |||
240 | public static com.vividsolutions.jts.geom.Geometry geometryToJts(Geometry geom) { |
||
241 | return geometryToJts(geom, geom.getType(), -1); |
||
242 | } |
||
243 | |||
244 | private static boolean isClosed(Coordinate firstCoordinate, Coordinate lastCoordinate){ |
||
245 | double diff = Math.abs(lastCoordinate.x - firstCoordinate.x); |
||
246 | if (diff > 0.000001) { |
||
247 | return false; |
||
248 | } |
||
249 | diff = Math.abs(lastCoordinate.y - firstCoordinate.y);
|
||
250 | if (diff > 0.000001) { |
||
251 | return false; |
||
252 | } |
||
253 | return true; |
||
254 | } |
||
255 | |||
256 | private static com.vividsolutions.jts.geom.Geometry curveToJts(Geometry shp, int srid){ |
||
257 | ArrayList arrayLines;
|
||
258 | LineString lin = null;
|
||
259 | int theType;
|
||
260 | int numParts = 0; |
||
261 | double[] dataLine = new double[3]; |
||
262 | double[] dataQuad = new double[3]; |
||
263 | double[] dataCubic = new double[3]; |
||
264 | ArrayList arrayCoords = null; |
||
265 | Coordinate coord; |
||
266 | int subType = shp.getGeometryType().getSubType();
|
||
267 | boolean is3D = subType == 1 || subType == 3; |
||
268 | |||
269 | arrayLines = new ArrayList(); |
||
270 | |||
271 | //El pathIterator no tiene en cuenta coordenadas 3D, por lo que de usar este, las Z's se perder?n
|
||
272 | //Las splines vienen con todos los puntos calculados por lo que no es necesario un
|
||
273 | //iterador que interpole. Por esto obtenemos el mismo resultado recorriendo los puntos.
|
||
274 | //Tiene su riesgo pero hasta que se soporte el 3D en el iterador funciona para todos los casos
|
||
275 | |||
276 | //theIterator = pol.getPathIterator(null, manager.getFlatness());
|
||
277 | GeneralPathX gp = shp.getGeneralPath(); |
||
278 | |||
279 | //while (!theIterator.isDone()) {
|
||
280 | int nPoint = 0; |
||
281 | for (int nType = 0; nType < gp.getNumTypes(); nType++) { |
||
282 | theType = gp.getTypeAt(nType); |
||
283 | switch (theType) {
|
||
284 | case PathIterator.SEG_MOVETO: |
||
285 | case PathIterator.SEG_LINETO: //Se lee un punto |
||
286 | dataLine = gp.get3DCoordinatesAt(nPoint); |
||
287 | nPoint ++; |
||
288 | break;
|
||
289 | case PathIterator.SEG_QUADTO: //Se leen dos puntos |
||
290 | dataLine = gp.get3DCoordinatesAt(nPoint); |
||
291 | dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
|
||
292 | nPoint += 2;
|
||
293 | break;
|
||
294 | case PathIterator.SEG_CUBICTO: //Se leen tres puntos |
||
295 | dataLine = gp.get3DCoordinatesAt(nPoint); |
||
296 | dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
|
||
297 | dataCubic = gp.get3DCoordinatesAt(nPoint + 2);
|
||
298 | nPoint += 3;
|
||
299 | break;
|
||
300 | } |
||
301 | |||
302 | switch (theType) {
|
||
303 | case PathIterator.SEG_MOVETO: |
||
304 | if (arrayCoords == null) { |
||
305 | arrayCoords = new ArrayList(); |
||
306 | } else {
|
||
307 | lin = geomFactory.createLineString( |
||
308 | CoordinateArrays.toCoordinateArray(arrayCoords)); |
||
309 | lin.setSRID(srid); |
||
310 | arrayLines.add(lin); |
||
311 | arrayCoords = new ArrayList(); |
||
312 | } |
||
313 | |||
314 | numParts++; |
||
315 | if(is3D)
|
||
316 | coord = new Coordinate(dataLine[0], dataLine[1], dataLine[2]); |
||
317 | else
|
||
318 | coord = new Coordinate(dataLine[0], dataLine[1]); |
||
319 | |||
320 | arrayCoords.add(coord); |
||
321 | break;
|
||
322 | |||
323 | case PathIterator.SEG_LINETO: |
||
324 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
325 | break;
|
||
326 | |||
327 | case PathIterator.SEG_QUADTO: |
||
328 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
329 | loadArrayCoordinates(arrayCoords, is3D, dataQuad); |
||
330 | break;
|
||
331 | |||
332 | case PathIterator.SEG_CUBICTO: |
||
333 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
334 | loadArrayCoordinates(arrayCoords, is3D, dataQuad); |
||
335 | loadArrayCoordinates(arrayCoords, is3D, dataCubic); |
||
336 | break;
|
||
337 | |||
338 | case PathIterator.SEG_CLOSE: |
||
339 | Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
|
||
340 | loadArrayCoordinates(arrayCoords, is3D, new double[]{firstCoord.x, firstCoord.y, firstCoord.z}); |
||
341 | break;
|
||
342 | } //end switch
|
||
343 | |||
344 | //theIterator.next();
|
||
345 | } //end while loop
|
||
346 | |||
347 | if (arrayCoords.size() < 2) { |
||
348 | |||
349 | } else {
|
||
350 | lin = new com.vividsolutions.jts.geom.GeometryFactory().createLineString(
|
||
351 | CoordinateArrays.toCoordinateArray(arrayCoords)); |
||
352 | lin.setSRID(srid); |
||
353 | } |
||
354 | |||
355 | return lin;
|
||
356 | } |
||
357 | |||
358 | /**
|
||
359 | * Convierte un Geometry de DAL a una Geometry del JTS. Para ello, utilizamos un
|
||
360 | * flattened PathIterator. El flattened indica que las curvas las pasa a
|
||
361 | * segmentos de linea recta AUTOMATICAMENTE!!!.
|
||
362 | *
|
||
363 | * @param shp FShape que se quiere convertir.
|
||
364 | *
|
||
365 | * @return Geometry de JTS.
|
||
366 | */
|
||
367 | private static com.vividsolutions.jts.geom.Geometry geometryToJts( |
||
368 | Geometry shp, int destinationType, int srid) { |
||
369 | com.vividsolutions.jts.geom.Geometry geoJTS = null;
|
||
370 | Coordinate coord; |
||
371 | ArrayList arrayCoords = null; |
||
372 | ArrayList arrayLines;
|
||
373 | LineString lin; |
||
374 | int theType;
|
||
375 | int numParts = 0; |
||
376 | int sourceType = shp.getGeometryType().getType();
|
||
377 | int subType = shp.getGeometryType().getSubType();
|
||
378 | boolean is3D = subType == 1 || subType == 3; |
||
379 | |||
380 | //Use this array to store segment coordinate data
|
||
381 | double[] dataLine = new double[3]; |
||
382 | double[] dataQuad = new double[3]; |
||
383 | double[] dataCubic = new double[3]; |
||
384 | |||
385 | switch (sourceType) {
|
||
386 | case Geometry.TYPES.POINT:
|
||
387 | if(is3D) {
|
||
388 | org.gvsig.fmap.geom.primitive.impl.Point2DZ p = (org.gvsig.fmap.geom.primitive.impl.Point2DZ) shp; |
||
389 | coord = new Coordinate(p.getX(), p.getY(), p.getCoordinateAt(Geometry.DIMENSIONS.Z));
|
||
390 | } else {
|
||
391 | org.gvsig.fmap.geom.primitive.impl.Point2D p = (org.gvsig.fmap.geom.primitive.impl.Point2D) shp; |
||
392 | coord = new Coordinate(p.getX(), p.getY());
|
||
393 | } |
||
394 | geoJTS = geomFactory.createPoint(coord); |
||
395 | geoJTS.setSRID(srid); |
||
396 | break;
|
||
397 | |||
398 | case Geometry.TYPES.CURVE:
|
||
399 | case Geometry.TYPES.ARC:
|
||
400 | case Geometry.TYPES.SPLINE:
|
||
401 | arrayLines = new ArrayList(); |
||
402 | |||
403 | //El pathIterator no tiene en cuenta coordenadas 3D, por lo que de usar este, las Z's se perder?n
|
||
404 | //Las splines vienen con todos los puntos calculados por lo que no es necesario un
|
||
405 | //iterador que interpole. Por esto obtenemos el mismo resultado recorriendo los puntos.
|
||
406 | //Tiene su riesgo pero hasta que se soporte el 3D en el iterador funciona para todos los casos
|
||
407 | |||
408 | //theIterator = pol.getPathIterator(null, manager.getFlatness());
|
||
409 | GeneralPathX gp = shp.getGeneralPath(); |
||
410 | |||
411 | //while (!theIterator.isDone()) {
|
||
412 | int nPoint = 0; |
||
413 | for (int nType = 0; nType < gp.getNumTypes(); nType++) { |
||
414 | theType = gp.getTypeAt(nType); |
||
415 | switch (theType) {
|
||
416 | case PathIterator.SEG_MOVETO: |
||
417 | case PathIterator.SEG_LINETO: //Se lee un punto |
||
418 | dataLine = gp.get3DCoordinatesAt(nPoint); |
||
419 | nPoint ++; |
||
420 | break;
|
||
421 | case PathIterator.SEG_QUADTO: //Se leen dos puntos |
||
422 | dataLine = gp.get3DCoordinatesAt(nPoint); |
||
423 | dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
|
||
424 | nPoint += 2;
|
||
425 | break;
|
||
426 | case PathIterator.SEG_CUBICTO: //Se leen tres puntos |
||
427 | dataLine = gp.get3DCoordinatesAt(nPoint); |
||
428 | dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
|
||
429 | dataCubic = gp.get3DCoordinatesAt(nPoint + 2);
|
||
430 | nPoint += 3;
|
||
431 | break;
|
||
432 | } |
||
433 | |||
434 | //Populate a segment of the new
|
||
435 | // GeneralPathX object.
|
||
436 | //Process the current segment to populate a new
|
||
437 | // segment of the new GeneralPathX object.
|
||
438 | switch (theType) {
|
||
439 | case PathIterator.SEG_MOVETO: |
||
440 | if (arrayCoords == null) { |
||
441 | arrayCoords = new ArrayList(); |
||
442 | } else {
|
||
443 | lin = geomFactory.createLineString(CoordinateArrays.toCoordinateArray(arrayCoords)); |
||
444 | lin.setSRID(srid); |
||
445 | arrayLines.add(lin); |
||
446 | arrayCoords = new ArrayList(); |
||
447 | } |
||
448 | |||
449 | numParts++; |
||
450 | if(is3D)
|
||
451 | coord = new Coordinate(dataLine[0], dataLine[1], dataLine[2]); |
||
452 | else
|
||
453 | coord = new Coordinate(dataLine[0], dataLine[1]); |
||
454 | |||
455 | arrayCoords.add(coord); |
||
456 | break;
|
||
457 | |||
458 | case PathIterator.SEG_LINETO: |
||
459 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
460 | break;
|
||
461 | |||
462 | case PathIterator.SEG_QUADTO: |
||
463 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
464 | loadArrayCoordinates(arrayCoords, is3D, dataQuad); |
||
465 | break;
|
||
466 | |||
467 | case PathIterator.SEG_CUBICTO: |
||
468 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
469 | loadArrayCoordinates(arrayCoords, is3D, dataQuad); |
||
470 | loadArrayCoordinates(arrayCoords, is3D, dataCubic); |
||
471 | break;
|
||
472 | |||
473 | case PathIterator.SEG_CLOSE: |
||
474 | Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
|
||
475 | loadArrayCoordinates(arrayCoords, is3D, new double[]{firstCoord.x, firstCoord.y, firstCoord.z}); |
||
476 | break;
|
||
477 | } //end switch
|
||
478 | |||
479 | //theIterator.next();
|
||
480 | } //end while loop
|
||
481 | |||
482 | if (arrayCoords.size() < 2) { |
||
483 | break;
|
||
484 | } |
||
485 | lin = new com.vividsolutions.jts.geom.GeometryFactory().createLineString(
|
||
486 | CoordinateArrays.toCoordinateArray(arrayCoords)); |
||
487 | |||
488 | lin.setSRID(srid); |
||
489 | // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
|
||
490 | // LO QUE HACE TO_DO EL MUNDO CUANDO ESCRIBE EN POSTGIS
|
||
491 | // O CON GEOTOOLS
|
||
492 | // if (numParts > 1) // Generamos una MultiLineString
|
||
493 | // {
|
||
494 | arrayLines.add(lin); |
||
495 | geoJTS = geomFactory.createMultiLineString( |
||
496 | com.vividsolutions.jts.geom.GeometryFactory.toLineStringArray(arrayLines)); |
||
497 | geoJTS.setSRID(srid); |
||
498 | break;
|
||
499 | |||
500 | case Geometry.TYPES.SURFACE:
|
||
501 | case Geometry.TYPES.CIRCLE:
|
||
502 | case Geometry.TYPES.ELLIPSE:
|
||
503 | arrayLines = new ArrayList(); |
||
504 | |||
505 | ArrayList shells = new ArrayList(); |
||
506 | ArrayList holes = new ArrayList(); |
||
507 | Coordinate[] points = null; |
||
508 | |||
509 | //El pathIterator no tiene en cuenta coordenadas 3D, pero para la creaci?n de elipses y circulos
|
||
510 | //es necesario el iterador que interpole puntos. El resultado es que en la creaci?n de geometr?as de este
|
||
511 | //tipo no se puede asignar la Z porque se perder?a, pero gvSIG tampoco dispone de esta funci?n, as? que
|
||
512 | //no se nota. Una vez creadas las geometr?a de tipo Elipse y circulo cuando las editamos ya tendr?n todos
|
||
513 | //los puntos calculados y se toman como l?neas por lo que ya se podr?a asignar la Z.
|
||
514 | |||
515 | PathIterator theIterator = shp.getPathIterator(null, manager.getFlatness()); |
||
516 | while (!theIterator.isDone()) {
|
||
517 | theType = theIterator.currentSegment(dataLine); |
||
518 | |||
519 | switch (theType) {
|
||
520 | case PathIterator.SEG_MOVETO: |
||
521 | if (arrayCoords == null) { |
||
522 | arrayCoords = new ArrayList(); |
||
523 | } else {
|
||
524 | points = CoordinateArrays.toCoordinateArray(arrayCoords); |
||
525 | |||
526 | try {
|
||
527 | LinearRing ring = geomFactory.createLinearRing(points); |
||
528 | |||
529 | if (CGAlgorithms.isCCW(points)) {
|
||
530 | holes.add(ring); |
||
531 | } else {
|
||
532 | shells.add(ring); |
||
533 | } |
||
534 | } catch (Exception e) { |
||
535 | boolean same = true; |
||
536 | for (int i = 0; i < points.length-1 && same; i++) { |
||
537 | if (points[i].x != points[i+1].x || |
||
538 | points[i].y != points[i+1].y /*|| |
||
539 | points[i].z != points[i+1].z*/
|
||
540 | ) { |
||
541 | same = false;
|
||
542 | } |
||
543 | } |
||
544 | if (same) {
|
||
545 | return geomFactory.createPoint(points[0]); |
||
546 | } |
||
547 | if (points.length>1 && points.length <= 3) { |
||
548 | // return geomFactory.createLineString(points);
|
||
549 | return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)}); |
||
550 | } |
||
551 | |||
552 | System.err.println(
|
||
553 | "Caught Topology exception in GMLLinearRingHandler");
|
||
554 | |||
555 | return null; |
||
556 | } |
||
557 | arrayCoords = new ArrayList(); |
||
558 | } |
||
559 | |||
560 | numParts++; |
||
561 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
562 | break;
|
||
563 | |||
564 | case PathIterator.SEG_LINETO: |
||
565 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
566 | break;
|
||
567 | |||
568 | case PathIterator.SEG_QUADTO: |
||
569 | break;
|
||
570 | |||
571 | case PathIterator.SEG_CUBICTO: |
||
572 | break;
|
||
573 | |||
574 | case PathIterator.SEG_CLOSE: |
||
575 | Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
|
||
576 | loadArrayCoordinates(arrayCoords, is3D, new double[]{firstCoord.x, firstCoord.y, firstCoord.z}); |
||
577 | break;
|
||
578 | } //end switch
|
||
579 | |||
580 | theIterator.next(); |
||
581 | } //end while loop
|
||
582 | |||
583 | |||
584 | Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
|
||
585 | Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords.size() - 1);
|
||
586 | if (!isClosed(firstCoord, lastCoord)) {
|
||
587 | arrayCoords.add(firstCoord); |
||
588 | } |
||
589 | points = CoordinateArrays.toCoordinateArray(arrayCoords); |
||
590 | |||
591 | try {
|
||
592 | LinearRing ring = geomFactory.createLinearRing(points); |
||
593 | |||
594 | if (CGAlgorithms.isCCW(points)) {
|
||
595 | holes.add(ring); |
||
596 | } else {
|
||
597 | shells.add(ring); |
||
598 | } |
||
599 | ring.setSRID(srid); |
||
600 | } catch (Exception e) { |
||
601 | boolean same = true; |
||
602 | for (int i = 0; i < points.length-1 && same; i++) { |
||
603 | if (points[i].x != points[i+1].x || |
||
604 | points[i].y != points[i+1].y /*|| |
||
605 | points[i].z != points[i+1].z*/
|
||
606 | ) { |
||
607 | same = false;
|
||
608 | } |
||
609 | } |
||
610 | if (same) {
|
||
611 | geoJTS = geomFactory.createPoint(points[0]);
|
||
612 | geoJTS.setSRID(srid); |
||
613 | return geoJTS;
|
||
614 | } |
||
615 | /*
|
||
616 | * caso cuando es una linea de 3 puntos, no creo un LinearRing, sino
|
||
617 | * una linea
|
||
618 | */
|
||
619 | if (points.length > 1 && points.length <= 3) { |
||
620 | // return geomFactory.createLineString(points);
|
||
621 | geoJTS = geomFactory.createMultiLineString(new LineString[] { geomFactory.createLineString(points) }); |
||
622 | geoJTS.setSRID(srid); |
||
623 | return geoJTS;
|
||
624 | } |
||
625 | System.err.println("Caught Topology exception in GMLLinearRingHandler"); |
||
626 | |||
627 | return null; |
||
628 | } |
||
629 | |||
630 | /* linRing = new GeometryFactory().createLinearRing(
|
||
631 | CoordinateArrays.toCoordinateArray(arrayCoords)); */
|
||
632 | |||
633 | // System.out.println("NumParts = " + numParts);
|
||
634 | //now we have a list of all shells and all holes
|
||
635 | ArrayList holesForShells = new ArrayList(shells.size()); |
||
636 | |||
637 | for (int i = 0; i < shells.size(); i++) { |
||
638 | holesForShells.add(new ArrayList()); |
||
639 | } |
||
640 | |||
641 | //find homes
|
||
642 | for (int i = 0; i < holes.size(); i++) { |
||
643 | LinearRing testRing = (LinearRing) holes.get(i); |
||
644 | LinearRing minShell = null;
|
||
645 | Envelope minEnv = null;
|
||
646 | Envelope testEnv = testRing.getEnvelopeInternal(); |
||
647 | Coordinate testPt = testRing.getCoordinateN(0);
|
||
648 | LinearRing tryRing = null;
|
||
649 | |||
650 | for (int j = 0; j < shells.size(); j++) { |
||
651 | tryRing = (LinearRing) shells.get(j); |
||
652 | |||
653 | Envelope tryEnv = tryRing.getEnvelopeInternal(); |
||
654 | |||
655 | if (minShell != null) { |
||
656 | minEnv = minShell.getEnvelopeInternal(); |
||
657 | } |
||
658 | |||
659 | boolean isContained = false; |
||
660 | Coordinate[] coordList = tryRing.getCoordinates();
|
||
661 | |||
662 | if (tryEnv.contains(testEnv) &&
|
||
663 | (CGAlgorithms.isPointInRing(testPt, coordList) || |
||
664 | (pointInList(testPt, coordList)))) { |
||
665 | isContained = true;
|
||
666 | } |
||
667 | |||
668 | // check if this new containing ring is smaller than the current minimum ring
|
||
669 | if (isContained) {
|
||
670 | if ((minShell == null) || minEnv.contains(tryEnv)) { |
||
671 | minShell = tryRing; |
||
672 | } |
||
673 | } |
||
674 | } |
||
675 | |||
676 | if (minShell == null) { |
||
677 | // System.out.println(
|
||
678 | // polygon found with a hole thats not inside a shell);
|
||
679 | // azabala: we do the assumption that this hole is really a shell (polygon)
|
||
680 | // whose point werent digitized in the right order
|
||
681 | Coordinate[] cs = testRing.getCoordinates();
|
||
682 | Coordinate[] reversed = new Coordinate[cs.length]; |
||
683 | int pointIndex = 0; |
||
684 | for(int z = cs.length-1; z >= 0; z--){ |
||
685 | reversed[pointIndex] = cs[z]; |
||
686 | pointIndex++; |
||
687 | } |
||
688 | LinearRing newRing = geomFactory.createLinearRing(reversed); |
||
689 | shells.add(newRing); |
||
690 | holesForShells.add(new ArrayList()); |
||
691 | } else {
|
||
692 | ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
|
||
693 | } |
||
694 | } |
||
695 | |||
696 | Polygon[] polygons = new Polygon[shells.size()]; |
||
697 | |||
698 | for (int i = 0; i < shells.size(); i++) { |
||
699 | polygons[i] = geomFactory.createPolygon( |
||
700 | (LinearRing) shells.get(i), |
||
701 | (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(new LinearRing[0])); |
||
702 | polygons[i].setSRID(srid); |
||
703 | } |
||
704 | // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
|
||
705 | // LO QUE HACE TO_DO EL MUNDO CUANDO ESCRIBE EN POSTGIS
|
||
706 | // O CON GEOTOOLS
|
||
707 | // if (numParts > 1) // Generamos una MultiLineString
|
||
708 | |||
709 | /* if (polygons.length == 1) {
|
||
710 | return polygons[0];
|
||
711 | } */
|
||
712 | |||
713 | // FIN CAMBIO
|
||
714 | |||
715 | holesForShells = null;
|
||
716 | shells = null;
|
||
717 | holes = null;
|
||
718 | |||
719 | if (polygons.length == 1) { |
||
720 | geoJTS = polygons[0];
|
||
721 | } else {
|
||
722 | // its a multi part
|
||
723 | geoJTS = geomFactory.createMultiPolygon(polygons); |
||
724 | } |
||
725 | geoJTS.setSRID(srid); |
||
726 | //its a multi part
|
||
727 | //geoJTS = geomFactory.createMultiPolygon(polygons);
|
||
728 | //geoJTS.setSRID(srid);
|
||
729 | |||
730 | break;
|
||
731 | |||
732 | case Geometry.TYPES.MULTICURVE:
|
||
733 | geoJTS = multiCurveToJts((MultiCurve)shp, srid); |
||
734 | geoJTS.setSRID(srid); |
||
735 | break;
|
||
736 | |||
737 | case Geometry.TYPES.MULTIPOINT:
|
||
738 | geoJTS = geometryToJts((MultiPoint)shp); |
||
739 | geoJTS.setSRID(srid); |
||
740 | break;
|
||
741 | |||
742 | case Geometry.TYPES.MULTISURFACE:
|
||
743 | geoJTS = multiSurfaceToJts((MultiSurface)shp, srid); |
||
744 | geoJTS.setSRID(srid); |
||
745 | break;
|
||
746 | } |
||
747 | |||
748 | if(destinationType != sourceType)
|
||
749 | geoJTS = convertTypes(geoJTS, sourceType, destinationType); |
||
750 | |||
751 | geoJTS.setSRID(srid); |
||
752 | return geoJTS;
|
||
753 | } |
||
754 | |||
755 | /**
|
||
756 | * This function is called when the we need force types, that is the destination
|
||
757 | * type does not match with the input geometry type
|
||
758 | * @param g
|
||
759 | * @param sourceType
|
||
760 | * @param destinationType
|
||
761 | * @return
|
||
762 | */
|
||
763 | private static com.vividsolutions.jts.geom.Geometry convertTypes( |
||
764 | com.vividsolutions.jts.geom.Geometry g, |
||
765 | int sourceType,
|
||
766 | int destinationType) {
|
||
767 | if((sourceType == Geometry.TYPES.CURVE ||
|
||
768 | sourceType == Geometry.TYPES.SPLINE || |
||
769 | sourceType == Geometry.TYPES.ARC) |
||
770 | && destinationType == Geometry.TYPES.MULTISURFACE) { |
||
771 | if(g instanceof MultiLineString) { |
||
772 | Polygon[] poly = new Polygon[((MultiLineString)g).getNumGeometries()]; |
||
773 | for (int i = 0; i < ((MultiLineString)g).getNumGeometries(); i++) { |
||
774 | com.vividsolutions.jts.geom.Geometry lineString = ((MultiLineString)g).getGeometryN(i); |
||
775 | poly[i] = convertLineStringToPolygon((LineString)lineString); |
||
776 | } |
||
777 | return geomFactory.createMultiPolygon(poly);
|
||
778 | } else
|
||
779 | return convertLineStringToPolygon((LineString)g);
|
||
780 | } |
||
781 | |||
782 | if((sourceType == Geometry.TYPES.CIRCLE ||
|
||
783 | sourceType == Geometry.TYPES.ELLIPSE) && |
||
784 | destinationType == Geometry.TYPES.MULTICURVE) { |
||
785 | if(g instanceof Polygon) { |
||
786 | Polygon poly = (Polygon)g; |
||
787 | LineString lineString = geomFactory.createLinearRing(poly.getCoordinates()); |
||
788 | return geomFactory.createMultiLineString(new LineString[]{lineString}); |
||
789 | } |
||
790 | } |
||
791 | return g;
|
||
792 | } |
||
793 | |||
794 | private static com.vividsolutions.jts.geom.Polygon convertLineStringToPolygon(LineString line) { |
||
795 | Coordinate[] coordinates = line.getCoordinates();
|
||
796 | LinearRing shell = geomFactory.createLinearRing(coordinates); |
||
797 | Polygon pol = geomFactory.createPolygon(shell, null); |
||
798 | return pol;
|
||
799 | } |
||
800 | |||
801 | /**
|
||
802 | * DOCUMENT ME!
|
||
803 | *
|
||
804 | * @param p DOCUMENT ME!
|
||
805 | *
|
||
806 | * @return DOCUMENT ME!
|
||
807 | */
|
||
808 | private static GeneralPathX toShape(Polygon p) { |
||
809 | GeneralPathX resul = new GeneralPathX();
|
||
810 | Coordinate coord; |
||
811 | |||
812 | for (int i = 0; i < p.getExteriorRing().getNumPoints(); i++) { |
||
813 | coord = p.getExteriorRing().getCoordinateN(i); |
||
814 | |||
815 | if (i == 0) { |
||
816 | resul.moveTo(coord.x, coord.y); |
||
817 | } else {
|
||
818 | resul.lineTo(coord.x, coord.y); |
||
819 | } |
||
820 | } |
||
821 | |||
822 | for (int j = 0; j < p.getNumInteriorRing(); j++) { |
||
823 | LineString hole = p.getInteriorRingN(j); |
||
824 | |||
825 | for (int k = 0; k < hole.getNumPoints(); k++) { |
||
826 | coord = hole.getCoordinateN(k); |
||
827 | |||
828 | if (k == 0) { |
||
829 | resul.moveTo(coord.x, coord.y); |
||
830 | } else {
|
||
831 | resul.lineTo(coord.x, coord.y); |
||
832 | } |
||
833 | } |
||
834 | } |
||
835 | |||
836 | return resul;
|
||
837 | } |
||
838 | |||
839 | |||
840 | private static GeneralPathX toShape(MultiLineString mls) |
||
841 | throws NoninvertibleTransformException, CreateGeometryException { |
||
842 | GeneralPathX path = new GeneralPathX();
|
||
843 | |||
844 | for (int i = 0; i < mls.getNumGeometries(); i++) { |
||
845 | LineString lineString = (LineString) mls.getGeometryN(i); |
||
846 | path.append(toShape(lineString).getPathIterator(null), false); |
||
847 | } |
||
848 | |||
849 | //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
|
||
850 | //converted to GeneralPathXs. [Jon Aquino]
|
||
851 | return path;
|
||
852 | } |
||
853 | |||
854 | /**
|
||
855 | * DOCUMENT ME!
|
||
856 | *
|
||
857 | * @param lineString DOCUMENT ME!
|
||
858 | *
|
||
859 | * @return DOCUMENT ME!
|
||
860 | *
|
||
861 | * @throws NoninvertibleTransformException DOCUMENT ME!
|
||
862 | * @throws CreateGeometryException
|
||
863 | */
|
||
864 | private static GeneralPathX toShape(LineString lineString) |
||
865 | throws NoninvertibleTransformException, CreateGeometryException { |
||
866 | GeneralPathX shape = new GeneralPathX();
|
||
867 | org.gvsig.fmap.geom.primitive.Point viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(0));
|
||
868 | shape.moveTo(viewPoint.getX(), viewPoint.getY()); |
||
869 | |||
870 | for (int i = 1; i < lineString.getNumPoints(); i++) { |
||
871 | viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(i)); |
||
872 | shape.lineTo(viewPoint.getX(), viewPoint.getY()); |
||
873 | } |
||
874 | |||
875 | //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
|
||
876 | //converted to GeneralPathXs. [Jon Aquino]
|
||
877 | return shape;
|
||
878 | } |
||
879 | |||
880 | |||
881 | /**
|
||
882 | *
|
||
883 | */
|
||
884 | private static GeneralPathX toShape(MultiPolygon mp) |
||
885 | throws NoninvertibleTransformException { |
||
886 | GeneralPathX path = new GeneralPathX();
|
||
887 | |||
888 | for (int i = 0; i < mp.getNumGeometries(); i++) { |
||
889 | Polygon polygon = (Polygon) mp.getGeometryN(i); |
||
890 | path.append(toShape(polygon).getPathIterator(null), false); |
||
891 | } |
||
892 | |||
893 | //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
|
||
894 | //converted to GeneralPathXs. [Jon Aquino]
|
||
895 | return path;
|
||
896 | } |
||
897 | /**
|
||
898 | * DOCUMENT ME!
|
||
899 | *
|
||
900 | * @param coord DOCUMENT ME!
|
||
901 | *
|
||
902 | * @return DOCUMENT ME!
|
||
903 | * @throws CreateGeometryException
|
||
904 | */
|
||
905 | public static org.gvsig.fmap.geom.primitive.Point coordinate2FPoint2D(Coordinate coord) throws CreateGeometryException { |
||
906 | return geomManager.createPoint(coord.x, coord.y, SUBTYPES.GEOM2D); //,coord.z); |
||
907 | } |
||
908 | |||
909 | /**
|
||
910 | * Convierte una Geometry de JTS a GeneralPathX.
|
||
911 | *
|
||
912 | * @param geometry Geometry a convertir.
|
||
913 | *
|
||
914 | * @return GeneralPathX.
|
||
915 | *
|
||
916 | * @throws NoninvertibleTransformException
|
||
917 | * @throws CreateGeometryException
|
||
918 | * @throws IllegalArgumentException
|
||
919 | */
|
||
920 | public static GeneralPathX toShape(com.vividsolutions.jts.geom.Geometry geometry) |
||
921 | throws NoninvertibleTransformException, CreateGeometryException { |
||
922 | if (geometry.isEmpty()) {
|
||
923 | return new GeneralPathX(); |
||
924 | } |
||
925 | |||
926 | if (geometry instanceof Polygon) { |
||
927 | return toShape((Polygon) geometry); |
||
928 | } |
||
929 | |||
930 | if (geometry instanceof MultiPolygon) { |
||
931 | return toShape((MultiPolygon) geometry);
|
||
932 | } |
||
933 | |||
934 | if (geometry instanceof LineString) { |
||
935 | return toShape((LineString) geometry);
|
||
936 | } |
||
937 | |||
938 | if (geometry instanceof MultiLineString) { |
||
939 | return toShape((MultiLineString) geometry);
|
||
940 | } |
||
941 | |||
942 | if (geometry instanceof GeometryCollection) { |
||
943 | return toShape(geometry);
|
||
944 | } |
||
945 | |||
946 | throw new IllegalArgumentException("Unrecognized Geometry class: " + |
||
947 | geometry.getClass()); |
||
948 | } |
||
949 | |||
950 | |||
951 | public static GeneralPathX transformToInts(GeneralPathX gp, AffineTransform at) { |
||
952 | GeneralPathX newGp = new GeneralPathX();
|
||
953 | PathIterator theIterator;
|
||
954 | int theType;
|
||
955 | int numParts = 0; |
||
956 | double[] theData = new double[6]; |
||
957 | java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
|
||
958 | java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
|
||
959 | boolean bFirst = true; |
||
960 | int xInt, yInt, antX = -1, antY = -1; |
||
961 | |||
962 | theIterator = gp.getPathIterator(null); //, flatness); |
||
963 | |||
964 | while (!theIterator.isDone()) {
|
||
965 | theType = theIterator.currentSegment(theData); |
||
966 | switch (theType) {
|
||
967 | case PathIterator.SEG_MOVETO: |
||
968 | numParts++; |
||
969 | ptSrc.setLocation(theData[0], theData[1]); |
||
970 | at.transform(ptSrc, ptDst); |
||
971 | antX = (int) ptDst.getX();
|
||
972 | antY = (int) ptDst.getY();
|
||
973 | newGp.moveTo(antX, antY); |
||
974 | bFirst = true;
|
||
975 | break;
|
||
976 | |||
977 | case PathIterator.SEG_LINETO: |
||
978 | ptSrc.setLocation(theData[0], theData[1]); |
||
979 | at.transform(ptSrc, ptDst); |
||
980 | xInt = (int) ptDst.getX();
|
||
981 | yInt = (int) ptDst.getY();
|
||
982 | if ((bFirst) || ((xInt != antX) || (yInt != antY)))
|
||
983 | { |
||
984 | newGp.lineTo(xInt, yInt); |
||
985 | antX = xInt; |
||
986 | antY = yInt; |
||
987 | bFirst = false;
|
||
988 | } |
||
989 | break;
|
||
990 | |||
991 | case PathIterator.SEG_QUADTO: |
||
992 | System.out.println("Not supported here"); |
||
993 | |||
994 | break;
|
||
995 | |||
996 | case PathIterator.SEG_CUBICTO: |
||
997 | System.out.println("Not supported here"); |
||
998 | |||
999 | break;
|
||
1000 | |||
1001 | case PathIterator.SEG_CLOSE: |
||
1002 | newGp.closePath(); |
||
1003 | |||
1004 | break;
|
||
1005 | } //end switch
|
||
1006 | |||
1007 | theIterator.next(); |
||
1008 | } //end while loop
|
||
1009 | |||
1010 | return newGp;
|
||
1011 | } |
||
1012 | public static Geometry transformToInts(Geometry gp, AffineTransform at) throws CreateGeometryException { |
||
1013 | GeneralPathX newGp = new GeneralPathX();
|
||
1014 | double[] theData = new double[6]; |
||
1015 | double[] aux = new double[6]; |
||
1016 | |||
1017 | // newGp.reset();
|
||
1018 | PathIterator theIterator;
|
||
1019 | int theType;
|
||
1020 | int numParts = 0; |
||
1021 | |||
1022 | java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
|
||
1023 | java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
|
||
1024 | boolean bFirst = true; |
||
1025 | int xInt, yInt, antX = -1, antY = -1; |
||
1026 | |||
1027 | |||
1028 | theIterator = gp.getPathIterator(null); //, flatness); |
||
1029 | int numSegmentsAdded = 0; |
||
1030 | while (!theIterator.isDone()) {
|
||
1031 | theType = theIterator.currentSegment(theData); |
||
1032 | |||
1033 | switch (theType) {
|
||
1034 | case PathIterator.SEG_MOVETO: |
||
1035 | numParts++; |
||
1036 | ptSrc.setLocation(theData[0], theData[1]); |
||
1037 | at.transform(ptSrc, ptDst); |
||
1038 | antX = (int) ptDst.getX();
|
||
1039 | antY = (int) ptDst.getY();
|
||
1040 | newGp.moveTo(antX, antY); |
||
1041 | numSegmentsAdded++; |
||
1042 | bFirst = true;
|
||
1043 | break;
|
||
1044 | |||
1045 | case PathIterator.SEG_LINETO: |
||
1046 | ptSrc.setLocation(theData[0], theData[1]); |
||
1047 | at.transform(ptSrc, ptDst); |
||
1048 | xInt = (int) ptDst.getX();
|
||
1049 | yInt = (int) ptDst.getY();
|
||
1050 | if ((bFirst) || ((xInt != antX) || (yInt != antY)))
|
||
1051 | { |
||
1052 | newGp.lineTo(xInt, yInt); |
||
1053 | antX = xInt; |
||
1054 | antY = yInt; |
||
1055 | bFirst = false;
|
||
1056 | numSegmentsAdded++; |
||
1057 | } |
||
1058 | break;
|
||
1059 | |||
1060 | case PathIterator.SEG_QUADTO: |
||
1061 | at.transform(theData,0,aux,0,2); |
||
1062 | newGp.quadTo(aux[0], aux[1], aux[2], aux[3]); |
||
1063 | numSegmentsAdded++; |
||
1064 | break;
|
||
1065 | |||
1066 | case PathIterator.SEG_CUBICTO: |
||
1067 | at.transform(theData,0,aux,0,3); |
||
1068 | newGp.curveTo(aux[0], aux[1], aux[2], aux[3], aux[4], aux[5]); |
||
1069 | numSegmentsAdded++; |
||
1070 | break;
|
||
1071 | |||
1072 | case PathIterator.SEG_CLOSE: |
||
1073 | if (numSegmentsAdded < 3) { |
||
1074 | newGp.lineTo(antX, antY); |
||
1075 | } |
||
1076 | newGp.closePath(); |
||
1077 | |||
1078 | break;
|
||
1079 | } //end switch
|
||
1080 | |||
1081 | theIterator.next(); |
||
1082 | } //end while loop
|
||
1083 | |||
1084 | Geometry shp = null;
|
||
1085 | switch (gp.getType())
|
||
1086 | { |
||
1087 | case Geometry.TYPES.POINT:
|
||
1088 | shp = geomManager.createPoint(ptDst.getX(), ptDst.getY(), SUBTYPES.GEOM2D); |
||
1089 | break;
|
||
1090 | |||
1091 | case Geometry.TYPES.CURVE:
|
||
1092 | case Geometry.TYPES.ARC:
|
||
1093 | try {
|
||
1094 | shp = geomManager.createCurve(newGp, SUBTYPES.GEOM2D); |
||
1095 | } catch (CreateGeometryException e1) {
|
||
1096 | logger.error("Error creating a curve", e1);
|
||
1097 | } |
||
1098 | break;
|
||
1099 | |||
1100 | case Geometry.TYPES.SURFACE:
|
||
1101 | case Geometry.TYPES.CIRCLE:
|
||
1102 | case Geometry.TYPES.ELLIPSE:
|
||
1103 | |||
1104 | try {
|
||
1105 | shp = geomManager.createSurface(newGp, SUBTYPES.GEOM2D); |
||
1106 | } catch (CreateGeometryException e) {
|
||
1107 | logger.error("Error creating a surface", e);
|
||
1108 | } |
||
1109 | break;
|
||
1110 | } |
||
1111 | return shp;
|
||
1112 | } |
||
1113 | |||
1114 | public static Rectangle2D convertEnvelopeToRectangle2D(Envelope jtsR) { |
||
1115 | Rectangle2D.Double r = new Rectangle2D.Double(jtsR.getMinX(), |
||
1116 | jtsR.getMinY(), jtsR.getWidth(), jtsR.getHeight()); |
||
1117 | return r;
|
||
1118 | } |
||
1119 | |||
1120 | public static Envelope convertEnvelopeToJTS(org.gvsig.fmap.geom.primitive.Envelope r) { |
||
1121 | Envelope e = new Envelope(r.getMinimum(0), r.getMaximum(0), r.getMinimum(1), |
||
1122 | r.getMaximum(1));
|
||
1123 | return e;
|
||
1124 | } |
||
1125 | |||
1126 | /**
|
||
1127 | * Return a correct polygon (no hole)
|
||
1128 | * @param coordinates
|
||
1129 | * @return
|
||
1130 | */
|
||
1131 | public static Geometry getExteriorPolygon(Coordinate[] coordinates) { |
||
1132 | // isCCW = true => it's a hole
|
||
1133 | Coordinate[] vs = new Coordinate[coordinates.length]; |
||
1134 | if (CGAlgorithms.isCCW(coordinates)) {
|
||
1135 | for (int i = vs.length-1;i >= 0; i--){ |
||
1136 | vs[i] = coordinates[i]; |
||
1137 | } |
||
1138 | } else {
|
||
1139 | vs = coordinates; |
||
1140 | } |
||
1141 | LinearRing ring = geomFactory.createLinearRing(vs); |
||
1142 | |||
1143 | try {
|
||
1144 | Surface surface = (Surface)manager.create(TYPES.SURFACE, SUBTYPES.GEOM2D); |
||
1145 | surface.setGeneralPath(toShape(ring)); |
||
1146 | return surface;
|
||
1147 | } catch (NoninvertibleTransformException e) { |
||
1148 | e.printStackTrace(); |
||
1149 | } catch (CreateGeometryException e) {
|
||
1150 | e.printStackTrace(); |
||
1151 | } |
||
1152 | return null; |
||
1153 | } |
||
1154 | |||
1155 | public static boolean isCCW(Point[] points) { |
||
1156 | int length = points.length;
|
||
1157 | Coordinate[] vs;
|
||
1158 | |||
1159 | if (points[0].getX() != points[length-1].getX() || points[0].getY() != points[length-1].getY()) { |
||
1160 | vs=new Coordinate[length+1]; |
||
1161 | vs[points.length] = new Coordinate(points[0].getX(), points[0].getY()); |
||
1162 | } else {
|
||
1163 | vs=new Coordinate[length];
|
||
1164 | } |
||
1165 | for (int i = 0; i < length; i++) { |
||
1166 | vs[i] = new Coordinate(points[i].getX(), points[i].getY());
|
||
1167 | } |
||
1168 | |||
1169 | return CGAlgorithms.isCCW(vs);
|
||
1170 | } |
||
1171 | |||
1172 | public static boolean isCCW(Surface pol) { |
||
1173 | com.vividsolutions.jts.geom.Geometry jtsGeom = Converter.geometryToJts(pol); |
||
1174 | if (jtsGeom.getNumGeometries() == 1) { |
||
1175 | Coordinate[] coords = jtsGeom.getCoordinates();
|
||
1176 | return CGAlgorithms.isCCW(coords);
|
||
1177 | } |
||
1178 | return false; |
||
1179 | } |
||
1180 | |||
1181 | /**
|
||
1182 | * Return a hole (CCW ordered points)
|
||
1183 | * @param coordinates
|
||
1184 | * @return
|
||
1185 | */
|
||
1186 | public static Geometry getHole(Coordinate[] coordinates) { |
||
1187 | Coordinate[] vs = new Coordinate[coordinates.length]; |
||
1188 | if (CGAlgorithms.isCCW(coordinates)) {
|
||
1189 | vs=coordinates; |
||
1190 | |||
1191 | }else{
|
||
1192 | for (int i = vs.length-1; i >= 0; i--) { |
||
1193 | vs[i] = coordinates[i]; |
||
1194 | } |
||
1195 | } |
||
1196 | LinearRing ring = geomFactory.createLinearRing(vs); |
||
1197 | |||
1198 | try {
|
||
1199 | Surface surface = (Surface)manager.create(TYPES.SURFACE, SUBTYPES.GEOM2D); |
||
1200 | surface.setGeneralPath(toShape(ring)); |
||
1201 | return surface;
|
||
1202 | } catch (NoninvertibleTransformException e) { |
||
1203 | e.printStackTrace(); |
||
1204 | } catch (CreateGeometryException e) {
|
||
1205 | e.printStackTrace(); |
||
1206 | } |
||
1207 | return null; |
||
1208 | } |
||
1209 | |||
1210 | public static Shape getExteriorPolygon(GeneralPathX gp) { |
||
1211 | Area area = new Area(gp); |
||
1212 | area.isSingular(); |
||
1213 | return area;
|
||
1214 | } |
||
1215 | |||
1216 | /**
|
||
1217 | * Use it ONLY for NOT multipart polygons.
|
||
1218 | * @param pol
|
||
1219 | * @return
|
||
1220 | */
|
||
1221 | public static Geometry getNotHolePolygon(Surface pol) { |
||
1222 | // isCCW == true => hole
|
||
1223 | Coordinate[] coords;
|
||
1224 | ArrayList arrayCoords = null; |
||
1225 | int theType;
|
||
1226 | int numParts = 0; |
||
1227 | |||
1228 | //Use this array to store segment coordinate data
|
||
1229 | double[] theData = new double[4]; |
||
1230 | |||
1231 | ArrayList shells = new ArrayList(); |
||
1232 | ArrayList holes = new ArrayList(); |
||
1233 | Coordinate[] points = null; |
||
1234 | |||
1235 | int subType = pol.getGeometryType().getSubType();
|
||
1236 | boolean is3D = subType == 1 || subType == 3; |
||
1237 | |||
1238 | //El pathIterator no tiene en cuenta coordenadas 3D
|
||
1239 | //theIterator = pol.getPathIterator(null, manager.getFlatness());
|
||
1240 | GeneralPathX gp = pol.getGeneralPath(); |
||
1241 | |||
1242 | //while (!theIterator.isDone()) {
|
||
1243 | for (int nPoint = 0; nPoint < gp.getNumCoords(); nPoint++) { |
||
1244 | theData = gp.getCoordinatesAt(nPoint); |
||
1245 | theType = gp.getTypeAt(nPoint); |
||
1246 | |||
1247 | //Populate a segment of the new
|
||
1248 | // GeneralPathX object.
|
||
1249 | //Process the current segment to populate a new
|
||
1250 | // segment of the new GeneralPathX object.
|
||
1251 | switch (theType) {
|
||
1252 | case PathIterator.SEG_MOVETO: |
||
1253 | |||
1254 | // System.out.println("SEG_MOVETO");
|
||
1255 | if (arrayCoords == null) { |
||
1256 | arrayCoords = new ArrayList(); |
||
1257 | } else {
|
||
1258 | points = CoordinateArrays.toCoordinateArray(arrayCoords); |
||
1259 | |||
1260 | try {
|
||
1261 | LinearRing ring = geomFactory.createLinearRing(points); |
||
1262 | |||
1263 | if (CGAlgorithms.isCCW(points)) {
|
||
1264 | holes.add(ring); |
||
1265 | } else {
|
||
1266 | shells.add(ring); |
||
1267 | } |
||
1268 | } catch (Exception e) { |
||
1269 | System.err.println("Caught Topology exception in GMLLinearRingHandler"); |
||
1270 | |||
1271 | return null; |
||
1272 | } |
||
1273 | arrayCoords = new ArrayList(); |
||
1274 | } |
||
1275 | |||
1276 | numParts++; |
||
1277 | if(is3D)
|
||
1278 | arrayCoords.add(new Coordinate(theData[0], theData[1], theData[2])); |
||
1279 | else
|
||
1280 | arrayCoords.add(new Coordinate(theData[0], theData[1])); |
||
1281 | |||
1282 | break;
|
||
1283 | |||
1284 | case PathIterator.SEG_LINETO: |
||
1285 | if(is3D)
|
||
1286 | arrayCoords.add(new Coordinate(theData[0], theData[1], theData[2])); |
||
1287 | else
|
||
1288 | arrayCoords.add(new Coordinate(theData[0], theData[1])); |
||
1289 | break;
|
||
1290 | case PathIterator.SEG_QUADTO: |
||
1291 | System.out.println("SEG_QUADTO Not supported here"); |
||
1292 | break;
|
||
1293 | case PathIterator.SEG_CUBICTO: |
||
1294 | System.out.println("SEG_CUBICTO Not supported here"); |
||
1295 | break;
|
||
1296 | case PathIterator.SEG_CLOSE: |
||
1297 | Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
|
||
1298 | if(is3D)
|
||
1299 | arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y, firstCoord.z));
|
||
1300 | else
|
||
1301 | arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y));
|
||
1302 | break;
|
||
1303 | } //end switch
|
||
1304 | |||
1305 | //theIterator.next();
|
||
1306 | } //end while loop
|
||
1307 | |||
1308 | arrayCoords.add(arrayCoords.get(0));
|
||
1309 | coords = CoordinateArrays.toCoordinateArray(arrayCoords); |
||
1310 | |||
1311 | if (numParts == 1) { |
||
1312 | return getExteriorPolygon(coords);
|
||
1313 | } |
||
1314 | return pol;
|
||
1315 | } |
||
1316 | |||
1317 | /**
|
||
1318 | * Metodo creado para construir un MultiSurface formado por varias surface
|
||
1319 | *
|
||
1320 | * @author Leticia Riestra
|
||
1321 | * @param geom
|
||
1322 | * @return
|
||
1323 | */
|
||
1324 | public static com.vividsolutions.jts.geom.Geometry multiSurfaceToJts(MultiSurface geom, int srid) { |
||
1325 | Polygon[] polygons = new Polygon[geom.getPrimitivesNumber()]; |
||
1326 | for (int i = 0; i < polygons.length; i++) { |
||
1327 | Primitive primit = geom.getPrimitiveAt(i); |
||
1328 | MultiPolygon polygon = null;
|
||
1329 | if(primit.getType() == Geometry.TYPES.ELLIPSE || primit.getType() == Geometry.TYPES.CIRCLE)
|
||
1330 | polygon = (MultiPolygon)ellipseToJts((geom.getPrimitiveAt(i)), srid); |
||
1331 | else
|
||
1332 | polygon = (MultiPolygon)surfaceToJts((geom.getPrimitiveAt(i)), srid); |
||
1333 | |||
1334 | polygons[i] = (Polygon)polygon.getGeometryN(0);//(Polygon) surfaceToJts((geom.getPrimitiveAt(i)), srid); |
||
1335 | } |
||
1336 | return new com.vividsolutions.jts.geom.GeometryFactory().createMultiPolygon(polygons); |
||
1337 | } |
||
1338 | |||
1339 | private static com.vividsolutions.jts.geom.Geometry surfaceToJts(Geometry shp, int srid) { |
||
1340 | com.vividsolutions.jts.geom.Geometry geoJTS = null;
|
||
1341 | int theType;
|
||
1342 | int numParts = 0; |
||
1343 | ArrayList arrayCoords = null; |
||
1344 | int subType = shp.getGeometryType().getSubType();
|
||
1345 | boolean is3D = subType == 1 || subType == 3; |
||
1346 | double[] dataLine = new double[3]; |
||
1347 | double[] dataQuad = new double[3]; |
||
1348 | double[] dataCubic = new double[3]; |
||
1349 | |||
1350 | |||
1351 | ArrayList shells = new ArrayList(); |
||
1352 | ArrayList holes = new ArrayList(); |
||
1353 | Coordinate[] points = null; |
||
1354 | |||
1355 | //El pathIterator no tiene en cuenta coordenadas 3D. En este caso no
|
||
1356 | //necesitamos un iterador que interpole porque las SURFACE vienen con todos
|
||
1357 | //los puntos calculados, as? que hacemos un recorrido en vez de usar el
|
||
1358 | //iterador para poder obtener la Z y no perderla.
|
||
1359 | |||
1360 | //theIterator = shp.getPathIterator(null, manager.getFlatness());
|
||
1361 | GeneralPathX gp = shp.getGeneralPath(); |
||
1362 | |||
1363 | //while (!theIterator.isDone()) {
|
||
1364 | int nPoint = 0; |
||
1365 | for (int nType = 0; nType < gp.getNumTypes(); nType++) { |
||
1366 | theType = gp.getTypeAt(nType); |
||
1367 | switch (theType) {
|
||
1368 | case PathIterator.SEG_MOVETO: |
||
1369 | case PathIterator.SEG_LINETO: //Se lee un punto |
||
1370 | dataLine = gp.get3DCoordinatesAt(nPoint); |
||
1371 | nPoint ++; |
||
1372 | break;
|
||
1373 | case PathIterator.SEG_QUADTO: //Se leen dos puntos |
||
1374 | dataLine = gp.get3DCoordinatesAt(nPoint); |
||
1375 | dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
|
||
1376 | nPoint += 2;
|
||
1377 | break;
|
||
1378 | case PathIterator.SEG_CUBICTO: //Se leen tres puntos |
||
1379 | dataLine = gp.get3DCoordinatesAt(nPoint); |
||
1380 | dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
|
||
1381 | dataCubic = gp.get3DCoordinatesAt(nPoint + 2);
|
||
1382 | nPoint += 3;
|
||
1383 | break;
|
||
1384 | } |
||
1385 | //theType = theIterator.currentSegment(theData);
|
||
1386 | |||
1387 | switch (theType) {
|
||
1388 | case PathIterator.SEG_MOVETO: |
||
1389 | |||
1390 | // System.out.println("SEG_MOVETO");
|
||
1391 | if (arrayCoords == null) { |
||
1392 | arrayCoords = new ArrayList(); |
||
1393 | } else {
|
||
1394 | points = CoordinateArrays.toCoordinateArray(arrayCoords); |
||
1395 | |||
1396 | try {
|
||
1397 | LinearRing ring = geomFactory.createLinearRing(points); |
||
1398 | |||
1399 | if (CGAlgorithms.isCCW(points)) {
|
||
1400 | holes.add(ring); |
||
1401 | } else {
|
||
1402 | shells.add(ring); |
||
1403 | } |
||
1404 | } catch (Exception e) { |
||
1405 | boolean same = true; |
||
1406 | for (int i = 0; i < points.length-1 && same; i++) { |
||
1407 | if (points[i].x != points[i+1].x || |
||
1408 | points[i].y != points[i+1].y /*|| |
||
1409 | points[i].z != points[i+1].z*/
|
||
1410 | ) { |
||
1411 | same = false;
|
||
1412 | } |
||
1413 | } |
||
1414 | if (same) {
|
||
1415 | return geomFactory.createPoint(points[0]); |
||
1416 | } |
||
1417 | |||
1418 | if (points.length > 1 && points.length <= 3) { |
||
1419 | // return geomFactory.createLineString(points);
|
||
1420 | return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)}); |
||
1421 | } |
||
1422 | |||
1423 | System.err.println(
|
||
1424 | "Caught Topology exception in GMLLinearRingHandler");
|
||
1425 | |||
1426 | return null; |
||
1427 | } |
||
1428 | |||
1429 | arrayCoords = new ArrayList(); |
||
1430 | } |
||
1431 | |||
1432 | numParts++; |
||
1433 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
1434 | break;
|
||
1435 | |||
1436 | case PathIterator.SEG_LINETO: |
||
1437 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
1438 | break;
|
||
1439 | |||
1440 | case PathIterator.SEG_QUADTO: |
||
1441 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
1442 | loadArrayCoordinates(arrayCoords, is3D, dataQuad); |
||
1443 | break;
|
||
1444 | |||
1445 | case PathIterator.SEG_CUBICTO: |
||
1446 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
1447 | loadArrayCoordinates(arrayCoords, is3D, dataQuad); |
||
1448 | loadArrayCoordinates(arrayCoords, is3D, dataCubic); |
||
1449 | break;
|
||
1450 | |||
1451 | case PathIterator.SEG_CLOSE: |
||
1452 | Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
|
||
1453 | loadArrayCoordinates(arrayCoords, is3D, new double[]{firstCoord.x, firstCoord.y, firstCoord.z}); |
||
1454 | break;
|
||
1455 | } //end switch
|
||
1456 | |||
1457 | //theIterator.next();
|
||
1458 | } //end while loop
|
||
1459 | |||
1460 | |||
1461 | Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
|
||
1462 | Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords.size() - 1);
|
||
1463 | |||
1464 | if (!isClosed(firstCoord, lastCoord)) {
|
||
1465 | arrayCoords.add(firstCoord); |
||
1466 | } |
||
1467 | points = CoordinateArrays.toCoordinateArray(arrayCoords); |
||
1468 | |||
1469 | try {
|
||
1470 | LinearRing ring = geomFactory.createLinearRing(points); |
||
1471 | |||
1472 | if (CGAlgorithms.isCCW(points)) {
|
||
1473 | holes.add(ring); |
||
1474 | } else {
|
||
1475 | shells.add(ring); |
||
1476 | } |
||
1477 | ring.setSRID(srid); |
||
1478 | } catch (Exception e) { |
||
1479 | boolean same = true; |
||
1480 | for (int i = 0; i < points.length-1 && same; i++) { |
||
1481 | if (points[i].x != points[i+1].x || |
||
1482 | points[i].y != points[i+1].y /*|| |
||
1483 | points[i].z != points[i+1].z*/
|
||
1484 | ) { |
||
1485 | same = false;
|
||
1486 | } |
||
1487 | } |
||
1488 | if (same) {
|
||
1489 | geoJTS = geomFactory.createPoint(points[0]);
|
||
1490 | geoJTS.setSRID(srid); |
||
1491 | return geoJTS;
|
||
1492 | } |
||
1493 | if (points.length > 1 && points.length <= 3) { |
||
1494 | // return geomFactory.createLineString(points);
|
||
1495 | geoJTS = geomFactory |
||
1496 | .createMultiLineString(new LineString[] { geomFactory |
||
1497 | .createLineString(points) }); |
||
1498 | geoJTS.setSRID(srid); |
||
1499 | return geoJTS;
|
||
1500 | } |
||
1501 | System.err.println(
|
||
1502 | "Caught Topology exception in GMLLinearRingHandler");
|
||
1503 | |||
1504 | return null; |
||
1505 | } |
||
1506 | |||
1507 | /* linRing = new GeometryFactory().createLinearRing(
|
||
1508 | CoordinateArrays.toCoordinateArray(arrayCoords)); */
|
||
1509 | |||
1510 | // System.out.println("NumParts = " + numParts);
|
||
1511 | //now we have a list of all shells and all holes
|
||
1512 | ArrayList holesForShells = new ArrayList(shells.size()); |
||
1513 | |||
1514 | for (int i = 0; i < shells.size(); i++) { |
||
1515 | holesForShells.add(new ArrayList()); |
||
1516 | } |
||
1517 | |||
1518 | //find homes
|
||
1519 | for (int i = 0; i < holes.size(); i++) { |
||
1520 | LinearRing testRing = (LinearRing) holes.get(i); |
||
1521 | LinearRing minShell = null;
|
||
1522 | Envelope minEnv = null;
|
||
1523 | Envelope testEnv = testRing.getEnvelopeInternal(); |
||
1524 | Coordinate testPt = testRing.getCoordinateN(0);
|
||
1525 | LinearRing tryRing = null;
|
||
1526 | |||
1527 | for (int j = 0; j < shells.size(); j++) { |
||
1528 | tryRing = (LinearRing) shells.get(j); |
||
1529 | |||
1530 | Envelope tryEnv = tryRing.getEnvelopeInternal(); |
||
1531 | |||
1532 | if (minShell != null) { |
||
1533 | minEnv = minShell.getEnvelopeInternal(); |
||
1534 | } |
||
1535 | |||
1536 | boolean isContained = false; |
||
1537 | Coordinate[] coordList = tryRing.getCoordinates();
|
||
1538 | |||
1539 | if (tryEnv.contains(testEnv) &&
|
||
1540 | (CGAlgorithms.isPointInRing(testPt, coordList) || |
||
1541 | (pointInList(testPt, coordList)))) { |
||
1542 | isContained = true;
|
||
1543 | } |
||
1544 | |||
1545 | // check if this new containing ring is smaller than the current minimum ring
|
||
1546 | if (isContained) {
|
||
1547 | if ((minShell == null) || minEnv.contains(tryEnv)) { |
||
1548 | minShell = tryRing; |
||
1549 | } |
||
1550 | } |
||
1551 | } |
||
1552 | |||
1553 | if (minShell == null) { |
||
1554 | // System.out.println(
|
||
1555 | // polygon found with a hole thats not inside a shell);
|
||
1556 | // azabala: we do the assumption that this hole is really a shell (polygon)
|
||
1557 | // whose point werent digitized in the right order
|
||
1558 | Coordinate[] cs = testRing.getCoordinates();
|
||
1559 | Coordinate[] reversed = new Coordinate[cs.length]; |
||
1560 | int pointIndex = 0; |
||
1561 | for(int z = cs.length-1; z >= 0; z--){ |
||
1562 | reversed[pointIndex] = cs[z]; |
||
1563 | pointIndex++; |
||
1564 | } |
||
1565 | LinearRing newRing = geomFactory.createLinearRing(reversed); |
||
1566 | shells.add(newRing); |
||
1567 | holesForShells.add(new ArrayList()); |
||
1568 | } else {
|
||
1569 | ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
|
||
1570 | } |
||
1571 | } |
||
1572 | |||
1573 | Polygon[] polygons = new Polygon[shells.size()]; |
||
1574 | |||
1575 | for (int i = 0; i < shells.size(); i++) { |
||
1576 | polygons[i] = geomFactory.createPolygon( |
||
1577 | (LinearRing) shells.get(i), |
||
1578 | (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(new LinearRing[0])); |
||
1579 | polygons[i].setSRID(srid); |
||
1580 | } |
||
1581 | |||
1582 | |||
1583 | holesForShells = null;
|
||
1584 | shells = null;
|
||
1585 | holes = null;
|
||
1586 | |||
1587 | geoJTS = geomFactory.createMultiPolygon(polygons); |
||
1588 | geoJTS.setSRID(srid); |
||
1589 | |||
1590 | return geoJTS;
|
||
1591 | } |
||
1592 | |||
1593 | private static com.vividsolutions.jts.geom.Geometry ellipseToJts(Geometry shp, int srid) { |
||
1594 | com.vividsolutions.jts.geom.Geometry geoJTS = null;
|
||
1595 | int theType;
|
||
1596 | int numParts = 0; |
||
1597 | ArrayList arrayCoords = null; |
||
1598 | int subType = shp.getGeometryType().getSubType();
|
||
1599 | boolean is3D = subType == 1 || subType == 3; |
||
1600 | double[] dataLine = new double[3]; |
||
1601 | |||
1602 | |||
1603 | ArrayList shells = new ArrayList(); |
||
1604 | ArrayList holes = new ArrayList(); |
||
1605 | Coordinate[] points = null; |
||
1606 | |||
1607 | //El pathIterator no tiene en cuenta coordenadas 3D, pero para la creaci?n de elipses y circulos
|
||
1608 | //es necesario el iterador que interpole puntos. El resultado es que en la creaci?n de geometr?as de este
|
||
1609 | //tipo no se puede asignar la Z porque se perder?a, pero gvSIG tampoco dispone de esta funci?n, as? que
|
||
1610 | //no se nota. Una vez creadas las geometr?a de tipo Elipse y circulo cuando las editamos ya tendr?n todos
|
||
1611 | //los puntos calculados y se toman como l?neas por lo que ya se podr?a asignar la Z.
|
||
1612 | |||
1613 | PathIterator theIterator = shp.getPathIterator(null, manager.getFlatness()); |
||
1614 | while (!theIterator.isDone()) {
|
||
1615 | theType = theIterator.currentSegment(dataLine); |
||
1616 | |||
1617 | switch (theType) {
|
||
1618 | case PathIterator.SEG_MOVETO: |
||
1619 | if (arrayCoords == null) { |
||
1620 | arrayCoords = new ArrayList(); |
||
1621 | } else {
|
||
1622 | points = CoordinateArrays.toCoordinateArray(arrayCoords); |
||
1623 | |||
1624 | try {
|
||
1625 | LinearRing ring = geomFactory.createLinearRing(points); |
||
1626 | |||
1627 | if (CGAlgorithms.isCCW(points)) {
|
||
1628 | holes.add(ring); |
||
1629 | } else {
|
||
1630 | shells.add(ring); |
||
1631 | } |
||
1632 | } catch (Exception e) { |
||
1633 | boolean same = true; |
||
1634 | for (int i = 0; i < points.length-1 && same; i++) { |
||
1635 | if (points[i].x != points[i+1].x || |
||
1636 | points[i].y != points[i+1].y /*|| |
||
1637 | points[i].z != points[i+1].z*/
|
||
1638 | ) { |
||
1639 | same = false;
|
||
1640 | } |
||
1641 | } |
||
1642 | if (same) {
|
||
1643 | return geomFactory.createPoint(points[0]); |
||
1644 | } |
||
1645 | |||
1646 | if (points.length > 1 && points.length <= 3) { |
||
1647 | // return geomFactory.createLineString(points);
|
||
1648 | return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)}); |
||
1649 | } |
||
1650 | |||
1651 | System.err.println(
|
||
1652 | "Caught Topology exception in GMLLinearRingHandler");
|
||
1653 | |||
1654 | return null; |
||
1655 | } |
||
1656 | |||
1657 | arrayCoords = new ArrayList(); |
||
1658 | } |
||
1659 | |||
1660 | numParts++; |
||
1661 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
1662 | break;
|
||
1663 | |||
1664 | case PathIterator.SEG_LINETO: |
||
1665 | loadArrayCoordinates(arrayCoords, is3D, dataLine); |
||
1666 | break;
|
||
1667 | |||
1668 | case PathIterator.SEG_QUADTO: |
||
1669 | break;
|
||
1670 | |||
1671 | case PathIterator.SEG_CUBICTO: |
||
1672 | break;
|
||
1673 | |||
1674 | case PathIterator.SEG_CLOSE: |
||
1675 | Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
|
||
1676 | loadArrayCoordinates(arrayCoords, is3D, new double[]{firstCoord.x, firstCoord.y, firstCoord.z}); |
||
1677 | break;
|
||
1678 | } //end switch
|
||
1679 | |||
1680 | theIterator.next(); |
||
1681 | } //end while loop
|
||
1682 | |||
1683 | |||
1684 | Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
|
||
1685 | Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords.size() - 1);
|
||
1686 | |||
1687 | if (!isClosed(firstCoord, lastCoord)) {
|
||
1688 | arrayCoords.add(firstCoord); |
||
1689 | } |
||
1690 | points = CoordinateArrays.toCoordinateArray(arrayCoords); |
||
1691 | |||
1692 | try {
|
||
1693 | LinearRing ring = geomFactory.createLinearRing(points); |
||
1694 | |||
1695 | if (CGAlgorithms.isCCW(points)) {
|
||
1696 | holes.add(ring); |
||
1697 | } else {
|
||
1698 | shells.add(ring); |
||
1699 | } |
||
1700 | ring.setSRID(srid); |
||
1701 | } catch (Exception e) { |
||
1702 | boolean same = true; |
||
1703 | for (int i = 0; i < points.length-1 && same; i++) { |
||
1704 | if (points[i].x != points[i+1].x || |
||
1705 | points[i].y != points[i+1].y /*|| |
||
1706 | points[i].z != points[i+1].z*/
|
||
1707 | ) { |
||
1708 | same = false;
|
||
1709 | } |
||
1710 | } |
||
1711 | if (same) {
|
||
1712 | geoJTS = geomFactory.createPoint(points[0]);
|
||
1713 | geoJTS.setSRID(srid); |
||
1714 | return geoJTS;
|
||
1715 | } |
||
1716 | if (points.length > 1 && points.length <= 3) { |
||
1717 | // return geomFactory.createLineString(points);
|
||
1718 | geoJTS = geomFactory |
||
1719 | .createMultiLineString(new LineString[] { geomFactory |
||
1720 | .createLineString(points) }); |
||
1721 | geoJTS.setSRID(srid); |
||
1722 | return geoJTS;
|
||
1723 | } |
||
1724 | System.err.println(
|
||
1725 | "Caught Topology exception in GMLLinearRingHandler");
|
||
1726 | |||
1727 | return null; |
||
1728 | } |
||
1729 | |||
1730 | /* linRing = new GeometryFactory().createLinearRing(
|
||
1731 | CoordinateArrays.toCoordinateArray(arrayCoords)); */
|
||
1732 | |||
1733 | // System.out.println("NumParts = " + numParts);
|
||
1734 | //now we have a list of all shells and all holes
|
||
1735 | ArrayList holesForShells = new ArrayList(shells.size()); |
||
1736 | |||
1737 | for (int i = 0; i < shells.size(); i++) { |
||
1738 | holesForShells.add(new ArrayList()); |
||
1739 | } |
||
1740 | |||
1741 | //find homes
|
||
1742 | for (int i = 0; i < holes.size(); i++) { |
||
1743 | LinearRing testRing = (LinearRing) holes.get(i); |
||
1744 | LinearRing minShell = null;
|
||
1745 | Envelope minEnv = null;
|
||
1746 | Envelope testEnv = testRing.getEnvelopeInternal(); |
||
1747 | Coordinate testPt = testRing.getCoordinateN(0);
|
||
1748 | LinearRing tryRing = null;
|
||
1749 | |||
1750 | for (int j = 0; j < shells.size(); j++) { |
||
1751 | tryRing = (LinearRing) shells.get(j); |
||
1752 | |||
1753 | Envelope tryEnv = tryRing.getEnvelopeInternal(); |
||
1754 | |||
1755 | if (minShell != null) { |
||
1756 | minEnv = minShell.getEnvelopeInternal(); |
||
1757 | } |
||
1758 | |||
1759 | boolean isContained = false; |
||
1760 | Coordinate[] coordList = tryRing.getCoordinates();
|
||
1761 | |||
1762 | if (tryEnv.contains(testEnv) &&
|
||
1763 | (CGAlgorithms.isPointInRing(testPt, coordList) || |
||
1764 | (pointInList(testPt, coordList)))) { |
||
1765 | isContained = true;
|
||
1766 | } |
||
1767 | |||
1768 | // check if this new containing ring is smaller than the current minimum ring
|
||
1769 | if (isContained) {
|
||
1770 | if ((minShell == null) || minEnv.contains(tryEnv)) { |
||
1771 | minShell = tryRing; |
||
1772 | } |
||
1773 | } |
||
1774 | } |
||
1775 | |||
1776 | if (minShell == null) { |
||
1777 | // System.out.println(
|
||
1778 | // polygon found with a hole thats not inside a shell);
|
||
1779 | // azabala: we do the assumption that this hole is really a shell (polygon)
|
||
1780 | // whose point werent digitized in the right order
|
||
1781 | Coordinate[] cs = testRing.getCoordinates();
|
||
1782 | Coordinate[] reversed = new Coordinate[cs.length]; |
||
1783 | int pointIndex = 0; |
||
1784 | for(int z = cs.length-1; z >= 0; z--){ |
||
1785 | reversed[pointIndex] = cs[z]; |
||
1786 | pointIndex++; |
||
1787 | } |
||
1788 | LinearRing newRing = geomFactory.createLinearRing(reversed); |
||
1789 | shells.add(newRing); |
||
1790 | holesForShells.add(new ArrayList()); |
||
1791 | } else {
|
||
1792 | ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
|
||
1793 | } |
||
1794 | } |
||
1795 | |||
1796 | Polygon[] polygons = new Polygon[shells.size()]; |
||
1797 | |||
1798 | for (int i = 0; i < shells.size(); i++) { |
||
1799 | polygons[i] = geomFactory.createPolygon( |
||
1800 | (LinearRing) shells.get(i), |
||
1801 | (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(new LinearRing[0])); |
||
1802 | polygons[i].setSRID(srid); |
||
1803 | } |
||
1804 | |||
1805 | |||
1806 | holesForShells = null;
|
||
1807 | shells = null;
|
||
1808 | holes = null;
|
||
1809 | |||
1810 | geoJTS = geomFactory.createMultiPolygon(polygons); |
||
1811 | geoJTS.setSRID(srid); |
||
1812 | |||
1813 | return geoJTS;
|
||
1814 | } |
||
1815 | |||
1816 | /**
|
||
1817 | * Loads one element in the <code>List</code> of coordinates with the
|
||
1818 | * data contained in the array of doubles
|
||
1819 | * @param arrayCoords
|
||
1820 | * @param is3D
|
||
1821 | * @param data
|
||
1822 | */
|
||
1823 | private static void loadArrayCoordinates(List arrayCoords, boolean is3D, double[] data) { |
||
1824 | if(is3D)
|
||
1825 | arrayCoords.add(new Coordinate(data[0], data[1], data[2])); |
||
1826 | else
|
||
1827 | arrayCoords.add(new Coordinate(data[0], data[1])); |
||
1828 | } |
||
1829 | |||
1830 | } |