001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002, 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;
009: * version 2.1 of the License.
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: */
017: package org.geotools.renderer.shape;
018:
019: import com.vividsolutions.jts.geom.Envelope;
020: import org.geotools.data.shapefile.shp.ShapeType;
021: import org.opengis.referencing.operation.MathTransform;
022: import org.opengis.referencing.operation.NoninvertibleTransformException;
023: import org.opengis.referencing.operation.TransformException;
024:
025: import java.awt.Rectangle;
026: import java.awt.geom.Point2D;
027: import java.nio.ByteBuffer;
028:
029: /**
030: * Useful methods common to all geometry handlers
031: *
032: * @author jeichar
033: *
034: * @since 2.1.x
035: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/shapefile-renderer/src/main/java/org/geotools/renderer/shape/GeometryHandlerUtilities.java $
036: */
037: public class GeometryHandlerUtilities {
038: /**
039: * DOCUMENT ME!
040: *
041: * @param buffer
042: *
043: * @return
044: */
045: public static Envelope readBounds(ByteBuffer buffer) {
046: double[] tmpbbox = new double[4];
047: tmpbbox[0] = buffer.getDouble();
048: tmpbbox[1] = buffer.getDouble();
049: tmpbbox[2] = buffer.getDouble();
050: tmpbbox[3] = buffer.getDouble();
051:
052: Envelope geomBBox = new Envelope(tmpbbox[0], tmpbbox[2],
053: tmpbbox[1], tmpbbox[3]);
054:
055: return geomBBox;
056: }
057:
058: public static void transform(ShapeType type, MathTransform mt,
059: double[] src, double[] dest) throws TransformException {
060: boolean startPointTransformed = true;
061:
062: for (int i = 0; i < dest.length; i += 2) {
063: try {
064: mt.transform(src, i, dest, i, 1);
065:
066: if (!startPointTransformed) {
067: startPointTransformed = true;
068:
069: for (int j = 0; j < i; j += 2) {
070: dest[j] = src[i];
071: dest[j + 1] = src[i + 1];
072: }
073: }
074: } catch (TransformException e) {
075: if (i == 0) {
076: startPointTransformed = false;
077: } else if (startPointTransformed) {
078: if ((i == (dest.length - 2))
079: && ((type == ShapeType.POLYGON)
080: || (type == ShapeType.POLYGONZ) || (type == ShapeType.POLYGONM))) {
081: dest[i] = dest[0];
082: dest[i + 1] = dest[1];
083: } else {
084: dest[i] = dest[i - 2];
085: dest[i + 1] = dest[i - 1];
086: }
087: }
088: }
089: }
090:
091: if (!startPointTransformed) {
092: throw new TransformException(
093: "Unable to transform any of the points in the shape");
094: }
095: }
096:
097: /**
098: * calculates the distance between the centers of the two pixels at x,y
099: *
100: * @param mt the transform to use to calculate the centers.
101: * @param x the x coordinate at which to make the calculation
102: * @param y the y coordinate at which to make the calculation
103: * @return a point whose x coord it the distance in world coordinates between x-0.5 and x+0.5 and the y is the span
104: * around the y point.
105: * @throws NoninvertibleTransformException
106: * @throws TransformException
107: */
108: public static Point2D calculateSpan(MathTransform mt, int x, int y)
109: throws NoninvertibleTransformException, TransformException {
110: MathTransform screenToWorld = mt.inverse();
111: double[] original = new double[] { x - 0.5, y - 0.5, x + 0.5,
112: y + 0.5 };
113: double[] coords = new double[4];
114: screenToWorld.transform(original, 0, coords, 0, 2);
115:
116: Point2D span = new Point2D.Double(Math.abs(coords[0]
117: - coords[2]), Math.abs(coords[1] - coords[3]));
118:
119: return span;
120: }
121:
122: public static ScreenMap calculateScreenSize(Rectangle screenSize,
123: boolean hasOpacity) throws TransformException,
124: NoninvertibleTransformException {
125: if (hasOpacity) {
126: // if opacity then this short optimization cannot be used
127: // so return a screenMap that always says to write there.
128: return new ScreenMap(0, 0, 0, 0) {
129: public boolean get(int x, int y) {
130: return false;
131: }
132:
133: public void set(int x, int y, boolean value) {
134: return;
135: }
136: };
137: }
138:
139: return new ScreenMap(screenSize.x, screenSize.y,
140: screenSize.width + 1, screenSize.height + 1);
141: }
142: }
|