Worldwind public release 0.2.1
[worldwind-tracker.git] / gov / nasa / worldwind / geom / SurfacePolygon.java
blob524182c735e8aaafcf02450ae5896d466d52aaff
1 /*
2 Copyright (C) 2001, 2006 United States Government
3 as represented by the Administrator of the
4 National Aeronautics and Space Administration.
5 All Rights Reserved.
6 */
7 package gov.nasa.worldwind.geom;
9 import java.awt.*;
10 import java.awt.geom.*;
11 import java.awt.image.*;
12 import java.util.*;
14 /**
15 * @author tag
16 * @version $Id: SurfacePolygon.java 2133 2007-06-23 02:08:28Z patrickmurris $
18 public class SurfacePolygon extends SurfaceShape
21 /**
22 * A Renderable polygon shape defined by a list of LatLon
24 * @param positions the list of LatLon positions that makes the polygon
25 * @param color the interior fill color
26 * @param borderColor the border color
28 public SurfacePolygon(Iterable<LatLon> positions, Color color, Color borderColor)
30 super(positions, color, borderColor);
33 /**
34 * A Renderable polygon shape defined by a list of LatLon
36 * @param positions the list of LatLon positions that makes the polygon
38 public SurfacePolygon(Iterable<LatLon> positions)
40 super(positions, null, null);
43 /**
44 * Draw all or part of the shape that intersects a given Sector into the given BufferedImage
46 protected final BufferedImage drawShape(BufferedImage image, Sector sector)
48 double minLat = sector.getMinLatitude().getDegrees();
49 double minLon = sector.getMinLongitude().getDegrees();
50 double dLat = sector.getDeltaLatDegrees();
51 double dLon = sector.getDeltaLonDegrees();
53 // Note : WWJ-36 negate latScale to define path upside-down
54 // (will be drawn with a mirror transform - this gets paint patterns right)
55 double latScale = dLat > 0 ? -image.getHeight() / dLat : 0;
56 double lonScale = dLon > 0 ? image.getWidth() / dLon : 0;
58 // If we may cross +-180 degrees longitude, then offset
59 // all longitudes 180 degrees the other way
60 double lonOffset = 0;
61 if (sector.getMaxLongitude().getDegrees() == 180 && dLon < 180)
62 lonOffset = -180;
63 if (sector.getMinLongitude().getDegrees() == -180 && dLon < 180)
64 lonOffset = 180;
66 GeneralPath path = new GeneralPath();
68 Iterator<LatLon> positions = this.getPositions().iterator();
69 if (!positions.hasNext())
70 return image;
72 // Start position
73 LatLon pos = this.computeDrawLatLon(positions.next(), sector, lonOffset);
74 path.moveTo(
75 (float) (lonScale * (pos.getLongitude().getDegrees() - minLon - lonOffset)),
76 (float) (latScale * (pos.getLatitude().getDegrees() - minLat)));
78 while (positions.hasNext())
80 // Next position
81 LatLon posNext = this.computeDrawLatLon(positions.next(), sector, lonOffset);
82 // Compute number of necessary steps
83 int numIntervals = (int) Math.max(1d,
84 this.getNumEdgeIntervalsPerDegree() *
85 LatLon.sphericalDistance(pos, posNext).degrees);
86 double delta = 1d / numIntervals;
87 // Draw segments to next position
88 for (int i = 1; i < numIntervals; i++)
90 // In between steps
91 LatLon p = LatLon.interpolate(i * delta, pos, posNext);
92 path.lineTo(
93 (float) (lonScale * (p.getLongitude().getDegrees() - minLon - lonOffset)),
94 (float) (latScale * (p.getLatitude().getDegrees() - minLat)));
97 // Set the last point directly to avoid any round-off error in the iteration above.
98 path.lineTo(
99 (float) (lonScale * (posNext.getLongitude().getDegrees() - minLon - lonOffset)),
100 (float) (latScale * (posNext.getLatitude().getDegrees() - minLat)));
101 // Next
103 pos = posNext;
106 Graphics2D g2 = image.createGraphics();
107 // Set mirror Y transform
108 g2.setTransform(AffineTransform.getScaleInstance(1, -1));
109 // Set antiliasing hint
110 if (this.isAntiAlias())
111 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
112 // Draw interior
113 if (this.isDrawInterior())
115 g2.setPaint(this.getPaint());
116 g2.fill(path);
118 // Draw border
119 if (this.isDrawBorder())
121 g2.setPaint(this.getBorderColor());
122 g2.setStroke(this.getStroke());
123 g2.draw(path);
126 return image;
130 * Returns the drawing LatLon relative to a given Sector and a longitude offset Can go beyond +-180 degrees
131 * longitude if the offset is zero
132 * @param pos the real LatLon
133 * @param sector the drawing Sector
134 * @param lonOffset the current longitude offset in degrees
135 * @return the appropiate drawing LatLon
137 private LatLon computeDrawLatLon(LatLon pos, Sector sector, double lonOffset)
139 int directionOffset;
140 directionOffset = sector.getMaxLongitude().degrees - pos.getLongitude().getDegrees() > 180 ?
141 360 : 0;
142 directionOffset = pos.getLongitude().getDegrees() - sector.getMinLongitude().getDegrees() > 180 ?
143 -360 : directionOffset;
144 return LatLon.fromDegrees(pos.getLatitude().getDegrees(),
145 pos.getLongitude().getDegrees() + directionOffset + lonOffset);