forked from geodmms/xdgnjobs

Dennis Kao
2014-01-15 94ae08701bbd7585a0b7e5a92d1975965a503c03
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ArcElement.java
@@ -5,6 +5,7 @@
import org.apache.log4j.Logger;
import com.vividsolutions.jts.algorithm.Angle;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
@@ -16,33 +17,28 @@
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/26 ¤U¤È 06:41:45
 * @since 2006/5/26 �U�� 06:41:45
 */
public class ArcElement extends Element implements GeometryConverter
{
public class ArcElement extends Element implements GeometryConverter {
    private static final Logger logger = Logger.getLogger(ArcElement.class);
    public ArcElement(byte[] raw)
    {
    ArcElement(byte[] raw) {
        super(raw);
    }
    public double getStartAngle()
    {
    public double getStartAngle() {
        int angle = (raw[18] & 0x0000ffff) << 16 | (raw[19] & 0x0000ffff);
        return DgnUtility.converIntToRotation(angle);
    }
    public void setStartAngle(double value)
    {
    public void setStartAngle(double value) {
        int angle = DgnUtility.converRotatioToInt(value);
        raw[18] = (short) (angle >>> 16 & 0x0000ffff);
        raw[19] = (short) (angle & 0x0000ffff);
    }
    public double getSweepAngle()
    {
    public double getSweepAngle() {
        int angle = (raw[20] & 0x0000ffff) << 16 | (raw[21] & 0x0000ffff);
        if (angle < 0)
            angle = -1 * (angle & 0x7fffffff);
@@ -50,11 +46,9 @@
        return DgnUtility.converIntToRotation(angle);
    }
    public void setSweepAngle(double value)
    {
    public void setSweepAngle(double value) {
        int angle = DgnUtility.converRotatioToInt(value);
        if (angle < 0)
        {
        if (angle < 0) {
            angle &= 0x7fffffff;
            angle |= 0x80000000;
        }
@@ -63,8 +57,7 @@
        raw[21] = (short) (angle & 0x0000ffff);
    }
    public double getPrimary()
    {
    public double getPrimary() {
        rawBuffer.position(22 * 2);
        ByteOrder bo = rawBuffer.order();
        rawBuffer.order(ByteOrder.BIG_ENDIAN);
@@ -74,16 +67,14 @@
        return DgnUtility.convertDGNToIEEEDouble(primary) / 1000.0;
    }
    public void setPrimary(double value)
    {
    public void setPrimary(double value) {
        double temp = value * 1000.0;
        short[] primary = DgnUtility.convertIEEEDoubleToDGN(temp);
        System.arraycopy(primary, 0, raw, 22, 4);
    }
    public double getSecondary()
    {
    public double getSecondary() {
        rawBuffer.position(26 * 2);
        ByteOrder bo = rawBuffer.order();
        rawBuffer.order(ByteOrder.BIG_ENDIAN);
@@ -93,32 +84,28 @@
        return DgnUtility.convertDGNToIEEEDouble(secondary) / 1000.0;
    }
    public void setSecondary(double value)
    {
    public void setSecondary(double value) {
        double temp = value * 1000.0;
        short[] secondary = DgnUtility.convertIEEEDoubleToDGN(temp);
        System.arraycopy(secondary, 0, raw, 26, 4);
    }
    public double getRotationAngle()
    {
    public double getRotationAngle() {
        int rotation = (raw[30] << 16 & 0xffff0000);
        rotation |= raw[31] & 0x0000ffff;
        return DgnUtility.converIntToRotation(rotation);
    }
    public void setRotationAngle(double value)
    {
    public void setRotationAngle(double value) {
        int angle = DgnUtility.converRotatioToInt(value);
        raw[30] = (short) (angle >> 16 & 0x0000ffff);
        raw[31] = (short) (angle & 0x0000ffff);
    }
    public Coordinate getOrigin()
    {
    public Coordinate getOrigin() {
        rawBuffer.position(32 * 2);
        ByteOrder bo = rawBuffer.order();
        rawBuffer.order(ByteOrder.BIG_ENDIAN);
@@ -135,8 +122,7 @@
        return new Coordinate(dx, dy);
    }
    public void setOrigin(Coordinate value)
    {
    public void setOrigin(Coordinate value) {
        double temp = DgnUtility.converCoordToUnit(value.x);
        short[] x = DgnUtility.convertIEEEDoubleToDGN(temp);
@@ -148,8 +134,7 @@
        System.arraycopy(y, 0, raw, 36, 4);
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
    public Geometry toGeometry(GeometryFactory factory) {
        double sweep = getSweepAngle();
        double temp = Math.abs(sweep);
        temp /= 4;
@@ -157,74 +142,73 @@
        return factory.createLineString(convertToLineString(pts));
    }
    private Coordinate[] convertToLineString(int pts)
    {
        ArrayList<Coordinate> result = new ArrayList<Coordinate>();
        double beta = DgnUtility.converRotationToRadian(-getRotationAngle());
        double startAngle = getStartAngle();
        double sweepAngle = getSweepAngle();
        double endAngle = startAngle + sweepAngle;
        double steps = sweepAngle / pts;
        double current;
        if (sweepAngle < 0)
        {
            for (current = startAngle; current > endAngle; current += steps)
            {
                Coordinate pt = computePointOnArcByAngle(beta, current);
                result.add(pt);
            }
    private double validAngle(double value) {
        if (value < 0.0) value += 360.0;
        else if (value > 360.0) value -= 360.0;
        } else
        {
            for (current = startAngle; current < endAngle; current += steps)
            {
                Coordinate pt = computePointOnArcByAngle(beta, current);
                result.add(pt);
            }
        return value;
    }
    private Coordinate[] convertToLineString(int pts) {
        ArrayList<Coordinate> result = new ArrayList<Coordinate>();
        double rotation = validAngle(360 - getRotationAngle());
        double beta = Angle.toRadians(-rotation);
        double startAngle = validAngle(getStartAngle());
        double sweepAngle = Math.abs(getSweepAngle());
        boolean clockwise = (getSweepAngle() < 0.0);
        double endAngle = validAngle(startAngle + getSweepAngle());
        double steps = sweepAngle / pts;
        double current;
        for (int i = 0; i < pts; i++) {
            if (clockwise)
                current = startAngle - i * steps;
            else
                current = startAngle + i * steps;
            current = validAngle(current);
            Coordinate pt = computePointOnArcByAngle(beta, current);
            result.add(pt);
        }
        Coordinate pt = computePointOnArcByAngle(beta, endAngle);
        current = validAngle(endAngle);
        Coordinate pt = computePointOnArcByAngle(beta, current);
        result.add(pt);
        return result.toArray(new Coordinate[result.size()]);
    }
    private Coordinate computePointOnArcByAngle(double beta, double current)
    {
    private Coordinate computePointOnArcByAngle(double beta, double angle) {
        double sinbeta = Math.sin(beta);
        double cosbeta = Math.cos(beta);
        Coordinate pt = new Coordinate();
        double alpha = DgnUtility.converRotationToRadian(current);
        double alpha = Angle.toRadians(angle);
        double sinalpha = Math.sin(alpha);
        double cosalpha = Math.cos(alpha);
        Coordinate pt = new Coordinate();
        pt.x = getOrigin().x + (getPrimary() * cosalpha * cosbeta -
                getSecondary() * sinalpha * sinbeta);
            getSecondary() * sinalpha * sinbeta);
        pt.y = getOrigin().y + (getPrimary() * cosalpha * sinbeta +
                getSecondary() * sinalpha * cosbeta);
            getSecondary() * sinalpha * cosbeta);
        return pt;
    }
    public static class ElementHandler extends Element.ElementHandler
    {
    public static class ElementHandler extends Element.ElementHandler {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
        public ElementHandler() {
            super(ElementType.ARC);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
        public static IElementHandler getInstance() {
            if (instance == null) {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
        protected Element createElement(byte[] raw) {
            return new ArcElement(raw);
        }
    }