Source Code Cross Referenced for LiteShape2.java in  » GIS » GeoTools-2.4.1 » org » geotools » geometry » jts » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.geometry.jts 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2004-2006, Geotools Project Managment Committee (PMC)
005:         *
006:         *    This library is free software; you can redistribute it and/or
007:         *    modify it under the terms of the GNU Lesser General Public
008:         *    License as published by the Free Software Foundation; either
009:         *    version 2.1 of the License, or (at your option) any later version.
010:         *
011:         *    This library is distributed in the hope that it will be useful,
012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         *    Lesser General Public License for more details.
015:         */
016:        package org.geotools.geometry.jts;
017:
018:        import java.awt.Rectangle;
019:        import java.awt.Shape;
020:        import java.awt.geom.AffineTransform;
021:        import java.awt.geom.PathIterator;
022:        import java.awt.geom.Point2D;
023:        import java.awt.geom.Rectangle2D;
024:        import java.util.ArrayList;
025:
026:        import org.opengis.referencing.FactoryException;
027:        import org.opengis.referencing.operation.MathTransform;
028:        import org.opengis.referencing.operation.TransformException;
029:
030:        import com.vividsolutions.jts.geom.Coordinate;
031:        import com.vividsolutions.jts.geom.Envelope;
032:        import com.vividsolutions.jts.geom.Geometry;
033:        import com.vividsolutions.jts.geom.GeometryCollection;
034:        import com.vividsolutions.jts.geom.GeometryFactory;
035:        import com.vividsolutions.jts.geom.LineString;
036:        import com.vividsolutions.jts.geom.LinearRing;
037:        import com.vividsolutions.jts.geom.Point;
038:        import com.vividsolutions.jts.geom.Polygon;
039:
040:        /**
041:         * A thin wrapper that adapts a JTS geometry to the Shape interface so that the
042:         * geometry can be used by java2d without coordinate cloning
043:         * 
044:         * @author Andrea Aime
045:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/geometry/jts/LiteShape2.java $
046:         * @version $Id: LiteShape2.java 26769 2007-08-30 12:49:25Z aaime $
047:         */
048:        public final class LiteShape2 implements  Shape, Cloneable {
049:
050:            /** The wrapped JTS geometry */
051:            private Geometry geometry;
052:
053:            private boolean generalize = false;
054:
055:            private double maxDistance = 1;
056:
057:            // cached iterators
058:            private LineIterator2 lineIterator = new LineIterator2();
059:
060:            private GeomCollectionIterator collIterator = new GeomCollectionIterator();
061:
062:            private EmptyIterator emptyiterator = new EmptyIterator();
063:
064:            private static GeometryFactory geomFac;
065:
066:            /** transform from dataspace to screenspace */
067:            private MathTransform mathTransform;
068:
069:            /**
070:             * Creates a new LiteShape object.
071:             * 
072:             * @param geom -
073:             *            the wrapped geometry
074:             * @param mathTransform -
075:             *            the transformation applied to the geometry in order to get to
076:             *            the shape points
077:             * @param decimator -
078:             *            
079:             * @param generalize -
080:             *            set to true if the geometry need to be generalized during
081:             *            rendering
082:             * @param maxDistance -
083:             *            distance used in the generalization process
084:             * @throws TransformException
085:             * @throws FactoryException
086:             */
087:            public LiteShape2(Geometry geom, MathTransform mathTransform,
088:                    Decimator decimator, boolean generalize, double maxDistance)
089:                    throws TransformException, FactoryException {
090:                this (geom, mathTransform, decimator, generalize);
091:                this .maxDistance = maxDistance;
092:            }
093:
094:            /**
095:             * Creates a new LiteShape object.
096:             * 
097:             * @param geom -
098:             *            the wrapped geometry
099:             * @param mathTransform -
100:             *            the transformation applied to the geometry in order to get to
101:             *            the shape points
102:             * @param decimator -
103:             *            
104:             * @param generalize -
105:             *            set to true if the geometry need to be generalized during
106:             *            rendering
107:             * 
108:             * @throws TransformException
109:             * @throws FactoryException
110:             */
111:            public LiteShape2(Geometry geom, MathTransform mathTransform,
112:                    Decimator decimator, boolean generalize)
113:                    throws TransformException, FactoryException {
114:                this (geom, mathTransform, decimator, generalize, true);
115:            }
116:
117:            /**
118:             * Creates a new LiteShape object.
119:             * 
120:             * @param geom -
121:             *            the wrapped geometry
122:             * @param mathTransform -
123:             *            the transformation applied to the geometry in order to get to
124:             *            the shape points
125:             * @param decimator -
126:             *            
127:             * @param generalize -
128:             *            set to true if the geometry need to be generalized during
129:             *            rendering
130:             *            
131:             * @param clone - if clone is false the original geometry may be modified directly, if true it will be
132:             *                cloned to make sure the original remains untouched
133:             * 
134:             * @throws TransformException
135:             * @throws FactoryException
136:             */
137:            public LiteShape2(Geometry geom, MathTransform mathTransform,
138:                    Decimator decimator, boolean generalize, boolean clone)
139:                    throws TransformException, FactoryException {
140:                if (geom != null) {
141:                    if (!clone
142:                            && geom.getFactory().getCoordinateSequenceFactory() instanceof  LiteCoordinateSequenceFactory)
143:                        this .geometry = geom;
144:                    else if (geom.getFactory().getCoordinateSequenceFactory() instanceof  LiteCoordinateSequenceFactory)
145:                        this .geometry = cloneGeometryLCS(geom); // optimized version
146:                    else
147:                        this .geometry = cloneGeometry(geom);
148:                }
149:
150:                this .mathTransform = mathTransform;
151:                if (decimator != null) {
152:                    decimator.decimateTransformGeneralize(this .geometry,
153:                            this .mathTransform);
154:                } else {
155:                    // if we have a transform a decimation span can be detected, so try to decimate anyways
156:                    if (mathTransform != null && !mathTransform.isIdentity()
157:                            && generalize)
158:                        new Decimator(mathTransform.inverse())
159:                                .decimate(this .geometry);
160:                    if (geometry != null)
161:                        transformGeometry(geometry);
162:                }
163:                this .generalize = false;
164:            }
165:
166:            /**
167:             *  changes this to a new CSF -- more efficient than the JTS way
168:             * @param geom
169:             */
170:            private final Geometry cloneGeometryLCS(Polygon geom) {
171:                LinearRing lr = (LinearRing) cloneGeometryLCS((LinearRing) geom
172:                        .getExteriorRing());
173:                LinearRing[] rings = new LinearRing[geom.getNumInteriorRing()];
174:                for (int t = 0; t < rings.length; t++) {
175:                    rings[t] = (LinearRing) cloneGeometryLCS((LinearRing) geom
176:                            .getInteriorRingN(t));
177:                }
178:                return getGeometryFactory().createPolygon(lr, rings);
179:            }
180:
181:            private final Geometry cloneGeometryLCS(Point geom) {
182:                return getGeometryFactory().createPoint(
183:                        new LiteCoordinateSequence(
184:                                (LiteCoordinateSequence) geom
185:                                        .getCoordinateSequence()));
186:            }
187:
188:            private final Geometry cloneGeometryLCS(LineString geom) {
189:                return getGeometryFactory().createLineString(
190:                        new LiteCoordinateSequence(
191:                                (LiteCoordinateSequence) geom
192:                                        .getCoordinateSequence()));
193:            }
194:
195:            private final Geometry cloneGeometryLCS(LinearRing geom) {
196:                return getGeometryFactory().createLinearRing(
197:                        new LiteCoordinateSequence(
198:                                (LiteCoordinateSequence) geom
199:                                        .getCoordinateSequence()));
200:            }
201:
202:            private final Geometry cloneGeometryLCS(Geometry geom) {
203:                if (geom instanceof  LineString)
204:                    return cloneGeometryLCS((LineString) geom);
205:                else if (geom instanceof  Polygon)
206:                    return cloneGeometryLCS((Polygon) geom);
207:                else if (geom instanceof  Point)
208:                    return cloneGeometryLCS((Point) geom);
209:                else
210:                    return cloneGeometryLCS((GeometryCollection) geom);
211:            }
212:
213:            private final Geometry cloneGeometryLCS(GeometryCollection geom) {
214:                if (geom.getNumGeometries() == 0) {
215:                    Geometry[] gs = new Geometry[0];
216:                    return getGeometryFactory().createGeometryCollection(gs);
217:                }
218:
219:                ArrayList gs = new ArrayList(geom.getNumGeometries());
220:                int n = geom.getNumGeometries();
221:                for (int t = 0; t < n; t++) {
222:                    gs.add(t, cloneGeometryLCS(geom.getGeometryN(t)));
223:                }
224:                return getGeometryFactory().buildGeometry(gs);
225:            }
226:
227:            /**
228:             *  changes this to a new CSF -- more efficient than the JTS way
229:             * @param geom
230:             */
231:            private final Geometry cloneGeometry(Polygon geom) {
232:                LinearRing lr = (LinearRing) cloneGeometry((LinearRing) geom
233:                        .getExteriorRing());
234:                LinearRing[] rings = new LinearRing[geom.getNumInteriorRing()];
235:                for (int t = 0; t < rings.length; t++) {
236:                    rings[t] = (LinearRing) cloneGeometry((LinearRing) geom
237:                            .getInteriorRingN(t));
238:                }
239:                return getGeometryFactory().createPolygon(lr, rings);
240:            }
241:
242:            private final Geometry cloneGeometry(Point geom) {
243:                return getGeometryFactory().createPoint(
244:                        new LiteCoordinateSequence((Coordinate[]) geom
245:                                .getCoordinates()));
246:            }
247:
248:            private final Geometry cloneGeometry(LineString geom) {
249:                return getGeometryFactory().createLineString(
250:                        new LiteCoordinateSequence((Coordinate[]) geom
251:                                .getCoordinates()));
252:            }
253:
254:            private final Geometry cloneGeometry(LinearRing geom) {
255:                return getGeometryFactory().createLinearRing(
256:                        new LiteCoordinateSequence((Coordinate[]) geom
257:                                .getCoordinates()));
258:            }
259:
260:            private final Geometry cloneGeometry(Geometry geom) {
261:                if (geom instanceof  LineString)
262:                    return cloneGeometry((LineString) geom);
263:                else if (geom instanceof  Polygon)
264:                    return cloneGeometry((Polygon) geom);
265:                else if (geom instanceof  Point)
266:                    return cloneGeometry((Point) geom);
267:                else
268:                    return cloneGeometry((GeometryCollection) geom);
269:            }
270:
271:            private final Geometry cloneGeometry(GeometryCollection geom) {
272:                if (geom.getNumGeometries() == 0) {
273:                    Geometry[] gs = new Geometry[0];
274:                    return getGeometryFactory().createGeometryCollection(gs);
275:                }
276:
277:                ArrayList gs = new ArrayList(geom.getNumGeometries());
278:                int n = geom.getNumGeometries();
279:                for (int t = 0; t < n; t++) {
280:                    gs.add(cloneGeometry(geom.getGeometryN(t)));
281:                }
282:                return getGeometryFactory().buildGeometry(gs);
283:            }
284:
285:            private void transformGeometry(Geometry geometry)
286:                    throws TransformException, FactoryException {
287:
288:                if (mathTransform == null || mathTransform.isIdentity())
289:                    return;
290:
291:                if (geometry instanceof  GeometryCollection) {
292:                    GeometryCollection collection = (GeometryCollection) geometry;
293:                    for (int i = 0; i < collection.getNumGeometries(); i++) {
294:                        transformGeometry(collection.getGeometryN(i));
295:                    }
296:                } else if (geometry instanceof  Point) {
297:                    LiteCoordinateSequence seq = (LiteCoordinateSequence) ((Point) geometry)
298:                            .getCoordinateSequence();
299:                    double[] coords = seq.getArray();
300:                    double[] newCoords = new double[coords.length];
301:                    mathTransform
302:                            .transform(coords, 0, newCoords, 0, seq.size());
303:                    seq.setArray(newCoords);
304:                } else if (geometry instanceof  Polygon) {
305:                    Polygon polygon = (Polygon) geometry;
306:                    transformGeometry(polygon.getExteriorRing());
307:                    for (int i = 0; i < polygon.getNumInteriorRing(); i++) {
308:                        transformGeometry(polygon.getInteriorRingN(i));
309:                    }
310:                } else if (geometry instanceof  LineString) {
311:                    LiteCoordinateSequence seq = (LiteCoordinateSequence) ((LineString) geometry)
312:                            .getCoordinateSequence();
313:                    double[] coords = seq.getArray();
314:                    mathTransform.transform(coords, 0, coords, 0, seq.size());
315:                    seq.setArray(coords);
316:                }
317:            }
318:
319:            private GeometryFactory getGeometryFactory() {
320:                if (geomFac == null) {
321:                    geomFac = new GeometryFactory(
322:                            new LiteCoordinateSequenceFactory());
323:                }
324:
325:                return geomFac;
326:            }
327:
328:            /**
329:             * Sets the geometry contained in this lite shape. Convenient to reuse this
330:             * object instead of creating it again and again during rendering
331:             * 
332:             * @param g
333:             * @throws TransformException
334:             * @throws FactoryException
335:             */
336:            public void setGeometry(Geometry g) throws TransformException,
337:                    FactoryException {
338:                if (g != null) {
339:                    this .geometry = getGeometryFactory().createGeometry(g);
340:                    transformGeometry(geometry);
341:                }
342:            }
343:
344:            /**
345:             * Tests if the interior of the <code>Shape</code> entirely contains the
346:             * specified <code>Rectangle2D</code>. This method might conservatively
347:             * return <code>false</code> when:
348:             * 
349:             * <ul>
350:             * <li>the <code>intersect</code> method returns <code>true</code> and
351:             * </li>
352:             * <li>the calculations to determine whether or not the <code>Shape</code>
353:             * entirely contains the <code>Rectangle2D</code> are prohibitively
354:             * expensive.</li>
355:             * </ul>
356:             * 
357:             * This means that this method might return <code>false</code> even though
358:             * the <code>Shape</code> contains the <code>Rectangle2D</code>. The
359:             * <code>Area</code> class can be used to perform more accurate
360:             * computations of geometric intersection for any <code>Shape</code>
361:             * object if a more precise answer is required.
362:             * 
363:             * @param r
364:             *            The specified <code>Rectangle2D</code>
365:             * 
366:             * @return <code>true</code> if the interior of the <code>Shape</code>
367:             *         entirely contains the <code>Rectangle2D</code>;
368:             *         <code>false</code> otherwise or, if the <code>Shape</code>
369:             *         contains the <code>Rectangle2D</code> and the
370:             *         <code>intersects</code> method returns <code>true</code> and
371:             *         the containment calculations would be too expensive to perform.
372:             * 
373:             * @see #contains(double, double, double, double)
374:             */
375:            public boolean contains(Rectangle2D r) {
376:                Geometry rect = rectangleToGeometry(r);
377:
378:                return geometry.contains(rect);
379:            }
380:
381:            /**
382:             * Tests if a specified {@link Point2D}is inside the boundary of the
383:             * <code>Shape</code>.
384:             * 
385:             * @param p
386:             *            a specified <code>Point2D</code>
387:             * 
388:             * @return <code>true</code> if the specified <code>Point2D</code> is
389:             *         inside the boundary of the <code>Shape</code>;
390:             *         <code>false</code> otherwise.
391:             */
392:            public boolean contains(Point2D p) {
393:                Coordinate coord = new Coordinate(p.getX(), p.getY());
394:                Geometry point = geometry.getFactory().createPoint(coord);
395:
396:                return geometry.contains(point);
397:            }
398:
399:            /**
400:             * Tests if the specified coordinates are inside the boundary of the
401:             * <code>Shape</code>.
402:             * 
403:             * @param x
404:             *            the specified coordinates, x value
405:             * @param y
406:             *            the specified coordinates, y value
407:             * 
408:             * @return <code>true</code> if the specified coordinates are inside the
409:             *         <code>Shape</code> boundary; <code>false</code> otherwise.
410:             */
411:            public boolean contains(double x, double y) {
412:                Coordinate coord = new Coordinate(x, y);
413:                Geometry point = geometry.getFactory().createPoint(coord);
414:
415:                return geometry.contains(point);
416:            }
417:
418:            /**
419:             * Tests if the interior of the <code>Shape</code> entirely contains the
420:             * specified rectangular area. All coordinates that lie inside the
421:             * rectangular area must lie within the <code>Shape</code> for the entire
422:             * rectanglar area to be considered contained within the <code>Shape</code>.
423:             * 
424:             * <p>
425:             * This method might conservatively return <code>false</code> when:
426:             * 
427:             * <ul>
428:             * <li>the <code>intersect</code> method returns <code>true</code> and
429:             * </li>
430:             * <li>the calculations to determine whether or not the <code>Shape</code>
431:             * entirely contains the rectangular area are prohibitively expensive.</li>
432:             * </ul>
433:             * 
434:             * This means that this method might return <code>false</code> even though
435:             * the <code>Shape</code> contains the rectangular area. The
436:             * <code>Area</code> class can be used to perform more accurate
437:             * computations of geometric intersection for any <code>Shape</code>
438:             * object if a more precise answer is required.
439:             * </p>
440:             * 
441:             * @param x
442:             *            the coordinates of the specified rectangular area, x value
443:             * @param y
444:             *            the coordinates of the specified rectangular area, y value
445:             * @param w
446:             *            the width of the specified rectangular area
447:             * @param h
448:             *            the height of the specified rectangular area
449:             * 
450:             * @return <code>true</code> if the interior of the <code>Shape</code>
451:             *         entirely contains the specified rectangular area;
452:             *         <code>false</code> otherwise or, if the <code>Shape</code>
453:             *         contains the rectangular area and the <code>intersects</code>
454:             *         method returns <code>true</code> and the containment
455:             *         calculations would be too expensive to perform.
456:             * 
457:             * @see java.awt.geom.Area
458:             * @see #intersects
459:             */
460:            public boolean contains(double x, double y, double w, double h) {
461:                Geometry rect = createRectangle(x, y, w, h);
462:
463:                return geometry.contains(rect);
464:            }
465:
466:            /**
467:             * Returns an integer {@link Rectangle}that completely encloses the
468:             * <code>Shape</code>. Note that there is no guarantee that the returned
469:             * <code>Rectangle</code> is the smallest bounding box that encloses the
470:             * <code>Shape</code>, only that the <code>Shape</code> lies entirely
471:             * within the indicated <code>Rectangle</code>. The returned
472:             * <code>Rectangle</code> might also fail to completely enclose the
473:             * <code>Shape</code> if the <code>Shape</code> overflows the limited
474:             * range of the integer data type. The <code>getBounds2D</code> method
475:             * generally returns a tighter bounding box due to its greater flexibility
476:             * in representation.
477:             * 
478:             * @return an integer <code>Rectangle</code> that completely encloses the
479:             *         <code>Shape</code>.
480:             * 
481:             * @see #getBounds2D
482:             */
483:            public Rectangle getBounds() {
484:                Coordinate[] coords = geometry.getEnvelope().getCoordinates();
485:
486:                // get out corners. the documentation doens't specify in which
487:                // order the bounding box coordinates are returned
488:                double x1;
489:
490:                // get out corners. the documentation doens't specify in which
491:                // order the bounding box coordinates are returned
492:                double y1;
493:
494:                // get out corners. the documentation doens't specify in which
495:                // order the bounding box coordinates are returned
496:                double x2;
497:
498:                // get out corners. the documentation doens't specify in which
499:                // order the bounding box coordinates are returned
500:                double y2;
501:                x1 = x2 = coords[0].x;
502:                y1 = y2 = coords[0].y;
503:
504:                for (int i = 1; i < 3; i++) {
505:                    double x = coords[i].x;
506:                    double y = coords[i].y;
507:
508:                    if (x < x1) {
509:                        x1 = x;
510:                    }
511:
512:                    if (x > x2) {
513:                        x2 = x;
514:                    }
515:
516:                    if (y < y1) {
517:                        y1 = y;
518:                    }
519:
520:                    if (y > y2) {
521:                        y2 = y;
522:                    }
523:                }
524:
525:                x1 = Math.ceil(x1);
526:                x2 = Math.floor(x2);
527:                y1 = Math.ceil(y1);
528:                y2 = Math.floor(y2);
529:
530:                return new Rectangle((int) x1, (int) y1, (int) (x2 - x1),
531:                        (int) (y2 - y1));
532:            }
533:
534:            /**
535:             * Returns a high precision and more accurate bounding box of the
536:             * <code>Shape</code> than the <code>getBounds</code> method. Note that
537:             * there is no guarantee that the returned {@link Rectangle2D}is the
538:             * smallest bounding box that encloses the <code>Shape</code>, only that
539:             * the <code>Shape</code> lies entirely within the indicated
540:             * <code>Rectangle2D</code>. The bounding box returned by this method is
541:             * usually tighter than that returned by the <code>getBounds</code> method
542:             * and never fails due to overflow problems since the return value can be an
543:             * instance of the <code>Rectangle2D</code> that uses double precision
544:             * values to store the dimensions.
545:             * 
546:             * @return an instance of <code>Rectangle2D</code> that is a
547:             *         high-precision bounding box of the <code>Shape</code>.
548:             * 
549:             * @see #getBounds
550:             */
551:            public Rectangle2D getBounds2D() {
552:                Envelope env = geometry.getEnvelopeInternal();
553:                return new Rectangle2D.Double(env.getMinX(), env.getMinY(), env
554:                        .getWidth(), env.getHeight());
555:            }
556:
557:            /**
558:             * Returns an iterator object that iterates along the <code>Shape</code>
559:             * boundary and provides access to the geometry of the <code>Shape</code>
560:             * outline. If an optional {@link AffineTransform}is specified, the
561:             * coordinates returned in the iteration are transformed accordingly.
562:             * 
563:             * <p>
564:             * Each call to this method returns a fresh <code>PathIterator</code>
565:             * object that traverses the geometry of the <code>Shape</code> object
566:             * independently from any other <code>PathIterator</code> objects in use
567:             * at the same time.
568:             * </p>
569:             * 
570:             * <p>
571:             * It is recommended, but not guaranteed, that objects implementing the
572:             * <code>Shape</code> interface isolate iterations that are in process
573:             * from any changes that might occur to the original object's geometry
574:             * during such iterations.
575:             * </p>
576:             * 
577:             * <p>
578:             * Before using a particular implementation of the <code>Shape</code>
579:             * interface in more than one thread simultaneously, refer to its
580:             * documentation to verify that it guarantees that iterations are isolated
581:             * from modifications.
582:             * </p>
583:             * 
584:             * @param at
585:             *            an optional <code>AffineTransform</code> to be applied to
586:             *            the coordinates as they are returned in the iteration, or
587:             *            <code>null</code> if untransformed coordinates are desired
588:             * 
589:             * @return a new <code>PathIterator</code> object, which independently
590:             *         traverses the geometry of the <code>Shape</code>.
591:             */
592:            public PathIterator getPathIterator(AffineTransform at) {
593:                PathIterator pi = null;
594:
595:                if (this .geometry.isEmpty())
596:                    return emptyiterator;
597:
598:                // return iterator according to the kind of geometry we include
599:                if (this .geometry instanceof  Point) {
600:                    pi = new PointIterator((Point) geometry, at);
601:                }
602:
603:                if (this .geometry instanceof  Polygon) {
604:
605:                    pi = new PolygonIterator((Polygon) geometry, at,
606:                            generalize, maxDistance);
607:                } else if (this .geometry instanceof  LineString) {
608:                    lineIterator.init((LineString) geometry, at);
609:                    pi = lineIterator;
610:                } else if (this .geometry instanceof  GeometryCollection) {
611:                    collIterator.init((GeometryCollection) geometry, at,
612:                            generalize, maxDistance);
613:                    pi = collIterator;
614:                }
615:                return pi;
616:            }
617:
618:            /**
619:             * Returns an iterator object that iterates along the <code>Shape</code>
620:             * boundary and provides access to a flattened view of the
621:             * <code>Shape</code> outline geometry.
622:             * 
623:             * <p>
624:             * Only SEG_MOVETO, SEG_LINETO, and SEG_CLOSE point types are returned by
625:             * the iterator.
626:             * </p>
627:             * 
628:             * <p>
629:             * If an optional <code>AffineTransform</code> is specified, the
630:             * coordinates returned in the iteration are transformed accordingly.
631:             * </p>
632:             * 
633:             * <p>
634:             * The amount of subdivision of the curved segments is controlled by the
635:             * <code>flatness</code> parameter, which specifies the maximum distance
636:             * that any point on the unflattened transformed curve can deviate from the
637:             * returned flattened path segments. Note that a limit on the accuracy of
638:             * the flattened path might be silently imposed, causing very small
639:             * flattening parameters to be treated as larger values. This limit, if
640:             * there is one, is defined by the particular implementation that is used.
641:             * </p>
642:             * 
643:             * <p>
644:             * Each call to this method returns a fresh <code>PathIterator</code>
645:             * object that traverses the <code>Shape</code> object geometry
646:             * independently from any other <code>PathIterator</code> objects in use
647:             * at the same time.
648:             * </p>
649:             * 
650:             * <p>
651:             * It is recommended, but not guaranteed, that objects implementing the
652:             * <code>Shape</code> interface isolate iterations that are in process
653:             * from any changes that might occur to the original object's geometry
654:             * during such iterations.
655:             * </p>
656:             * 
657:             * <p>
658:             * Before using a particular implementation of this interface in more than
659:             * one thread simultaneously, refer to its documentation to verify that it
660:             * guarantees that iterations are isolated from modifications.
661:             * </p>
662:             * 
663:             * @param at
664:             *            an optional <code>AffineTransform</code> to be applied to
665:             *            the coordinates as they are returned in the iteration, or
666:             *            <code>null</code> if untransformed coordinates are desired
667:             * @param flatness
668:             *            the maximum distance that the line segments used to
669:             *            approximate the curved segments are allowed to deviate from
670:             *            any point on the original curve
671:             * 
672:             * @return a new <code>PathIterator</code> that independently traverses
673:             *         the <code>Shape</code> geometry.
674:             */
675:            public PathIterator getPathIterator(AffineTransform at,
676:                    double flatness) {
677:                return getPathIterator(at);
678:            }
679:
680:            /**
681:             * Tests if the interior of the <code>Shape</code> intersects the interior
682:             * of a specified <code>Rectangle2D</code>. This method might
683:             * conservatively return <code>true</code> when:
684:             * 
685:             * <ul>
686:             * <li>there is a high probability that the <code>Rectangle2D</code> and
687:             * the <code>Shape</code> intersect, but</li>
688:             * <li>the calculations to accurately determine this intersection are
689:             * prohibitively expensive.</li>
690:             * </ul>
691:             * 
692:             * This means that this method might return <code>true</code> even though
693:             * the <code>Rectangle2D</code> does not intersect the <code>Shape</code>.
694:             * 
695:             * @param r
696:             *            the specified <code>Rectangle2D</code>
697:             * 
698:             * @return <code>true</code> if the interior of the <code>Shape</code>
699:             *         and the interior of the specified <code>Rectangle2D</code>
700:             *         intersect, or are both highly likely to intersect and
701:             *         intersection calculations would be too expensive to perform;
702:             *         <code>false</code> otherwise.
703:             * 
704:             * @see #intersects(double, double, double, double)
705:             */
706:            public boolean intersects(Rectangle2D r) {
707:                Geometry rect = rectangleToGeometry(r);
708:
709:                return geometry.intersects(rect);
710:            }
711:
712:            /**
713:             * Tests if the interior of the <code>Shape</code> intersects the interior
714:             * of a specified rectangular area. The rectangular area is considered to
715:             * intersect the <code>Shape</code> if any point is contained in both the
716:             * interior of the <code>Shape</code> and the specified rectangular area.
717:             * 
718:             * <p>
719:             * This method might conservatively return <code>true</code> when:
720:             * 
721:             * <ul>
722:             * <li>there is a high probability that the rectangular area and the
723:             * <code>Shape</code> intersect, but</li>
724:             * <li>the calculations to accurately determine this intersection are
725:             * prohibitively expensive.</li>
726:             * </ul>
727:             * 
728:             * This means that this method might return <code>true</code> even though
729:             * the rectangular area does not intersect the <code>Shape</code>. The
730:             * {@link java.awt.geom.Area Area}class can be used to perform more
731:             * accurate computations of geometric intersection for any
732:             * <code>Shape</code> object if a more precise answer is required.
733:             * </p>
734:             * 
735:             * @param x
736:             *            the coordinates of the specified rectangular area, x value
737:             * @param y
738:             *            the coordinates of the specified rectangular area, y value
739:             * @param w
740:             *            the width of the specified rectangular area
741:             * @param h
742:             *            the height of the specified rectangular area
743:             * 
744:             * @return <code>true</code> if the interior of the <code>Shape</code>
745:             *         and the interior of the rectangular area intersect, or are both
746:             *         highly likely to intersect and intersection calculations would be
747:             *         too expensive to perform; <code>false</code> otherwise.
748:             * 
749:             * @see java.awt.geom.Area
750:             */
751:            public boolean intersects(double x, double y, double w, double h) {
752:                Geometry rect = createRectangle(x, y, w, h);
753:
754:                return geometry.intersects(rect);
755:            }
756:
757:            /**
758:             * Converts the Rectangle2D passed as parameter in a jts Geometry object
759:             * 
760:             * @param r
761:             *            the rectangle to be converted
762:             * 
763:             * @return a geometry with the same vertices as the rectangle
764:             */
765:            private Geometry rectangleToGeometry(Rectangle2D r) {
766:                return createRectangle(r.getMinX(), r.getMinY(), r.getWidth(),
767:                        r.getHeight());
768:            }
769:
770:            /**
771:             * Creates a jts Geometry object representing a rectangle with the given
772:             * parameters
773:             * 
774:             * @param x
775:             *            left coordinate
776:             * @param y
777:             *            bottom coordinate
778:             * @param w
779:             *            width
780:             * @param h
781:             *            height
782:             * 
783:             * @return a rectangle with the specified position and size
784:             */
785:            private Geometry createRectangle(double x, double y, double w,
786:                    double h) {
787:                Coordinate[] coords = { new Coordinate(x, y),
788:                        new Coordinate(x, y + h), new Coordinate(x + w, y + h),
789:                        new Coordinate(x + w, y), new Coordinate(x, y) };
790:                LinearRing lr = geometry.getFactory().createLinearRing(coords);
791:
792:                return geometry.getFactory().createPolygon(lr, null);
793:            }
794:
795:            public MathTransform getMathTransform() {
796:                return mathTransform;
797:            }
798:
799:            public Geometry getGeometry() {
800:                return geometry;
801:            }
802:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.