001: package net.refractions.udig.render.gridcoverage.basic;
002:
003: import java.awt.AlphaComposite;
004: import java.awt.Composite;
005: import java.awt.Graphics2D;
006: import java.awt.Rectangle;
007: import java.awt.RenderingHints;
008: import java.awt.geom.AffineTransform;
009:
010: import net.refractions.udig.project.internal.ProjectPlugin;
011: import net.refractions.udig.project.internal.StyleBlackboard;
012: import net.refractions.udig.project.render.IRenderContext;
013:
014: import org.geotools.coverage.grid.GridGeometry2D;
015: import org.geotools.coverage.processing.DefaultProcessor;
016: import org.geotools.factory.Hints;
017: import org.geotools.filter.Expression;
018: import org.geotools.renderer.lite.GridCoverageRenderer;
019: import org.geotools.renderer.lite.RendererUtilities;
020: import org.geotools.styling.RasterSymbolizer;
021: import org.geotools.styling.Rule;
022: import org.geotools.styling.Style;
023: import org.opengis.coverage.grid.GridCoverage;
024: import org.opengis.parameter.ParameterValueGroup;
025: import org.opengis.referencing.crs.CoordinateReferenceSystem;
026:
027: import com.vividsolutions.jts.geom.Envelope;
028:
029: public class GridCoverageRendererUtils {
030:
031: public static GridCoverageRenderer createRenderer(
032: GridCoverage coverage, CoordinateReferenceSystem targetCRS) {
033: CoordinateReferenceSystem coverageCRS = coverage
034: .getCoordinateReferenceSystem();
035: // Hack for 2.2.x GridCoverage (our custom reprojection code)
036: //TODO: remove for GeoTools 2.3.x
037: if (coverageCRS != null && targetCRS != null
038: && !coverageCRS.equals(targetCRS)) {
039: coverage = projectTo(coverage, targetCRS, null);
040: }
041: return new GridCoverageRenderer(coverage, targetCRS);
042: }
043:
044: /**
045: * @deprecated soon to be private
046: * @param coverage
047: * @param crs
048: * @param geometry
049: * @return
050: */
051: public static GridCoverage projectTo(final GridCoverage coverage,
052: final CoordinateReferenceSystem crs,
053: final GridGeometry2D geometry) {
054: RenderingHints hints = new RenderingHints(
055: Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);
056: DefaultProcessor processor = new DefaultProcessor(hints);
057:
058: ParameterValueGroup params = processor
059: .getOperation("Resample").getParameters(); //$NON-NLS-1$
060: params.parameter("Source").setValue(coverage); //$NON-NLS-1$
061: if (geometry != null) {
062: params.parameter("GridGeometry").setValue(geometry); //$NON-NLS-1$
063: }
064: if (crs != null) {
065: params.parameter("CoordinateReferenceSystem").setValue(crs); //$NON-NLS-1$
066: }
067: return (GridCoverage) processor.doOperation(params);
068: }
069:
070: public static void paintGraphic(GridCoverageRenderer renderer,
071: Graphics2D graphics, State state) {
072: // setup composite
073: Composite oldComposite = graphics.getComposite();
074: graphics.setComposite(AlphaComposite.getInstance(
075: AlphaComposite.SRC_OVER, state.opacity));
076:
077: // setup affine transform for on screen rendering
078: Rectangle displayArea = state.displayArea;
079:
080: AffineTransform at = RendererUtilities.worldToScreenTransform(
081: state.bounds, displayArea);
082: AffineTransform tempTransform = graphics.getTransform();
083: AffineTransform atg = new AffineTransform(tempTransform);
084: atg.concatenate(at);
085: graphics.setTransform(atg);
086:
087: renderer.paint(graphics);
088:
089: // reset previous configuration
090: graphics.setComposite(oldComposite);
091: graphics.setTransform(tempTransform);
092: }
093:
094: /**
095: * Extract symbolizer parameters from the style blackboard
096: */
097: public static State getRenderState(IRenderContext context) {
098: StyleBlackboard styleBlackboard = (StyleBlackboard) context
099: .getLayer().getStyleBlackboard();
100: Style style = (Style) styleBlackboard.lookup(Style.class);
101: double minScale = Double.MIN_VALUE;
102: double maxScale = Double.MAX_VALUE;
103: float opacity = 1.0f;
104: if (style != null) {
105: try {
106: Rule rule = style.getFeatureTypeStyles()[0].getRules()[0];
107: minScale = rule.getMinScaleDenominator();
108: maxScale = rule.getMaxScaleDenominator();
109: if (rule.getSymbolizers()[0] instanceof RasterSymbolizer) {
110: RasterSymbolizer rs = (RasterSymbolizer) rule
111: .getSymbolizers()[0];
112: opacity = getOpacity(rs);
113: }
114:
115: } catch (Exception e) {
116: ProjectPlugin.getPlugin().log(e);
117: }
118: } else {
119: opacity = 1;
120: minScale = 0;
121: maxScale = Double.MAX_VALUE;
122: }
123:
124: Rectangle displayArea = new Rectangle(context.getMapDisplay()
125: .getWidth(), context.getMapDisplay().getHeight());
126:
127: return new State(context, context.getViewportModel()
128: .getBounds(), displayArea, opacity, minScale, maxScale);
129: }
130:
131: public static float getOpacity(RasterSymbolizer sym) {
132: float alpha = 1.0f;
133: Expression exp = sym.getOpacity();
134: if (exp == null)
135: return alpha;
136: Object obj = exp.getValue(null);
137: if (obj == null)
138: return alpha;
139: Number num = null;
140: if (obj instanceof Number)
141: num = (Number) obj;
142: if (num == null)
143: return alpha;
144: return num.floatValue();
145: }
146:
147: public static Rectangle getPaintArea(Envelope imageBounds,
148: Envelope mapBounds, Rectangle mapRect) {
149: if (imageBounds.equals(mapBounds)) {
150: return mapRect;
151: }
152: if (!mapBounds.intersects(imageBounds)) {
153: //don't bother, there is nothing to draw
154: return new Rectangle(0, 0, 0, 0);
155: }
156: int w = 0;
157: int h = 0;
158: int x = 0;
159: int y = 0;
160: //cases:
161: // 1. Map is completely contained inside the image
162: // 2. Image is completely contained inside the map
163: // 3. Map shows the edge of the image
164: if (imageBounds.contains(mapBounds)) { //case 1
165: return mapRect;
166: } else if (mapBounds.contains(imageBounds)) { //case 2
167: double horizScale = imageBounds.getWidth()
168: / mapBounds.getWidth();
169: double vertScale = imageBounds.getHeight()
170: / mapBounds.getHeight();
171: double horizOffset = imageBounds.getMinX()
172: - mapBounds.getMinX();
173: double vertOffset = imageBounds.getMinY()
174: - mapBounds.getMinY();
175: w = (int) (mapRect.width * horizScale);
176: h = (int) (mapRect.height * vertScale);
177: x = (int) (mapRect.x + (horizOffset * mapRect.width / mapBounds
178: .getWidth()));
179: y = (int) (mapRect.y + mapRect.getMaxY() - h - (vertOffset
180: * mapRect.height / mapBounds.getHeight()));
181: return new Rectangle(x, y, w, h);
182: } else { //case 3
183: //image boundary!
184: return mapRect;
185: }
186: }
187:
188: }
|