Revision 23047 trunk/libraries/libTopology/src/org/gvsig/fmap/core/NewFConverter.java
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