view gnv-artifacts/src/main/java/de/intevation/gnv/utils/IndexBuffer.java @ 522:c896282c2601

Issue 156 solved. Added width, height and points as parameter to svg and pdf output mode. Width and height have an effact on the width and height of the export, points is a boolean property which enables/disables the drawing of data points. gnv-artifacts/trunk@616 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Mon, 25 Jan 2010 09:18:31 +0000
parents 555483213f78
children b1f5f2a8840f
line wrap: on
line source
package de.intevation.gnv.utils;

import java.awt.geom.Point2D;

import java.awt.Point;

import java.util.List;

/**
 * Create buffers around integer pairs (i_1..n), j_1..n).
 *
 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
 */
public class IndexBuffer
{
    public static final double EPSILON = 1e-6d;
    public static final double OFFSET  = 1.0d;

    public static final String I_COLUMN = "IPOSITION";
    public static final String J_COLUMN = "JPOSITION";

    public static final class Segment {

        private Segment next;

        private Point2D.Double n;
        private double         d1;
        private double         d2;

        private int iMin;
        private int iMax;

        private int jMin;
        private int jMax;

        public Segment(Point a, Point b, Segment next) {

            this.next = next;

            iMin = Math.min(a.x, b.x)-1;
            iMax = Math.max(a.x, b.x)+1;

            jMin = Math.min(a.y, b.y)-1;
            jMax = Math.max(a.y, b.y)+1;

            if (a.x > b.x) {
                Point p = a; a = b; b = p;
            }

            Point2D.Double p1, p2, p3;

            if (a.y < b.y) {
                p1 = new Point2D.Double(a.x -     OFFSET, a.y + 1 + OFFSET);
                p2 = new Point2D.Double(b.x -     OFFSET, b.y + 1 + OFFSET);
                p3 = new Point2D.Double(a.x + 1 + OFFSET, a.y     - OFFSET);
            }
            else {
                p1 = new Point2D.Double(a.x + 1 + OFFSET, a.y + 1 + OFFSET);
                p2 = new Point2D.Double(b.x + 1 + OFFSET, b.y + 1 + OFFSET);
                p3 = new Point2D.Double(b.x     - OFFSET, b.y     - OFFSET);
            }

            n = normalize(orthogonal(sub(p1, p2)));

            d1 = dot(n, p1);
            d2 = dot(n, p3);

            if (d1 > d2) {
                double d = d1;
                d1 = d2;
                d2 = d;
            }
        }

        public boolean check(int i, int j) {
            if (i < iMin || i > iMax || j < jMin || j > jMax) {
                return false;
            }
            double v = dot(n, i, j);
            return v >= d1 && v <= d2;
        }

        public void toWhereClause(StringBuilder sb, String iColumn, String jColumn) {
            sb.append('(')
              .append(iColumn).append(" >= ").append(iMin).append(" AND ")
              .append(iColumn).append(" <= ").append(iMax).append(" AND ")
              .append(jColumn).append(" >= ").append(jMin).append(" AND ")
              .append(jColumn).append(" <= ").append(jMax).append(" AND (")
              .append(n.x).append('*').append(iColumn).append(" + ")
              .append(n.y).append('*').append(jColumn)
              .append(") BETWEEN ").append(d1).append(" AND ").append(d2).append(')');
        }
    } // class Segment

    protected Segment head;

    protected String iColumn;
    protected String jColumn;

    public IndexBuffer(List<? extends Point> points) {
        this(points, I_COLUMN, J_COLUMN);
    }

    public IndexBuffer(List<? extends Point> points, String iColumn, String jColumn) {
        this.iColumn = iColumn;
        this.jColumn = jColumn;

        for (int i = 1, N = points.size(); i < N; ++i) {
            Point p1 = (Point)points.get(i-1);
            Point p2 = (Point)points.get(i);
            head = new Segment(p1, p2, head);
        }
    }

    public boolean check(int i, int j) {

        Segment current = head;
        while (current != null) {
            if (current.check(i, j)) {
                return true;
            }
            current = current.next;
        }
        return false;
    }

    public String toWhereClause() {

        StringBuilder sb = new StringBuilder();

        Segment current = head;

        while (current != null) {
            if (current != head) {
                sb.append(" OR ");
            }
            current.toWhereClause(sb, iColumn, jColumn);
            current = current.next;
        }

        return sb.toString();
    }

    public static Point2D.Double sub(Point2D.Double p1, Point2D.Double p2) {
        return new Point2D.Double(p1.x - p2.x, p1.y - p2.y);
    }

    public static final double dot(Point2D.Double p1, Point2D.Double p2) {
        return p1.x*p2.x + p1.y*p2.y;
    }

    public static final double dot(Point2D.Double p1, double x, double y) {
        return p1.x*x + p1.y*y;
    }

    public static final Point2D.Double scale(Point2D.Double p, double s) {
        return new Point2D.Double(s*p.x, s*p.y);
    }

    public static final Point2D.Double normalize(Point2D.Double p) {
        double len2 = Math.sqrt(dot(p, p));
        return len2 > EPSILON ? scale(p, 1d/len2) : p;
    }

    public static final Point2D.Double orthogonal(Point2D.Double p) {
        return new Point2D.Double(p.y, -p.x);
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:

http://dive4elements.wald.intevation.org