Revision 23047 trunk/libraries/libTopology/src/org/gvsig/fmap/core/NewFConverter.java

View differences:

NewFConverter.java
58 58

  
59 59
import org.gvsig.jts.JtsUtil;
60 60

  
61
import com.iver.cit.gvsig.fmap.core.FGeometry;
61 62
import com.iver.cit.gvsig.fmap.core.FGeometryCollection;
63
import com.iver.cit.gvsig.fmap.core.FMultiPoint2D;
62 64
import com.iver.cit.gvsig.fmap.core.FPoint2D;
63 65
import com.iver.cit.gvsig.fmap.core.FPolygon2D;
64 66
import com.iver.cit.gvsig.fmap.core.FPolyline2D;
......
69 71
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
70 72
import com.vividsolutions.jts.algorithm.CGAlgorithms;
71 73
import com.vividsolutions.jts.algorithm.RobustCGAlgorithms;
74
import com.vividsolutions.jts.algorithms.SnapCGAlgorithms;
72 75
import com.vividsolutions.jts.geom.Coordinate;
73 76
import com.vividsolutions.jts.geom.CoordinateArrays;
74 77
import com.vividsolutions.jts.geom.Envelope;
......
86 89
 * 
87 90
 * Offers the same functionality than
88 91
 * com.iver.cit.gvsig.fmap.core.v02.FConverter, but doesnt do some checks that
89
 * FConverter does (for example, it doesnt close unclosed Polygons)
92
 * FConverter does (for example, it doesnt close unclosed Polygons).
90 93
 * 
94
 * Also, it works with Jts.GEOMETRY_FACTORY, a global geometry factory which
95
 * works with a precision model selected by user. Precision Model is very important
96
 * to determine the number of significant digits of geometries, and to avoid precision problems.
97
 * 
91 98
 * @author Alvaro Zabala
92 99
 * 
93 100
 */
......
354 361
		case FShape.POINT:
355 362
		case FShape.POINT + FShape.Z:
356 363
			geoJTS = createPoint(shp);
357

  
364
			break;
358 365
		case FShape.LINE:
359 366
		case FShape.ARC:
360 367
		case FShape.LINE + FShape.Z:
......
1027 1034
			return new FGeometryCollection(fmapGeoms);
1028 1035
	}
1029 1036

  
1037
	public static MultiPolygon toJtsPolygon(FShape shp) {
1038
	
1039
		ArrayList<LinearRing> shells = new ArrayList<LinearRing>();
1040
		ArrayList<LinearRing> holes = new ArrayList<LinearRing>();
1041
	
1042
		List<Point2D[]> shpPoints = ShapePointExtractor.extractPoints(shp);
1043
		for (int i = 0; i < shpPoints.size(); i++) {
1044
			Point2D[] partPoints = shpPoints.get(i);
1045
			Coordinate[] coords = JtsUtil.getPoint2DAsCoordinates(partPoints);
1046
			try {
1047
				LinearRing ring = JtsUtil.GEOMETRY_FACTORY
1048
						.createLinearRing(coords);
1049
	
1050
				// TODO REPORTAR ESTO EN FMAP, CREO QUE EST? MAL PORQUE LO HACE
1051
				// AL REV?S.
1052
				// EL TEMA EST? EN QUE JTS HACE LAS COSAS AL REVES QUE EL
1053
				// FORMATO SHP
1054
				if (CGAlgorithms.isCCW(coords)) {
1055
					shells.add(ring);
1056
				} else {
1057
					holes.add(ring);
1058
				}
1059
			} catch (Exception e) {
1060
				/*
1061
				 * Leer la cabecera del metodo: FConverter no deber?a hacer
1062
				 * estos tratamientos boolean same = true; for (int j = 0; i <
1063
				 * coords.length - 1 && same; j++) { if (coords[i].x !=
1064
				 * coords[i+1].x || coords[i].y != coords[i+1].y) same = false; }
1065
				 * if (same) return JtsUtil.geomFactory.createPoint(coords[0]);
1066
				 */
1067
	
1068
				/*
1069
				 * caso cuando es una l?nea de 3 puntos, no creo un LinearRing,
1070
				 * sino una linea
1071
				 */
1072
				/*
1073
				 * if (coords.length > 1 && coords.length <= 3) // return
1074
				 * geomFactory.createLineString(points); return
1075
				 * JtsUtil.geomFactory.createMultiLineString(new LineString[]
1076
				 * {JtsUtil.geomFactory.createLineString(coords)});
1077
				 */
1078
				System.err
1079
						.println("Caught Topology exception in GMLLinearRingHandler");
1080
				return null;
1081
			}
1082
		}// for
1083
	
1084
		// At this point, we have a collection of shells and a collection of
1085
		// holes
1086
		// Now we have to find for each shell its holes
1087
		ArrayList<List<LinearRing>> holesForShells = new ArrayList<List<LinearRing>>(
1088
				shells.size());
1089
		for (int i = 0; i < shells.size(); i++) {
1090
			holesForShells.add(new ArrayList<LinearRing>());
1091
		}
1092
	
1093
		/*
1094
		 * Now, for each hole we look for the minimal shell that contains it. We
1095
		 * look for minimal because many shells could contain the same hole.
1096
		 */
1097
		for (int i = 0; i < holes.size(); i++) {// for each hole
1098
			LinearRing testHole = holes.get(i);
1099
			LinearRing minShell = null;
1100
			Envelope minEnv = null;
1101
			Envelope testEnv = testHole.getEnvelopeInternal();
1102
			Coordinate testPt = testHole.getCoordinateN(0);
1103
			LinearRing tryRing = null;
1104
	
1105
			for (int j = 0; j < shells.size(); j++) {// for each shell
1106
				tryRing = (LinearRing) shells.get(j);
1107
				Envelope tryEnv = tryRing.getEnvelopeInternal();
1108
				boolean isContained = false;
1109
				Coordinate[] coordList = tryRing.getCoordinates();
1110
	
1111
				// if testpoint is in ring, or test point is a shell point, is
1112
				// contained
1113
				if (tryEnv.contains(testEnv)
1114
						&& (SnapCGAlgorithms.isPointInRing(testPt, coordList) || JtsUtil
1115
								.pointInList(testPt, coordList))) {
1116
					isContained = true;
1117
				}
1118
	
1119
				// check if this new containing ring is smaller than the current
1120
				// minimum ring
1121
				if (isContained) {
1122
					if ((minShell == null) || minEnv.contains(tryEnv)) {
1123
						minShell = tryRing;
1124
						minEnv = minShell.getEnvelopeInternal();
1125
					}
1126
				}
1127
			}// for shells
1128
	
1129
			// At this point, minShell is the shell that contains a testHole
1130
			// if minShell is null, we have a SHELL which points were digitized
1131
			// in the
1132
			// wrong order
1133
	
1134
			if (minShell == null) {
1135
	
1136
				/*
1137
				 * TODO Si las clases de FMap incluyesen en su semantica la
1138
				 * diferencia entre un shell y un hole, no deberiamos hacer esta
1139
				 * suposicion.
1140
				 * 
1141
				 * Pero como java.awt.geom.Shape no hace esta distincion,
1142
				 * tenemos que hacerla.
1143
				 * 
1144
				 * 
1145
				 */
1146
				LinearRing reversed = (LinearRing) JtsUtil.reverse(testHole);
1147
				shells.add(reversed);
1148
				holesForShells.add(new ArrayList<LinearRing>());
1149
			} else {
1150
				((ArrayList<LinearRing>) holesForShells.get(shells
1151
						.indexOf(minShell))).add(testHole);
1152
			}
1153
		}// for each hole
1154
	
1155
		Polygon[] polygons = new Polygon[shells.size()];
1156
		for (int i = 0; i < shells.size(); i++) {
1157
			polygons[i] = JtsUtil.GEOMETRY_FACTORY.createPolygon(
1158
					(LinearRing) shells.get(i),
1159
					(LinearRing[]) ((ArrayList<LinearRing>) holesForShells
1160
							.get(i)).toArray(new LinearRing[0]));
1161
		}
1162
		return JtsUtil.GEOMETRY_FACTORY.createMultiPolygon(polygons);
1163
	
1164
	}
1165

  
1166
	public static Geometry toJtsGeometry(IGeometry fmapGeometry) {
1167
		Geometry solution = null;
1168
		if (fmapGeometry instanceof FGeometry) {
1169
			FShape shp = (FShape) ((FGeometry) fmapGeometry).getInternalShape();
1170
			solution = java2d_to_jts(shp);
1171
		} else if (fmapGeometry instanceof FGeometryCollection) {
1172
			IGeometry[] geometries = ((FGeometryCollection) fmapGeometry)
1173
					.getGeometries();
1174
			Geometry[] theGeoms = new Geometry[geometries.length];
1175
			for (int i = 0; i < geometries.length; i++) {
1176
				theGeoms[i] = NewFConverter.toJtsGeometry(((IGeometry) geometries[i]));
1177
			}
1178
			solution = JtsUtil.GEOMETRY_FACTORY.createGeometryCollection(theGeoms);
1179
	
1180
		} else if (fmapGeometry instanceof FMultiPoint2D) {
1181
			solution = ((FMultiPoint2D) fmapGeometry).toJTSGeometry();
1182
		}
1183
		return solution;
1184
	}
1185

  
1030 1186
}

Also available in: Unified diff