001: package net.refractions.udig.core.internal;
002:
003: import java.util.AbstractCollection;
004: import java.util.ArrayList;
005: import java.util.Collection;
006: import java.util.HashMap;
007: import java.util.Iterator;
008: import java.util.Map;
009: import java.util.Set;
010:
011: import org.geotools.data.DataUtilities;
012: import org.geotools.feature.AttributeType;
013: import org.geotools.feature.Feature;
014: import org.geotools.feature.FeatureCollection;
015: import org.geotools.feature.FeatureType;
016: import org.geotools.feature.GeometryAttributeType;
017: import org.geotools.feature.collection.AbstractFeatureCollection;
018: import org.geotools.geometry.jts.JTS;
019: import org.geotools.referencing.CRS;
020: import org.opengis.referencing.crs.CoordinateReferenceSystem;
021: import org.opengis.referencing.operation.MathTransform;
022: import org.opengis.referencing.operation.TransformException;
023: import org.opengis.util.CodeList;
024:
025: import com.vividsolutions.jts.geom.Coordinate;
026: import com.vividsolutions.jts.geom.Geometry;
027: import com.vividsolutions.jts.geom.GeometryCollection;
028: import com.vividsolutions.jts.geom.LineString;
029: import com.vividsolutions.jts.geom.LinearRing;
030: import com.vividsolutions.jts.geom.MultiLineString;
031: import com.vividsolutions.jts.geom.MultiPoint;
032: import com.vividsolutions.jts.geom.MultiPolygon;
033: import com.vividsolutions.jts.geom.Point;
034: import com.vividsolutions.jts.geom.Polygon;
035:
036: /**
037: * A utility class for playing with features.
038: *
039: * @author jeichar
040: */
041: public class FeatureUtils {
042:
043: /**
044: * Create a new Features from the provided coordinates and of the type indicated by geomType
045: *
046: * @param coordCRS The crs of the coordinates provided
047: * @param destinationCRS The desired crs of the geometry
048: * @param type the feature type of the object created
049: * @param coordinates the coordinates that will be used to create the new feature
050: * @param geomType the type of geometry that will be created
051: * @return A new features.
052: * @throws Exception
053: */
054: public static <T extends Geometry> Feature createFeature(
055: CoordinateReferenceSystem coordCRS,
056: CoordinateReferenceSystem destinationCRS, FeatureType type,
057: Coordinate[] coordinates, Class<T> geomType)
058: throws Exception {
059:
060: transform(coordCRS, destinationCRS, coordinates);
061: Object[] attrs = new Object[type.getAttributeCount()];
062: for (int i = 0; i < attrs.length; i++) {
063: attrs[i] = setDefaultValue(type.getAttributeType(i));
064: }
065: final Feature newFeature = type.create(attrs);
066: // Class geomType = type.getDefaultGeometry().getType();
067:
068: T geom = GeometryBuilder.create().safeCreateGeometry(geomType,
069: coordinates);
070: newFeature.setDefaultGeometry(geom);
071:
072: return newFeature;
073: }
074:
075: /**
076: * @param object
077: * @param object2
078: */
079: private static Object setDefaultValue(AttributeType type) {
080: if (type.createDefaultValue() != null)
081: return type.createDefaultValue();
082: if (Boolean.class.isAssignableFrom(type.getType())
083: || boolean.class.isAssignableFrom(type.getType()))
084: return Boolean.valueOf(false);
085: if (String.class.isAssignableFrom(type.getType()))
086: return ""; //$NON-NLS-1$
087: if (Integer.class.isAssignableFrom(type.getType()))
088: return Integer.valueOf(0);
089: if (Double.class.isAssignableFrom(type.getType()))
090: return Double.valueOf(0);
091: if (Float.class.isAssignableFrom(type.getType()))
092: return Float.valueOf(0);
093: if (CodeList.class.isAssignableFrom(type.getType())) {
094: return type.createDefaultValue();
095: }
096: return null;
097: }
098:
099: /**
100: * Transforms coordinates into the layer CRS if nessecary
101: *
102: * @throws Exception
103: */
104: private static void transform(CoordinateReferenceSystem coordCRS,
105: CoordinateReferenceSystem destinationCRS,
106: Coordinate[] coordinates) throws Exception {
107: if (coordCRS == null || destinationCRS == null)
108: return;
109: MathTransform mt = CRS
110: .transform(coordCRS, destinationCRS, true);
111: if (mt == null || mt.isIdentity())
112: return;
113: double[] coords = new double[coordinates.length * 2];
114: for (int i = 0; i < coordinates.length; i++) {
115: coords[i * 2] = coordinates[i].x;
116: coords[i * 2 + 1] = coordinates[i].y;
117: }
118: mt.transform(coords, 0, coords, 0, coordinates.length);
119: for (int i = 0; i < coordinates.length; i++) {
120: coordinates[i].x = coords[i * 2];
121: coordinates[i].y = coords[i * 2 + 1];
122: }
123: }
124:
125: /**
126: * Returns 0 if the features are the same. 1 if the attributes are the same but have different
127: * featureIDs and -1 if attributes are different or are of different featureTypes.
128: *
129: * @param feature1
130: * @param feature2
131: * @return
132: */
133: public static int same(Feature feature1, Feature feature2) {
134: if (DataUtilities.compare(feature1.getFeatureType(), feature2
135: .getFeatureType()) != 0) {
136: return -1;
137: }
138: for (int i = 0; i < feature1.getNumberOfAttributes(); i++) {
139: if (feature1.getAttribute(i) == null) {
140: if (feature2.getAttribute(i) != null)
141: return -1;
142: else
143: continue;
144: }
145: if (feature1.getAttribute(i) instanceof Geometry) {
146: Geometry geom1 = (Geometry) feature1.getAttribute(i);
147: if (feature2.getAttribute(i) instanceof Geometry) {
148: Geometry geom2 = (Geometry) feature2
149: .getAttribute(i);
150: if (geom1.equalsExact(geom2))
151: continue;
152: else
153: return -1;
154: } else
155: return -1;
156: }
157: if (!feature1.getAttribute(i).equals(
158: feature2.getAttribute(i)))
159: return -1;
160: }
161:
162: return feature1.getID().equals(feature2.getID()) ? 0 : 1;
163: }
164:
165: public static Map<String, String> createAttributeMapping(
166: FeatureType sourceSchema, FeatureType targetSchema) {
167: Map<String, String> queryAttributes = new HashMap<String, String>();
168: performDirectMapping(sourceSchema, targetSchema,
169: queryAttributes);
170: mapGeometryAttributes(sourceSchema, targetSchema,
171: queryAttributes);
172: return queryAttributes;
173: }
174:
175: /**
176: * Maps the default geometry attribute regardless of whether they are the same type.
177: */
178: @SuppressWarnings("unchecked")
179: private static void mapGeometryAttributes(FeatureType sourceSchema,
180: FeatureType targetSchema,
181: Map<String, String> queryAttributes) {
182: // Now we'll match the geometry on type only. I don't care if it has the same type name.
183: GeometryAttributeType defaultGeometry = targetSchema
184: .getDefaultGeometry();
185: if (defaultGeometry == null)
186: return;
187: if (!queryAttributes.containsKey(defaultGeometry.getName())) {
188: // first check source's default geom and see if it matches
189: if (defaultGeometry.getType().isAssignableFrom(
190: sourceSchema.getDefaultGeometry().getType())) {
191: queryAttributes.put(defaultGeometry.getName(),
192: sourceSchema.getDefaultGeometry().getName());
193: } else if (sourceSchema.getDefaultGeometry().getType()
194: .isAssignableFrom(GeometryCollection.class)
195: && !defaultGeometry.getType().isAssignableFrom(
196: GeometryCollection.class)) {
197:
198: } else {
199: // we have to look through all the source attributes looking for a geometry that
200: // matches.
201: boolean found = false;
202: for (int i = 0; i < sourceSchema.getAttributeCount(); i++) {
203: AttributeType source = sourceSchema
204: .getAttributeType(i);
205: if (defaultGeometry.getType().isAssignableFrom(
206: source.getType())) {
207: queryAttributes.put(defaultGeometry.getName(),
208: source.getName());
209: found = true;
210: break;
211: }
212: }
213: // ok so we're going to have to do some transformations. Match default geometries
214: // then.
215: if (!found) {
216: queryAttributes
217: .put(defaultGeometry.getName(),
218: sourceSchema.getDefaultGeometry()
219: .getName());
220: }
221: }
222: }
223: }
224:
225: /**
226: * Maps attributes with the same name and same types to each other.
227: */
228: @SuppressWarnings("unchecked")
229: private static void performDirectMapping(FeatureType sourceSchema,
230: FeatureType targetSchema,
231: Map<String, String> queryAttributes) {
232: for (int i = 0; i < sourceSchema.getAttributeCount(); i++) {
233: AttributeType source = sourceSchema.getAttributeType(i);
234: for (int j = 0; j < targetSchema.getAttributeCount(); j++) {
235: AttributeType target = targetSchema.getAttributeType(j);
236:
237: // don't worry about case of attribute name
238: if (target.getName().equalsIgnoreCase(source.getName())
239: && target.getType().isAssignableFrom(
240: source.getType())) {
241: queryAttributes.put(target.getName(), source
242: .getName());
243: }
244: }
245: }
246: }
247:
248: private static GeometryBuilder geomBuilder = GeometryBuilder
249: .create();
250:
251: /**
252: * Adapts a collection of features to a FeatureCollection
253: *
254: * @param collection
255: * @return
256: */
257: public static FeatureCollection toFeatureCollection(
258: final Collection<Feature> collection, FeatureType type) {
259: return new AbstractFeatureCollection(type) {
260:
261: @Override
262: protected void closeIterator(Iterator arg0) {
263: }
264:
265: @Override
266: protected Iterator openIterator() {
267: return collection.iterator();
268: }
269:
270: @Override
271: public int size() {
272: return collection.size();
273: }
274:
275: };
276: }
277:
278: public static Collection<Feature> copyFeature(final Feature source,
279: final FeatureType destinationSchema,
280: final Map<String, String> attributeMap,
281: final MathTransform mt) {
282:
283: return new AbstractCollection<Feature>() {
284: public Iterator<Feature> iterator() {
285: final Map<String, Iterator<? extends Geometry>> geometries = new HashMap<String, Iterator<? extends Geometry>>();
286: final Object[] attributes = copyAttributes(
287: destinationSchema, source, geometries,
288: attributeMap, mt);
289:
290: return new Iterator<Feature>() {
291: Feature next, template;
292:
293: public boolean hasNext() {
294: if (template == null) {
295: try {
296: template = next = destinationSchema
297: .create(attributes);
298:
299: } catch (Exception e) {
300: // try then next one then
301: CorePlugin.log("", e); //$NON-NLS-1$
302: }
303: return true;
304: }
305: if (geometries.isEmpty())
306: return false;
307:
308: while (next == null && !geometries.isEmpty()) {
309: try {
310: next = destinationSchema
311: .duplicate(template);
312: Set<Map.Entry<String, Iterator<? extends Geometry>>> entries = geometries
313: .entrySet();
314: for (Iterator<Map.Entry<String, Iterator<? extends Geometry>>> iter = entries
315: .iterator(); iter.hasNext();) {
316: Map.Entry<String, Iterator<? extends Geometry>> entry = iter
317: .next();
318: Geometry geom = entry.getValue()
319: .next();
320: next.setAttribute(entry.getKey(),
321: transformGeom(geom, mt));
322: if (!entry.getValue().hasNext())
323: iter.remove();
324: }
325: return true;
326:
327: } catch (Exception e) {
328: // try then next one then
329: CorePlugin.log("", e); //$NON-NLS-1$
330: }
331: }
332: return false;
333: }
334:
335: public Feature next() {
336: if (next == null)
337: throw new IndexOutOfBoundsException(
338: "No more elements in iterator."); //$NON-NLS-1$
339: Feature result = next;
340: next = null;
341: return result;
342: }
343:
344: public void remove() {
345: throw new UnsupportedOperationException();
346: }
347: };
348: }
349:
350: public int size() {
351: int size = 0;
352: for (Iterator<Feature> iter = iterator(); iter
353: .hasNext(); iter.next())
354: size++;
355: return size;
356: }
357: };
358: }
359:
360: private static Object[] copyAttributes(FeatureType destSchema,
361: Feature source,
362: Map<String, Iterator<? extends Geometry>> geometries,
363: Map<String, String> attributeMap, MathTransform mt) {
364: Object[] attributes = new Object[destSchema.getAttributeCount()];
365: for (int i = 0; i < attributes.length; i++) {
366: String sourceAttributeName = destSchema.getAttributeType(i)
367: .getName();
368: String name = attributeMap.get(sourceAttributeName);
369: if (name != null)
370: attributes[i] = source.getAttribute(name);
371: else {
372: attributes[i] = destSchema.getAttributeType(i)
373: .createDefaultValue();
374: }
375: if (attributes[i] instanceof Geometry) {
376: Class<? extends Geometry> geomType = (Class<? extends Geometry>) destSchema
377: .getAttributeType(i).getType();
378: if (!geomType
379: .isAssignableFrom(attributes[i].getClass())) {
380: Collection<? extends Geometry> geom = createCompatibleGeometry(
381: (Geometry) attributes[i], geomType);
382: Iterator<? extends Geometry> giter = geom
383: .iterator();
384: attributes[i] = giter.next();
385: if (giter.hasNext())
386: geometries.put(sourceAttributeName, giter);
387: }
388: attributes[i] = transformGeom((Geometry) attributes[i],
389: mt);
390: }
391: }
392: return attributes;
393: }
394:
395: private static Geometry transformGeom(Geometry geom,
396: MathTransform mt) {
397: if (mt != null) {
398: try {
399: return JTS.transform(geom, mt);
400: } catch (TransformException e) {
401: CorePlugin.log("", e); //$NON-NLS-1$
402: return geom;
403: }
404: }
405: return geom;
406: }
407:
408: private static Collection<? extends Geometry> createCompatibleGeometry(
409: Geometry geom, Class<? extends Geometry> targetType) {
410: Collection<Geometry> result = new ArrayList<Geometry>();
411: if (nonCollectionToPoint(geom, targetType, result))
412: return result;
413: else if (collectionToPoint(geom, targetType, result))
414: return result;
415: else if (nonCollectionToMultiPoint(geom, targetType, result))
416: return result;
417: else if (collectionToMultiPoint(geom, targetType, result))
418: return result;
419: else if (simpleToLine(geom, targetType, result))
420: return result;
421: else if (collectionToLine(geom, targetType, result))
422: return result;
423: else if (simpleToMultiLine(geom, targetType, result))
424: return result;
425: else if (collectionToMultiLine(geom, targetType, result))
426: return result;
427: else if (polygonToMultiLine(geom, targetType, result))
428: return result;
429: else if (polygonToLine(geom, targetType, result))
430: return result;
431: else if (multiPolygonToLine(geom, targetType, result))
432: return result;
433: else if (multiPolygonToMultiLine(geom, targetType, result))
434: return result;
435: else if (simpleToPolygon(geom, targetType, result))
436: return result;
437: else if (collectionToPolygon(geom, targetType, result))
438: return result;
439: else if (multiPolygonToPolygon(geom, targetType, result))
440: return result;
441: else if (simpleToMultiPolygon(geom, targetType, result))
442: return result;
443: else if (collectionToMultiPolygon(geom, targetType, result))
444: return result;
445: else if (polygonToMultiPolygon(geom, targetType, result))
446: return result;
447: else if (toLinearRing(geom, targetType, result))
448: return result;
449: throw new IllegalArgumentException(
450: "do not know how transform from " + geom.getClass().getName() + " to " + targetType.getName()); //$NON-NLS-1$ //$NON-NLS-2$
451:
452: }
453:
454: /**
455: * return true if Geometry is a point and targetType is a point. Result will be populated
456: * with the new point
457: */
458: private static boolean nonCollectionToPoint(Geometry geom,
459: Class<? extends Geometry> targetType,
460: Collection<Geometry> result) {
461: if (!(geom instanceof GeometryCollection)
462: && Point.class == targetType) {
463: result.add(geom.getCentroid());
464: return true;
465: }
466: return false;
467: }
468:
469: private static boolean collectionToPoint(Geometry geom,
470: Class<? extends Geometry> targetType,
471: Collection<Geometry> result) {
472: if (geom instanceof GeometryCollection
473: && Point.class == targetType) {
474: for (int i = 0; i < geom.getNumGeometries(); i++) {
475: result.add(geom.getGeometryN(i).getCentroid());
476: }
477: return true;
478: }
479: return false;
480: }
481:
482: private static boolean collectionToMultiPoint(Geometry geom,
483: Class<? extends Geometry> targetType,
484: Collection<Geometry> result) {
485: if (geom instanceof GeometryCollection
486: && MultiPoint.class == targetType) {
487: Point[] points = new Point[geom.getNumGeometries()];
488: for (int i = 0; i < geom.getNumGeometries(); i++) {
489: points[i] = geom.getGeometryN(i).getCentroid();
490: }
491: result.add(geomBuilder.factory.createMultiPoint(points));
492: return true;
493: }
494: return false;
495: }
496:
497: private static boolean nonCollectionToMultiPoint(Geometry geom,
498: Class<? extends Geometry> targetType,
499: Collection<Geometry> result) {
500: if (!(geom instanceof GeometryCollection)
501: && MultiPoint.class == targetType) {
502: result.add(geomBuilder.factory.createMultiPoint(geom
503: .getCentroid().getCoordinates()));
504: return true;
505: }
506: return false;
507: }
508:
509: private static boolean simpleToLine(Geometry geom,
510: Class<? extends Geometry> targetType,
511: Collection<Geometry> result) {
512: if (!(geom instanceof Polygon)
513: && !(geom instanceof GeometryCollection)
514: && LineString.class == targetType) {
515: result.add(geomBuilder.safeCreateGeometry(targetType, geom
516: .getCoordinates()));
517: return true;
518: }
519: return false;
520: }
521:
522: private static boolean collectionToLine(Geometry geom,
523: Class<? extends Geometry> targetType,
524: Collection<Geometry> result) {
525: if (!(geom instanceof Polygon)
526: && !(geom instanceof MultiPolygon)
527: && (geom instanceof GeometryCollection)
528: && LineString.class == targetType) {
529: for (int i = 0; i < geom.getNumGeometries(); i++) {
530: result.add(geomBuilder.safeCreateGeometry(targetType,
531: geom.getGeometryN(i).getCoordinates()));
532: }
533: return true;
534: }
535: return false;
536: }
537:
538: private static boolean simpleToMultiLine(Geometry geom,
539: Class<? extends Geometry> targetType,
540: Collection<Geometry> result) {
541: if (!(geom instanceof Polygon)
542: && !(geom instanceof GeometryCollection)
543: && MultiLineString.class == targetType) {
544: result.add(geomBuilder.safeCreateGeometry(targetType, geom
545: .getCoordinates()));
546: return true;
547: }
548: return false;
549: }
550:
551: private static boolean collectionToMultiLine(Geometry geom,
552: Class<? extends Geometry> targetType,
553: Collection<Geometry> result) {
554: if (!(geom instanceof Polygon)
555: && !(geom instanceof MultiPolygon)
556: && (geom instanceof GeometryCollection)
557: && MultiLineString.class == targetType) {
558: LineString[] geoms = new LineString[geom.getNumGeometries()];
559: for (int i = 0; i < geom.getNumGeometries(); i++) {
560: geoms[i] = geomBuilder.safeCreateGeometry(
561: LineString.class, geom.getGeometryN(i)
562: .getCoordinates());
563: }
564: result
565: .add(geomBuilder.factory
566: .createMultiLineString(geoms));
567: return true;
568: }
569: return false;
570: }
571:
572: private static boolean simpleToPolygon(Geometry geom,
573: Class<? extends Geometry> targetType,
574: Collection<Geometry> result) {
575: if (!(geom instanceof Polygon)
576: && !(geom instanceof GeometryCollection)
577: && Polygon.class == targetType) {
578: result.add(geomBuilder.safeCreateGeometry(targetType, geom
579: .getCoordinates()));
580: return true;
581: }
582: return false;
583: }
584:
585: private static boolean collectionToPolygon(Geometry geom,
586: Class<? extends Geometry> targetType,
587: Collection<Geometry> result) {
588: if (!(geom instanceof MultiPolygon)
589: && geom instanceof GeometryCollection
590: && Polygon.class == targetType) {
591: for (int i = 0; i < geom.getNumGeometries(); i++) {
592: result.add(geomBuilder.safeCreateGeometry(targetType,
593: geom.getGeometryN(i).getCoordinates()));
594: }
595: return true;
596: }
597: return false;
598: }
599:
600: private static boolean polygonToLine(Geometry geom,
601: Class<? extends Geometry> targetType,
602: Collection<Geometry> result) {
603: if (geom instanceof Polygon && LineString.class == targetType) {
604: Polygon polygon = (Polygon) geom;
605: result.add(geomBuilder.safeCreateGeometry(LineString.class,
606: polygon.getExteriorRing().getCoordinates()));
607: int i = 0;
608: while (i < polygon.getNumInteriorRing()) {
609: result.add(geomBuilder.safeCreateGeometry(
610: LineString.class, polygon.getInteriorRingN(i)
611: .getCoordinates()));
612: i++;
613: }
614: return true;
615: }
616: return false;
617: }
618:
619: private static boolean polygonToMultiLine(Geometry geom,
620: Class<? extends Geometry> targetType,
621: Collection<Geometry> result) {
622: if (geom instanceof Polygon
623: && MultiLineString.class == targetType) {
624: ArrayList<Geometry> tmp = new ArrayList<Geometry>();
625: if (!polygonToLine(geom, LineString.class, tmp))
626: throw new RuntimeException(
627: "Huh? multi polygons should only have polygons in them"); //$NON-NLS-1$
628: result.add(geomBuilder.factory.createMultiLineString(tmp
629: .toArray(new LineString[0])));
630: return true;
631: }
632: return false;
633: }
634:
635: private static boolean multiPolygonToLine(Geometry geom,
636: Class<? extends Geometry> targetType,
637: Collection<Geometry> result) {
638: if (geom instanceof MultiPolygon
639: && LineString.class == targetType) {
640: for (int i = 0; i < geom.getNumGeometries(); i++) {
641: if (!polygonToLine(geom.getGeometryN(i), targetType,
642: result))
643: throw new RuntimeException(
644: "Huh? multi polygons should only have polygons in them"); //$NON-NLS-1$
645: }
646: return true;
647: }
648: return false;
649: }
650:
651: private static boolean multiPolygonToMultiLine(Geometry geom,
652: Class<? extends Geometry> targetType,
653: Collection<Geometry> result) {
654: if (geom instanceof MultiPolygon
655: && MultiLineString.class == targetType) {
656:
657: for (int i = 0; i < geom.getNumGeometries(); i++) {
658: if (!polygonToMultiLine(geom.getGeometryN(i),
659: targetType, result))
660: throw new RuntimeException(
661: "Huh? multi polygons should only have polygons in them, found a " + geom.getGeometryN(i)); //$NON-NLS-1$
662: }
663:
664: return true;
665: }
666: return false;
667: }
668:
669: private static boolean multiPolygonToPolygon(Geometry geom,
670: Class<? extends Geometry> targetType,
671: Collection<Geometry> result) {
672: if (geom instanceof MultiPolygon && Polygon.class == targetType) {
673: for (int j = 0; j < geom.getNumGeometries(); j++) {
674: result.add(geom.getGeometryN(j));
675: }
676:
677: return true;
678: }
679: return false;
680: }
681:
682: private static boolean simpleToMultiPolygon(Geometry geom,
683: Class<? extends Geometry> targetType,
684: Collection<Geometry> result) {
685: if (!(geom instanceof Polygon)
686: && !(geom instanceof GeometryCollection)
687: && MultiPolygon.class == targetType) {
688: result.add(geomBuilder.safeCreateGeometry(targetType, geom
689: .getCoordinates()));
690: return true;
691: }
692: return false;
693: }
694:
695: private static boolean collectionToMultiPolygon(Geometry geom,
696: Class<? extends Geometry> targetType,
697: Collection<Geometry> result) {
698: if (!(geom instanceof Polygon)
699: && geom instanceof GeometryCollection
700: && MultiPolygon.class == targetType) {
701: for (int i = 0; i < geom.getNumGeometries(); i++) {
702: result.add(geomBuilder.safeCreateGeometry(targetType,
703: geom.getGeometryN(i).getCoordinates()));
704: }
705: return true;
706: }
707: return false;
708: }
709:
710: private static boolean polygonToMultiPolygon(Geometry geom,
711: Class<? extends Geometry> targetType,
712: Collection<Geometry> result) {
713: if (geom instanceof Polygon && MultiPolygon.class == targetType) {
714: result
715: .add(geomBuilder.factory
716: .createMultiPolygon(new Polygon[] { (Polygon) geom }));
717: return true;
718: }
719: return false;
720: }
721:
722: private static boolean toLinearRing(Geometry geom,
723: Class<? extends Geometry> targetType,
724: Collection<Geometry> result) {
725: if (!(targetType == LinearRing.class))
726: return false;
727: ArrayList<Geometry> tmp = new ArrayList<Geometry>();
728: if (!simpleToLine(geom, LineString.class, tmp)) {
729: if (!collectionToLine(geom, LineString.class, tmp)) {
730: if (!polygonToLine(geom, LineString.class, tmp)) {
731: if (!multiPolygonToLine(geom, LineString.class, tmp)) {
732: return false;
733: }
734: }
735: }
736: }
737:
738: for (Geometry geometry : tmp) {
739: result.add(geomBuilder.safeCreateGeometry(targetType,
740: geometry.getCoordinates()));
741: }
742: return true;
743: }
744:
745: }
|