Revision 23047
trunk/libraries/libTopology/src/org/gvsig/jcs/JCSUtil.java | ||
---|---|---|
49 | 49 |
package org.gvsig.jcs; |
50 | 50 |
|
51 | 51 |
import java.util.ArrayList; |
52 |
import java.util.Iterator; |
|
53 | 52 |
import java.util.List; |
54 |
import java.util.Map; |
|
55 | 53 |
|
56 | 54 |
import org.gvsig.fmap.core.NewFConverter; |
57 | 55 |
import org.gvsig.jts.JtsUtil; |
... | ... | |
61 | 59 |
import org.gvsig.jump.adapter.FeatureSchemaLayerDefinitionAdapter; |
62 | 60 |
import org.gvsig.jump.adapter.IFeatureAdapter; |
63 | 61 |
import org.gvsig.jump.adapter.TaskMonitorAdapter; |
62 |
import org.gvsig.topology.Messages; |
|
64 | 63 |
|
65 | 64 |
import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
65 |
import com.iver.cit.gvsig.exceptions.layers.LoadLayerException; |
|
66 | 66 |
import com.iver.cit.gvsig.fmap.core.IFeature; |
67 |
import com.iver.cit.gvsig.fmap.core.IGeometry; |
|
68 | 67 |
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator; |
68 |
import com.iver.cit.gvsig.fmap.layers.FLayerGenericVectorial; |
|
69 | 69 |
import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
70 | 70 |
import com.vividsolutions.jcs.conflate.boundarymatch.BoundaryMatcher; |
71 | 71 |
import com.vividsolutions.jcs.conflate.boundarymatch.BoundaryMatcherParameters; |
... | ... | |
73 | 73 |
import com.vividsolutions.jcs.conflate.coverage.CoverageAligner; |
74 | 74 |
import com.vividsolutions.jcs.conflate.coverage.CoverageGapRemover; |
75 | 75 |
import com.vividsolutions.jcs.conflate.polygonmatch.AngleHistogramMatcher; |
76 |
import com.vividsolutions.jcs.conflate.polygonmatch.AreaFilterFCMatchFinder; |
|
77 |
import com.vividsolutions.jcs.conflate.polygonmatch.BasicFCMatchFinder; |
|
78 | 76 |
import com.vividsolutions.jcs.conflate.polygonmatch.CentroidAligner; |
79 | 77 |
import com.vividsolutions.jcs.conflate.polygonmatch.CentroidDistanceMatcher; |
80 |
import com.vividsolutions.jcs.conflate.polygonmatch.ChainMatcher; |
|
81 | 78 |
import com.vividsolutions.jcs.conflate.polygonmatch.CompactnessMatcher; |
82 |
import com.vividsolutions.jcs.conflate.polygonmatch.DisambiguatingFCMatchFinder; |
|
83 |
import com.vividsolutions.jcs.conflate.polygonmatch.FCMatchFinder; |
|
84 | 79 |
import com.vividsolutions.jcs.conflate.polygonmatch.FeatureMatcher; |
85 | 80 |
import com.vividsolutions.jcs.conflate.polygonmatch.HausdorffDistanceMatcher; |
86 | 81 |
import com.vividsolutions.jcs.conflate.polygonmatch.Matches; |
87 | 82 |
import com.vividsolutions.jcs.conflate.polygonmatch.SymDiffMatcher; |
88 |
import com.vividsolutions.jcs.conflate.polygonmatch.TargetUnioningFCMatchFinder; |
|
89 | 83 |
import com.vividsolutions.jcs.conflate.polygonmatch.WeightedMatcher; |
90 |
import com.vividsolutions.jcs.conflate.polygonmatch.WindowFilter; |
|
91 | 84 |
import com.vividsolutions.jcs.conflate.roads.ConflationSession; |
92 | 85 |
import com.vividsolutions.jcs.conflate.roads.match.EdgeMatchOptions; |
93 | 86 |
import com.vividsolutions.jcs.conflate.roads.match.RoadMatchOptions; |
94 | 87 |
import com.vividsolutions.jcs.conflate.roads.match.RoadMatcherProcess; |
95 | 88 |
import com.vividsolutions.jcs.conflate.roads.model.ReferenceDatasetPrecedenceRuleEngine; |
96 |
import com.vividsolutions.jcs.conflate.roads.model.RoadNetwork; |
|
97 |
import com.vividsolutions.jcs.conflate.roads.model.SourceFeature; |
|
98 | 89 |
import com.vividsolutions.jcs.conflate.roads.model.Statistics; |
99 | 90 |
import com.vividsolutions.jcs.qa.InternalMatchedSegmentFinder; |
100 | 91 |
import com.vividsolutions.jcs.qa.OverlapFinder; |
... | ... | |
306 | 297 |
} |
307 | 298 |
|
308 | 299 |
|
309 |
public static void alignCoverate(FLyrVect lyr, FLyrVect lyr2, double clusterTolerance, double angleTolerance){ |
|
300 |
public static FLyrVect getGaps(FLyrVect lyr, double clusterTolerance){ |
|
301 |
InternalMatchedSegmentFinder.Parameters msfParam |
|
302 |
= new InternalMatchedSegmentFinder.Parameters(); |
|
303 |
msfParam.distanceTolerance = clusterTolerance; |
|
304 |
double angleTolerance = 22.5d; |
|
305 |
msfParam.angleTolerance = angleTolerance; |
|
306 |
InternalMatchedSegmentFinder msf = |
|
307 |
new InternalMatchedSegmentFinder(new FeatureCollectionAdapter(lyr.getSource()), |
|
308 |
msfParam); |
|
309 |
FeatureCollection gapsCandidates = msf.getMatchedFeatures(); |
|
310 |
FeatureCollectionDataSourceAdapter driver = |
|
311 |
new FeatureCollectionDataSourceAdapter(Messages.getText("GAPS"), |
|
312 |
gapsCandidates, |
|
313 |
new FeatureSchemaLayerDefinitionAdapter(gapsCandidates.getFeatureSchema())); |
|
314 |
FLayerGenericVectorial solution = new FLayerGenericVectorial(); |
|
315 |
solution.setName(driver.getName()); |
|
316 |
solution.setProjection(lyr.getProjection()); |
|
317 |
solution.setDriver(driver); |
|
318 |
try { |
|
319 |
solution.load(); |
|
320 |
|
|
321 |
} catch (LoadLayerException e) { |
|
322 |
e.printStackTrace(); |
|
323 |
} |
|
324 |
return solution; |
|
325 |
} |
|
326 |
|
|
327 |
|
|
328 |
public static void alignCoverage(FLyrVect lyr, FLyrVect lyr2, double clusterTolerance, double angleTolerance){ |
|
310 | 329 |
FeatureCollectionAdapter fc = new FeatureCollectionAdapter(lyr.getSource()); |
311 | 330 |
FeatureCollectionAdapter fc2 = new FeatureCollectionAdapter(lyr2.getSource()); |
312 | 331 |
CoverageAligner.Parameters param = new CoverageAligner.Parameters(); |
... | ... | |
352 | 371 |
IFeature feature = iterator.next(); |
353 | 372 |
if(feature.getID().equals(linearFeature.getID())) |
354 | 373 |
continue; |
355 |
Geometry geom = feature.getGeometry().toJTSGeometry();
|
|
374 |
Geometry geom = NewFConverter.toJtsGeometry(feature.getGeometry());
|
|
356 | 375 |
LineString[] lineStrings = JtsUtil.extractLineStrings(geom); |
357 | 376 |
for (int i = 0; i < lineStrings.length; i++) { |
358 | 377 |
LineString lineStr = lineStrings[i]; |
trunk/libraries/libTopology/src/org/gvsig/jts/JtsUtil.java | ||
---|---|---|
61 | 61 |
import java.util.List; |
62 | 62 |
import java.util.Stack; |
63 | 63 |
|
64 |
import org.gvsig.fmap.core.NewFConverter; |
|
65 |
|
|
66 |
import com.iver.cit.gvsig.fmap.core.FGeometry; |
|
67 |
import com.iver.cit.gvsig.fmap.core.FGeometryCollection; |
|
68 |
import com.iver.cit.gvsig.fmap.core.FMultiPoint2D; |
|
69 |
import com.iver.cit.gvsig.fmap.core.FShape; |
|
70 |
import com.iver.cit.gvsig.fmap.core.IGeometry; |
|
71 | 64 |
import com.vividsolutions.jts.algorithm.CGAlgorithms; |
72 | 65 |
import com.vividsolutions.jts.algorithms.SnapCGAlgorithms; |
73 | 66 |
import com.vividsolutions.jts.geom.Coordinate; |
74 |
import com.vividsolutions.jts.geom.CoordinateSequence; |
|
75 |
import com.vividsolutions.jts.geom.CoordinateSequences; |
|
76 | 67 |
import com.vividsolutions.jts.geom.Envelope; |
77 | 68 |
import com.vividsolutions.jts.geom.Geometry; |
78 | 69 |
import com.vividsolutions.jts.geom.GeometryCollection; |
... | ... | |
409 | 400 |
* @param ring |
410 | 401 |
* @return |
411 | 402 |
*/ |
412 |
public static LinearRing reverse(LinearRing ring) { |
|
413 |
CoordinateSequence seq = ring.getCoordinateSequence(); |
|
414 |
CoordinateSequences.reverse(seq); |
|
415 |
LinearRing solution = GEOMETRY_FACTORY.createLinearRing(seq); |
|
403 |
// public static LinearRing reverse(LinearRing ring) { |
|
404 |
// CoordinateSequence seq = ring.getCoordinateSequence(); |
|
405 |
// CoordinateSequences.reverse(seq); |
|
406 |
// LinearRing solution = GEOMETRY_FACTORY.createLinearRing(seq); |
|
407 |
// return solution; |
|
408 |
// } |
|
409 |
// |
|
410 |
// |
|
411 |
public static LineString reverse(LineString lineString){ |
|
412 |
LineString solution = lineString.reverse(); |
|
413 |
if(lineString instanceof LinearRing) |
|
414 |
solution = toLinearRing(lineString); |
|
416 | 415 |
return solution; |
416 |
|
|
417 | 417 |
} |
418 | 418 |
|
419 | 419 |
public static Geometry douglasPeuckerSimplify(Geometry geometry, double distTolerance){ |
... | ... | |
424 | 424 |
return TopologyPreservingSimplifier.simplify(geometry, distTolerance); |
425 | 425 |
} |
426 | 426 |
|
427 |
public static Geometry toJtsGeometry(IGeometry fmapGeometry) { |
|
428 |
Geometry solution = null; |
|
429 |
if (fmapGeometry instanceof FGeometry) { |
|
430 |
FShape shp = (FShape) ((FGeometry) fmapGeometry).getInternalShape(); |
|
431 |
solution = NewFConverter.java2d_to_jts(shp); |
|
432 |
} else if (fmapGeometry instanceof FGeometryCollection) { |
|
433 |
IGeometry[] geometries = ((FGeometryCollection) fmapGeometry) |
|
434 |
.getGeometries(); |
|
435 |
Geometry[] theGeoms = new Geometry[geometries.length]; |
|
436 |
for (int i = 0; i < geometries.length; i++) { |
|
437 |
theGeoms[i] = ((IGeometry) geometries[i]).toJTSGeometry(); |
|
438 |
} |
|
439 |
solution = GEOMETRY_FACTORY.createGeometryCollection(theGeoms); |
|
440 |
|
|
441 |
} else if (fmapGeometry instanceof FMultiPoint2D) { |
|
442 |
solution = ((FMultiPoint2D) fmapGeometry).toJTSGeometry(); |
|
443 |
} |
|
444 |
return solution; |
|
445 |
} |
|
446 |
|
|
447 | 427 |
public static Envelope toSnapRectangle(Coordinate coord, |
448 | 428 |
double snapTolerance) { |
449 | 429 |
Envelope solution = null; |
... | ... | |
922 | 902 |
//we do the assumption that this hole is really a |
923 | 903 |
// shell (polygon) |
924 | 904 |
// whose point werent digitized in the right order |
925 |
LinearRing newRing = JtsUtil.reverse(testRing); |
|
905 |
LinearRing newRing = (LinearRing) JtsUtil.reverse(testRing);
|
|
926 | 906 |
shells.add(newRing); |
927 | 907 |
holesForShells.add(new ArrayList<LinearRing>()); |
928 | 908 |
} else { |
trunk/libraries/libTopology/src/org/gvsig/fmap/core/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 |
} |
trunk/libraries/libTopology/src/org/gvsig/fmap/core/FGeometryUtil.java | ||
---|---|---|
85 | 85 |
import com.iver.cit.gvsig.fmap.core.IGeometry; |
86 | 86 |
import com.iver.cit.gvsig.fmap.core.ShapeFactory; |
87 | 87 |
import com.iver.cit.gvsig.fmap.core.gt2.FLiteShape; |
88 |
import com.iver.cit.gvsig.fmap.core.v02.FConverter; |
|
89 |
import com.vividsolutions.jts.algorithm.CGAlgorithms; |
|
90 |
import com.vividsolutions.jts.algorithms.SnapCGAlgorithms; |
|
91 | 88 |
import com.vividsolutions.jts.geom.Coordinate; |
92 | 89 |
import com.vividsolutions.jts.geom.Envelope; |
93 | 90 |
import com.vividsolutions.jts.geom.Geometry; |
94 | 91 |
import com.vividsolutions.jts.geom.LineString; |
95 | 92 |
import com.vividsolutions.jts.geom.LinearRing; |
96 |
import com.vividsolutions.jts.geom.MultiPolygon; |
|
97 | 93 |
import com.vividsolutions.jts.geom.Polygon; |
98 | 94 |
import com.vividsolutions.jts.util.GeometricShapeFactory; |
99 | 95 |
|
... | ... | |
376 | 372 |
|
377 | 373 |
processedGeometries.add(ShapeFactory.createPolygon2D(shape)); |
378 | 374 |
}else{ |
379 |
Geometry jtsGeom = nextGeometry.toJTSGeometry();
|
|
375 |
Geometry jtsGeom = NewFConverter.toJtsGeometry(nextGeometry);
|
|
380 | 376 |
Geometry correctedGeom = JtsUtil.removeOverShoot(jtsGeom, clusterTolerance); |
381 |
IGeometry correctedFGeo = FConverter.jts_to_igeometry(correctedGeom);
|
|
377 |
IGeometry correctedFGeo = NewFConverter.toFMap(correctedGeom);
|
|
382 | 378 |
processedGeometries.add(correctedFGeo); |
383 | 379 |
} |
384 | 380 |
}//for i |
... | ... | |
513 | 509 |
* |
514 | 510 |
*/ |
515 | 511 |
|
516 |
public static MultiPolygon toJtsPolygon(FShape shp) { |
|
517 |
|
|
518 |
ArrayList<LinearRing> shells = new ArrayList<LinearRing>(); |
|
519 |
ArrayList<LinearRing> holes = new ArrayList<LinearRing>(); |
|
520 |
|
|
521 |
List<Point2D[]> shpPoints = ShapePointExtractor.extractPoints(shp); |
|
522 |
for (int i = 0; i < shpPoints.size(); i++) { |
|
523 |
Point2D[] partPoints = shpPoints.get(i); |
|
524 |
Coordinate[] coords = JtsUtil.getPoint2DAsCoordinates(partPoints); |
|
525 |
try { |
|
526 |
LinearRing ring = JtsUtil.GEOMETRY_FACTORY |
|
527 |
.createLinearRing(coords); |
|
528 |
|
|
529 |
// TODO REPORTAR ESTO EN FMAP, CREO QUE EST? MAL PORQUE LO HACE |
|
530 |
// AL REV?S. |
|
531 |
// EL TEMA EST? EN QUE JTS HACE LAS COSAS AL REVES QUE EL |
|
532 |
// FORMATO SHP |
|
533 |
if (CGAlgorithms.isCCW(coords)) { |
|
534 |
shells.add(ring); |
|
535 |
} else { |
|
536 |
holes.add(ring); |
|
537 |
} |
|
538 |
} catch (Exception e) { |
|
539 |
/* |
|
540 |
* Leer la cabecera del metodo: FConverter no deber?a hacer |
|
541 |
* estos tratamientos boolean same = true; for (int j = 0; i < |
|
542 |
* coords.length - 1 && same; j++) { if (coords[i].x != |
|
543 |
* coords[i+1].x || coords[i].y != coords[i+1].y) same = false; } |
|
544 |
* if (same) return JtsUtil.geomFactory.createPoint(coords[0]); |
|
545 |
*/ |
|
546 |
|
|
547 |
/* |
|
548 |
* caso cuando es una l?nea de 3 puntos, no creo un LinearRing, |
|
549 |
* sino una linea |
|
550 |
*/ |
|
551 |
/* |
|
552 |
* if (coords.length > 1 && coords.length <= 3) // return |
|
553 |
* geomFactory.createLineString(points); return |
|
554 |
* JtsUtil.geomFactory.createMultiLineString(new LineString[] |
|
555 |
* {JtsUtil.geomFactory.createLineString(coords)}); |
|
556 |
*/ |
|
557 |
System.err |
|
558 |
.println("Caught Topology exception in GMLLinearRingHandler"); |
|
559 |
return null; |
|
560 |
} |
|
561 |
}// for |
|
562 |
|
|
563 |
// At this point, we have a collection of shells and a collection of |
|
564 |
// holes |
|
565 |
// Now we have to find for each shell its holes |
|
566 |
ArrayList<List<LinearRing>> holesForShells = new ArrayList<List<LinearRing>>( |
|
567 |
shells.size()); |
|
568 |
for (int i = 0; i < shells.size(); i++) { |
|
569 |
holesForShells.add(new ArrayList<LinearRing>()); |
|
570 |
} |
|
571 |
|
|
572 |
/* |
|
573 |
* Now, for each hole we look for the minimal shell that contains it. We |
|
574 |
* look for minimal because many shells could contain the same hole. |
|
575 |
*/ |
|
576 |
for (int i = 0; i < holes.size(); i++) {// for each hole |
|
577 |
LinearRing testHole = holes.get(i); |
|
578 |
LinearRing minShell = null; |
|
579 |
Envelope minEnv = null; |
|
580 |
Envelope testEnv = testHole.getEnvelopeInternal(); |
|
581 |
Coordinate testPt = testHole.getCoordinateN(0); |
|
582 |
LinearRing tryRing = null; |
|
583 |
|
|
584 |
for (int j = 0; j < shells.size(); j++) {// for each shell |
|
585 |
tryRing = (LinearRing) shells.get(j); |
|
586 |
Envelope tryEnv = tryRing.getEnvelopeInternal(); |
|
587 |
boolean isContained = false; |
|
588 |
Coordinate[] coordList = tryRing.getCoordinates(); |
|
589 |
|
|
590 |
// if testpoint is in ring, or test point is a shell point, is |
|
591 |
// contained |
|
592 |
if (tryEnv.contains(testEnv) |
|
593 |
&& (SnapCGAlgorithms.isPointInRing(testPt, coordList) || JtsUtil |
|
594 |
.pointInList(testPt, coordList))) { |
|
595 |
isContained = true; |
|
596 |
} |
|
597 |
|
|
598 |
// check if this new containing ring is smaller than the current |
|
599 |
// minimum ring |
|
600 |
if (isContained) { |
|
601 |
if ((minShell == null) || minEnv.contains(tryEnv)) { |
|
602 |
minShell = tryRing; |
|
603 |
minEnv = minShell.getEnvelopeInternal(); |
|
604 |
} |
|
605 |
} |
|
606 |
}// for shells |
|
607 |
|
|
608 |
// At this point, minShell is the shell that contains a testHole |
|
609 |
// if minShell is null, we have a SHELL which points were digitized |
|
610 |
// in the |
|
611 |
// wrong order |
|
612 |
|
|
613 |
if (minShell == null) { |
|
614 |
|
|
615 |
/* |
|
616 |
* TODO Si las clases de FMap incluyesen en su semantica la |
|
617 |
* diferencia entre un shell y un hole, no deberiamos hacer esta |
|
618 |
* suposicion. |
|
619 |
* |
|
620 |
* Pero como java.awt.geom.Shape no hace esta distincion, |
|
621 |
* tenemos que hacerla. |
|
622 |
* |
|
623 |
* |
|
624 |
*/ |
|
625 |
LinearRing reversed = JtsUtil.reverse(testHole); |
|
626 |
shells.add(reversed); |
|
627 |
holesForShells.add(new ArrayList<LinearRing>()); |
|
628 |
} else { |
|
629 |
((ArrayList<LinearRing>) holesForShells.get(shells |
|
630 |
.indexOf(minShell))).add(testHole); |
|
631 |
} |
|
632 |
}// for each hole |
|
633 |
|
|
634 |
Polygon[] polygons = new Polygon[shells.size()]; |
|
635 |
for (int i = 0; i < shells.size(); i++) { |
|
636 |
polygons[i] = JtsUtil.GEOMETRY_FACTORY.createPolygon( |
|
637 |
(LinearRing) shells.get(i), |
|
638 |
(LinearRing[]) ((ArrayList<LinearRing>) holesForShells |
|
639 |
.get(i)).toArray(new LinearRing[0])); |
|
640 |
} |
|
641 |
return JtsUtil.GEOMETRY_FACTORY.createMultiPolygon(polygons); |
|
642 |
|
|
643 |
} |
|
644 |
|
|
645 | 512 |
public static Point2D[] getCoordinatesAsPoint2D(Coordinate[] coords) { |
646 | 513 |
Point2D[] solution = new Point2D[coords.length]; |
647 | 514 |
for (int i = 0; i < coords.length; i++) { |
... | ... | |
689 | 556 |
* @return |
690 | 557 |
*/ |
691 | 558 |
public static boolean isInBoundary(IGeometry geometry, Point2D point2d, double tolerance){ |
692 |
Geometry jtsGeom = geometry.toJTSGeometry();
|
|
559 |
Geometry jtsGeom = NewFConverter.toJtsGeometry(geometry);
|
|
693 | 560 |
Coordinate coord = new Coordinate(point2d.getX(), point2d.getY()); |
694 | 561 |
Coordinate base = new Coordinate(coord.x - tolerance, coord.y - tolerance); |
695 | 562 |
GeometricShapeFactory shpFactory = new GeometricShapeFactory(JtsUtil.GEOMETRY_FACTORY); |
Also available in: Unified diff